Changeset 81954 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Nov 18, 2019 5:18:45 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 134751
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevHPET.cpp
r81953 r81954 156 156 do { \ 157 157 int rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSect, (a_rcBusy)); \ 158 if ( rcLock == VINF_SUCCESS) \158 if (RT_LIKELY(rcLock == VINF_SUCCESS)) \ 159 159 { /* likely */ } \ 160 160 else \ … … 171 171 /** 172 172 * Acquires the TM lock and HPET lock, returns on failure. 173 * @todo r=bird: Aren't the timers using the same critsect?!? 173 174 */ 174 175 #define DEVHPET_LOCK_BOTH_RETURN(a_pDevIns, a_pThis, a_rcBusy) \ 175 176 do { \ 176 int rcLock = TMTimerLock((a_pThis)->aTimers[0].CTX_SUFF(pTimer), (a_rcBusy)); \177 if ( rcLock == VINF_SUCCESS) \177 int rcLock = PDMDevHlpTimerLock((a_pDevIns), (a_pThis)->aTimers[0].hTimer, (a_rcBusy)); \ 178 if (RT_LIKELY(rcLock == VINF_SUCCESS)) \ 178 179 { \ 179 180 rcLock = PDMDevHlpCritSectEnter((a_pDevIns), &(a_pThis)->CritSect, (a_rcBusy)); \ 180 if ( rcLock == VINF_SUCCESS) \181 if (RT_LIKELY(rcLock == VINF_SUCCESS)) \ 181 182 break; /* likely */ \ 182 TMTimerUnlock((a_pThis)->aTimers[0].CTX_SUFF(pTimer)); \183 PDMDevHlpTimerUnlock((a_pDevIns), (a_pThis)->aTimers[0].hTimer); \ 183 184 } \ 184 185 return rcLock; \ … … 192 193 do { \ 193 194 PDMDevHlpCritSectLeave((a_pDevIns), &(a_pThis)->CritSect); \ 194 TMTimerUnlock((a_pThis)->aTimers[0].CTX_SUFF(pTimer)); \195 PDMDevHlpTimerUnlock((a_pDevIns), (a_pThis)->aTimers[0].hTimer); \ 195 196 } while (0) 196 197 … … 204 205 typedef struct HPETTIMER 205 206 { 206 /** The HPET timer - R3 Ptr. */ 207 PTMTIMERR3 pTimerR3; 207 /** The HPET timer. */ 208 TMTIMERHANDLE hTimer; 209 208 210 /** Pointer to the instance data - R3 Ptr. */ 209 211 R3PTRTYPE(struct HPET *) pHpetR3; 210 211 /** The HPET timer - R0 Ptr. */212 PTMTIMERR0 pTimerR0;213 212 /** Pointer to the instance data - R0 Ptr. */ 214 213 R0PTRTYPE(struct HPET *) pHpetR0; 215 216 /** The HPET timer - RC Ptr. */217 PTMTIMERRC pTimerRC;218 214 /** Pointer to the instance data - RC Ptr. */ 219 215 RCPTRTYPE(struct HPET *) pHpetRC; … … 223 219 /** Wrap. */ 224 220 uint8_t u8Wrap; 225 /** Alignment. */226 uint 32_t alignment0;221 /** Explicit padding. */ 222 uint8_t abPadding[2]; 227 223 228 224 /** @name Memory-mapped, software visible timer registers. … … 328 324 } 329 325 330 DECLINLINE(uint64_t) hpetGetTicks(PCHPET pThis) 331 { 332 /* 333 * We can use any timer to get current time, they all go 334 * with the same speed. 335 */ 336 return nsToHpetTicks(pThis, 337 TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)) 338 + pThis->u64HpetOffset); 326 DECLINLINE(uint64_t) hpetGetTicks(PPDMDEVINS pDevIns, PCHPET pThis) 327 { 328 /* 329 * We can use any timer to get current time, they all go with the same speed. 330 */ 331 return nsToHpetTicks(pThis, PDMDevHlpTimerGet(pDevIns, pThis->aTimers[0].hTimer) + pThis->u64HpetOffset); 339 332 } 340 333 … … 396 389 * Sets the frequency hint if it's a periodic timer. 397 390 * 391 * @param pDevIns The device instance. 398 392 * @param pThis The shared HPET state. 399 393 * @param pHpetTimer The timer. 400 394 */ 401 DECLINLINE(void) hpetTimerSetFrequencyHint(P HPET pThis, PHPETTIMER pHpetTimer)395 DECLINLINE(void) hpetTimerSetFrequencyHint(PPDMDEVINS pDevIns, PHPET pThis, PHPETTIMER pHpetTimer) 402 396 { 403 397 if (pHpetTimer->u64Config & HPET_TN_PERIODIC) … … 406 400 uint32_t const u32Freq = pThis->u32Period; 407 401 if (u64Period > 0 && u64Period < u32Freq) 408 TMTimerSetFrequencyHint(pHpetTimer->CTX_SUFF(pTimer), u32Freq / (uint32_t)u64Period);409 } 410 } 411 412 413 static void hpetProgramTimer(P HPET pThis, PHPETTIMER pHpetTimer)402 PDMDevHlpTimerSetFrequencyHint(pDevIns, pHpetTimer->hTimer, u32Freq / (uint32_t)u64Period); 403 } 404 } 405 406 407 static void hpetProgramTimer(PPDMDEVINS pDevIns, PHPET pThis, PHPETTIMER pHpetTimer) 414 408 { 415 409 /* no wrapping on new timers */ 416 410 pHpetTimer->u8Wrap = 0; 417 411 418 uint64_t u64Ticks = hpetGetTicks(p HpetTimer->CTX_SUFF(pHpet));412 uint64_t u64Ticks = hpetGetTicks(pDevIns, pHpetTimer->CTX_SUFF(pHpet)); 419 413 hpetAdjustComparator(pHpetTimer, u64Ticks); 420 414 … … 450 444 { 451 445 Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff))); 452 TMTimerSetNano(pHpetTimer->CTX_SUFF(pTimer), hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff));446 PDMDevHlpTimerSetNano(pDevIns, pHpetTimer->hTimer, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)); 453 447 } 454 448 else … … 456 450 LogRelMax(10, ("HPET: Not scheduling an interrupt more than 100 years in the future.\n")); 457 451 } 458 hpetTimerSetFrequencyHint(p HpetTimer->CTX_SUFF(pHpet), pHpetTimer);452 hpetTimerSetFrequencyHint(pDevIns, pThis, pHpetTimer); 459 453 } 460 454 … … 545 539 static int hpetTimerRegWrite32(PPDMDEVINS pDevIns, PHPET pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue) 546 540 { 547 Assert(!PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));541 Assert(!PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect) || PDMDevHlpTimerIsLockOwner(pDevIns, pThis->aTimers[0].hTimer)); 548 542 549 543 if ( iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities) … … 605 599 606 600 if (pThis->u64HpetConfig & HPET_CFG_ENABLE) 607 hpetProgramTimer(p This, pHpetTimer);601 hpetProgramTimer(pDevIns, pThis, pHpetTimer); 608 602 DEVHPET_UNLOCK_BOTH(pDevIns, pThis); 609 603 break; … … 625 619 626 620 if (pThis->u64HpetConfig & HPET_CFG_ENABLE) 627 hpetProgramTimer(p This, pHpetTimer);621 hpetProgramTimer(pDevIns, pThis, pHpetTimer); 628 622 } 629 623 DEVHPET_UNLOCK_BOTH(pDevIns, pThis); … … 704 698 uint64_t u64Ticks; 705 699 if (pThis->u64HpetConfig & HPET_CFG_ENABLE) 706 u64Ticks = hpetGetTicks(p This);700 u64Ticks = hpetGetTicks(pDevIns, pThis); 707 701 else 708 702 u64Ticks = pThis->u64HpetCounter; … … 750 744 static int hpetConfigRegWrite32(PPDMDEVINS pDevIns, PHPET pThis, uint32_t idxReg, uint32_t u32NewValue) 751 745 { 752 Assert(!PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));746 Assert(!PDMDevHlpCritSectIsOwner(pDevIns, &pThis->CritSect) || PDMDevHlpTimerIsLockOwner(pDevIns, pThis->aTimers[0].hTimer)); 753 747 754 748 int rc = VINF_SUCCESS; … … 798 792 { 799 793 pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter) 800 - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));794 - PDMDevHlpTimerGet(pDevIns, pThis->aTimers[0].hTimer); 801 795 } 802 796 else … … 804 798 LogRelMax(10, ("HPET: Counter set more than 100 years in the future, reducing.\n")); 805 799 pThis->u64HpetOffset = 1000000LL * 60 * 60 * 24 * 365 * 100 806 - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));800 - PDMDevHlpTimerGet(pDevIns, pThis->aTimers[0].hTimer); 807 801 } 808 802 for (uint32_t i = 0; i < cTimers; i++) 809 803 if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i])) 810 hpetProgramTimer(p This, &pThis->aTimers[i]);804 hpetProgramTimer(pDevIns, pThis, &pThis->aTimers[i]); 811 805 } 812 806 else if (hpetBitJustCleared(iOldValue, u32NewValue, HPET_CFG_ENABLE)) 813 807 { 814 808 /* Halt main counter and disable interrupt generation. */ 815 pThis->u64HpetCounter = hpetGetTicks(p This);809 pThis->u64HpetCounter = hpetGetTicks(pDevIns, pThis); 816 810 for (uint32_t i = 0; i < cTimers; i++) 817 TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer));811 PDMDevHlpTimerStop(pDevIns, pThis->aTimers[i].hTimer); 818 812 } 819 813 … … 924 918 DEVHPET_LOCK_BOTH_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ); 925 919 if (pThis->u64HpetConfig & HPET_CFG_ENABLE) 926 pValue->u = hpetGetTicks(p This);920 pValue->u = hpetGetTicks(pDevIns, pThis); 927 921 else 928 922 pValue->u = pThis->u64HpetCounter; … … 1074 1068 static DECLCALLBACK(void) hpetR3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser) 1075 1069 { 1076 PHPET pThis = PDMDEVINS_2_DATA(pDevIns, PHPET); 1077 PHPETTIMER pHpetTimer = (HPETTIMER *)pvUser; 1078 uint64_t u64Period = pHpetTimer->u64Period; 1079 uint64_t u64CurTick = hpetGetTicks(pThis); 1080 uint64_t u64Diff; 1070 PHPET pThis = PDMDEVINS_2_DATA(pDevIns, PHPET); 1071 PHPETTIMER pHpetTimer = (HPETTIMER *)pvUser; 1072 uint64_t u64Period = pHpetTimer->u64Period; 1073 uint64_t u64CurTick = hpetGetTicks(pDevIns, pThis); 1074 uint64_t u64Diff; 1075 RT_NOREF(pTimer); 1081 1076 1082 1077 if (pHpetTimer->u64Config & HPET_TN_PERIODIC) 1083 1078 { 1084 if (u64Period) { 1079 if (u64Period) 1080 { 1085 1081 hpetAdjustComparator(pHpetTimer, u64CurTick); 1086 1082 … … 1091 1087 { 1092 1088 Log4(("HPET: periodic: next in %llu\n", hpetTicksToNs(pThis, u64Diff))); 1093 TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));1089 PDMDevHlpTimerSetNano(pDevIns, pHpetTimer->hTimer, hpetTicksToNs(pThis, u64Diff)); 1094 1090 } 1095 1091 else … … 1105 1101 { 1106 1102 u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick); 1107 TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));1103 PDMDevHlpTimerSetNano(pDevIns, pHpetTimer->hTimer, hpetTicksToNs(pThis, u64Diff)); 1108 1104 pHpetTimer->u8Wrap = 0; 1109 1105 } … … 1186 1182 { 1187 1183 PHPETTIMER pHpetTimer = &pThis->aTimers[iTimer]; 1188 TMR3TimerSave(pHpetTimer->pTimerR3, pSSM);1184 PDMDevHlpTimerSave(pDevIns, pHpetTimer->hTimer, pSSM); 1189 1185 pHlp->pfnSSMPutU8(pSSM, pHpetTimer->u8Wrap); 1190 1186 pHlp->pfnSSMPutU64(pSSM, pHpetTimer->u64Config); … … 1238 1234 { 1239 1235 PHPETTIMER pHpetTimer = &pThis->aTimers[iTimer]; 1240 TMR3TimerLoad(pHpetTimer->pTimerR3, pSSM);1236 PDMDevHlpTimerLoad(pDevIns, pHpetTimer->hTimer, pSSM); 1241 1237 pHlp->pfnSSMGetU8(pSSM, &pHpetTimer->u8Wrap); 1242 1238 pHlp->pfnSSMGetU64(pSSM, &pHpetTimer->u64Config); … … 1267 1263 { 1268 1264 PHPETTIMER pHpetTimer = &pThis->aTimers[iTimer]; 1269 if ( TMTimerIsActive(pHpetTimer->CTX_SUFF(pTimer)))1270 hpetTimerSetFrequencyHint(p This, pHpetTimer);1265 if (PDMDevHlpTimerIsActive(pDevIns, pHpetTimer->hTimer)) 1266 hpetTimerSetFrequencyHint(pDevIns, pThis, pHpetTimer); 1271 1267 } 1272 1268 PDMDevHlpCritSectLeave(pDevIns, &pThis->CritSect); … … 1293 1289 { 1294 1290 PHPETTIMER pTm = &pThis->aTimers[i]; 1295 if (pTm->pTimerR3)1296 pTm->pTimerRC = TMTimerRCPtr(pTm->pTimerR3);1297 1291 pTm->pHpetRC = PDMINS_2_DATA_RCPTR(pDevIns); 1298 1292 } … … 1311 1305 * The timers first. 1312 1306 */ 1313 TMTimerLock(pThis->aTimers[0].pTimerR3, VERR_IGNORED);1307 PDMDevHlpTimerLock(pDevIns, pThis->aTimers[0].hTimer, VERR_IGNORED); 1314 1308 for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++) 1315 1309 { 1316 1310 PHPETTIMER pHpetTimer = &pThis->aTimers[i]; 1317 1311 Assert(pHpetTimer->idxTimer == i); 1318 TMTimerStop(pHpetTimer->pTimerR3);1312 PDMDevHlpTimerStop(pDevIns, pHpetTimer->hTimer); 1319 1313 1320 1314 /* capable of periodic operations and 64-bits */ … … 1333 1327 pHpetTimer->u64Cmp = hpetInvalidValue(pHpetTimer); 1334 1328 } 1335 TMTimerUnlock(pThis->aTimers[0].pTimerR3);1329 PDMDevHlpTimerUnlock(pDevIns, pThis->aTimers[0].hTimer); 1336 1330 1337 1331 /* … … 1419 1413 PHPETTIMER pHpetTimer = &pThis->aTimers[i]; 1420 1414 1421 rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetR3Timer, pHpetTimer, 1422 TMTIMER_FLAGS_NO_CRIT_SECT, "HPET Timer", 1423 &pThis->aTimers[i].pTimerR3); 1415 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetR3Timer, pHpetTimer, 1416 TMTIMER_FLAGS_NO_CRIT_SECT, "HPET Timer", &pThis->aTimers[i].hTimer); 1424 1417 AssertRCReturn(rc, rc); 1425 pThis->aTimers[i].pTimerRC = TMTimerRCPtr(pThis->aTimers[i].pTimerR3); 1426 pThis->aTimers[i].pTimerR0 = TMTimerR0Ptr(pThis->aTimers[i].pTimerR3); 1427 rc = TMR3TimerSetCritSect(pThis->aTimers[i].pTimerR3, &pThis->CritSect); 1418 /** @todo r=bird: This is TOTALLY MESSED UP! Why do we need 1419 * DEVHPET_LOCK_BOTH_RETURN() when the timers use the same critsect as 1420 * we do?!? */ 1421 rc = PDMDevHlpTimerSetCritSect(pDevIns, pThis->aTimers[i].hTimer, &pThis->CritSect); 1428 1422 AssertRCReturn(rc, rc); 1429 1423 }
Note:
See TracChangeset
for help on using the changeset viewer.