Changeset 40040 in vbox for trunk/src/VBox/Devices/Input/DevPS2.cpp
- Timestamp:
- Feb 8, 2012 4:49:31 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DevPS2.cpp
r39972 r40040 98 98 #define KBD_CCMD_RESET 0xFE 99 99 100 /* Keyboard Commands */101 #define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */102 #define KBD_CMD_ECHO 0xEE103 #define KBD_CMD_SCANCODE 0xF0 /* Get/set scancode set */104 #define KBD_CMD_GET_ID 0xF2 /* get keyboard ID */105 #define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */106 #define KBD_CMD_ENABLE 0xF4 /* Enable scanning */107 #define KBD_CMD_RESET_DISABLE 0xF5 /* reset and disable scanning */108 #define KBD_CMD_RESET_ENABLE 0xF6 /* reset and enable scanning */109 #define KBD_CMD_RESET 0xFF /* Reset */110 111 /* Keyboard Replies */112 #define KBD_REPLY_POR 0xAA /* Power on reset */113 #define KBD_REPLY_ACK 0xFA /* Command ACK */114 #define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */115 116 100 /* Status Register Bits */ 117 101 #define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */ … … 157 141 #define MOUSE_STATUS_SCALE21 0x10 158 142 159 #define KBD_QUEUE_SIZE 256160 161 143 /** Supported mouse protocols */ 162 144 enum … … 173 155 /** @} */ 174 156 175 typedef struct {176 uint8_t data[KBD_QUEUE_SIZE];177 int rptr, wptr, count;178 } KBDQueue;179 180 157 #define MOUSE_CMD_QUEUE_SIZE 8 181 158 … … 194 171 195 172 typedef struct KBDState { 196 KBDQueue queue;197 173 MouseCmdQueue mouse_command_queue; 198 174 MouseEventQueue mouse_event_queue; … … 202 178 uint8_t dbbout; /* data buffer byte */ 203 179 /* keyboard state */ 204 int32_t kbd_write_cmd;205 int32_t scan_enabled;206 180 int32_t translate; 207 int32_t scancode_set; /* 1=XT, 2=AT, 3=PS/2 */208 181 int32_t xlat_state; 209 182 /* mouse state */ … … 242 215 #endif 243 216 244 #if OLD_KBD245 /**246 * Keyboard port - LUN#0.247 *248 * @implements PDMIBASE249 * @implements PDMIKEYBOARDPORT250 */251 struct252 {253 /** The base interface for the keyboard port. */254 PDMIBASE IBase;255 /** The keyboard port base interface. */256 PDMIKEYBOARDPORT IPort;257 258 /** The base interface of the attached keyboard driver. */259 R3PTRTYPE(PPDMIBASE) pDrvBase;260 /** The keyboard interface of the attached keyboard driver. */261 R3PTRTYPE(PPDMIKEYBOARDCONNECTOR) pDrv;262 } Keyboard;263 #endif264 265 217 /** 266 218 * Mouse port - LUN#1. … … 283 235 } KBDState; 284 236 285 /* Table to convert from PC scancodes to scan code set 2. */286 static const unsigned char ps2_raw_keycode_set2[128] = {287 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,288 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,289 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42,290 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88, 5, 6, 4, 12, 3,291 11, 2, 10, 1, 9,119,126,108,117,125,123,107,115,116,121,105,292 114,122,112,113,127, 96, 97,120, 7, 15, 23, 31, 39, 47, 55, 63,293 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,294 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110295 };296 297 /* Table to convert from PC scancodes to scan code set 3. */298 static const unsigned char ps2_raw_keycode_set3[128] = {299 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,300 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 17, 28, 27,301 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 92, 26, 34, 33, 42,302 50, 49, 58, 65, 73, 74, 89,124, 25, 41, 20, 5, 6, 4, 12, 3,303 11, 2, 10, 1, 9,118,126,108,117,125,123,107,115,116,121,105,304 114,122,112,113,127, 96, 19,120, 7, 15, 23, 31, 39, 47, 55, 63,305 71, 79, 86, 94, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111,306 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110307 };308 309 237 #ifndef VBOX_DEVICE_STRUCT_TESTCASE 310 238 … … 312 240 static void kbd_update_irq(KBDState *s) 313 241 { 314 KBDQueue *q = &s->queue;315 242 MouseCmdQueue *mcq = &s->mouse_command_queue; 316 243 MouseEventQueue *meq = &s->mouse_event_queue; … … 328 255 s->status &= ~KBD_STAT_MOUSE_OBF; 329 256 /* Keyboard data has priority if both kbd and aux data is available. */ 330 #ifdef OLD_KBD331 if (q->count && !(s->mode & KBD_MODE_DISABLE_KBD))332 {333 s->status |= KBD_STAT_OBF;334 s->dbbout = q->data[q->rptr];335 if (++q->rptr == KBD_QUEUE_SIZE)336 q->rptr = 0;337 q->count--;338 }339 #else340 257 if (!(s->mode & KBD_MODE_DISABLE_KBD) && PS2KByteFromKbd(&s->Kbd, &val) == VINF_SUCCESS) 341 258 { … … 368 285 } 369 286 } 370 #endif371 287 else if ((mcq->count || meq->count) && !(s->mode & KBD_MODE_DISABLE_MOUSE)) 372 288 { … … 413 329 static void kbd_queue(KBDState *s, int b, int aux) 414 330 { 415 KBDQueue *q = &s->queue;416 331 MouseCmdQueue *mcq = &s->mouse_command_queue; 417 332 MouseEventQueue *meq = &s->mouse_event_queue; … … 430 345 { 431 346 case 0: /* keyboard */ 432 if (q->count >= KBD_QUEUE_SIZE) 433 return; 434 q->data[q->wptr] = b; 435 if (++q->wptr == KBD_QUEUE_SIZE) 436 q->wptr = 0; 437 q->count++; 347 AssertMsgFailed(("kbd_queue() no longer supported for keyboard!\n")); 438 348 break; 439 349 case 1: /* mouse command response */ … … 458 368 kbd_update_irq(s); 459 369 } 460 461 #ifdef IN_RING3462 static void pc_kbd_put_keycode(void *opaque, int keycode)463 {464 KBDState *s = (KBDState*)opaque;465 466 /* XXX: add support for scancode sets 1 and 3 */467 if (!s->translate && keycode < 0xe0 && s->scancode_set >= 2)468 {469 if (keycode & 0x80)470 kbd_queue(s, 0xf0, 0);471 if (s->scancode_set == 2)472 keycode = ps2_raw_keycode_set2[keycode & 0x7f];473 else if (s->scancode_set == 3)474 keycode = ps2_raw_keycode_set3[keycode & 0x7f];475 }476 kbd_queue(s, keycode, 0);477 }478 #endif /* IN_RING3 */479 370 480 371 static void kbc_dbb_out(void *opaque, uint8_t val) … … 651 542 } 652 543 653 #ifdef OLD_KBD654 655 static void kbd_reset_keyboard(KBDState *s)656 {657 s->scan_enabled = 1;658 s->scancode_set = 2;659 /* Flush the keyboard queue. */660 s->queue.count = 0;661 s->queue.rptr = 0;662 s->queue.wptr = 0;663 }664 665 /* The keyboard BAT is specified to take several hundred milliseconds. We need666 * to delay sending the result to the host for at least a tiny little while.667 */668 static DECLCALLBACK(void) kbd_timer_cb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)669 {670 KBDState *pThis = PDMINS_2_DATA(pDevIns, KBDState *);671 int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY);672 AssertReleaseRC(rc);673 674 kbd_queue(pThis, KBD_REPLY_POR, 0);675 676 PDMCritSectLeave(&pThis->CritSect);677 }678 679 static int kbd_write_keyboard(KBDState *s, int val)680 {681 switch(s->kbd_write_cmd) {682 default:683 case -1:684 switch(val) {685 case 0x00:686 kbd_queue(s, KBD_REPLY_ACK, 0);687 break;688 case 0x05:689 kbd_queue(s, KBD_REPLY_RESEND, 0);690 break;691 case KBD_CMD_GET_ID:692 kbd_queue(s, KBD_REPLY_ACK, 0);693 kbd_queue(s, 0xab, 0);694 kbd_queue(s, 0x83, 0);695 break;696 case KBD_CMD_ECHO:697 kbd_queue(s, KBD_CMD_ECHO, 0);698 break;699 case KBD_CMD_ENABLE:700 s->scan_enabled = 1;701 kbd_queue(s, KBD_REPLY_ACK, 0);702 break;703 case KBD_CMD_SCANCODE:704 case KBD_CMD_SET_LEDS:705 case KBD_CMD_SET_RATE:706 s->kbd_write_cmd = val;707 kbd_queue(s, KBD_REPLY_ACK, 0);708 break;709 case KBD_CMD_RESET_DISABLE:710 kbd_reset_keyboard(s);711 s->scan_enabled = 0;712 kbd_queue(s, KBD_REPLY_ACK, 0);713 break;714 case KBD_CMD_RESET_ENABLE:715 kbd_reset_keyboard(s);716 s->scan_enabled = 1;717 kbd_queue(s, KBD_REPLY_ACK, 0);718 break;719 case KBD_CMD_RESET:720 kbd_reset_keyboard(s);721 kbd_queue(s, KBD_REPLY_ACK, 0);722 kbd_queue(s, KBD_REPLY_POR, 0);723 break;724 default:725 kbd_queue(s, KBD_REPLY_ACK, 0);726 break;727 }728 break;729 case KBD_CMD_SCANCODE:730 #ifdef IN_RING3731 if (val == 0) {732 if (s->scancode_set == 1)733 pc_kbd_put_keycode(s, 0x43);734 else if (s->scancode_set == 2)735 pc_kbd_put_keycode(s, 0x41);736 else if (s->scancode_set == 3)737 pc_kbd_put_keycode(s, 0x3f);738 } else {739 if (val >= 1 && val <= 3) {740 LogRel(("kbd: scan code set %d selected\n", val));741 s->scancode_set = val;742 }743 kbd_queue(s, KBD_REPLY_ACK, 0);744 }745 #else746 return VINF_IOM_HC_IOPORT_WRITE;747 #endif748 case KBD_CMD_SET_LEDS:749 {750 #ifdef IN_RING3751 PDMKEYBLEDS enmLeds = PDMKEYBLEDS_NONE;752 if (val & 0x01)753 enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_SCROLLLOCK);754 if (val & 0x02)755 enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_NUMLOCK);756 if (val & 0x04)757 enmLeds = (PDMKEYBLEDS)(enmLeds | PDMKEYBLEDS_CAPSLOCK);758 s->Keyboard.pDrv->pfnLedStatusChange(s->Keyboard.pDrv, enmLeds);759 #else760 return VINF_IOM_HC_IOPORT_WRITE;761 #endif762 kbd_queue(s, KBD_REPLY_ACK, 0);763 s->kbd_write_cmd = -1;764 }765 break;766 case KBD_CMD_SET_RATE:767 kbd_queue(s, KBD_REPLY_ACK, 0);768 s->kbd_write_cmd = -1;769 break;770 }771 772 return VINF_SUCCESS;773 }774 775 #else776 544 PS2K *GetPS2KFromDevIns(PPDMDEVINS pDevIns) 777 545 { … … 779 547 return &pThis->Kbd; 780 548 } 781 #endif782 549 783 550 static void kbd_mouse_set_reported_buttons(KBDState *s, unsigned fButtons, unsigned fButtonMask) … … 1152 919 /* Automatically enables keyboard interface. */ 1153 920 s->mode &= ~KBD_MODE_DISABLE_KBD; 1154 #ifdef OLD_KBD1155 rc = kbd_write_keyboard(s, val);1156 #else1157 921 rc = PS2KByteToKbd(&s->Kbd, val); 1158 922 if (rc == VINF_SUCCESS) 1159 923 kbd_update_irq(s); 1160 #endif1161 924 break; 1162 925 case KBD_CCMD_WRITE_MODE: … … 1206 969 { 1207 970 KBDState *s = (KBDState*)opaque; 1208 KBDQueue *q;1209 971 MouseCmdQueue *mcq; 1210 972 MouseEventQueue *meq; 1211 973 1212 s->kbd_write_cmd = -1;1213 974 s->mouse_write_cmd = -1; 1214 975 s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT; … … 1216 977 /* Resetting everything, keyword was not working right on NT4 reboot. */ 1217 978 s->write_cmd = 0; 1218 s->scan_enabled = 0;1219 979 s->translate = 0; 1220 s->scancode_set = 2;1221 980 if (s->mouse_status) 1222 981 { … … 1236 995 s->mouse_buttons = 0; 1237 996 s->mouse_buttons_reported = 0; 1238 q = &s->queue;1239 q->rptr = 0;1240 q->wptr = 0;1241 q->count = 0;1242 997 mcq = &s->mouse_command_queue; 1243 998 mcq->rptr = 0; … … 1275 1030 qemu_put_8s(f, &s->mouse_buttons_reported); 1276 1031 1277 #ifdef OLD_KBD1278 /* XXX: s->scancode_set isn't being saved, but we only really support set 2,1279 * so no real harm done.1280 */1281 1282 /*1283 * We have to save the queues too.1284 */1285 cItems = s->queue.count;1286 SSMR3PutU32(f, cItems);1287 for (i = s->queue.rptr; cItems-- > 0; i = (i + 1) % RT_ELEMENTS(s->queue.data))1288 SSMR3PutU8(f, s->queue.data[i]);1289 Log(("kbd_save: %d keyboard queue items stored\n", s->queue.count));1290 #endif1291 1292 1032 cItems = s->mouse_command_queue.count; 1293 1033 SSMR3PutU32(f, cItems); … … 1327 1067 if (version_id <= 5) 1328 1068 { 1329 qemu_get_be32s(f, (uint32_t *)& s->kbd_write_cmd);1330 qemu_get_be32s(f, (uint32_t *)& s->scan_enabled);1069 qemu_get_be32s(f, (uint32_t *)&u32Dummy); 1070 qemu_get_be32s(f, (uint32_t *)&u32Dummy); 1331 1071 } 1332 1072 else … … 1359 1099 if (version_id == 4) 1360 1100 SSMR3GetU8(f, &u8Dummy); 1361 s->queue.count = 0;1362 s->queue.rptr = 0;1363 s->queue.wptr = 0;1364 1101 s->mouse_command_queue.count = 0; 1365 1102 s->mouse_command_queue.rptr = 0; … … 1371 1108 /* Determine the translation state. */ 1372 1109 s->translate = (s->mode & KBD_MODE_KCC) == KBD_MODE_KCC; 1373 s->scancode_set = 2; /* XXX: See comment in kbd_save(). */1374 1110 1375 1111 /* … … 1381 1117 if (RT_FAILURE(rc)) 1382 1118 return rc; 1383 if (u32 > RT_ELEMENTS(s->queue.data))1384 {1385 AssertMsgFailed(("u32=%#x\n", u32));1386 return VERR_SSM_DATA_UNIT_FORMAT_CHANGED;1387 }1388 1119 for (i = 0; i < u32; i++) 1389 1120 { 1390 rc = SSMR3GetU8(f, & s->queue.data[i]);1121 rc = SSMR3GetU8(f, &u8Dummy); 1391 1122 if (RT_FAILURE(rc)) 1392 1123 return rc; 1393 1124 } 1394 s->queue.wptr = u32 % RT_ELEMENTS(s->queue.data); 1395 s->queue.count = u32; 1396 Log(("kbd_load: %d keyboard queue items loaded\n", u32)); 1125 Log(("kbd_load: %d keyboard queue items discarded from old saved state\n", u32)); 1397 1126 } 1398 1127 … … 1625 1354 1626 1355 kbd_reset(pThis); 1627 #ifdef OLD_KBD1628 /* Activate the PS/2 keyboard by default. */1629 if (pThis->Keyboard.pDrv)1630 pThis->Keyboard.pDrv->pfnSetActive(pThis->Keyboard.pDrv, true);1631 #else1632 1356 PS2KReset(&pThis->Kbd); 1633 #endif 1634 } 1635 1636 #ifdef OLD_KBD 1637 1638 /* -=-=-=-=-=- Keyboard: IBase -=-=-=-=-=- */ 1639 1640 /** 1641 * @interface_method_impl{PDMIBASE,pfnQueryInterface} 1642 */ 1643 static DECLCALLBACK(void *) kbdKeyboardQueryInterface(PPDMIBASE pInterface, const char *pszIID) 1644 { 1645 KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IBase); 1646 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->Keyboard.IBase); 1647 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIKEYBOARDPORT, &pThis->Keyboard.IPort); 1648 return NULL; 1649 } 1650 1651 1652 /* -=-=-=-=-=- Keyboard: IKeyboardPort -=-=-=-=-=- */ 1653 1654 /** 1655 * Keyboard event handler. 1656 * 1657 * @returns VBox status code. 1658 * @param pInterface Pointer to the keyboard port interface (KBDState::Keyboard.IPort). 1659 * @param u8KeyCode The keycode. 1660 */ 1661 static DECLCALLBACK(int) kbdKeyboardPutEvent(PPDMIKEYBOARDPORT pInterface, uint8_t u8KeyCode) 1662 { 1663 KBDState *pThis = RT_FROM_MEMBER(pInterface, KBDState, Keyboard.IPort); 1664 int rc = PDMCritSectEnter(&pThis->CritSect, VERR_SEM_BUSY); 1665 AssertReleaseRC(rc); 1666 1667 pc_kbd_put_keycode(pThis, u8KeyCode); 1668 1669 PDMCritSectLeave(&pThis->CritSect); 1670 return VINF_SUCCESS; 1671 } 1672 #endif 1357 } 1673 1358 1674 1359 … … 1747 1432 /* LUN #0: keyboard */ 1748 1433 case 0: 1749 #ifdef OLD_KBD1750 rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThis->Keyboard.IBase, &pThis->Keyboard.pDrvBase, "Keyboard Port");1751 if (RT_SUCCESS(rc))1752 {1753 pThis->Keyboard.pDrv = PDMIBASE_QUERY_INTERFACE(pThis->Keyboard.pDrvBase, PDMIKEYBOARDCONNECTOR);1754 if (!pThis->Keyboard.pDrv)1755 {1756 AssertLogRelMsgFailed(("LUN #0 doesn't have a keyboard interface! rc=%Rrc\n", rc));1757 rc = VERR_PDM_MISSING_INTERFACE;1758 }1759 }1760 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)1761 {1762 Log(("%s/%d: warning: no driver attached to LUN #0!\n", pDevIns->pReg->szName, pDevIns->iInstance));1763 rc = VINF_SUCCESS;1764 }1765 else1766 AssertLogRelMsgFailed(("Failed to attach LUN #0! rc=%Rrc\n", rc));1767 #else1768 1434 rc = PS2KAttach(pDevIns, &pThis->Kbd, iLUN, fFlags); 1769 1435 if (RT_FAILURE(rc)) 1770 1436 return rc; 1771 1772 #endif1773 1437 break; 1774 1438 … … 1911 1575 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 1912 1576 1913 #if OLD_KBD1914 pThis->Keyboard.IBase.pfnQueryInterface = kbdKeyboardQueryInterface;1915 pThis->Keyboard.IPort.pfnPutEvent = kbdKeyboardPutEvent;1916 #else1917 1577 rc = PS2KConstruct(pDevIns, &pThis->Kbd, pThis, iInstance); 1918 1578 if (RT_FAILURE(rc)) 1919 1579 return rc; 1920 #endif1921 1580 1922 1581 pThis->Mouse.IBase.pfnQueryInterface = kbdMouseQueryInterface;
Note:
See TracChangeset
for help on using the changeset viewer.