aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/boot/tty.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-07-11 15:18:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-12 13:55:55 -0400
commit1543610ad79ac4cc61c26f8a29c84e4229faa9a3 (patch)
treec7aac5c00be2e18eb2e966c3f12e7a8b69d00eb7 /arch/i386/boot/tty.c
parente44c22f65f96217692e1a915032fbe7d22236751 (diff)
Console-writing code for the new x86 setup code
This implements writing text to the console, including printf(). Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/boot/tty.c')
-rw-r--r--arch/i386/boot/tty.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/arch/i386/boot/tty.c b/arch/i386/boot/tty.c
new file mode 100644
index 000000000000..a8db78736b02
--- /dev/null
+++ b/arch/i386/boot/tty.c
@@ -0,0 +1,112 @@
1/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
5 *
6 * This file is part of the Linux kernel, and is made available under
7 * the terms of the GNU General Public License version 2.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * arch/i386/boot/tty.c
13 *
14 * Very simple screen I/O
15 * XXX: Probably should add very simple serial I/O?
16 */
17
18#include "boot.h"
19
20/*
21 * These functions are in .inittext so they can be used to signal
22 * error during initialization.
23 */
24
25void __attribute__((section(".inittext"))) putchar(int ch)
26{
27 unsigned char c = ch;
28
29 if (c == '\n')
30 putchar('\r'); /* \n -> \r\n */
31
32 /* int $0x10 is known to have bugs involving touching registers
33 it shouldn't. Be extra conservative... */
34 asm volatile("pushal; int $0x10; popal"
35 : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
36}
37
38void __attribute__((section(".inittext"))) puts(const char *str)
39{
40 int n = 0;
41 while (*str) {
42 putchar(*str++);
43 n++;
44 }
45}
46
47/*
48 * Read the CMOS clock through the BIOS, and return the
49 * seconds in BCD.
50 */
51
52static u8 gettime(void)
53{
54 u16 ax = 0x0200;
55 u16 cx, dx;
56
57 asm("int $0x1a"
58 : "+a" (ax), "=c" (cx), "=d" (dx)
59 : : "ebx", "esi", "edi");
60
61 return dx >> 8;
62}
63
64/*
65 * Read from the keyboard
66 */
67int getchar(void)
68{
69 u16 ax = 0;
70 asm("int $0x16" : "+a" (ax));
71
72 return ax & 0xff;
73}
74
75static int kbd_pending(void)
76{
77 u8 pending;
78 asm("int $0x16; setnz %0"
79 : "=rm" (pending)
80 : "a" (0x0100));
81 return pending;
82}
83
84void kbd_flush(void)
85{
86 for (;;) {
87 if (!kbd_pending())
88 break;
89 getchar();
90 }
91}
92
93int getchar_timeout(void)
94{
95 int cnt = 30;
96 int t0, t1;
97
98 t0 = gettime();
99
100 while (cnt) {
101 if (kbd_pending())
102 return getchar();
103
104 t1 = gettime();
105 if (t0 != t1) {
106 cnt--;
107 t0 = t1;
108 }
109 }
110
111 return 0; /* Timeout! */
112}