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