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 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 { 26 struct biosregs ireg; 27 28 if (ch == '\n') 29 putchar('\r'); /* \n -> \r\n */ 30 31 initregs(&ireg); 32 ireg.bx = 0x0007; 33 ireg.cx = 0x0001; 34 ireg.ah = 0x0e; 35 ireg.al = ch; 36 intcall(0x10, &ireg, NULL); 37 } 38 39 void __attribute__((section(".inittext"))) puts(const char *str) 40 { 41 while (*str) 42 putchar(*str++); 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 struct biosregs ireg, oreg; 53 54 initregs(&ireg); 55 ireg.ah = 0x02; 56 intcall(0x1a, &ireg, &oreg); 57 58 return oreg.dh; 59 } 60 61 /* 62 * Read from the keyboard 63 */ 64 int getchar(void) 65 { 66 struct biosregs ireg, oreg; 67 68 initregs(&ireg); 69 /* ireg.ah = 0x00; */ 70 intcall(0x16, &ireg, &oreg); 71 72 return oreg.al; 73 } 74 75 static int kbd_pending(void) 76 { 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); 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 } 115