blob: 01ec69c901c7a595e88748f24880a5104af553fe [file] [log] [blame]
H. Peter Anvin15436102007-07-11 12:18:45 -07001/* -*- linux-c -*- ------------------------------------------------------- *
2 *
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 * Copyright 2007 rPath, Inc. - All Rights Reserved
H. Peter Anvindf7699c2009-04-01 18:13:46 -07005 * Copyright 2009 Intel Corporation; author H. Peter Anvin
H. Peter Anvin15436102007-07-11 12:18:45 -07006 *
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/*
H. Peter Anvin15436102007-07-11 12:18:45 -070013 * 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
24void __attribute__((section(".inittext"))) putchar(int ch)
25{
H. Peter Anvindf7699c2009-04-01 18:13:46 -070026 struct biosregs ireg;
H. Peter Anvin15436102007-07-11 12:18:45 -070027
H. Peter Anvindf7699c2009-04-01 18:13:46 -070028 if (ch == '\n')
H. Peter Anvin15436102007-07-11 12:18:45 -070029 putchar('\r'); /* \n -> \r\n */
30
H. Peter Anvindf7699c2009-04-01 18:13:46 -070031 initregs(&ireg);
32 ireg.bx = 0x0007;
33 ireg.cx = 0x0001;
34 ireg.ah = 0x0e;
35 ireg.al = ch;
36 intcall(0x10, &ireg, NULL);
H. Peter Anvin15436102007-07-11 12:18:45 -070037}
38
39void __attribute__((section(".inittext"))) puts(const char *str)
40{
H. Peter Anvindf7699c2009-04-01 18:13:46 -070041 while (*str)
H. Peter Anvin15436102007-07-11 12:18:45 -070042 putchar(*str++);
H. Peter Anvin15436102007-07-11 12:18:45 -070043}
44
45/*
46 * Read the CMOS clock through the BIOS, and return the
47 * seconds in BCD.
48 */
49
50static u8 gettime(void)
51{
H. Peter Anvindf7699c2009-04-01 18:13:46 -070052 struct biosregs ireg, oreg;
H. Peter Anvin15436102007-07-11 12:18:45 -070053
H. Peter Anvindf7699c2009-04-01 18:13:46 -070054 initregs(&ireg);
55 ireg.ah = 0x02;
56 intcall(0x1a, &ireg, &oreg);
H. Peter Anvin15436102007-07-11 12:18:45 -070057
H. Peter Anvindf7699c2009-04-01 18:13:46 -070058 return oreg.dh;
H. Peter Anvin15436102007-07-11 12:18:45 -070059}
60
61/*
62 * Read from the keyboard
63 */
64int getchar(void)
65{
H. Peter Anvindf7699c2009-04-01 18:13:46 -070066 struct biosregs ireg, oreg;
H. Peter Anvin15436102007-07-11 12:18:45 -070067
H. Peter Anvindf7699c2009-04-01 18:13:46 -070068 initregs(&ireg);
69 /* ireg.ah = 0x00; */
70 intcall(0x16, &ireg, &oreg);
71
72 return oreg.al;
H. Peter Anvin15436102007-07-11 12:18:45 -070073}
74
75static int kbd_pending(void)
76{
H. Peter Anvindf7699c2009-04-01 18:13:46 -070077 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);
H. Peter Anvin15436102007-07-11 12:18:45 -070084}
85
86void kbd_flush(void)
87{
88 for (;;) {
89 if (!kbd_pending())
90 break;
91 getchar();
92 }
93}
94
95int 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}