]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/x86/boot/tty.c
Merge tag 'arc-v3.11-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / 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  *   Copyright 2009 Intel Corporation; author H. Peter Anvin
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 /*
13  * Very simple screen and serial I/O
14  */
15
16 #include "boot.h"
17
18 int early_serial_base;
19
20 #define XMTRDY          0x20
21
22 #define TXR             0       /*  Transmit register (WRITE) */
23 #define LSR             5       /*  Line Status               */
24
25 /*
26  * These functions are in .inittext so they can be used to signal
27  * error during initialization.
28  */
29
30 static void __attribute__((section(".inittext"))) serial_putchar(int ch)
31 {
32         unsigned timeout = 0xffff;
33
34         while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
35                 cpu_relax();
36
37         outb(ch, early_serial_base + TXR);
38 }
39
40 static void __attribute__((section(".inittext"))) bios_putchar(int ch)
41 {
42         struct biosregs ireg;
43
44         initregs(&ireg);
45         ireg.bx = 0x0007;
46         ireg.cx = 0x0001;
47         ireg.ah = 0x0e;
48         ireg.al = ch;
49         intcall(0x10, &ireg, NULL);
50 }
51
52 void __attribute__((section(".inittext"))) putchar(int ch)
53 {
54         if (ch == '\n')
55                 putchar('\r');  /* \n -> \r\n */
56
57         bios_putchar(ch);
58
59         if (early_serial_base != 0)
60                 serial_putchar(ch);
61 }
62
63 void __attribute__((section(".inittext"))) puts(const char *str)
64 {
65         while (*str)
66                 putchar(*str++);
67 }
68
69 /*
70  * Read the CMOS clock through the BIOS, and return the
71  * seconds in BCD.
72  */
73
74 static u8 gettime(void)
75 {
76         struct biosregs ireg, oreg;
77
78         initregs(&ireg);
79         ireg.ah = 0x02;
80         intcall(0x1a, &ireg, &oreg);
81
82         return oreg.dh;
83 }
84
85 /*
86  * Read from the keyboard
87  */
88 int getchar(void)
89 {
90         struct biosregs ireg, oreg;
91
92         initregs(&ireg);
93         /* ireg.ah = 0x00; */
94         intcall(0x16, &ireg, &oreg);
95
96         return oreg.al;
97 }
98
99 static int kbd_pending(void)
100 {
101         struct biosregs ireg, oreg;
102
103         initregs(&ireg);
104         ireg.ah = 0x01;
105         intcall(0x16, &ireg, &oreg);
106
107         return !(oreg.eflags & X86_EFLAGS_ZF);
108 }
109
110 void kbd_flush(void)
111 {
112         for (;;) {
113                 if (!kbd_pending())
114                         break;
115                 getchar();
116         }
117 }
118
119 int getchar_timeout(void)
120 {
121         int cnt = 30;
122         int t0, t1;
123
124         t0 = gettime();
125
126         while (cnt) {
127                 if (kbd_pending())
128                         return getchar();
129
130                 t1 = gettime();
131                 if (t0 != t1) {
132                         cnt--;
133                         t0 = t1;
134                 }
135         }
136
137         return 0;               /* Timeout! */
138 }
139