2 * -----------------------------------------------------------------------
4 * Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
5 * Copyright 2009 Intel Corporation; author: H. Peter Anvin
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
10 * Boston MA 02111-1307, USA; either version 2 of the License, or
11 * (at your option) any later version; incorporated herein by reference.
13 * -----------------------------------------------------------------------
18 * Console I/O code, except:
19 * writechr, writestr_early - module-dependent
20 * writestr, crlf - writestr.inc
21 * writehex* - writehex.inc
35 union screen _screensize
;
38 * Serial console stuff.
40 __export
uint16_t SerialPort
= 0; /* Serial port base (or 0 for no serial port) */
41 __export
uint8_t FlowInput
= 0; /* Input bits for serial flow */
42 __export
uint16_t BaudDivisor
= 115200/9600; /* Baud rate divisor */
43 __export
uint8_t FlowIgnore
= 0; /* Ignore input unless these bits set */
44 __export
uint16_t DisplayCon
= 0x01; /* Display console enabled */
45 __export
uint8_t FlowOutput
= 0; /* Output to assert for serial flow */
47 __export
uint8_t DisplayMask
= 0x07; /* Display modes mask */
49 uint8_t ScrollAttribute
= 0x07; /* Grey on white (normal text color) */
52 * loadkeys: Load a LILO-style keymap
54 * Returns 0 on success, or -1 on error.
56 __export
int loadkeys(char *filename
)
60 f
= fopen(filename
, "r");
64 fread(KbdMap
, 1, sizeof(KbdMap
), f
);
71 * write_serial: If serial output is enabled, write character on
74 __export
void write_serial(char data
)
79 if (!(DisplayMask
& 0x04))
85 ch
= inb(SerialPort
+ 5); /* LSR */
87 /* Wait for space in transmit register */
91 /* Wait for input flow control */
92 ch
= inb(SerialPort
+ 6);
100 outb(data
, SerialPort
); /* Send data */
104 void pm_write_serial(com32sys_t
*regs
)
106 write_serial(regs
->eax
.b
[0]);
109 void pm_serialcfg(com32sys_t
*regs
)
113 regs
->eax
.w
[0] = SerialPort
;
114 regs
->ecx
.w
[0] = BaudDivisor
;
126 regs
->ebx
.w
[0] = al
| (ah
<< 8);
130 * write_serial_str: write_serial for strings
132 __export
void write_serial_str(char *data
)
136 while ((ch
= *data
++))
141 * pollchar: check if we have an input character pending
143 * Returns 1 if character pending.
145 __export
int pollchar(void)
147 com32sys_t ireg
, oreg
;
150 memset(&ireg
, 0, sizeof(ireg
));
152 ireg
.eax
.b
[1] = 0x11; /* Poll keyboard */
153 __intcall(0x16, &ireg
, &oreg
);
155 if (!(oreg
.eflags
.l
& EFLAGS_ZF
))
161 /* Already-queued input? */
162 if (SerialTail
== SerialHead
) {
164 data
= !(inb(SerialPort
+ 5) & 1);
167 data
= inb(SerialPort
+ 6);
169 /* Required status bits */
172 if (data
== FlowIgnore
)
186 void pm_pollchar(com32sys_t
*regs
)
189 regs
->eflags
.l
&= ~EFLAGS_ZF
;
191 regs
->eflags
.l
|= EFLAGS_ZF
;
194 extern void do_idle(void);
197 * getchar: Read a character from keyboard or serial port
199 __export
char getchar(char *hi
)
201 com32sys_t ireg
, oreg
;
204 memset(&ireg
, 0, sizeof(ireg
));
205 memset(&oreg
, 0, sizeof(oreg
));
207 call16(do_idle
, &zero_regs
, NULL
);
209 ireg
.eax
.b
[1] = 0x11; /* Poll keyboard */
210 __intcall(0x16, &ireg
, &oreg
);
212 if (oreg
.eflags
.l
& EFLAGS_ZF
) {
217 if (SerialTail
!= SerialHead
) {
219 sti(); /* We already know we'll consume data */
220 data
= *SerialTail
++;
222 if (SerialTail
> SerialHead
+ serial_buf_size
)
223 SerialTail
= SerialHead
;
226 data
= inb(SerialPort
+ 5) & 1;
231 data
= inb(SerialPort
+ 6);
233 if (data
!= FlowIgnore
) {
238 data
= inb(SerialPort
);
243 /* Keyboard input? */
244 ireg
.eax
.b
[1] = 0x10; /* Get keyboard input */
245 __intcall(0x16, &ireg
, &oreg
);
247 data
= oreg
.eax
.b
[0];
254 /* Convert character sets */
262 reset_idle(); /* Character received */
266 void pm_getchar(com32sys_t
*regs
)
268 regs
->eax
.b
[0] = getchar((char *)®s
->eax
.b
[1]);