xref: /openbmc/linux/arch/x86/boot/tty.c (revision 96ae6ea0)
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 
25 void __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; pushw %%ds; int $0x10; popw %%ds; popal"
35 		     : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
36 }
37 
38 void __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 
52 static u8 gettime(void)
53 {
54 	u16 ax = 0x0200;
55 	u16 cx, dx;
56 
57 	asm volatile("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  */
67 int getchar(void)
68 {
69 	u16 ax = 0;
70 	asm volatile("int $0x16" : "+a" (ax));
71 
72 	return ax & 0xff;
73 }
74 
75 static int kbd_pending(void)
76 {
77 	u8 pending;
78 	asm volatile("int $0x16; setnz %0"
79 		     : "=rm" (pending)
80 		     : "a" (0x0100));
81 	return pending;
82 }
83 
84 void kbd_flush(void)
85 {
86 	for (;;) {
87 		if (!kbd_pending())
88 			break;
89 		getchar();
90 	}
91 }
92 
93 int 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 }
113