Annotation of qemu/roms/openbios/drivers/pc_kbd.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.