2 * Copyright (C) 2003, 2004 Stefan Reinauer
4 * See the file "COPYING" for further information about
5 * the copyright and warranty status of this work.
9 #include "kernel/kernel.h"
11 #include "libopenbios/console.h"
13 #ifdef CONFIG_DEBUG_CONSOLE
15 /* ******************************************************************
16 * serial console functions
17 * ****************************************************************** */
19 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
21 #define RBR(x) x==2?0x2f8:0x3f8
22 #define THR(x) x==2?0x2f8:0x3f8
23 #define IER(x) x==2?0x2f9:0x3f9
24 #define IIR(x) x==2?0x2fa:0x3fa
25 #define LCR(x) x==2?0x2fb:0x3fb
26 #define MCR(x) x==2?0x2fc:0x3fc
27 #define LSR(x) x==2?0x2fd:0x3fd
28 #define MSR(x) x==2?0x2fe:0x3fe
29 #define SCR(x) x==2?0x2ff:0x3ff
30 #define DLL(x) x==2?0x2f8:0x3f8
31 #define DLM(x) x==2?0x2f9:0x3f9
33 static int uart_charav(int port)
37 return ((inb(LSR(port)) & 1) != 0);
40 static char uart_getchar(int port)
44 while (!uart_charav(port));
45 return ((char) inb(RBR(port)) & 0177);
48 static void uart_putchar(int port, unsigned char c)
53 uart_putchar(port, '\r');
54 while (!(inb(LSR(port)) & 0x20));
58 static void uart_init_line(int port, unsigned long baud)
84 outb(0x87, LCR(port));
85 outb(0x00, DLM(port));
86 outb(baudconst, DLL(port));
87 outb(0x07, LCR(port));
88 outb(0x0f, MCR(port));
90 for (i = 10; i > 0; i--) {
91 if (inb(LSR(port)) == (unsigned int) 0)
97 int uart_init(int port, unsigned long speed)
100 uart_init_line(port, speed);
104 static void serial_putchar(int c)
106 uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff));
109 static void serial_cls(void)
121 /* ******************************************************************
122 * simple polling video/keyboard console functions
123 * ****************************************************************** */
125 #ifdef CONFIG_DEBUG_CONSOLE_VGA
127 /* raw vga text mode */
128 #define COLUMNS 80 /* The number of columns. */
129 #define LINES 25 /* The number of lines. */
130 #define ATTRIBUTE 7 /* The attribute of an character. */
132 #define VGA_BASE 0xB8000 /* The video memory address. */
134 /* VGA Index and Data Registers */
135 #define VGA_REG_INDEX 0x03D4 /* VGA index register */
136 #define VGA_REG_DATA 0x03D5 /* VGA data register */
138 #define VGA_IDX_CURMSL 0x09 /* cursor maximum scan line */
139 #define VGA_IDX_CURSTART 0x0A /* cursor start */
140 #define VGA_IDX_CUREND 0x0B /* cursor end */
141 #define VGA_IDX_CURLO 0x0F /* cursor position (low 8 bits) */
142 #define VGA_IDX_CURHI 0x0E /* cursor position (high 8 bits) */
144 /* Save the X and Y position. */
145 static int xpos, ypos;
146 /* Point to the video memory. */
147 static volatile unsigned char *video = (unsigned char *) VGA_BASE;
149 static void video_initcursor(void)
152 outb(VGA_IDX_CURMSL, VGA_REG_INDEX);
153 val = inb(VGA_REG_DATA) & 0x1f; /* maximum scan line -1 */
155 outb(VGA_IDX_CURSTART, VGA_REG_INDEX);
156 outb(0, VGA_REG_DATA);
158 outb(VGA_IDX_CUREND, VGA_REG_INDEX);
159 outb(val, VGA_REG_DATA);
164 static void video_poscursor(unsigned int x, unsigned int y)
168 /* Calculate new cursor position as a function of x and y */
169 pos = (y * COLUMNS) + x;
171 /* Output the new position to VGA card */
172 outb(VGA_IDX_CURLO, VGA_REG_INDEX); /* output low 8 bits */
173 outb((u8) (pos), VGA_REG_DATA);
174 outb(VGA_IDX_CURHI, VGA_REG_INDEX); /* output high 8 bits */
175 outb((u8) (pos >> 8), VGA_REG_DATA);
180 static void video_newline(void)
184 if (ypos < LINES - 1) {
188 memmove((void *) video, (void *) (video + 2 * COLUMNS),
189 (LINES - 1) * COLUMNS * 2);
191 for (i = ((LINES - 1) * 2 * COLUMNS);
192 i < 2 * COLUMNS * LINES;) {
194 video[i++] = ATTRIBUTE;
200 /* Put the character C on the screen. */
201 static void video_putchar(int c)
205 if (c == '\n' || c == '\r') {
220 *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
221 *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
226 video_poscursor(xpos, ypos);
229 static void video_cls(void)
233 for (i = 0; i < 2 * COLUMNS * LINES;) {
235 video[i++] = ATTRIBUTE;
243 video_poscursor(xpos, ypos);
246 void video_init(void)
248 video=phys_to_virt((unsigned char*)VGA_BASE);
255 static const char normal[] = {
256 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
257 '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
258 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
259 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
260 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
261 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
262 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
265 static const char shifted[] = {
266 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
267 '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
268 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
269 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
270 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
271 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
272 '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
276 static int key_lshift = 0, key_rshift = 0, key_caps = 0;
278 static char last_key;
280 static void keyboard_cmd(unsigned char cmd, unsigned char val)
283 /* wait until keyboard controller accepts cmds: */
284 while (inb(0x64) & 2);
286 while (inb(0x64) & 2);
289 static char keyboard_poll(void)
313 keyboard_cmd(0xed, 0);
316 keyboard_cmd(0xed, 4); /* set caps led */
322 // void printk(const char *format, ...);
323 printk("extended keycode: %x\n", c);
329 if (c & 0x80) /* unhandled key release */
332 if (key_lshift || key_rshift)
333 return key_caps ? normal[c] : shifted[c];
335 return key_caps ? shifted[c] : normal[c];
340 static int keyboard_dataready(void)
345 last_key = keyboard_poll();
347 return (last_key != 0);
350 static unsigned char keyboard_readdata(void)
353 while (!keyboard_dataready());
361 /* ******************************************************************
362 * common functions, implementing simple concurrent console
363 * ****************************************************************** */
365 static int arch_putchar(int c)
367 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
370 #ifdef CONFIG_DEBUG_CONSOLE_VGA
376 static int arch_availchar(void)
378 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
379 if (uart_charav(CONFIG_SERIAL_PORT))
382 #ifdef CONFIG_DEBUG_CONSOLE_VGA
383 if (keyboard_dataready())
389 static int arch_getchar(void)
391 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
392 if (uart_charav(CONFIG_SERIAL_PORT))
393 return (uart_getchar(CONFIG_SERIAL_PORT));
395 #ifdef CONFIG_DEBUG_CONSOLE_VGA
396 if (keyboard_dataready())
397 return (keyboard_readdata());
404 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
407 #ifdef CONFIG_DEBUG_CONSOLE_VGA
412 struct _console_ops arch_console_ops = {
413 .putchar = arch_putchar,
414 .availchar = arch_availchar,
415 .getchar = arch_getchar
418 #endif // CONFIG_DEBUG_CONSOLE