Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/boot/tty.c
10817 views
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
140
141