|
|
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 "libopenbios/bindings.h" ! 10: #include "kernel/kernel.h" ! 11: #include "drivers/drivers.h" ! 12: #include "libc/vsprintf.h" ! 13: ! 14: /* ****************************************************************** ! 15: * simple polling video/keyboard console functions ! 16: * ****************************************************************** */ ! 17: ! 18: /* ! 19: * keyboard driver ! 20: */ ! 21: ! 22: static const char normal[] = { ! 23: 0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', ! 24: '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', ! 25: 'p', '[', ']', 0xa, 0x0, 'a', 's', 'd', 'f', 'g', 'h', 'j', ! 26: 'k', 'l', ';', 0x27, 0x60, 0x0, 0x5c, 'z', 'x', 'c', 'v', 'b', ! 27: 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, ! 28: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ! 29: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '0', 0x7f ! 30: }; ! 31: ! 32: static const char shifted[] = { ! 33: 0x0, 0x1b, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', ! 34: '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', ! 35: 'P', '{', '}', 0xa, 0x0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', ! 36: 'K', 'L', ':', 0x22, '~', 0x0, '|', 'Z', 'X', 'C', 'V', 'B', ! 37: 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, ! 38: 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', ! 39: '9', 0x0, '4', '5', '6', 0x0, '1', '2', '3', '0', 0x7f ! 40: }; ! 41: ! 42: static int key_ext; ! 43: static int key_lshift = 0, key_rshift = 0, key_caps = 0; ! 44: ! 45: static char last_key; ! 46: ! 47: static void pc_kbd_cmd(unsigned char cmd, unsigned char val) ! 48: { ! 49: outb(cmd, 0x60); ! 50: /* wait until keyboard controller accepts cmds: */ ! 51: while (inb(0x64) & 2); ! 52: outb(val, 0x60); ! 53: while (inb(0x64) & 2); ! 54: } ! 55: ! 56: static void pc_kbd_controller_cmd(unsigned char cmd, unsigned char val) ! 57: { ! 58: outb(cmd, 0x64); ! 59: /* wait until keyboard controller accepts cmds: */ ! 60: while (inb(0x64) & 2); ! 61: outb(val, 0x60); ! 62: while (inb(0x64) & 2); ! 63: } ! 64: ! 65: static char pc_kbd_poll(void) ! 66: { ! 67: unsigned int c; ! 68: if (inb(0x64) & 1) { ! 69: c = inb(0x60); ! 70: switch (c) { ! 71: case 0xe0: ! 72: key_ext = 1; ! 73: return 0; ! 74: case 0x2a: ! 75: key_lshift = 1; ! 76: return 0; ! 77: case 0x36: ! 78: key_rshift = 1; ! 79: return 0; ! 80: case 0xaa: ! 81: key_lshift = 0; ! 82: return 0; ! 83: case 0xb6: ! 84: key_rshift = 0; ! 85: return 0; ! 86: case 0x3a: ! 87: if (key_caps) { ! 88: key_caps = 0; ! 89: pc_kbd_cmd(0xed, 0); ! 90: } else { ! 91: key_caps = 1; ! 92: pc_kbd_cmd(0xed, 4); /* set caps led */ ! 93: } ! 94: return 0; ! 95: } ! 96: ! 97: if (key_ext) { ! 98: // void printk(const char *format, ...); ! 99: printk("extended keycode: %x\n", c); ! 100: ! 101: key_ext = 0; ! 102: return 0; ! 103: } ! 104: ! 105: if (c & 0x80) /* unhandled key release */ ! 106: return 0; ! 107: ! 108: if (key_lshift || key_rshift) ! 109: return key_caps ? normal[c] : shifted[c]; ! 110: else ! 111: return key_caps ? shifted[c] : normal[c]; ! 112: } ! 113: return 0; ! 114: } ! 115: ! 116: int pc_kbd_dataready(void) ! 117: { ! 118: if (last_key) ! 119: return 1; ! 120: ! 121: last_key = pc_kbd_poll(); ! 122: ! 123: return (last_key != 0); ! 124: } ! 125: ! 126: unsigned char pc_kbd_readdata(void) ! 127: { ! 128: char tmp; ! 129: while (!pc_kbd_dataready()); ! 130: tmp = last_key; ! 131: last_key = 0; ! 132: return tmp; ! 133: } ! 134: ! 135: /* ( addr len -- actual ) */ ! 136: static void ! 137: pc_kbd_read(void) ! 138: { ! 139: unsigned char *addr; ! 140: int len; ! 141: ! 142: len = POP(); ! 143: addr = (unsigned char *)POP(); ! 144: ! 145: if (len != 1) ! 146: printk("pc_kbd_read: bad len, addr %lx len %x\n", (unsigned long)addr, len); ! 147: ! 148: if (pc_kbd_dataready()) { ! 149: *addr = pc_kbd_readdata(); ! 150: PUSH(1); ! 151: } else { ! 152: PUSH(0); ! 153: } ! 154: } ! 155: ! 156: static void ! 157: pc_kbd_close(void) ! 158: { ! 159: } ! 160: ! 161: static void ! 162: pc_kbd_open(unsigned long *address) ! 163: { ! 164: int len; ! 165: phandle_t ph; ! 166: unsigned long *prop; ! 167: ! 168: fword("my-self"); ! 169: fword("ihandle>phandle"); ! 170: ph = (phandle_t)POP(); ! 171: prop = (unsigned long *)get_property(ph, "address", &len); ! 172: *address = *prop; ! 173: ! 174: RET ( -1 ); ! 175: } ! 176: ! 177: DECLARE_UNNAMED_NODE(pc_kbd, INSTALL_OPEN, sizeof(unsigned long)); ! 178: ! 179: NODE_METHODS(pc_kbd) = { ! 180: { "open", pc_kbd_open }, ! 181: { "close", pc_kbd_close }, ! 182: { "read", pc_kbd_read }, ! 183: }; ! 184: ! 185: void ! 186: ob_pc_kbd_init(const char *path, const char *dev_name, uint64_t base, ! 187: uint64_t offset, int intr) ! 188: { ! 189: phandle_t chosen, aliases; ! 190: char nodebuff[128]; ! 191: ! 192: snprintf(nodebuff, sizeof(nodebuff), "%s/%s", path, dev_name); ! 193: REGISTER_NAMED_NODE(pc_kbd, nodebuff); ! 194: ! 195: push_str(nodebuff); ! 196: fword("find-device"); ! 197: ! 198: push_str(dev_name); ! 199: fword("device-name"); ! 200: ! 201: push_str("serial"); ! 202: fword("device-type"); ! 203: ! 204: PUSH(-1); ! 205: fword("encode-int"); ! 206: push_str("keyboard"); ! 207: fword("property"); ! 208: ! 209: PUSH(0); ! 210: fword("encode-int"); ! 211: push_str("reg"); ! 212: fword("property"); ! 213: ! 214: chosen = find_dev("/chosen"); ! 215: push_str(nodebuff); ! 216: fword("open-dev"); ! 217: set_int_property(chosen, "keyboard", POP()); ! 218: ! 219: aliases = find_dev("/aliases"); ! 220: set_property(aliases, "keyboard", nodebuff, strlen(nodebuff) + 1); ! 221: ! 222: pc_kbd_controller_cmd(0x60, 0x40); // Write mode command, translated mode ! 223: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.