Changeset 71351 in vbox
- Timestamp:
- Mar 15, 2018 1:26:21 PM (7 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Input/DevPS2.cpp
r69704 r71351 963 963 * Validate and read the configuration. 964 964 */ 965 if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0R0Enabled\0 "))965 if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0R0Enabled\0KbdThrottleEnabled\0")) 966 966 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 967 967 rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true); … … 981 981 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns); 982 982 983 rc = PS2KConstruct(&pThis->Kbd, pDevIns, pThis, iInstance );983 rc = PS2KConstruct(&pThis->Kbd, pDevIns, pThis, iInstance, pCfg); 984 984 if (RT_FAILURE(rc)) 985 985 return rc; -
trunk/src/VBox/Devices/Input/PS2Dev.h
r69500 r71351 46 46 int PS2KByteFromKbd(PPS2K pThis, uint8_t *pVal); 47 47 48 int PS2KConstruct(PPS2K pThis, PPDMDEVINS pDevIns, void *pParent, int iInstance );48 int PS2KConstruct(PPS2K pThis, PPDMDEVINS pDevIns, void *pParent, int iInstance, PCFGMNODE pCfg); 49 49 int PS2KAttach(PPS2K pThis, PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags); 50 50 void PS2KReset(PPS2K pThis); -
trunk/src/VBox/Devices/Input/PS2K.cpp
r69500 r71351 30 30 * However, Num Lock is not and the keyboard internally tracks its state. 31 31 * - The way Print Screen works in scan set 1/2 is totally insane. 32 * - A PS/2 keyboard can send at most 1,000 to 1,500 bytes per second. There is 33 * software which relies on that fact and assumes that a scan code can be 34 * read twice before the next scan code comes in. 32 35 */ 33 36 … … 112 115 #define KBD_DFL_RATE_DELAY 0x2B 113 116 117 /* Input throttling delay in milliseconds. */ 118 #define KBD_THROTTLE_DELAY 1 119 114 120 /** Define a simple PS/2 input device queue. */ 115 121 #define DEF_PS2Q_TYPE(name, size) \ … … 132 138 * Structures and Typedefs * 133 139 *********************************************************************************************************************************/ 134 135 /** Scancode translator state. */136 typedef enum {137 SS_IDLE, /**< Starting state. */138 SS_EXT, /**< E0 byte was received. */139 SS_EXT1 /**< E1 byte was received. */140 } scan_state_t;141 140 142 141 /** Typematic state. */ … … 188 187 /** Typematic repeat period in milliseconds. */ 189 188 unsigned uTypematicRepeat; 190 #if HC_ARCH_BITS == 32 191 uint32_t Alignment0; 192 #endif 189 /** Set if the throttle delay is currently active. */ 190 bool fThrottleActive; 191 /** Set if the input rate should be throttled. */ 192 bool fThrottleEnabled; 193 194 uint8_t Alignment0[2]; 193 195 194 196 /** Command delay timer - RC Ptr. */ … … 196 198 /** Typematic timer - RC Ptr. */ 197 199 PTMTIMERRC pKbdTypematicTimerRC; 200 /** Input throttle timer - RC Ptr. */ 201 PTMTIMERRC pThrottleTimerRC; 198 202 199 203 /** The device critical section protecting everything - R3 Ptr */ 200 204 R3PTRTYPE(PPDMCRITSECT) pCritSectR3; 205 201 206 /** Command delay timer - R3 Ptr. */ 202 207 PTMTIMERR3 pKbdDelayTimerR3; 203 208 /** Typematic timer - R3 Ptr. */ 204 209 PTMTIMERR3 pKbdTypematicTimerR3; 205 RTR3PTR Alignment2; 210 /** Input throttle timer - R3 Ptr. */ 211 PTMTIMERR3 pThrottleTimerR3; 206 212 207 213 /** Command delay timer - R0 Ptr. */ … … 209 215 /** Typematic timer - R0 Ptr. */ 210 216 PTMTIMERR0 pKbdTypematicTimerR0; 211 212 scan_state_t XlatState; /// @todo temporary 213 uint32_t Alignment1; 217 /** Input throttle timer - R0 Ptr. */ 218 PTMTIMERR0 pThrottleTimerR0; 214 219 215 220 /** … … 576 581 577 582 } 583 584 /** 585 * Query the number of items currently in a queue. 586 * 587 * @param pQ Pointer to the queue. 588 * 589 * @return uint32_t Number of items in queue. 590 */ 591 static uint32_t ps2kInQueue(GeneriQ *pQ) 592 { 593 return pQ->cUsed; 594 } 595 578 596 #endif /* IN_RING3 */ 579 597 … … 785 803 rc = ps2kRemoveQueue((GeneriQ *)&pThis->cmdQ, pb); 786 804 if (rc != VINF_SUCCESS && !pThis->u8CurrCmd && pThis->fScanning) 787 rc = ps2kRemoveQueue((GeneriQ *)&pThis->keyQ, pb); 805 if (!pThis->fThrottleActive) 806 { 807 rc = ps2kRemoveQueue((GeneriQ *)&pThis->keyQ, pb); 808 if (pThis->fThrottleEnabled) { 809 pThis->fThrottleActive = true; 810 TMTimerSetMillies(pThis->CTX_SUFF(pThrottleTimer), KBD_THROTTLE_DELAY); 811 } 812 } 788 813 789 814 LogFlowFunc(("keyboard sends 0x%02x (%svalid data)\n", *pb, rc == VINF_SUCCESS ? "" : "not ")); … … 1007 1032 } 1008 1033 1034 /* Throttling timer to emulate the finite keyboard communication speed. A PS/2 keyboard is 1035 * limited by the serial link speed and cannot send much more than 1,000 bytes per second. 1036 * Some software (notably Borland Pascal and programs built with its run-time) relies on 1037 * being able to read an incoming scan-code twice. Throttling the data rate enables such 1038 * software to function, while human typists cannot tell any difference. 1039 * 1040 * Note: The throttling is currently only done for keyboard data, not command responses. 1041 * The throttling could and perhaps should be done for any data (including command 1042 * response) scoming from PS/2 devices, both keyboard and auxiliary. That is not currently 1043 * done because it would needlessly slow things down. 1044 */ 1045 static DECLCALLBACK(void) ps2kThrottleTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1046 { 1047 RT_NOREF2(pDevIns, pTimer); 1048 PPS2K pThis = (PS2K *)pvUser; 1049 unsigned uHaveData; 1050 1051 /* Grab the lock to avoid races with event delivery or EMTs. */ 1052 int rc = PDMCritSectEnter(pThis->pCritSectR3, VERR_SEM_BUSY); 1053 AssertReleaseRC(rc); 1054 1055 /* If data is available, poke the KBC. Once the data 1056 * is actually read, the timer may be re-triggered. 1057 */ 1058 pThis->fThrottleActive = false; 1059 uHaveData = ps2kInQueue((GeneriQ *)&pThis->keyQ); 1060 LogFlowFunc(("Have%s bytes\n", uHaveData ? "" : " no")); 1061 if (uHaveData) 1062 KBCUpdateInterrupts(pThis->pParent); 1063 1064 PDMCritSectLeave(pThis->pCritSectR3); 1065 } 1066 1009 1067 /* Timer handler for emulating typematic keys. Note that only the last key 1010 1068 * held down repeats (if typematic). … … 1365 1423 1366 1424 pThis->fScanning = true; 1425 pThis->fThrottleActive = false; 1367 1426 pThis->u8ScanSet = 2; 1368 1427 pThis->u8CurrCmd = 0; … … 1390 1449 } 1391 1450 1392 int PS2KConstruct(PPS2K pThis, PPDMDEVINS pDevIns, void *pParent, int iInstance )1451 int PS2KConstruct(PPS2K pThis, PPDMDEVINS pDevIns, void *pParent, int iInstance, PCFGMNODE pCfg) 1393 1452 { 1394 1453 RT_NOREF2(pDevIns, iInstance); … … 1396 1455 1397 1456 pThis->pParent = pParent; 1457 1458 bool fThrottleEnabled; 1459 int rc = CFGMR3QueryBoolDef(pCfg, "KbdThrottleEnabled", &fThrottleEnabled, true); 1460 if (RT_FAILURE(rc)) 1461 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to query \"KbdThrottleEnabled\" from the config")); 1462 Log(("KbdThrottleEnabled=%u\n", fThrottleEnabled)); 1463 pThis->fThrottleEnabled = fThrottleEnabled; 1398 1464 1399 1465 /* Initialize the queues. */ … … 1410 1476 1411 1477 /* 1478 * Create the input rate throttling timer. Does not use virtual time! 1479 */ 1480 PTMTIMER pTimer; 1481 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, ps2kThrottleTimer, pThis, 1482 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Throttle Timer", &pTimer); 1483 if (RT_FAILURE(rc)) 1484 return rc; 1485 1486 pThis->pThrottleTimerR3 = pTimer; 1487 pThis->pThrottleTimerR0 = TMTimerR0Ptr(pTimer); 1488 pThis->pThrottleTimerRC = TMTimerRCPtr(pTimer); 1489 1490 /* 1412 1491 * Create the typematic delay/repeat timer. Does not use virtual time! 1413 1492 */ 1414 PTMTIMER pTimer; 1415 int rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, ps2kTypematicTimer, pThis, 1416 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Typematic Timer", &pTimer); 1493 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_REAL, ps2kTypematicTimer, pThis, 1494 TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "PS2K Typematic Timer", &pTimer); 1417 1495 if (RT_FAILURE(rc)) 1418 1496 return rc; -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp
r71210 r71351 439 439 GEN_CHECK_OFF(PS2K, cmdQ); 440 440 GEN_CHECK_OFF(PS2K, uTypematicDelay); 441 GEN_CHECK_OFF(PS2K, fThrottleActive); 441 442 GEN_CHECK_OFF(PS2K, pKbdDelayTimerRC); 442 443 GEN_CHECK_OFF(PS2K, pKbdDelayTimerR3); … … 445 446 GEN_CHECK_OFF(PS2K, pKbdTypematicTimerR3); 446 447 GEN_CHECK_OFF(PS2K, pKbdTypematicTimerR0); 448 GEN_CHECK_OFF(PS2K, pThrottleTimerRC); 449 GEN_CHECK_OFF(PS2K, pThrottleTimerR3); 450 GEN_CHECK_OFF(PS2K, pThrottleTimerR0); 447 451 GEN_CHECK_OFF(PS2K, pCritSectR3); 448 452 GEN_CHECK_OFF(PS2K, Keyboard.IBase);
Note:
See TracChangeset
for help on using the changeset viewer.