1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * Miniature keyboard driver for bootstrap.  This allows keyboard
  30  * support to continue after we take over interrupts and disable
  31  * BIOS keyboard support.
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <sys/archsystm.h>
  36 #include <sys/boot_console.h>
  37 #include "boot_keyboard_table.h"
  38 
  39 #if defined(_BOOT)
  40 #include "dboot/dboot_asm.h"
  41 #include "dboot/dboot_xboot.h"
  42 #endif /* _BOOT */
  43 
  44 /*
  45  * Definitions for BIOS keyboard state.  We use BIOS's variable to store
  46  * state, ensuring that we stay in sync with it.
  47  */
  48 #define BIOS_KB_FLAG            0x417
  49 #define BIOS_RIGHT_SHIFT        0x01
  50 #define BIOS_LEFT_SHIFT         0x02
  51 #define BIOS_EITHER_SHIFT       (BIOS_LEFT_SHIFT | BIOS_RIGHT_SHIFT)
  52 #define BIOS_CTL_SHIFT          0x04
  53 #define BIOS_ALT_SHIFT          0x08
  54 #define BIOS_SCROLL_STATE       0x10
  55 #define BIOS_NUM_STATE          0x20
  56 #define BIOS_CAPS_STATE         0x40
  57 #define BIOS_INS_STATE          0x80
  58 
  59 #define BIOS_KB_FLAG_1          0x418
  60 #define BIOS_SYS_SHIFT          0x04
  61 #define BIOS_HOLD_STATE         0x08
  62 #define BIOS_SCROLL_SHIFT       0x10
  63 #define BIOS_NUM_SHIFT          0x20
  64 #define BIOS_CAPS_SHIFT         0x40
  65 #define BIOS_INS_SHIFT          0x80
  66 
  67 #if defined(__xpv) && defined(_BOOT)
  68 
  69 /*
  70  * Device memory addresses
  71  *
  72  * In dboot under the hypervisor we don't have any memory mappings
  73  * for the first meg of low memory so we can't access devices there.
  74  * Intead we've mapped the device memory that we need to access into
  75  * a local variable within dboot so we can access the device memory
  76  * there.
  77  */
  78 extern unsigned short *kb_status;
  79 #define kb_flag         ((unsigned char *)&kb_status[BIOS_KB_FLAG])
  80 #define kb_flag_1       ((unsigned char *)&kb_status[BIOS_KB_FLAG_1])
  81 
  82 #else /* __xpv && _BOOT */
  83 
  84 /* Device memory addresses */
  85 #define kb_flag         ((unsigned char *)BIOS_KB_FLAG)
  86 #define kb_flag_1       ((unsigned char *)BIOS_KB_FLAG_1)
  87 
  88 #endif /* __xpv && _BOOT */
  89 
  90 /*
  91  * Keyboard controller registers
  92  */
  93 #define I8042_DATA              0x60
  94 #define I8042_STAT              0x64
  95 #define I8042_CMD               0x64
  96 
  97 /*
  98  * Keyboard controller status register bits
  99  */
 100 #define I8042_STAT_OUTBF        0x01
 101 #define I8042_STAT_INBF         0x02
 102 #define I8042_STAT_AUXBF        0x20
 103 
 104 /*
 105  * Keyboard controller commands
 106  */
 107 #define I8042_RCB               0x20
 108 #define I8042_WCB               0x60
 109 
 110 /*
 111  * Keyboard commands
 112  */
 113 #define KB_SET_LED              0xED    /* LED byte follows... */
 114 #define KB_LED_SCROLL_LOCK      0x01    /* Bits for LED byte */
 115 #define KB_LED_NUM_LOCK         0x02
 116 #define KB_LED_CAPS_LOCK        0x04
 117 
 118 #ifndef ASSERT
 119 #define ASSERT(x)
 120 #endif
 121 
 122 #define peek8(p)        (*(p))
 123 #define poke8(p, val)   (*(p) = (val))
 124 
 125 static struct {
 126         boolean_t       initialized;
 127         enum { KB_LED_IDLE, KB_LED_COMMAND_SENT, KB_LED_VALUE_SENT }
 128                         led_state;
 129         int             led_commanded;
 130         /*
 131          * Possible values:
 132          *
 133          * -1           Nothing pending
 134          * 0x000-0x0ff  Pending byte
 135          * 0x100-0x1ff  Needs leading zero, then low byte next.
 136          *
 137          * Others undefined.
 138          */
 139         int             pending;
 140 } kb = {
 141         B_FALSE,        /* initialized? */
 142         KB_LED_IDLE,    /* LED command state */
 143         -1,             /* commanded LEDs - force refresh */
 144         -1,             /* pending */
 145 };
 146 
 147 static int kb_translate(unsigned char code);
 148 static void kb_send(unsigned char cmd);
 149 static void kb_update_leds(void);
 150 static uchar_t kb_calculate_leds(void);
 151 
 152 int
 153 kb_getchar(void)
 154 {
 155         int ret;
 156 
 157         while (!kb_ischar())
 158                 /* LOOP */;
 159 
 160         /*
 161          * kb_ischar() doesn't succeed without leaving kb.pending
 162          * set.
 163          */
 164         ASSERT(kb.pending >= 0);
 165 
 166         if (kb.pending & 0x100) {
 167                 ret = 0;
 168                 kb.pending &= 0xff;
 169         } else {
 170                 ret = kb.pending;
 171                 kb.pending = -1;
 172         }
 173 
 174         return (ret);
 175 }
 176 
 177 int
 178 kb_ischar(void)
 179 {
 180         unsigned char buffer_stat;
 181         unsigned char code;
 182         unsigned char leds;
 183 
 184         if (!kb.initialized) {
 185                 kb_init();
 186                 kb.initialized = B_TRUE;
 187         }
 188 
 189         if (kb.pending >= 0)
 190                 return (1);
 191 
 192         for (;;) {
 193                 buffer_stat = inb(I8042_STAT);
 194                 if (buffer_stat == 0xff)
 195                         return (0);
 196                 buffer_stat &= (I8042_STAT_OUTBF | I8042_STAT_AUXBF);
 197 
 198                 switch (buffer_stat) {
 199                 case 0:
 200                 case I8042_STAT_AUXBF:
 201                         return (0);
 202                 case (I8042_STAT_OUTBF | I8042_STAT_AUXBF):
 203                         /*
 204                          * Discard unwanted mouse data.
 205                          */
 206                         (void) inb(I8042_DATA);
 207                         continue;
 208                 }
 209 
 210                 code = inb(I8042_DATA);
 211 
 212                 switch (code) {
 213                 /*
 214                  * case 0xAA:
 215                  *
 216                  * You might think that we should ignore 0xAA on the
 217                  * grounds that it is the BAT Complete response and will
 218                  * occur on keyboard detach/reattach.  Unfortunately,
 219                  * it is ambiguous - this is also the code for a break
 220                  * of the left shift key.  Since it will be harmless for
 221                  * us to "spuriously" process a break of Left Shift,
 222                  * we just let the normal code handle it.  Perhaps we
 223                  * should take a hint and refresh the LEDs, but I
 224                  * refuse to get very worried about hot-plug issues
 225                  * in this mini-driver.
 226                  */
 227                 case 0xFA:
 228 
 229                         switch (kb.led_state) {
 230                         case KB_LED_IDLE:
 231                                 /*
 232                                  * Spurious.  Oh well, ignore it.
 233                                  */
 234                                 break;
 235                         case KB_LED_COMMAND_SENT:
 236                                 leds = kb_calculate_leds();
 237                                 kb_send(leds);
 238                                 kb.led_commanded = leds;
 239                                 kb.led_state = KB_LED_VALUE_SENT;
 240                                 break;
 241                         case KB_LED_VALUE_SENT:
 242                                 kb.led_state = KB_LED_IDLE;
 243                                 /*
 244                                  * Check for changes made while we were
 245                                  * working on the last change.
 246                                  */
 247                                 kb_update_leds();
 248                                 break;
 249                         }
 250                         continue;
 251 
 252                 case 0xE0:
 253                 case 0xE1:
 254                         /*
 255                          * These are used to distinguish the keys added on
 256                          * the AT-101 keyboard from the original 84 keys.
 257                          * We don't care, and the codes are carefully arranged
 258                          * so that we don't have to.
 259                          */
 260                         continue;
 261 
 262                 default:
 263                         if (code & 0x80) {
 264                                 /* Release */
 265                                 code &= 0x7f;
 266                                 switch (keyboard_translate[code].normal) {
 267                                 case KBTYPE_SPEC_LSHIFT:
 268                                         poke8(kb_flag, peek8(kb_flag) &
 269                                             ~BIOS_LEFT_SHIFT);
 270                                         break;
 271                                 case KBTYPE_SPEC_RSHIFT:
 272                                         poke8(kb_flag, peek8(kb_flag) &
 273                                             ~BIOS_RIGHT_SHIFT);
 274                                         break;
 275                                 case KBTYPE_SPEC_CTRL:
 276                                         poke8(kb_flag, peek8(kb_flag) &
 277                                             ~BIOS_CTL_SHIFT);
 278                                         break;
 279                                 case KBTYPE_SPEC_ALT:
 280                                         poke8(kb_flag, peek8(kb_flag) &
 281                                             ~BIOS_ALT_SHIFT);
 282                                         break;
 283                                 case KBTYPE_SPEC_CAPS_LOCK:
 284                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 285                                             ~BIOS_CAPS_SHIFT);
 286                                         break;
 287                                 case KBTYPE_SPEC_NUM_LOCK:
 288                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 289                                             ~BIOS_NUM_SHIFT);
 290                                         break;
 291                                 case KBTYPE_SPEC_SCROLL_LOCK:
 292                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 293                                             ~BIOS_SCROLL_SHIFT);
 294                                         break;
 295                                 default:
 296                                         /*
 297                                          * Ignore all other releases.
 298                                          */
 299                                         break;
 300                                 }
 301                         } else {
 302                                 /* Press */
 303 
 304                                 kb.pending = kb_translate(code);
 305                                 if (kb.pending >= 0) {
 306                                         return (1);
 307                                 }
 308                         }
 309                 }
 310         }
 311 }
 312 
 313 int
 314 kb_translate(unsigned char code)
 315 {
 316         struct keyboard_translate *k;
 317         unsigned short action;
 318         boolean_t shifted;
 319 
 320         k = keyboard_translate + code;
 321 
 322         shifted = (peek8(kb_flag) & BIOS_EITHER_SHIFT) != 0;
 323 
 324         switch (k->normal & 0xFF00) {
 325         case KBTYPE_NUMPAD:
 326                 if (peek8(kb_flag) & BIOS_NUM_STATE)
 327                         shifted = !shifted;
 328                 break;
 329         case KBTYPE_ALPHA:
 330                 if (peek8(kb_flag) & BIOS_CAPS_STATE)
 331                         shifted = !shifted;
 332                 break;
 333         }
 334 
 335         if (peek8(kb_flag) & BIOS_ALT_SHIFT)
 336                 action = k->alted;
 337         else if (peek8(kb_flag) & BIOS_CTL_SHIFT)
 338                 action = k->ctrled;
 339         else if (shifted)
 340                 action = k->shifted;
 341         else
 342                 action = k->normal;
 343 
 344         switch (action & 0xFF00) {
 345         case KBTYPE_NORMAL:
 346         case KBTYPE_ALPHA:
 347                 return (action & 0xFF);
 348 
 349         case KBTYPE_NUMPAD:
 350         case KBTYPE_FUNC:
 351                 return ((action & 0xFF) | 0x100);
 352 
 353         case KBTYPE_SPEC:
 354                 break;
 355 
 356         default:
 357                 /*
 358                  * Bad entry.
 359                  */
 360                 ASSERT(0);
 361                 return (-1);
 362         }
 363 
 364         /*
 365          * Handle special keys, mostly shifts.
 366          */
 367         switch (action) {
 368         case KBTYPE_SPEC_NOP:
 369         case KBTYPE_SPEC_UNDEF:
 370                 break;
 371 
 372         case KBTYPE_SPEC_LSHIFT:
 373                 poke8(kb_flag, peek8(kb_flag) | BIOS_LEFT_SHIFT);
 374                 break;
 375 
 376         case KBTYPE_SPEC_RSHIFT:
 377                 poke8(kb_flag, peek8(kb_flag) | BIOS_RIGHT_SHIFT);
 378                 break;
 379 
 380         case KBTYPE_SPEC_CTRL:
 381                 poke8(kb_flag, peek8(kb_flag) | BIOS_CTL_SHIFT);
 382                 break;
 383 
 384         case KBTYPE_SPEC_ALT:
 385                 poke8(kb_flag, peek8(kb_flag) | BIOS_ALT_SHIFT);
 386                 break;
 387 
 388         case KBTYPE_SPEC_CAPS_LOCK:
 389                 if (!(peek8(kb_flag_1) & BIOS_CAPS_SHIFT)) {
 390                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_CAPS_SHIFT);
 391                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_CAPS_STATE);
 392                 }
 393                 break;
 394 
 395         case KBTYPE_SPEC_NUM_LOCK:
 396                 if (!(peek8(kb_flag_1) & BIOS_NUM_SHIFT)) {
 397                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_NUM_SHIFT);
 398                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_NUM_STATE);
 399                 }
 400                 break;
 401 
 402         case KBTYPE_SPEC_SCROLL_LOCK:
 403                 if (!(peek8(kb_flag_1) & BIOS_SCROLL_SHIFT)) {
 404                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_SCROLL_SHIFT);
 405                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_SCROLL_STATE);
 406                 }
 407                 break;
 408 
 409         case KBTYPE_SPEC_MAYBE_REBOOT:
 410 #if 0   /* Solaris doesn't reboot via ctrl-alt-del */
 411                 if ((peek8(kb_flag) & (BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) ==
 412                     (BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) {
 413                         reset();
 414                         /* NOTREACHED */
 415                 }
 416 #endif
 417                 break;
 418 
 419         default:
 420                 /*
 421                  * Bad entry
 422                  */
 423                 ASSERT(0);
 424                 break;
 425         }
 426 
 427         /*
 428          * Consider updating the LEDs.  This does nothing if nothing
 429          * needs to be done.
 430          */
 431         kb_update_leds();
 432 
 433         return (-1);
 434 }
 435 
 436 void
 437 kb_send(unsigned char cmd)
 438 {
 439         int retries;
 440 
 441         for (retries = 0;
 442             (inb(I8042_STAT) & I8042_STAT_INBF) != 0 && retries < 100000;
 443             retries++)
 444                 /* LOOP */;
 445         outb(I8042_DATA, cmd);
 446 }
 447 
 448 void
 449 kb_update_leds(void)
 450 {
 451         if (kb.led_state != KB_LED_IDLE) {
 452                 /*
 453                  * The state machine will take care of any additional
 454                  * changes that are necessary.
 455                  */
 456                 return;
 457         }
 458 
 459         if (kb_calculate_leds() == kb.led_commanded) {
 460                 kb.led_state = KB_LED_IDLE;
 461         } else {
 462                 kb_send(KB_SET_LED);
 463                 kb.led_state = KB_LED_COMMAND_SENT;
 464         }
 465 }
 466 
 467 #define MIMR_PORT       0x21    /* Mask register for master PIC */
 468 #define MIMR_KB         2       /* Keyboard mask bit in master PIC */
 469 
 470 void
 471 kb_init(void)
 472 {
 473         /*
 474          * Resist the urge to muck with the keyboard/mouse.  Just assume
 475          * that the bios, grub, and any optional hypervisor have left
 476          * the keyboard in a sane and usable state.  Messing with it now
 477          * could result it making it unusuable, which would break early
 478          * kmdb debugging support.  Note that we don't actually need to
 479          * disable interrupts for the keyboard/mouse since we're already
 480          * in protected mode and we're not compeating with the bios for
 481          * keyboard access.  Also, we don't need to disable the mouse
 482          * port since our polled input routine will just drop any mouse
 483          * data that it recieves.
 484          */
 485         kb_update_leds();
 486 }
 487 
 488 unsigned char
 489 kb_calculate_leds(void)
 490 {
 491         int res;
 492 
 493         res = 0;
 494 
 495         if (peek8(kb_flag) & BIOS_CAPS_STATE)
 496                 res |= KB_LED_CAPS_LOCK;
 497 
 498         if (peek8(kb_flag) & BIOS_NUM_STATE)
 499                 res |= KB_LED_NUM_LOCK;
 500 
 501         if (peek8(kb_flag) & BIOS_SCROLL_STATE)
 502                 res |= KB_LED_SCROLL_LOCK;
 503 
 504         return ((char)res);
 505 }