|
|
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 const 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 const 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.