Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / openbios / arch / x86 / console.c
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 #include "libopenbios/console.h"
12
13 #ifdef CONFIG_DEBUG_CONSOLE
14
15 /* ******************************************************************
16  *                       serial console functions
17  * ****************************************************************** */
18
19 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
20
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
32
33 static int uart_charav(int port)
34 {
35         if (!port)
36                 return -1;
37         return ((inb(LSR(port)) & 1) != 0);
38 }
39
40 static char uart_getchar(int port)
41 {
42         if (!port)
43                 return -1;
44         while (!uart_charav(port));
45         return ((char) inb(RBR(port)) & 0177);
46 }
47
48 static void uart_putchar(int port, unsigned char c)
49 {
50         if (!port)
51                 return;
52         if (c == '\n')
53                 uart_putchar(port, '\r');
54         while (!(inb(LSR(port)) & 0x20));
55         outb(c, THR(port));
56 }
57
58 static void uart_init_line(int port, unsigned long baud)
59 {
60         int i, baudconst;
61
62         if (!port)
63                 return;
64
65         switch (baud) {
66         case 115200:
67                 baudconst = 1;
68                 break;
69         case 57600:
70                 baudconst = 2;
71                 break;
72         case 38400:
73                 baudconst = 3;
74                 break;
75         case 19200:
76                 baudconst = 6;
77                 break;
78         case 9600:
79         default:
80                 baudconst = 12;
81                 break;
82         }
83
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));
89
90         for (i = 10; i > 0; i--) {
91                 if (inb(LSR(port)) == (unsigned int) 0)
92                         break;
93                 inb(RBR(port));
94         }
95 }
96
97 int uart_init(int port, unsigned long speed)
98 {
99         if (port)
100                 uart_init_line(port, speed);
101         return -1;
102 }
103
104 static void serial_putchar(int c)
105 {
106         uart_putchar(CONFIG_SERIAL_PORT, (unsigned char) (c & 0xff));
107 }
108
109 static void serial_cls(void)
110 {
111         serial_putchar(27);
112         serial_putchar('[');
113         serial_putchar('H');
114         serial_putchar(27);
115         serial_putchar('[');
116         serial_putchar('J');
117 }
118
119 #endif
120
121 /* ******************************************************************
122  *          simple polling video/keyboard console functions
123  * ****************************************************************** */
124
125 #ifdef CONFIG_DEBUG_CONSOLE_VGA
126
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.  */
131
132 #define VGA_BASE                0xB8000 /* The video memory address.  */
133
134 /* VGA Index and Data Registers */
135 #define VGA_REG_INDEX    0x03D4 /* VGA index register */
136 #define VGA_REG_DATA     0x03D5 /* VGA data register */
137
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) */
143
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;
148
149 static void video_initcursor(void)
150 {
151         u8 val;
152         outb(VGA_IDX_CURMSL, VGA_REG_INDEX);
153         val = inb(VGA_REG_DATA) & 0x1f; /* maximum scan line -1 */
154
155         outb(VGA_IDX_CURSTART, VGA_REG_INDEX);
156         outb(0, VGA_REG_DATA);
157
158         outb(VGA_IDX_CUREND, VGA_REG_INDEX);
159         outb(val, VGA_REG_DATA);
160 }
161
162
163
164 static void video_poscursor(unsigned int x, unsigned int y)
165 {
166         unsigned short pos;
167
168         /* Calculate new cursor position as a function of x and y */
169         pos = (y * COLUMNS) + x;
170
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);
176
177 };
178
179
180 static void video_newline(void)
181 {
182         xpos = 0;
183
184         if (ypos < LINES - 1) {
185                 ypos++;
186         } else {
187                 int i;
188                 memmove((void *) video, (void *) (video + 2 * COLUMNS),
189                         (LINES - 1) * COLUMNS * 2);
190
191                 for (i = ((LINES - 1) * 2 * COLUMNS);
192                      i < 2 * COLUMNS * LINES;) {
193                         video[i++] = 0;
194                         video[i++] = ATTRIBUTE;
195                 }
196         }
197
198 }
199
200 /* Put the character C on the screen.  */
201 static void video_putchar(int c)
202 {
203         int p=1;
204
205         if (c == '\n' || c == '\r') {
206                 video_newline();
207                 return;
208         }
209
210         if (c == '\b') {
211                 if (xpos) xpos--;
212                 c=' ';
213                 p=0;
214         }
215
216
217         if (xpos >= COLUMNS)
218                 video_newline();
219
220         *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
221         *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
222
223         if (p)
224                 xpos++;
225
226         video_poscursor(xpos, ypos);
227 }
228
229 static void video_cls(void)
230 {
231         int i;
232
233         for (i = 0; i < 2 * COLUMNS * LINES;) {
234                 video[i++] = 0;
235                 video[i++] = ATTRIBUTE;
236         }
237
238
239         xpos = 0;
240         ypos = 0;
241
242         video_initcursor();
243         video_poscursor(xpos, ypos);
244 }
245
246 void video_init(void)
247 {
248         video=phys_to_virt((unsigned char*)VGA_BASE);
249 }
250
251 /*
252  *  keyboard driver
253  */
254
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
263 };
264
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
273 };
274
275 static int key_ext;
276 static int key_lshift = 0, key_rshift = 0, key_caps = 0;
277
278 static char last_key;
279
280 static void keyboard_cmd(unsigned char cmd, unsigned char val)
281 {
282         outb(cmd, 0x60);
283         /* wait until keyboard controller accepts cmds: */
284         while (inb(0x64) & 2);
285         outb(val, 0x60);
286         while (inb(0x64) & 2);
287 }
288
289 static char keyboard_poll(void)
290 {
291         unsigned int c;
292         if (inb(0x64) & 1) {
293                 c = inb(0x60);
294                 switch (c) {
295                 case 0xe0:
296                         key_ext = 1;
297                         return 0;
298                 case 0x2a:
299                         key_lshift = 1;
300                         return 0;
301                 case 0x36:
302                         key_rshift = 1;
303                         return 0;
304                 case 0xaa:
305                         key_lshift = 0;
306                         return 0;
307                 case 0xb6:
308                         key_rshift = 0;
309                         return 0;
310                 case 0x3a:
311                         if (key_caps) {
312                                 key_caps = 0;
313                                 keyboard_cmd(0xed, 0);
314                         } else {
315                                 key_caps = 1;
316                                 keyboard_cmd(0xed, 4);  /* set caps led */
317                         }
318                         return 0;
319                 }
320
321                 if (key_ext) {
322                         // void printk(const char *format, ...);
323                         printk("extended keycode: %x\n", c);
324
325                         key_ext = 0;
326                         return 0;
327                 }
328
329                 if (c & 0x80)   /* unhandled key release */
330                         return 0;
331
332                 if (key_lshift || key_rshift)
333                         return key_caps ? normal[c] : shifted[c];
334                 else
335                         return key_caps ? shifted[c] : normal[c];
336         }
337         return 0;
338 }
339
340 static int keyboard_dataready(void)
341 {
342         if (last_key)
343                 return 1;
344
345         last_key = keyboard_poll();
346
347         return (last_key != 0);
348 }
349
350 static unsigned char keyboard_readdata(void)
351 {
352         char tmp;
353         while (!keyboard_dataready());
354         tmp = last_key;
355         last_key = 0;
356         return tmp;
357 }
358 #endif
359
360
361 /* ******************************************************************
362  *      common functions, implementing simple concurrent console
363  * ****************************************************************** */
364
365 static int arch_putchar(int c)
366 {
367 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
368         serial_putchar(c);
369 #endif
370 #ifdef CONFIG_DEBUG_CONSOLE_VGA
371         video_putchar(c);
372 #endif
373         return c;
374 }
375
376 static int arch_availchar(void)
377 {
378 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
379         if (uart_charav(CONFIG_SERIAL_PORT))
380                 return 1;
381 #endif
382 #ifdef CONFIG_DEBUG_CONSOLE_VGA
383         if (keyboard_dataready())
384                 return 1;
385 #endif
386         return 0;
387 }
388
389 static int arch_getchar(void)
390 {
391 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
392         if (uart_charav(CONFIG_SERIAL_PORT))
393                 return (uart_getchar(CONFIG_SERIAL_PORT));
394 #endif
395 #ifdef CONFIG_DEBUG_CONSOLE_VGA
396         if (keyboard_dataready())
397                 return (keyboard_readdata());
398 #endif
399         return 0;
400 }
401
402 void cls(void)
403 {
404 #ifdef CONFIG_DEBUG_CONSOLE_SERIAL
405         serial_cls();
406 #endif
407 #ifdef CONFIG_DEBUG_CONSOLE_VGA
408         video_cls();
409 #endif
410 }
411
412 struct _console_ops arch_console_ops = {
413         .putchar = arch_putchar,
414         .availchar = arch_availchar,
415         .getchar = arch_getchar
416 };
417
418 #endif                          // CONFIG_DEBUG_CONSOLE