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 uint8_t ScrollAttribute
= 0x07; /* Grey on white (normal text color) */
50 * loadkeys: Load a LILO-style keymap
52 * Returns 0 on success, or -1 on error.
54 __export
int loadkeys(char *filename
)
58 f
= fopen(filename
, "r");
62 fread(KbdMap
, 1, sizeof(KbdMap
), f
);
69 * write_serial: If serial output is enabled, write character on
72 __export
void write_serial(char data
)
80 ch
= inb(SerialPort
+ 5); /* LSR */
82 /* Wait for space in transmit register */
86 /* Wait for input flow control */
87 ch
= inb(SerialPort
+ 6);
95 outb(data
, SerialPort
); /* Send data */
99 void pm_write_serial(com32sys_t
*regs
)
101 write_serial(regs
->eax
.b
[0]);
104 void pm_serialcfg(com32sys_t
*regs
)
108 regs
->eax
.w
[0] = SerialPort
;
109 regs
->ecx
.w
[0] = BaudDivisor
;
121 regs
->ebx
.w
[0] = al
| (ah
<< 8);
125 * write_serial_str: write_serial for strings
127 __export
void write_serial_str(char *data
)
131 while ((ch
= *data
++))
136 * pollchar: check if we have an input character pending
138 * Returns 1 if character pending.
140 __export
int pollchar(void)
142 com32sys_t ireg
, oreg
;
145 memset(&ireg
, 0, sizeof(ireg
));
147 ireg
.eax
.b
[1] = 0x11; /* Poll keyboard */
148 __intcall(0x16, &ireg
, &oreg
);
150 if (!(oreg
.eflags
.l
& EFLAGS_ZF
))
156 /* Already-queued input? */
157 if (SerialTail
== SerialHead
) {
159 data
= inb(SerialPort
+ 5) & 1;
162 data
= inb(SerialPort
+ 6);
164 /* Required status bits */
167 if (data
!= FlowIgnore
)
180 void pm_pollchar(com32sys_t
*regs
)
183 regs
->eflags
.l
&= ~EFLAGS_ZF
;
185 regs
->eflags
.l
|= EFLAGS_ZF
;
188 extern void do_idle(void);
191 * getchar: Read a character from keyboard or serial port
193 __export
char getchar(char *hi
)
195 com32sys_t ireg
, oreg
;
198 memset(&ireg
, 0, sizeof(ireg
));
199 memset(&oreg
, 0, sizeof(oreg
));
201 call16(do_idle
, &zero_regs
, NULL
);
203 ireg
.eax
.b
[1] = 0x11; /* Poll keyboard */
204 __intcall(0x16, &ireg
, &oreg
);
206 if (oreg
.eflags
.l
& EFLAGS_ZF
) {
211 if (SerialTail
!= SerialHead
) {
213 sti(); /* We already know we'll consume data */
214 data
= *SerialTail
++;
216 SerialTail
= (char *)((unsigned long)SerialTail
& (serial_buf_size
- 1));
219 data
= inb(SerialPort
+ 5) & 1;
224 data
= inb(SerialPort
+ 6);
226 if (data
!= FlowIgnore
) {
231 data
= inb(SerialPort
);
236 /* Keyboard input? */
237 ireg
.eax
.b
[1] = 0x10; /* Get keyboard input */
238 __intcall(0x16, &ireg
, &oreg
);
240 data
= oreg
.eax
.b
[0];
247 /* Convert character sets */
255 reset_idle(); /* Character received */
259 void pm_getchar(com32sys_t
*regs
)
261 regs
->eax
.b
[0] = getchar((char *)®s
->eax
.b
[1]);