Merge git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-2.6-dm
[linux-2.6] / arch / x86 / boot / tty.c
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  * Very simple screen I/O
13  * XXX: Probably should add very simple serial I/O?
14  */
15
16 #include "boot.h"
17
18 /*
19  * These functions are in .inittext so they can be used to signal
20  * error during initialization.
21  */
22
23 void __attribute__((section(".inittext"))) putchar(int ch)
24 {
25         unsigned char c = ch;
26
27         if (c == '\n')
28                 putchar('\r');  /* \n -> \r\n */
29
30         /* int $0x10 is known to have bugs involving touching registers
31            it shouldn't.  Be extra conservative... */
32         asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
33                      : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
34 }
35
36 void __attribute__((section(".inittext"))) puts(const char *str)
37 {
38         int n = 0;
39         while (*str) {
40                 putchar(*str++);
41                 n++;
42         }
43 }
44
45 /*
46  * Read the CMOS clock through the BIOS, and return the
47  * seconds in BCD.
48  */
49
50 static u8 gettime(void)
51 {
52         u16 ax = 0x0200;
53         u16 cx, dx;
54
55         asm volatile("int $0x1a"
56                      : "+a" (ax), "=c" (cx), "=d" (dx)
57                      : : "ebx", "esi", "edi");
58
59         return dx >> 8;
60 }
61
62 /*
63  * Read from the keyboard
64  */
65 int getchar(void)
66 {
67         u16 ax = 0;
68         asm volatile("int $0x16" : "+a" (ax));
69
70         return ax & 0xff;
71 }
72
73 static int kbd_pending(void)
74 {
75         u8 pending;
76         asm volatile("int $0x16; setnz %0"
77                      : "=rm" (pending)
78                      : "a" (0x0100));
79         return pending;
80 }
81
82 void kbd_flush(void)
83 {
84         for (;;) {
85                 if (!kbd_pending())
86                         break;
87                 getchar();
88         }
89 }
90
91 int getchar_timeout(void)
92 {
93         int cnt = 30;
94         int t0, t1;
95
96         t0 = gettime();
97
98         while (cnt) {
99                 if (kbd_pending())
100                         return getchar();
101
102                 t1 = gettime();
103                 if (t0 != t1) {
104                         cnt--;
105                         t0 = t1;
106                 }
107         }
108
109         return 0;               /* Timeout! */
110 }