|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: */ ! 27: ! 28: /* ! 29: * Olivetti Mach Console driver v0.0 ! 30: * Copyright Ing. C. Olivetti & C. S.p.A. 1988, 1989 ! 31: * All rights reserved. ! 32: * ! 33: */ ! 34: /* ! 35: * Copyright 1988, 1989 by Olivetti Advanced Technology Center, Inc., ! 36: * Cupertino, California. ! 37: * ! 38: * All Rights Reserved ! 39: * ! 40: * Permission to use, copy, modify, and distribute this software and ! 41: * its documentation for any purpose and without fee is hereby ! 42: * granted, provided that the above copyright notice appears in all ! 43: * copies and that both the copyright notice and this permission notice ! 44: * appear in supporting documentation, and that the name of Olivetti ! 45: * not be used in advertising or publicity pertaining to distribution ! 46: * of the software without specific, written prior permission. ! 47: * ! 48: * OLIVETTI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 49: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, ! 50: * IN NO EVENT SHALL OLIVETTI BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 51: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 52: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 53: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION ! 54: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 55: * ! 56: * ! 57: * Copyright 1988, 1989 by Intel Corporation, Santa Clara, California. ! 58: * ! 59: * All Rights Reserved ! 60: * ! 61: * Permission to use, copy, modify, and distribute this software and ! 62: * its documentation for any purpose and without fee is hereby ! 63: * granted, provided that the above copyright notice appears in all ! 64: * copies and that both the copyright notice and this permission notice ! 65: * appear in supporting documentation, and that the name of Intel ! 66: * not be used in advertising or publicity pertaining to distribution ! 67: * of the software without specific, written prior permission. ! 68: * ! 69: * INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 70: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, ! 71: * IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR ! 72: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 73: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, ! 74: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION ! 75: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 76: */ ! 77: ! 78: /* $ Header: $ */ ! 79: ! 80: #include <string.h> ! 81: #include "kd.h" ! 82: ! 83: #include <mach/i386/vm_param.h> ! 84: ! 85: #define at386_io_lock_state() ! 86: #define at386_io_lock(op) (TRUE) ! 87: #define at386_io_unlock() ! 88: ! 89: ! 90: typedef unsigned short i386_ioport_t; ! 91: ! 92: /* read a byte */ ! 93: extern unsigned char inb( ! 94: i386_ioport_t port); ! 95: /* write a longword */ ! 96: extern void outb( ! 97: i386_ioport_t port, ! 98: unsigned char datum); ! 99: ! 100: extern __inline__ unsigned char inb( ! 101: i386_ioport_t port) ! 102: { ! 103: unsigned char datum; ! 104: __asm__ volatile("inb %1, %0" : "=a" (datum) : "d" (port)); ! 105: return(datum); ! 106: } ! 107: ! 108: extern __inline__ void outb( ! 109: i386_ioport_t port, ! 110: unsigned char datum) ! 111: { ! 112: __asm__ volatile("outb %0, %1" : : "a" (datum), "d" (port)); ! 113: } ! 114: ! 115: /* Forward */ ! 116: ! 117: extern void kd_sendcmd(unsigned char ch); ! 118: extern void kdreboot(void); ! 119: extern int kd_dogetc(int wait); ! 120: extern void kd_handle_ack(void); ! 121: extern void kd_resend(void); ! 122: extern int do_modifier( ! 123: int state, ! 124: Scancode c, ! 125: int up); ! 126: extern int kdcheckmagic( ! 127: Scancode sc, ! 128: int * regs); ! 129: extern int kdstate2idx( ! 130: int state, ! 131: int extended); ! 132: extern void kdinit(void); ! 133: extern void kd_belloff(void); ! 134: extern void kd_bellon(void); ! 135: extern void kd_senddata(unsigned char c); ! 136: extern unsigned char kd_getdata(void); ! 137: extern unsigned char kd_cmdreg_read(void); ! 138: extern void set_kd_state( ! 139: int newstate); ! 140: extern unsigned char state2leds( ! 141: int state); ! 142: extern void kd_setleds1( ! 143: unsigned char val); ! 144: extern void kd_setleds2(void); ! 145: extern void cnsetleds( ! 146: unsigned char val); ! 147: extern int kd_kbd_magic( ! 148: int scancode); ! 149: ! 150: extern int cngetc(void); ! 151: extern int cnmaygetc(void); ! 152: extern void kdreboot(void); ! 153: extern int kd_dogetc(int wait); ! 154: ! 155: /* reboot on CTL-ALT-DEL ? */ ! 156: extern int rebootflag; ! 157: /* enter kernel debugger on CTR-ALT-d ? */ ! 158: int kbdkdbflag = 1; ! 159: /* allow keyboard mouse ? */ ! 160: int kbdmouseflag = 0; ! 161: ! 162: /* ! 163: * kd_state shows the state of the modifier keys (ctrl, caps lock, ! 164: * etc.) It should normally be changed by calling set_kd_state(), so ! 165: * that the keyboard status LEDs are updated correctly. ! 166: */ ! 167: int kd_state = KS_NORMAL; ! 168: int kb_mode = KB_ASCII; /* event/ascii */ ! 169: ! 170: int kd_kbd_mouse = 0; ! 171: int kd_kbd_magic_scale = 6; ! 172: int kd_kbd_magic_button = 0; ! 173: ! 174: /* ! 175: * Some keyboard commands work by sending a command, waiting for an ! 176: * ack (handled by kdintr), then sending data, which generates a ! 177: * second ack. If we are in the middle of such a sequence, kd_ack ! 178: * shows what the ack is for. ! 179: * ! 180: * When a byte is sent to the keyboard, it is kept around in last_sent ! 181: * in case it needs to be resent. ! 182: * ! 183: * The rest of the variables here hold the data required to complete ! 184: * the sequence. ! 185: * ! 186: * XXX - the System V driver keeps a command queue, I guess in case we ! 187: * want to start a command while another is in progress. Is this ! 188: * something we should worry about? ! 189: */ ! 190: enum why_ack {NOT_WAITING, SET_LEDS, DATA_ACK}; ! 191: enum why_ack kd_ack = NOT_WAITING; ! 192: ! 193: unsigned char last_sent = 0; ! 194: ! 195: unsigned char kd_nextled = 0; ! 196: ! 197: /* ! 198: * We don't provide any mutex protection for this flag because we know ! 199: * that this module will have been initialized by the time multiple ! 200: * threads are running. ! 201: */ ! 202: int kd_initialized = FALSE; /* driver initialized? */ ! 203: int kd_extended = FALSE; ! 204: ! 205: /* ! 206: * This array maps scancodes to Ascii characters (or character ! 207: * sequences). ! 208: * Each row corresponds to one key. There are NUMOUTPUT bytes per key ! 209: * state. The states are ordered: Normal, SHIFT, CTRL, ALT, ! 210: * SHIFT/ALT. ! 211: */ ! 212: unsigned char key_map[NUMKEYS][WIDTH_KMAP] = { ! 213: {NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC}, ! 214: {K_ESC,NC,NC, K_ESC,NC,NC, K_ESC,NC,NC, K_ESC,NC,NC, K_ESC,NC,NC}, ! 215: {K_ONE,NC,NC, K_BANG,NC,NC, K_ONE,NC,NC, 0x1b,0x4e,0x31, 0x1b,0x4e,0x21}, ! 216: {K_TWO,NC,NC, K_ATSN,NC,NC, K_NUL,NC,NC, 0x1b,0x4e,0x32, 0x1b,0x4e,0x40}, ! 217: {K_THREE,NC,NC, K_POUND,NC,NC, K_THREE,NC,NC, 0x1b,0x4e,0x33, 0x1b,0x4e,0x23}, ! 218: {K_FOUR,NC,NC, K_DOLLAR,NC,NC, K_FOUR,NC,NC, 0x1b,0x4e,0x34, 0x1b,0x4e,0x24}, ! 219: {K_FIVE,NC,NC, K_PERC,NC,NC, K_FIVE,NC,NC, 0x1b,0x4e,0x35, 0x1b,0x4e,0x25}, ! 220: {K_SIX,NC,NC, K_CARET,NC,NC, K_RS,NC,NC, 0x1b,0x4e,0x36, 0x1b,0x4e,0x5e}, ! 221: {K_SEVEN,NC,NC, K_AMPER,NC,NC, K_SEVEN,NC,NC, 0x1b,0x4e,0x37, 0x1b,0x4e,0x26}, ! 222: {K_EIGHT,NC,NC, K_ASTER,NC,NC, K_EIGHT,NC,NC, 0x1b,0x4e,0x38, 0x1b,0x4e,0x2a}, ! 223: {K_NINE,NC,NC, K_LPAREN,NC,NC, K_NINE,NC,NC, 0x1b,0x4e,0x39,0x1b,0x4e,0x28}, ! 224: {K_ZERO,NC,NC, K_RPAREN,NC,NC, K_ZERO,NC,NC, 0x1b,0x4e,0x30,0x1b,0x4e,0x29}, ! 225: {K_MINUS,NC,NC, K_UNDSC,NC,NC, K_US,NC,NC, 0x1b,0x4e,0x2d, 0x1b,0x4e,0x5f}, ! 226: {K_EQL,NC,NC, K_PLUS,NC,NC, K_EQL,NC,NC, 0x1b,0x4e,0x3d, 0x1b,0x4e,0x2b}, ! 227: {K_BS,NC,NC, K_BS,NC,NC, K_BS,NC,NC, K_BS,NC,NC, K_BS,NC,NC}, ! 228: {K_HT,NC,NC, K_GS,NC,NC, K_HT,NC,NC, K_HT,NC,NC, K_GS,NC,NC}, ! 229: {K_q,NC,NC, K_Q,NC,NC, K_DC1,NC,NC, 0x1b,0x4e,0x71, 0x1b,0x4e,0x51}, ! 230: {K_w,NC,NC, K_W,NC,NC, K_ETB,NC,NC, 0x1b,0x4e,0x77, 0x1b,0x4e,0x57}, ! 231: {K_e,NC,NC, K_E,NC,NC, K_ENQ,NC,NC, 0x1b,0x4e,0x65, 0x1b,0x4e,0x45}, ! 232: {K_r,NC,NC, K_R,NC,NC, K_DC2,NC,NC, 0x1b,0x4e,0x72, 0x1b,0x4e,0x52}, ! 233: {K_t,NC,NC, K_T,NC,NC, K_DC4,NC,NC, 0x1b,0x4e,0x74, 0x1b,0x4e,0x54}, ! 234: {K_y,NC,NC, K_Y,NC,NC, K_EM,NC,NC, 0x1b,0x4e,0x79, 0x1b,0x4e,0x59}, ! 235: {K_u,NC,NC, K_U,NC,NC, K_NAK,NC,NC, 0x1b,0x4e,0x75, 0x1b,0x4e,0x55}, ! 236: {K_i,NC,NC, K_I,NC,NC, K_HT,NC,NC, 0x1b,0x4e,0x69, 0x1b,0x4e,0x49}, ! 237: {K_o,NC,NC, K_O,NC,NC, K_SI,NC,NC, 0x1b,0x4e,0x6f, 0x1b,0x4e,0x4f}, ! 238: {K_p,NC,NC, K_P,NC,NC, K_DLE,NC,NC, 0x1b,0x4e,0x70, 0x1b,0x4e,0x50}, ! 239: {K_LBRKT,NC,NC, K_LBRACE,NC,NC, K_ESC,NC,NC, 0x1b,0x4e,0x5b, 0x1b,0x4e,0x7b}, ! 240: {K_RBRKT,NC,NC, K_RBRACE,NC,NC, K_GS,NC,NC, 0x1b,0x4e,0x5d, 0x1b,0x4e,0x7d}, ! 241: {K_CR,NC,NC, K_CR,NC,NC, K_CR,NC,NC, K_CR,NC,NC, K_CR,NC,NC}, ! 242: {K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, K_SCAN,K_CTLSC,NC, ! 243: K_SCAN,K_CTLSC,NC}, ! 244: {K_a,NC,NC, K_A,NC,NC, K_SOH,NC,NC, 0x1b,0x4e,0x61, 0x1b,0x4e,0x41}, ! 245: {K_s,NC,NC, K_S,NC,NC, K_DC3,NC,NC, 0x1b,0x4e,0x73, 0x1b,0x4e,0x53}, ! 246: {K_d,NC,NC, K_D,NC,NC, K_EOT,NC,NC, 0x1b,0x4e,0x65, 0x1b,0x4e,0x45}, ! 247: {K_f,NC,NC, K_F,NC,NC, K_ACK,NC,NC, 0x1b,0x4e,0x66, 0x1b,0x4e,0x46}, ! 248: {K_g,NC,NC, K_G,NC,NC, K_BEL,NC,NC, 0x1b,0x4e,0x67, 0x1b,0x4e,0x47}, ! 249: {K_h,NC,NC, K_H,NC,NC, K_BS,NC,NC, 0x1b,0x4e,0x68, 0x1b,0x4e,0x48}, ! 250: {K_j,NC,NC, K_J,NC,NC, K_LF,NC,NC, 0x1b,0x4e,0x6a, 0x1b,0x4e,0x4a}, ! 251: {K_k,NC,NC, K_K,NC,NC, K_VT,NC,NC, 0x1b,0x4e,0x6b, 0x1b,0x4e,0x4b}, ! 252: {K_l,NC,NC, K_L,NC,NC, K_FF,NC,NC, 0x1b,0x4e,0x6c, 0x1b,0x4e,0x4c}, ! 253: {K_SEMI,NC,NC, K_COLON,NC,NC, K_SEMI,NC,NC, 0x1b,0x4e,0x3b, 0x1b,0x4e,0x3a}, ! 254: {K_SQUOTE,NC,NC,K_DQUOTE,NC,NC,K_SQUOTE,NC,NC,0x1b,0x4e,0x27,0x1b,0x4e,0x22}, ! 255: {K_GRAV,NC,NC, K_TILDE,NC,NC, K_RS,NC,NC, 0x1b,0x4e,0x60, 0x1b,0x4e,0x7e}, ! 256: {K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, K_SCAN,K_LSHSC,NC, ! 257: K_SCAN,K_LSHSC,NC}, ! 258: {K_BSLSH,NC,NC, K_PIPE,NC,NC, K_FS,NC,NC, 0x1b,0x4e,0x5c, 0x1b,0x4e,0x7c}, ! 259: {K_z,NC,NC, K_Z,NC,NC, K_SUB,NC,NC, 0x1b,0x4e,0x7a, 0x1b,0x4e,0x5a}, ! 260: {K_x,NC,NC, K_X,NC,NC, K_CAN,NC,NC, 0x1b,0x4e,0x78, 0x1b,0x4e,0x58}, ! 261: {K_c,NC,NC, K_C,NC,NC, K_ETX,NC,NC, 0x1b,0x4e,0x63, 0x1b,0x4e,0x43}, ! 262: {K_v,NC,NC, K_V,NC,NC, K_SYN,NC,NC, 0x1b,0x4e,0x76, 0x1b,0x4e,0x56}, ! 263: {K_b,NC,NC, K_B,NC,NC, K_STX,NC,NC, 0x1b,0x4e,0x62, 0x1b,0x4e,0x42}, ! 264: {K_n,NC,NC, K_N,NC,NC, K_SO,NC,NC, 0x1b,0x4e,0x6e, 0x1b,0x4e,0x4e}, ! 265: {K_m,NC,NC, K_M,NC,NC, K_CR,NC,NC, 0x1b,0x4e,0x6d, 0x1b,0x4e,0x4d}, ! 266: {K_COMMA,NC,NC, K_LTHN,NC,NC, K_COMMA,NC,NC, 0x1b,0x4e,0x2c, 0x1b,0x4e,0x3c}, ! 267: {K_PERIOD,NC,NC, K_GTHN,NC,NC, K_PERIOD,NC,NC,0x1b,0x4e,0x2e,0x1b,0x4e,0x3e}, ! 268: {K_SLASH,NC,NC, K_QUES,NC,NC, K_SLASH,NC,NC, 0x1b,0x4e,0x2f, 0x1b,0x4e,0x3f}, ! 269: {K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, K_SCAN,K_RSHSC,NC, ! 270: K_SCAN,K_RSHSC,NC}, ! 271: {K_ASTER,NC,NC, K_ASTER,NC,NC, K_ASTER,NC,NC, 0x1b,0x4e,0x2a,0x1b,0x4e,0x2a}, ! 272: {K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, K_SCAN,K_ALTSC,NC, ! 273: K_SCAN,K_ALTSC,NC}, ! 274: {K_SPACE,NC,NC, K_SPACE,NC,NC, K_NUL,NC,NC, K_SPACE,NC,NC, K_SPACE,NC,NC}, ! 275: {K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC, ! 276: K_SCAN,K_CLCKSC,NC, K_SCAN,K_CLCKSC,NC}, ! 277: {K_F1, K_F1S, K_F1, K_F1, K_F1S}, ! 278: {K_F2, K_F2S, K_F2, K_F2, K_F2S}, ! 279: {K_F3, K_F3S, K_F3, K_F3, K_F3S}, ! 280: {K_F4, K_F4S, K_F4, K_F4, K_F4S}, ! 281: {K_F5, K_F5S, K_F5, K_F5, K_F5S}, ! 282: {K_F6, K_F6S, K_F6, K_F6, K_F6S}, ! 283: {K_F7, K_F7S, K_F7, K_F7, K_F7S}, ! 284: {K_F8, K_F8S, K_F8, K_F8, K_F8S}, ! 285: {K_F9, K_F9S, K_F9, K_F9, K_F9S}, ! 286: {K_F10, K_F10S, K_F10, K_F10, K_F10S}, ! 287: {K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC, ! 288: K_SCAN,K_NLCKSC,NC, K_SCAN,K_NLCKSC,NC}, ! 289: {K_SCRL, K_NUL,NC,NC, K_SCRL, K_SCRL, K_NUL,NC,NC}, ! 290: {K_HOME, K_SEVEN,NC,NC, K_HOME, K_HOME, 0x1b,0x4e,0x37}, ! 291: {K_UA, K_EIGHT,NC,NC, K_UA, K_UA, 0x1b,0x4e,0x38}, ! 292: {K_PUP, K_NINE,NC,NC, K_PUP, K_PUP, 0x1b,0x4e,0x39}, ! 293: {0x1b,0x5b,0x53, K_MINUS,NC,NC, 0x1b,0x5b,0x53,0x1b,0x5b,0x53,0x1b,0x4e,0x2d}, ! 294: {K_LA, K_FOUR,NC,NC, K_LA, K_LA, 0x1b,0x4e,0x34}, ! 295: {0x1b,0x5b,0x47,K_FIVE,NC,NC,0x1b,0x5b,0x47, 0x1b,0x5b,0x47, 0x1b,0x4e,0x35}, ! 296: {K_RA, K_SIX,NC,NC, K_RA, K_RA, 0x1b,0x4e,0x36}, ! 297: {0x1b,0x5b,0x54,K_PLUS,NC,NC, 0x1b,0x5b,0x54, 0x1b,0x5b,0x54, 0x1b,0x4e,0x2b}, ! 298: {K_END, K_ONE,NC,NC, K_END, K_END, 0x1b,0x4e,0x31}, ! 299: {K_DA, K_TWO,NC,NC, K_DA, K_DA, 0x1b,0x4e,0x32}, ! 300: {K_PDN, K_THREE,NC,NC, K_PDN, K_PDN, 0x1b,0x4e,0x33}, ! 301: {K_INS, K_ZERO,NC,NC, K_INS, K_INS, 0x1b,0x4e,0x30}, ! 302: {K_DEL,NC,NC, K_PERIOD,NC,NC, K_DEL,NC,NC, K_DEL,NC,NC, 0x1b,0x4e,0x2e}, ! 303: {NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC}, ! 304: {NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC}, ! 305: {NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC,NC}, ! 306: {K_F11, K_F11S, K_F11, K_F11, K_F11S}, ! 307: {K_F12, K_F12S, K_F12, K_F12, K_F12S} ! 308: }; ! 309: ! 310: extern void cnputc(unsigned char ch); ! 311: ! 312: /* ! 313: * Switch for poll vs. interrupt. ! 314: */ ! 315: int kd_pollc = 0; ! 316: ! 317: int (*cgetc)( ! 318: int wait) = kd_dogetc; ! 319: /* get a char. from console */ ! 320: void (*cputc)( ! 321: char ch) = cnputc; ! 322: /* put a char. to console */ ! 323: ! 324: /* ! 325: * cngetc: ! 326: * ! 327: * Get one character using polling, rather than interrupts. Used ! 328: * by the kernel debugger. Note that Caps Lock is ignored. ! 329: * Normally this routine is called with interrupts already ! 330: * disabled, but there is code in place so that it will be more ! 331: * likely to work even if interrupts are turned on. ! 332: */ ! 333: ! 334: int ! 335: cngetc(void) ! 336: { ! 337: int ret; ! 338: ! 339: ret = (*cgetc)(TRUE); ! 340: ! 341: return ret; ! 342: } ! 343: ! 344: int ! 345: cnmaygetc(void) ! 346: { ! 347: int ret; ! 348: ! 349: ret = (*cgetc)(FALSE); ! 350: ! 351: return ret; ! 352: } ! 353: ! 354: int ! 355: kd_dogetc( ! 356: int wait) ! 357: { ! 358: unsigned char c; ! 359: unsigned char scancode; ! 360: unsigned int char_idx; ! 361: int up; ! 362: ! 363: kdinit(); ! 364: kd_extended = FALSE; ! 365: ! 366: for ( ; ; ) { ! 367: while (!(inb(K_STATUS) & K_OBUF_FUL)) ! 368: if (!wait) ! 369: return (-1); ! 370: up = FALSE; ! 371: /* ! 372: * We'd come here for mouse events in debugger, if ! 373: * the mouse were on. ! 374: */ ! 375: if ((inb(K_STATUS) & 0x20) == 0x20) { ! 376: printf("M%xP", inb(K_RDWR)); ! 377: continue; ! 378: } ! 379: scancode = inb(K_RDWR); ! 380: /* ! 381: * Handle extend modifier and ! 382: * ack/resend, otherwise we may never receive ! 383: * a key. ! 384: */ ! 385: if (scancode == K_EXTEND) { ! 386: kd_extended = TRUE; ! 387: continue; ! 388: } else if (scancode == K_RESEND) { ! 389: /* printf("kd_getc: resend"); */ ! 390: kd_resend(); ! 391: continue; ! 392: } else if (scancode == K_ACKSC) { ! 393: /* printf("kd_getc: handle_ack"); */ ! 394: kd_handle_ack(); ! 395: continue; ! 396: } ! 397: if (scancode & K_UP) { ! 398: up = TRUE; ! 399: scancode &= ~K_UP; ! 400: } ! 401: if (kd_kbd_mouse) ! 402: kd_kbd_magic(scancode); ! 403: if (scancode < NUMKEYS) { ! 404: /* Lookup in map, then process. */ ! 405: char_idx = kdstate2idx(kd_state, kd_extended); ! 406: c = key_map[scancode][char_idx]; ! 407: if (c == K_SCAN) { ! 408: c = key_map[scancode][++char_idx]; ! 409: kd_state = do_modifier(kd_state, c, up); ! 410: #ifdef notdef ! 411: cnsetleds(state2leds(kd_state)); ! 412: #endif ! 413: } else if (!up) { ! 414: /* regular key-down */ ! 415: if (c == K_CR) ! 416: c = K_LF; ! 417: #ifdef notdef ! 418: splx(o_pri); ! 419: #endif ! 420: return(c & 0177); ! 421: } ! 422: } ! 423: } ! 424: } ! 425: ! 426: ! 427: int old_kb_mode; ! 428: ! 429: #if MACH_KDB ! 430: #define poll_spl() db_splhigh() /* prevent race w/ kdintr() */ ! 431: #define poll_splx(s) db_splx(s) ! 432: #else /* MACH_KDB */ ! 433: #define poll_spl() SPLKD() ! 434: #define poll_splx(s) splx(s) ! 435: #endif /* MACH_KDB */ ! 436: ! 437: ! 438: void ! 439: cnpollc( ! 440: int on) ! 441: { ! 442: int old_spl; /* spl we're called at... */ ! 443: ! 444: if (cpu_number()) { ! 445: return; ! 446: } ! 447: if (on) { ! 448: old_spl = poll_spl(); ! 449: ! 450: old_kb_mode = kb_mode; ! 451: kb_mode = KB_ASCII; ! 452: poll_splx(old_spl); ! 453: ! 454: kd_pollc++; ! 455: } else { ! 456: --kd_pollc; ! 457: ! 458: old_spl = poll_spl(); ! 459: kb_mode = old_kb_mode; ! 460: poll_splx(old_spl); ! 461: ! 462: ! 463: } ! 464: } ! 465: ! 466: /* ! 467: * kd_handle_ack: ! 468: * ! 469: * For pending commands, complete the command. For data bytes, ! 470: * drop the ack on the floor. ! 471: */ ! 472: ! 473: void ! 474: kd_handle_ack(void) ! 475: { ! 476: switch (kd_ack) { ! 477: case SET_LEDS: ! 478: kd_setleds2(); ! 479: kd_ack = DATA_ACK; ! 480: break; ! 481: case DATA_ACK: ! 482: kd_ack = NOT_WAITING; ! 483: break; ! 484: case NOT_WAITING: ! 485: printf("unexpected ACK from keyboard\n"); ! 486: break; ! 487: default: ! 488: panic("bogus kd_ack\n"); ! 489: break; ! 490: } ! 491: } ! 492: ! 493: /* ! 494: * kd_resend: ! 495: * ! 496: * Resend a missed keyboard command or data byte. ! 497: */ ! 498: ! 499: void ! 500: kd_resend(void) ! 501: { ! 502: if (kd_ack == NOT_WAITING) ! 503: printf("unexpected RESEND from keyboard\n"); ! 504: else ! 505: kd_senddata(last_sent); ! 506: } ! 507: ! 508: ! 509: /* ! 510: * do_modifier: ! 511: * ! 512: * Change keyboard state according to which modifier key and ! 513: * whether it went down or up. ! 514: * ! 515: * input: the current state, the key, and the key's direction. ! 516: * The key can be any key, not just a modifier key. ! 517: * ! 518: * output: the new state ! 519: */ ! 520: ! 521: int ! 522: do_modifier( ! 523: int state, ! 524: Scancode c, ! 525: int up) ! 526: { ! 527: switch (c) { ! 528: case (K_ALTSC): ! 529: if (up) ! 530: state &= ~KS_ALTED; ! 531: else ! 532: state |= KS_ALTED; ! 533: kd_extended = FALSE; ! 534: break; ! 535: #ifndef ORC ! 536: case (K_CLCKSC): ! 537: #endif /* ORC */ ! 538: case (K_CTLSC): ! 539: if (up) ! 540: state &= ~KS_CTLED; ! 541: else ! 542: state |= KS_CTLED; ! 543: kd_extended = FALSE; ! 544: break; ! 545: #ifdef ORC ! 546: case (K_CLCKSC): ! 547: if (!up) ! 548: state ^= KS_CLKED; ! 549: break; ! 550: #endif /* ORC */ ! 551: case (K_NLCKSC): ! 552: if (!up) ! 553: state ^= KS_NLKED; ! 554: break; ! 555: case (K_LSHSC): ! 556: case (K_RSHSC): ! 557: if (up) ! 558: state &= ~KS_SHIFTED; ! 559: else ! 560: state |= KS_SHIFTED; ! 561: kd_extended = FALSE; ! 562: break; ! 563: } ! 564: ! 565: return(state); ! 566: } ! 567: ! 568: ! 569: /* ! 570: * kdcheckmagic: ! 571: * ! 572: * Check for magic keystrokes for invoking the debugger or ! 573: * rebooting or ... ! 574: * ! 575: * input: an unprocessed scancode ! 576: * ! 577: * output: TRUE if a magic key combination was recognized and ! 578: * processed. FALSE otherwise. ! 579: * ! 580: * side effects: ! 581: * various actions possible, depending on which keys are ! 582: * pressed. If the debugger is called, steps are taken ! 583: * to ensure that the system doesn't think the magic keys ! 584: * are still held down. ! 585: */ ! 586: ! 587: int ! 588: kdcheckmagic( ! 589: Scancode scancode, ! 590: int *regs) ! 591: { ! 592: static int magic_state = KS_NORMAL; /* like kd_state */ ! 593: int up = FALSE; ! 594: extern int rebootflag; ! 595: ! 596: if (scancode == 0x46 && kbdmouseflag) /* scroll lock */ ! 597: { ! 598: kd_kbd_mouse = !kd_kbd_mouse; ! 599: kd_kbd_magic_button = 0; ! 600: return(TRUE); ! 601: } ! 602: if (scancode & K_UP) { ! 603: up = TRUE; ! 604: scancode &= ~K_UP; ! 605: } ! 606: magic_state = do_modifier(magic_state, scancode, up); ! 607: ! 608: if ((magic_state&(KS_CTLED|KS_ALTED)) == (KS_CTLED|KS_ALTED)) { ! 609: switch (scancode) { ! 610: #if MACH_KDB ! 611: case K_dSC: /* ctl-alt-d */ ! 612: if (!kbdkdbflag) ! 613: return(FALSE); ! 614: ! 615: kdb_kintr(); /* invoke debugger */ ! 616: ! 617: /* Returned from debugger, so reset kbd state. */ ! 618: (void)SPLKD(); ! 619: magic_state = KS_NORMAL; ! 620: if (kb_mode == KB_ASCII) ! 621: kd_state = KS_NORMAL; ! 622: /* setting leds kills kbd */ ! 623: ! 624: return(TRUE); ! 625: break; ! 626: #endif /* MACH_KDB */ ! 627: case K_DELSC: /* ctl-alt-del */ ! 628: /* if rebootflag is on, reboot the system */ ! 629: if (rebootflag) ! 630: kdreboot(); ! 631: break; ! 632: } ! 633: } ! 634: return(FALSE); ! 635: } ! 636: ! 637: ! 638: /* ! 639: * kdstate2idx: ! 640: * ! 641: * Return the value for the 2nd index into key_map that ! 642: * corresponds to the given state. ! 643: */ ! 644: ! 645: int ! 646: kdstate2idx( ! 647: int state, /* bit vector, not a state index */ ! 648: int extended) ! 649: { ! 650: int state_idx = NORM_STATE; ! 651: ! 652: if ((!extended) && state != KS_NORMAL) { ! 653: if ((state&(KS_SHIFTED|KS_ALTED)) == (KS_SHIFTED|KS_ALTED)) ! 654: state_idx = SHIFT_ALT; ! 655: else if (state&KS_SHIFTED) ! 656: state_idx = SHIFT_STATE; ! 657: else if (state&KS_ALTED) ! 658: state_idx = ALT_STATE; ! 659: else if (state&KS_CTLED) ! 660: state_idx = CTRL_STATE; ! 661: } ! 662: ! 663: return (CHARIDX(state_idx)); ! 664: } ! 665: ! 666: /* ! 667: * kdinit: ! 668: * ! 669: * This code initializes the structures and sets up the port registers ! 670: * for the console driver. ! 671: * ! 672: * Each bitmap-based graphics card is likely to require a unique ! 673: * way to determine the card's presence. The driver runs through ! 674: * each "special" card that it knows about and uses the first one ! 675: * that it finds. If it doesn't find any, it assumes that an ! 676: * EGA-like card is installed. ! 677: * ! 678: * input : None. Interrupts are assumed to be disabled ! 679: * output : Driver is initialized ! 680: * ! 681: */ ! 682: ! 683: void ! 684: kdinit(void) ! 685: { ! 686: unsigned char k_comm; /* keyboard command byte */ ! 687: unsigned char kd_stat; ! 688: ! 689: if (kd_initialized) ! 690: return; ! 691: kd_initialized = TRUE; ! 692: ! 693: /* get rid of any garbage in output buffer */ ! 694: if (inb(K_STATUS) & K_OBUF_FUL) ! 695: (void)inb(K_RDWR); ! 696: ! 697: cnsetleds(kd_state = KS_NORMAL); ! 698: ! 699: kd_sendcmd(KC_CMD_READ); /* ask for the ctlr command byte */ ! 700: k_comm = kd_getdata(); ! 701: k_comm &= ~K_CB_DISBLE; /* clear keyboard disable bit */ ! 702: k_comm |= K_CB_ENBLIRQ; /* enable interrupt */ ! 703: kd_sendcmd(KC_CMD_WRITE); /* write new ctlr command byte */ ! 704: kd_senddata(k_comm); ! 705: ! 706: /* set_kd_state(KS_NORMAL); does only HALF of set-leds sequence - ! 707: leaves kbd dead */ ! 708: ! 709: /* get rid of any garbage in output buffer */ ! 710: (void)inb(K_RDWR); ! 711: } ! 712: ! 713: /* ! 714: * kd_belloff: ! 715: * ! 716: * This routine shuts the bell off, by sending the appropriate code ! 717: * to the speaker port. ! 718: * ! 719: * input : None ! 720: * output : bell is turned off ! 721: * ! 722: */ ! 723: ! 724: void ! 725: kd_belloff(void) ! 726: { ! 727: unsigned char status; ! 728: ! 729: status = (inb(K_PORTB) & ~(K_SPKRDATA | K_ENABLETMR2)); ! 730: outb(K_PORTB, status); ! 731: } ! 732: ! 733: ! 734: /* ! 735: * kd_bellon: ! 736: * ! 737: * This routine turns the bell on. ! 738: * ! 739: * input : None ! 740: * output : bell is turned on ! 741: * ! 742: */ ! 743: ! 744: void ! 745: kd_bellon(void) ! 746: { ! 747: unsigned char status; ! 748: ! 749: /* program timer 2 */ ! 750: outb(K_TMRCTL, K_SELTMR2 | K_RDLDTWORD | K_TSQRWAVE | K_TBINARY); ! 751: outb(K_TMR2, 1500 & 0xff); /* LSB */ ! 752: outb(K_TMR2, (int)1500 >> 8); /* MSB */ ! 753: ! 754: /* start speaker - why must we turn on K_SPKRDATA? */ ! 755: status = (inb(K_PORTB)| K_ENABLETMR2 | K_SPKRDATA); ! 756: outb(K_PORTB, status); ! 757: return; ! 758: } ! 759: ! 760: /* ! 761: * kd_senddata: ! 762: * ! 763: * This function sends a byte to the keyboard RDWR port, but ! 764: * first waits until the input/output data buffer is clear before ! 765: * sending the data. Note that this byte can be either data or a ! 766: * keyboard command. ! 767: * ! 768: */ ! 769: ! 770: void ! 771: kd_senddata( ! 772: unsigned char ch) ! 773: { ! 774: while (inb(K_STATUS) & K_IBUF_FUL); ! 775: outb(K_RDWR, ch); ! 776: last_sent = ch; ! 777: } ! 778: ! 779: /* ! 780: * kd_sendcmd: ! 781: * ! 782: * This function sends a command byte to the keyboard command ! 783: * port, but first waits until the input/output data buffer is ! 784: * clear before sending the data. ! 785: * ! 786: */ ! 787: ! 788: void ! 789: kd_sendcmd( ! 790: unsigned char ch) ! 791: { ! 792: while (inb(K_STATUS) & K_IBUF_FUL); ! 793: outb(K_CMD, ch); ! 794: } ! 795: ! 796: ! 797: /* ! 798: * kd_getdata: ! 799: * ! 800: * This function returns a data byte from the keyboard RDWR port, ! 801: * after waiting until the port is flagged as having something to ! 802: * read. ! 803: */ ! 804: ! 805: unsigned char ! 806: kd_getdata(void) ! 807: { ! 808: while ((inb(K_STATUS) & K_OBUF_FUL) == 0); ! 809: return(inb(K_RDWR)); ! 810: } ! 811: ! 812: unsigned char ! 813: kd_cmdreg_read(void) ! 814: { ! 815: int ch=KC_CMD_READ; ! 816: ! 817: while (inb(K_STATUS) & (K_IBUF_FUL | K_OBUF_FUL)); ! 818: outb(K_CMD, ch); ! 819: ! 820: while ((inb(K_STATUS) & K_OBUF_FUL) == 0); ! 821: return(inb(K_RDWR)); ! 822: } ! 823: ! 824: void ! 825: kd_cmdreg_write( ! 826: unsigned char val) ! 827: { ! 828: int ch=KC_CMD_WRITE; ! 829: ! 830: while (inb(K_STATUS) & K_IBUF_FUL); ! 831: outb(K_CMD, ch); ! 832: ! 833: while (inb(K_STATUS) & K_IBUF_FUL); ! 834: outb(K_RDWR, val); ! 835: } ! 836: ! 837: int kd_mouse_write_no_ack = 0; ! 838: ! 839: int ! 840: kd_mouse_write( ! 841: unsigned char val) ! 842: { ! 843: int ch=0xd4; /* output byte to aux device (i.e. mouse) */ ! 844: int ret = 0; ! 845: ! 846: while (inb(K_STATUS) & K_IBUF_FUL); ! 847: outb(K_CMD, ch); ! 848: ! 849: while (inb(K_STATUS) & K_IBUF_FUL); ! 850: outb(K_RDWR, val); ! 851: ! 852: if (kd_mouse_write_no_ack) goto done; ! 853: ! 854: while ((inb(K_STATUS) & K_OBUF_FUL) == 0); ! 855: if ((inb(K_STATUS) & 0x20) == 0x20) { ! 856: switch (ret = inb(K_RDWR)) { ! 857: case 0xfa: ! 858: break; ! 859: case 0xfe: ! 860: case 0xfc: ! 861: default: ! 862: printf("kd_mouse_write: saw %x for %x\n", ! 863: ret, val); ! 864: } ! 865: } else { /* abort */ ! 866: printf("kd_mouse_write: sync error ??? on %x\n", val); ! 867: } ! 868: ! 869: done: ! 870: return ret; ! 871: } ! 872: ! 873: void ! 874: kd_mouse_read( ! 875: int no, ! 876: char *buf) ! 877: { ! 878: ! 879: while (no-- > 0) { ! 880: while ((inb(K_STATUS) & K_OBUF_FUL) == 0); ! 881: /* ! 882: * We may have seen a mouse event. ! 883: */ ! 884: if ((inb(K_STATUS) & 0x20) == 0x20) { ! 885: *buf++ = (unsigned char)inb(K_RDWR); ! 886: } else { /* abort */ ! 887: int junk = inb(K_RDWR); ! 888: printf("kd_mouse_read: sync error, received: 0x%x\n", ! 889: junk); ! 890: break; ! 891: } ! 892: } ! 893: } ! 894: ! 895: void ! 896: kd_mouse_drain(void) ! 897: { ! 898: int i; ! 899: while(inb(K_STATUS) & K_IBUF_FUL); ! 900: while((i = inb(K_STATUS)) & K_OBUF_FUL) ! 901: printf("kbd: S = %x D = %x\n", i, inb(K_RDWR)); ! 902: } ! 903: ! 904: /* ! 905: * set_kd_state: ! 906: * ! 907: * Set kd_state and update the keyboard status LEDs. ! 908: */ ! 909: ! 910: void ! 911: set_kd_state( ! 912: int newstate) ! 913: { ! 914: kd_state = newstate; ! 915: kd_setleds1(state2leds(newstate)); ! 916: } ! 917: ! 918: /* ! 919: * state2leds: ! 920: * ! 921: * Return a byte containing LED settings for the keyboard, given ! 922: * a state vector. ! 923: */ ! 924: ! 925: unsigned char ! 926: state2leds( ! 927: int state) ! 928: { ! 929: unsigned char result = 0; ! 930: ! 931: if (state & KS_NLKED) ! 932: result |= K_LED_NUMLK; ! 933: if (state & KS_CLKED) ! 934: result |= K_LED_CAPSLK; ! 935: return(result); ! 936: } ! 937: ! 938: /* ! 939: * kd_setleds[12]: ! 940: * ! 941: * Set the keyboard LEDs according to the given byte. ! 942: */ ! 943: ! 944: void ! 945: kd_setleds1( ! 946: unsigned char val) ! 947: { ! 948: if (kd_ack != NOT_WAITING) { ! 949: printf("kd_setleds1: unexpected state (%d)\n", kd_ack); ! 950: return; ! 951: } ! 952: ! 953: kd_ack = SET_LEDS; ! 954: kd_nextled = val; ! 955: kd_senddata(K_CMD_LEDS); ! 956: } ! 957: ! 958: void ! 959: kd_setleds2(void) ! 960: { ! 961: kd_senddata(kd_nextled); ! 962: } ! 963: ! 964: ! 965: /* ! 966: * cnsetleds: ! 967: * ! 968: * like kd_setleds[12], but not interrupt-based. ! 969: * Currently disabled because cngetc ignores caps lock and num ! 970: * lock anyway. ! 971: */ ! 972: ! 973: void ! 974: cnsetleds( ! 975: unsigned char val) ! 976: { ! 977: kd_senddata(K_CMD_LEDS); ! 978: (void)kd_getdata(); /* XXX - assume is ACK */ ! 979: kd_senddata(val); ! 980: (void)kd_getdata(); /* XXX - assume is ACK */ ! 981: } ! 982: ! 983: void ! 984: kdreboot(void) ! 985: { ! 986: kd_sendcmd(0xFE); /* XXX - magic # */ ! 987: /* ! 988: * DRAT. We're still here. Let's try a "CPU shutdown", which consists ! 989: * of clearing the IDTR and causing an exception. It's in locore.s ! 990: */ ! 991: cpu_shutdown(); ! 992: /*NOTREACHED*/ ! 993: } ! 994: ! 995: int ! 996: kd_kbd_magic( ! 997: int scancode) ! 998: { ! 999: int new_button = 0; ! 1000: ! 1001: if (kd_kbd_mouse == 2) ! 1002: printf("sc = %x\n", scancode); ! 1003: ! 1004: switch (scancode) { ! 1005: /* f1 f2 f3 */ ! 1006: case 0x3d: ! 1007: new_button++; ! 1008: case 0x3c: ! 1009: new_button++; ! 1010: case 0x3b: ! 1011: new_button++; ! 1012: if (kd_kbd_magic_button && (new_button != kd_kbd_magic_button)) { ! 1013: /* down w/o up */ ! 1014: } ! 1015: /* normal */ ! 1016: if (kd_kbd_magic_button == new_button) { ! 1017: kd_kbd_magic_button = 0; ! 1018: } else { ! 1019: kd_kbd_magic_button = new_button; ! 1020: } ! 1021: break; ! 1022: default: ! 1023: return 0; ! 1024: } ! 1025: return 1; ! 1026: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.