Annotation of qemu/roms/openbios/drivers/pc_kbd.c, revision 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.