Merge branch 'for-2.6.28' of git://linux-nfs.org/~bfields/linux
[linux-2.6-block.git] / arch / x86 / boot / tty.c
CommitLineData
1543610a
PA
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/*
1543610a
PA
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
23void __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... */
8c027ae2 32 asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
1543610a
PA
33 : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
34}
35
36void __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
50static u8 gettime(void)
51{
52 u16 ax = 0x0200;
53 u16 cx, dx;
54
b015124e
PA
55 asm volatile("int $0x1a"
56 : "+a" (ax), "=c" (cx), "=d" (dx)
57 : : "ebx", "esi", "edi");
1543610a
PA
58
59 return dx >> 8;
60}
61
62/*
63 * Read from the keyboard
64 */
65int getchar(void)
66{
67 u16 ax = 0;
b015124e 68 asm volatile("int $0x16" : "+a" (ax));
1543610a
PA
69
70 return ax & 0xff;
71}
72
73static int kbd_pending(void)
74{
75 u8 pending;
b015124e 76 asm volatile("int $0x16; setnz %0"
5cf02b7b 77 : "=qm" (pending)
b015124e 78 : "a" (0x0100));
1543610a
PA
79 return pending;
80}
81
82void kbd_flush(void)
83{
84 for (;;) {
85 if (!kbd_pending())
86 break;
87 getchar();
88 }
89}
90
91int 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}