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 #define KTAB_STRLEN 3
 148 static char keystringtab[KTAB_STRLEN] = {'\033', '[', ' '};
 149 static int keystring = -1;
 150 
 151 static int kb_translate(unsigned char code);
 152 static void kb_send(unsigned char cmd);
 153 static void kb_update_leds(void);
 154 static uchar_t kb_calculate_leds(void);
 155 
 156 int
 157 kb_getchar(void)
 158 {
 159         int ret;
 160 
 161         while (!kb_ischar())
 162                 /* LOOP */;
 163 
 164         if (keystring >= 0) {
 165                 ret = keystringtab[keystring++];
 166                 if (keystring == KTAB_STRLEN) {
 167                         keystring = -1;
 168                         kb.pending = -1;
 169                 }
 170                 return (ret);
 171         }
 172 
 173         /*
 174          * kb_ischar() doesn't succeed without leaving kb.pending
 175          * set.
 176          */
 177         ASSERT(kb.pending >= 0);
 178 
 179         if (kb.pending & 0x100) {
 180                 kb.pending &= 0xff;
 181                 switch (kb.pending) {
 182                 case 'H':               /* Up */
 183                         keystringtab[2] = 'A';
 184                         keystring = 0;
 185                         return (kb_getchar());
 186                 case 'P':               /* Down */
 187                         keystringtab[2] = 'B';
 188                         keystring = 0;
 189                         return (kb_getchar());
 190                 case 'M':               /* Right */
 191                         keystringtab[2] = 'C';
 192                         keystring = 0;
 193                         return (kb_getchar());
 194                 case 'K':               /* Left */
 195                         keystringtab[2] = 'D';
 196                         keystring = 0;
 197                         return (kb_getchar());
 198                 default:
 199                         ret = 0;
 200                 }
 201         } else {
 202                 ret = kb.pending;
 203                 kb.pending = -1;
 204         }
 205 
 206         return (ret);
 207 }
 208 
 209 int
 210 kb_ischar(void)
 211 {
 212         unsigned char buffer_stat;
 213         unsigned char code;
 214         unsigned char leds;
 215 
 216         if (!kb.initialized) {
 217                 kb_init();
 218                 kb.initialized = B_TRUE;
 219         }
 220 
 221         if (kb.pending >= 0)
 222                 return (1);
 223 
 224         for (;;) {
 225                 buffer_stat = inb(I8042_STAT);
 226                 if (buffer_stat == 0xff)
 227                         return (0);
 228                 buffer_stat &= (I8042_STAT_OUTBF | I8042_STAT_AUXBF);
 229 
 230                 switch (buffer_stat) {
 231                 case 0:
 232                 case I8042_STAT_AUXBF:
 233                         return (0);
 234                 case (I8042_STAT_OUTBF | I8042_STAT_AUXBF):
 235                         /*
 236                          * Discard unwanted mouse data.
 237                          */
 238                         (void) inb(I8042_DATA);
 239                         continue;
 240                 }
 241 
 242                 code = inb(I8042_DATA);
 243 
 244                 switch (code) {
 245                 /*
 246                  * case 0xAA:
 247                  *
 248                  * You might think that we should ignore 0xAA on the
 249                  * grounds that it is the BAT Complete response and will
 250                  * occur on keyboard detach/reattach.  Unfortunately,
 251                  * it is ambiguous - this is also the code for a break
 252                  * of the left shift key.  Since it will be harmless for
 253                  * us to "spuriously" process a break of Left Shift,
 254                  * we just let the normal code handle it.  Perhaps we
 255                  * should take a hint and refresh the LEDs, but I
 256                  * refuse to get very worried about hot-plug issues
 257                  * in this mini-driver.
 258                  */
 259                 case 0xFA:
 260 
 261                         switch (kb.led_state) {
 262                         case KB_LED_IDLE:
 263                                 /*
 264                                  * Spurious.  Oh well, ignore it.
 265                                  */
 266                                 break;
 267                         case KB_LED_COMMAND_SENT:
 268                                 leds = kb_calculate_leds();
 269                                 kb_send(leds);
 270                                 kb.led_commanded = leds;
 271                                 kb.led_state = KB_LED_VALUE_SENT;
 272                                 break;
 273                         case KB_LED_VALUE_SENT:
 274                                 kb.led_state = KB_LED_IDLE;
 275                                 /*
 276                                  * Check for changes made while we were
 277                                  * working on the last change.
 278                                  */
 279                                 kb_update_leds();
 280                                 break;
 281                         }
 282                         continue;
 283 
 284                 case 0xE0:
 285                 case 0xE1:
 286                         /*
 287                          * These are used to distinguish the keys added on
 288                          * the AT-101 keyboard from the original 84 keys.
 289                          * We don't care, and the codes are carefully arranged
 290                          * so that we don't have to.
 291                          */
 292                         continue;
 293 
 294                 default:
 295                         if (code & 0x80) {
 296                                 /* Release */
 297                                 code &= 0x7f;
 298                                 switch (keyboard_translate[code].normal) {
 299                                 case KBTYPE_SPEC_LSHIFT:
 300                                         poke8(kb_flag, peek8(kb_flag) &
 301                                             ~BIOS_LEFT_SHIFT);
 302                                         break;
 303                                 case KBTYPE_SPEC_RSHIFT:
 304                                         poke8(kb_flag, peek8(kb_flag) &
 305                                             ~BIOS_RIGHT_SHIFT);
 306                                         break;
 307                                 case KBTYPE_SPEC_CTRL:
 308                                         poke8(kb_flag, peek8(kb_flag) &
 309                                             ~BIOS_CTL_SHIFT);
 310                                         break;
 311                                 case KBTYPE_SPEC_ALT:
 312                                         poke8(kb_flag, peek8(kb_flag) &
 313                                             ~BIOS_ALT_SHIFT);
 314                                         break;
 315                                 case KBTYPE_SPEC_CAPS_LOCK:
 316                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 317                                             ~BIOS_CAPS_SHIFT);
 318                                         break;
 319                                 case KBTYPE_SPEC_NUM_LOCK:
 320                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 321                                             ~BIOS_NUM_SHIFT);
 322                                         break;
 323                                 case KBTYPE_SPEC_SCROLL_LOCK:
 324                                         poke8(kb_flag_1, peek8(kb_flag_1) &
 325                                             ~BIOS_SCROLL_SHIFT);
 326                                         break;
 327                                 default:
 328                                         /*
 329                                          * Ignore all other releases.
 330                                          */
 331                                         break;
 332                                 }
 333                         } else {
 334                                 /* Press */
 335 
 336                                 kb.pending = kb_translate(code);
 337                                 if (kb.pending >= 0) {
 338                                         return (1);
 339                                 }
 340                         }
 341                 }
 342         }
 343 }
 344 
 345 int
 346 kb_translate(unsigned char code)
 347 {
 348         struct keyboard_translate *k;
 349         unsigned short action;
 350         boolean_t shifted;
 351 
 352         k = keyboard_translate + code;
 353 
 354         shifted = (peek8(kb_flag) & BIOS_EITHER_SHIFT) != 0;
 355 
 356         switch (k->normal & 0xFF00) {
 357         case KBTYPE_NUMPAD:
 358                 if (peek8(kb_flag) & BIOS_NUM_STATE)
 359                         shifted = !shifted;
 360                 break;
 361         case KBTYPE_ALPHA:
 362                 if (peek8(kb_flag) & BIOS_CAPS_STATE)
 363                         shifted = !shifted;
 364                 break;
 365         }
 366 
 367         if (peek8(kb_flag) & BIOS_ALT_SHIFT)
 368                 action = k->alted;
 369         else if (peek8(kb_flag) & BIOS_CTL_SHIFT)
 370                 action = k->ctrled;
 371         else if (shifted)
 372                 action = k->shifted;
 373         else
 374                 action = k->normal;
 375 
 376         switch (action & 0xFF00) {
 377         case KBTYPE_NORMAL:
 378         case KBTYPE_ALPHA:
 379                 return (action & 0xFF);
 380 
 381         case KBTYPE_NUMPAD:
 382         case KBTYPE_FUNC:
 383                 return ((action & 0xFF) | 0x100);
 384 
 385         case KBTYPE_SPEC:
 386                 break;
 387 
 388         default:
 389                 /*
 390                  * Bad entry.
 391                  */
 392                 ASSERT(0);
 393                 return (-1);
 394         }
 395 
 396         /*
 397          * Handle special keys, mostly shifts.
 398          */
 399         switch (action) {
 400         case KBTYPE_SPEC_NOP:
 401         case KBTYPE_SPEC_UNDEF:
 402                 break;
 403 
 404         case KBTYPE_SPEC_LSHIFT:
 405                 poke8(kb_flag, peek8(kb_flag) | BIOS_LEFT_SHIFT);
 406                 break;
 407 
 408         case KBTYPE_SPEC_RSHIFT:
 409                 poke8(kb_flag, peek8(kb_flag) | BIOS_RIGHT_SHIFT);
 410                 break;
 411 
 412         case KBTYPE_SPEC_CTRL:
 413                 poke8(kb_flag, peek8(kb_flag) | BIOS_CTL_SHIFT);
 414                 break;
 415 
 416         case KBTYPE_SPEC_ALT:
 417                 poke8(kb_flag, peek8(kb_flag) | BIOS_ALT_SHIFT);
 418                 break;
 419 
 420         case KBTYPE_SPEC_CAPS_LOCK:
 421                 if (!(peek8(kb_flag_1) & BIOS_CAPS_SHIFT)) {
 422                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_CAPS_SHIFT);
 423                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_CAPS_STATE);
 424                 }
 425                 break;
 426 
 427         case KBTYPE_SPEC_NUM_LOCK:
 428                 if (!(peek8(kb_flag_1) & BIOS_NUM_SHIFT)) {
 429                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_NUM_SHIFT);
 430                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_NUM_STATE);
 431                 }
 432                 break;
 433 
 434         case KBTYPE_SPEC_SCROLL_LOCK:
 435                 if (!(peek8(kb_flag_1) & BIOS_SCROLL_SHIFT)) {
 436                         poke8(kb_flag_1, peek8(kb_flag_1) | BIOS_SCROLL_SHIFT);
 437                         poke8(kb_flag, peek8(kb_flag) ^ BIOS_SCROLL_STATE);
 438                 }
 439                 break;
 440 
 441         case KBTYPE_SPEC_MAYBE_REBOOT:
 442 #if 0   /* Solaris doesn't reboot via ctrl-alt-del */
 443                 if ((peek8(kb_flag) & (BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) ==
 444                     (BIOS_CTL_SHIFT|BIOS_ALT_SHIFT)) {
 445                         reset();
 446                         /* NOTREACHED */
 447                 }
 448 #endif
 449                 break;
 450 
 451         default:
 452                 /*
 453                  * Bad entry
 454                  */
 455                 ASSERT(0);
 456                 break;
 457         }
 458 
 459         /*
 460          * Consider updating the LEDs.  This does nothing if nothing
 461          * needs to be done.
 462          */
 463         kb_update_leds();
 464 
 465         return (-1);
 466 }
 467 
 468 void
 469 kb_send(unsigned char cmd)
 470 {
 471         int retries;
 472 
 473         for (retries = 0;
 474             (inb(I8042_STAT) & I8042_STAT_INBF) != 0 && retries < 100000;
 475             retries++)
 476                 /* LOOP */;
 477         outb(I8042_DATA, cmd);
 478 }
 479 
 480 void
 481 kb_update_leds(void)
 482 {
 483         if (kb.led_state != KB_LED_IDLE) {
 484                 /*
 485                  * The state machine will take care of any additional
 486                  * changes that are necessary.
 487                  */
 488                 return;
 489         }
 490 
 491         if (kb_calculate_leds() == kb.led_commanded) {
 492                 kb.led_state = KB_LED_IDLE;
 493         } else {
 494                 kb_send(KB_SET_LED);
 495                 kb.led_state = KB_LED_COMMAND_SENT;
 496         }
 497 }
 498 
 499 #define MIMR_PORT       0x21    /* Mask register for master PIC */
 500 #define MIMR_KB         2       /* Keyboard mask bit in master PIC */
 501 
 502 void
 503 kb_init(void)
 504 {
 505         /*
 506          * Resist the urge to muck with the keyboard/mouse.  Just assume
 507          * that the bios, grub, and any optional hypervisor have left
 508          * the keyboard in a sane and usable state.  Messing with it now
 509          * could result it making it unusuable, which would break early
 510          * kmdb debugging support.  Note that we don't actually need to
 511          * disable interrupts for the keyboard/mouse since we're already
 512          * in protected mode and we're not compeating with the bios for
 513          * keyboard access.  Also, we don't need to disable the mouse
 514          * port since our polled input routine will just drop any mouse
 515          * data that it recieves.
 516          */
 517         kb_update_leds();
 518 }
 519 
 520 unsigned char
 521 kb_calculate_leds(void)
 522 {
 523         int res;
 524 
 525         res = 0;
 526 
 527         if (peek8(kb_flag) & BIOS_CAPS_STATE)
 528                 res |= KB_LED_CAPS_LOCK;
 529 
 530         if (peek8(kb_flag) & BIOS_NUM_STATE)
 531                 res |= KB_LED_NUM_LOCK;
 532 
 533         if (peek8(kb_flag) & BIOS_SCROLL_STATE)
 534                 res |= KB_LED_SCROLL_LOCK;
 535 
 536         return ((char)res);
 537 }