Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/boot/tty.c
26424 views
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
16
int 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
28
static 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
38
static 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
50
void __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
61
void __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
72
static 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
*/
86
int 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
97
static 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
108
void kbd_flush(void)
109
{
110
for (;;) {
111
if (!kbd_pending())
112
break;
113
getchar();
114
}
115
}
116
117
int 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
138
139