|
|
1.1 root 1: /*
2: * Copyright (C) 2003, 2004 Stefan Reinauer
3: *
4: * See the file "COPYING" for further information about
5: * the copyright and warranty status of this work.
6: */
7:
8: #include "config.h"
9: #include "kernel/kernel.h"
10: #include "openbios.h"
11:
12: #ifdef CONFIG_DEBUG_CONSOLE
13:
14: /* ******************************************************************
15: * serial console functions
16: * ****************************************************************** */
17:
18: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
19:
20: #define RBR(x) x==2?0x2f8:0x3f8
21: #define THR(x) x==2?0x2f8:0x3f8
22: #define IER(x) x==2?0x2f9:0x3f9
23: #define IIR(x) x==2?0x2fa:0x3fa
24: #define LCR(x) x==2?0x2fb:0x3fb
25: #define MCR(x) x==2?0x2fc:0x3fc
26: #define LSR(x) x==2?0x2fd:0x3fd
27: #define MSR(x) x==2?0x2fe:0x3fe
28: #define SCR(x) x==2?0x2ff:0x3ff
29: #define DLL(x) x==2?0x2f8:0x3f8
30: #define DLM(x) x==2?0x2f9:0x3f9
31:
32: static int uart_charav(int port)
33: {
34: if (!port)
35: return -1;
36: return ((inb(LSR(port)) & 1) != 0);
37: }
38:
39: static char uart_getchar(int port)
40: {
41: if (!port)
42: return -1;
43: while (!uart_charav(port));
44: return ((char) inb(RBR(port)) & 0177);
45: }
46:
47: static void uart_putchar(int port, unsigned char c)
48: {
49: if (!port)
50: return;
51: if (c == '\n')
52: uart_putchar(port, '\r');
53: while (!(inb(LSR(port)) & 0x20));
54: outb(c, THR(port));
55: }
56:
57: static void uart_init_line(int port, unsigned long baud)
58: {
59: int i, baudconst;
60:
61: if (!port)
62: return;
63:
64: switch (baud) {
65: case 115200:
66: baudconst = 1;
67: break;
68: case 57600:
69: baudconst = 2;
70: break;
71: case 38400:
72: baudconst = 3;
73: break;
74: case 19200:
75: baudconst = 6;
76: break;
77: case 9600:
78: default:
79: baudconst = 12;
80: break;
81: }
82:
83: outb(0x87, LCR(port));
84: outb(0x00, DLM(port));
85: outb(baudconst, DLL(port));
86: outb(0x07, LCR(port));
87: outb(0x0f, MCR(port));
88:
89: for (i = 10; i > 0; i--) {
90: if (inb(LSR(port)) == (unsigned int) 0)
91: break;
92: inb(RBR(port));
93: }
94: }
95:
96: int uart_init(int port, unsigned long speed)
97: {
98: if (port)
99: uart_init_line(port, speed);
100: return -1;
101: }
102:
103: static void serial_putchar(int c)
104: {
105: uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff));
106: }
107:
108: static void serial_cls(void)
109: {
110: serial_putchar(27);
111: serial_putchar('[');
112: serial_putchar('H');
113: serial_putchar(27);
114: serial_putchar('[');
115: serial_putchar('J');
116: }
117:
118: #endif
119:
120: /* ******************************************************************
121: * simple polling video/keyboard console functions
122: * ****************************************************************** */
123:
124: #ifdef CONFIG_DEBUG_CONSOLE_VGA
125:
126: /* raw vga text mode */
127: #define COLUMNS 80 /* The number of columns. */
128: #define LINES 25 /* The number of lines. */
129: #define ATTRIBUTE 7 /* The attribute of an character. */
130:
131: #define VGA_BASE 0xB8000 /* The video memory address. */
132:
133: /* VGA Index and Data Registers */
134: #define VGA_REG_INDEX 0x03D4 /* VGA index register */
135: #define VGA_REG_DATA 0x03D5 /* VGA data register */
136:
137: #define VGA_IDX_CURMSL 0x09 /* cursor maximum scan line */
138: #define VGA_IDX_CURSTART 0x0A /* cursor start */
139: #define VGA_IDX_CUREND 0x0B /* cursor end */
140: #define VGA_IDX_CURLO 0x0F /* cursor position (low 8 bits) */
141: #define VGA_IDX_CURHI 0x0E /* cursor position (high 8 bits) */
142:
143: /* Save the X and Y position. */
144: static int xpos, ypos;
145: /* Point to the video memory. */
146: static volatile unsigned char *video = (unsigned char *) VGA_BASE;
147:
148: static void video_initcursor(void)
149: {
150: u8 val;
151: outb(VGA_IDX_CURMSL, VGA_REG_INDEX);
152: val = inb(VGA_REG_DATA) & 0x1f; /* maximum scan line -1 */
153:
154: outb(VGA_IDX_CURSTART, VGA_REG_INDEX);
155: outb(0, VGA_REG_DATA);
156:
157: outb(VGA_IDX_CUREND, VGA_REG_INDEX);
158: outb(val, VGA_REG_DATA);
159: }
160:
161:
162:
163: static void video_poscursor(unsigned int x, unsigned int y)
164: {
165: unsigned short pos;
166:
167: /* Calculate new cursor position as a function of x and y */
168: pos = (y * COLUMNS) + x;
169:
170: /* Output the new position to VGA card */
171: outb(VGA_IDX_CURLO, VGA_REG_INDEX); /* output low 8 bits */
172: outb((u8) (pos), VGA_REG_DATA);
173: outb(VGA_IDX_CURHI, VGA_REG_INDEX); /* output high 8 bits */
174: outb((u8) (pos >> 8), VGA_REG_DATA);
175:
176: };
177:
178:
179: static void video_newline(void)
180: {
181: xpos = 0;
182:
183: if (ypos < LINES - 1) {
184: ypos++;
185: } else {
186: int i;
187: memmove((void *) video, (void *) (video + 2 * COLUMNS),
188: (LINES - 1) * COLUMNS * 2);
189:
190: for (i = ((LINES - 1) * 2 * COLUMNS);
191: i < 2 * COLUMNS * LINES;) {
192: video[i++] = 0;
193: video[i++] = ATTRIBUTE;
194: }
195: }
196:
197: }
198:
199: /* Put the character C on the screen. */
200: static void video_putchar(int c)
201: {
202: int p=1;
203:
204: if (c == '\n' || c == '\r') {
205: video_newline();
206: return;
207: }
208:
209: if (c == '\b') {
210: if (xpos) xpos--;
211: c=' ';
212: p=0;
213: }
214:
215:
216: if (xpos >= COLUMNS)
217: video_newline();
218:
219: *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
220: *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
221:
222: if (p)
223: xpos++;
224:
225: video_poscursor(xpos, ypos);
226: }
227:
228: static void video_cls(void)
229: {
230: int i;
231:
232: for (i = 0; i < 2 * COLUMNS * LINES;) {
233: video[i++] = 0;
234: video[i++] = ATTRIBUTE;
235: }
236:
237:
238: xpos = 0;
239: ypos = 0;
240:
241: video_initcursor();
242: video_poscursor(xpos, ypos);
243: }
244:
245: void video_init(void)
246: {
247: video=phys_to_virt((unsigned char*)VGA_BASE);
248: }
249:
250: /*
251: * keyboard driver
252: */
253:
254: static char normal[] = {
255: 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-',
256: '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o',
257: 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j',
258: 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b',
259: 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
260: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
261: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f
262: };
263:
264: static char shifted[] = {
265: 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_',
266: '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O',
267: 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J',
268: 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B',
269: 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0,
270: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8',
271: '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f
272: };
273:
274: static int key_ext;
275: static int key_lshift = 0, key_rshift = 0, key_caps = 0;
276:
277: static char last_key;
278:
279: static void keyboard_cmd(unsigned char cmd, unsigned char val)
280: {
281: outb(cmd, 0x60);
282: /* wait until keyboard controller accepts cmds: */
283: while (inb(0x64) & 2);
284: outb(val, 0x60);
285: while (inb(0x64) & 2);
286: }
287:
288: static char keyboard_poll(void)
289: {
290: unsigned int c;
291: if (inb(0x64) & 1) {
292: c = inb(0x60);
293: switch (c) {
294: case 0xe0:
295: key_ext = 1;
296: return 0;
297: case 0x2a:
298: key_lshift = 1;
299: return 0;
300: case 0x36:
301: key_rshift = 1;
302: return 0;
303: case 0xaa:
304: key_lshift = 0;
305: return 0;
306: case 0xb6:
307: key_rshift = 0;
308: return 0;
309: case 0x3a:
310: if (key_caps) {
311: key_caps = 0;
312: keyboard_cmd(0xed, 0);
313: } else {
314: key_caps = 1;
315: keyboard_cmd(0xed, 4); /* set caps led */
316: }
317: return 0;
318: }
319:
320: if (key_ext) {
321: // void printk(const char *format, ...);
322: printk("extended keycode: %x\n", c);
323:
324: key_ext = 0;
325: return 0;
326: }
327:
328: if (c & 0x80) /* unhandled key release */
329: return 0;
330:
331: if (key_lshift || key_rshift)
332: return key_caps ? normal[c] : shifted[c];
333: else
334: return key_caps ? shifted[c] : normal[c];
335: }
336: return 0;
337: }
338:
339: static int keyboard_dataready(void)
340: {
341: if (last_key)
342: return 1;
343:
344: last_key = keyboard_poll();
345:
346: return (last_key != 0);
347: }
348:
349: static unsigned char keyboard_readdata(void)
350: {
351: char tmp;
352: while (!keyboard_dataready());
353: tmp = last_key;
354: last_key = 0;
355: return tmp;
356: }
357: #endif
358:
359:
360: /* ******************************************************************
361: * common functions, implementing simple concurrent console
362: * ****************************************************************** */
363:
364: int putchar(int c)
365: {
366: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
367: serial_putchar(c);
368: #endif
369: #ifdef CONFIG_DEBUG_CONSOLE_VGA
370: video_putchar(c);
371: #endif
372: return c;
373: }
374:
375: int availchar(void)
376: {
377: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
378: if (uart_charav(CONFIG_SERIAL_PORT))
379: return 1;
380: #endif
381: #ifdef CONFIG_DEBUG_CONSOLE_VGA
382: if (keyboard_dataready())
383: return 1;
384: #endif
385: return 0;
386: }
387:
388: int getchar(void)
389: {
390: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
391: if (uart_charav(CONFIG_SERIAL_PORT))
392: return (uart_getchar(CONFIG_SERIAL_PORT));
393: #endif
394: #ifdef CONFIG_DEBUG_CONSOLE_VGA
395: if (keyboard_dataready())
396: return (keyboard_readdata());
397: #endif
398: return 0;
399: }
400:
401: void cls(void)
402: {
403: #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
404: serial_cls();
405: #endif
406: #ifdef CONFIG_DEBUG_CONSOLE_VGA
407: video_cls();
408: #endif
409: }
410:
411:
412: #endif // CONFIG_DEBUG_CONSOLE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.