Commit | Line | Data |
---|---|---|
1543610a PA |
1 | /* -*- linux-c -*- ------------------------------------------------------- * |
2 | * | |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | |
df7699c5 | 5 | * Copyright 2009 Intel Corporation; author H. Peter Anvin |
1543610a PA |
6 | * |
7 | * This file is part of the Linux kernel, and is made available under | |
8 | * the terms of the GNU General Public License version 2. | |
9 | * | |
10 | * ----------------------------------------------------------------------- */ | |
11 | ||
12 | /* | |
1543610a PA |
13 | * Very simple screen I/O |
14 | * XXX: Probably should add very simple serial I/O? | |
15 | */ | |
16 | ||
17 | #include "boot.h" | |
18 | ||
19 | /* | |
20 | * These functions are in .inittext so they can be used to signal | |
21 | * error during initialization. | |
22 | */ | |
23 | ||
24 | void __attribute__((section(".inittext"))) putchar(int ch) | |
25 | { | |
df7699c5 | 26 | struct biosregs ireg; |
1543610a | 27 | |
df7699c5 | 28 | if (ch == '\n') |
1543610a PA |
29 | putchar('\r'); /* \n -> \r\n */ |
30 | ||
df7699c5 PA |
31 | initregs(&ireg); |
32 | ireg.bx = 0x0007; | |
33 | ireg.cx = 0x0001; | |
34 | ireg.ah = 0x0e; | |
35 | ireg.al = ch; | |
36 | intcall(0x10, &ireg, NULL); | |
1543610a PA |
37 | } |
38 | ||
39 | void __attribute__((section(".inittext"))) puts(const char *str) | |
40 | { | |
df7699c5 | 41 | while (*str) |
1543610a | 42 | putchar(*str++); |
1543610a PA |
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 | { | |
df7699c5 | 52 | struct biosregs ireg, oreg; |
1543610a | 53 | |
df7699c5 PA |
54 | initregs(&ireg); |
55 | ireg.ah = 0x02; | |
56 | intcall(0x1a, &ireg, &oreg); | |
1543610a | 57 | |
df7699c5 | 58 | return oreg.dh; |
1543610a PA |
59 | } |
60 | ||
61 | /* | |
62 | * Read from the keyboard | |
63 | */ | |
64 | int getchar(void) | |
65 | { | |
df7699c5 PA |
66 | struct biosregs ireg, oreg; |
67 | ||
68 | initregs(&ireg); | |
69 | /* ireg.ah = 0x00; */ | |
70 | intcall(0x16, &ireg, &oreg); | |
1543610a | 71 | |
df7699c5 | 72 | return oreg.al; |
1543610a PA |
73 | } |
74 | ||
75 | static int kbd_pending(void) | |
76 | { | |
df7699c5 PA |
77 | struct biosregs ireg, oreg; |
78 | ||
79 | initregs(&ireg); | |
80 | ireg.ah = 0x01; | |
81 | intcall(0x16, &ireg, &oreg); | |
82 | ||
83 | return !(oreg.eflags & X86_EFLAGS_ZF); | |
1543610a PA |
84 | } |
85 | ||
86 | void kbd_flush(void) | |
87 | { | |
88 | for (;;) { | |
89 | if (!kbd_pending()) | |
90 | break; | |
91 | getchar(); | |
92 | } | |
93 | } | |
94 | ||
95 | int getchar_timeout(void) | |
96 | { | |
97 | int cnt = 30; | |
98 | int t0, t1; | |
99 | ||
100 | t0 = gettime(); | |
101 | ||
102 | while (cnt) { | |
103 | if (kbd_pending()) | |
104 | return getchar(); | |
105 | ||
106 | t1 = gettime(); | |
107 | if (t0 != t1) { | |
108 | cnt--; | |
109 | t0 = t1; | |
110 | } | |
111 | } | |
112 | ||
113 | return 0; /* Timeout! */ | |
114 | } |