xref: /openbmc/linux/arch/x86/boot/tty.c (revision 5cf02b7b)
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 		     : "=qm" (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 }
111