Changeset 36837 in vbox
- Timestamp:
- Apr 25, 2011 8:41:44 AM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevHPET.cpp
r36649 r36837 50 50 */ 51 51 #define HPET_NUM_TIMERS 3 52 #define HPET_NUM_TIMERS_ICH9 4 52 53 53 54 /* … … 55 56 */ 56 57 #define HPET_CLK_PERIOD 10000000UL 58 59 /* 60 * 69841279 femtoseconds == 69.84 ns 61 */ 62 #define HPET_CLK_PERIOD_ICH9 69841279UL 57 63 58 64 /* … … 130 136 RCPTRTYPE(struct HpetState *) pHpetRC; 131 137 132 /* timer number*/138 /* Timer number. */ 133 139 uint8_t u8TimerNumber; 134 /* Wrap */140 /* Wrap. */ 135 141 uint8_t u8Wrap; 136 /* Alignment */142 /* Alignment. */ 137 143 uint32_t alignment0; 138 /* Memory-mapped, software visible timer registers */139 /* Configuration/capabilities */144 /* Memory-mapped, software visible timer registers. */ 145 /* Configuration/capabilities. */ 140 146 uint64_t u64Config; 141 /* comparator */147 /* comparator. */ 142 148 uint64_t u64Cmp; 143 /* FSB route, not supported now */149 /* FSB route, not supported now. */ 144 150 uint64_t u64Fsb; 145 151 146 /* Hidden register state */147 /* Last value written to comparator */152 /* Hidden register state. */ 153 /* Last value written to comparator. */ 148 154 uint64_t u64Period; 149 155 } HpetTimer; … … 166 172 PCPDMHPETHLPRC pHpetHlpRC; 167 173 168 /* Timer structures */174 /* Timer structures. */ 169 175 HpetTimer aTimers[HPET_NUM_TIMERS]; 170 176 171 /* Offset realtive to the system clock */177 /* Offset realtive to the system clock. */ 172 178 uint64_t u64HpetOffset; 173 179 174 180 /* Memory-mapped, software visible registers */ 175 /* capabilities */181 /* capabilities. */ 176 182 uint64_t u64Capabilities; 177 /* configuration*/183 /* Configuration. */ 178 184 uint64_t u64HpetConfig; 179 /* interrupt status register*/185 /* Interrupt status register. */ 180 186 uint64_t u64Isr; 181 /* main counter*/187 /* Main counter. */ 182 188 uint64_t u64HpetCounter; 183 189 184 /* Global device lock */190 /* Global device lock. */ 185 191 PDMCRITSECT csLock; 192 193 /* If we emulate ICH9 HPET (different frequency and counter rollover behavior 194 in 32-bit mode). */ 195 uint8_t fIch9; 196 uint8_t padding0[7]; 186 197 } HpetState; 187 198 … … 232 243 } 233 244 234 static uint64_t hpetTicksToNs( uint64_t value)235 { 236 return (ASMMultU64ByU32DivByU32(value, HPET_CLK_PERIOD, FS_PER_NS));237 } 238 239 static uint64_t nsToHpetTicks( uint64_t u64Value)240 { 241 return (ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, HPET_CLK_PERIOD));245 static uint64_t hpetTicksToNs(HpetState* pThis, uint64_t value) 246 { 247 return (ASMMultU64ByU32DivByU32(value, (uint32_t)(pThis->u64Capabilities >> 32), FS_PER_NS)); 248 } 249 250 static uint64_t nsToHpetTicks(HpetState* pThis, uint64_t u64Value) 251 { 252 return (ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, (uint32_t)(pThis->u64Capabilities >> 32))); 242 253 } 243 254 … … 248 259 * with the same speed. 249 260 */ 250 return nsToHpetTicks(TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)) +251 pThis->u64HpetOffset);261 return nsToHpetTicks(pThis, TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)) + 262 pThis->u64HpetOffset); 252 263 } 253 264 … … 329 340 u64Diff = hpetComputeDiff(pTimer, u64Ticks); 330 341 331 /* Spec says in one-shot 32-bit mode, generate an interrupt when342 /* HPET spec says in one-shot 32-bit mode, generate an interrupt when 332 343 * counter wraps in addition to an interrupt with comparator match. 344 * 345 * ICH9 spec doesn't mention that, so we disable wraparound behavior for ICH9, 346 * see public trac defect #8707. 333 347 */ 334 if ((pTimer->u64Config & HPET_TN_32BIT) && !(pTimer->u64Config & HPET_TN_PERIODIC)) 335 { 336 u32TillWrap = 0xffffffff - (uint32_t)u64Ticks; 337 if (u32TillWrap < (uint32_t)u64Diff) 338 { 339 u64Diff = u32TillWrap; 340 pTimer->u8Wrap = 1; 348 if (!pTimer->CTX_SUFF(pHpet)->fIch9) 349 { 350 if ((pTimer->u64Config & HPET_TN_32BIT) && !(pTimer->u64Config & HPET_TN_PERIODIC)) 351 { 352 u32TillWrap = 0xffffffff - (uint32_t)u64Ticks; 353 if (u32TillWrap < (uint32_t)u64Diff) 354 { 355 u64Diff = u32TillWrap; 356 pTimer->u8Wrap = 1; 357 } 341 358 } 342 359 } … … 349 366 #endif 350 367 351 Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs( u64Diff)));352 353 TMTimerSetNano(pTimer->CTX_SUFF(pTimer), hpetTicksToNs( u64Diff));368 Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pTimer->CTX_SUFF(pHpet), u64Diff))); 369 370 TMTimerSetNano(pTimer->CTX_SUFF(pTimer), hpetTicksToNs(pTimer->CTX_SUFF(pHpet), u64Diff)); 354 371 } 355 372 … … 410 427 default: 411 428 LogRel(("invalid HPET register read %d on %d\n", iTimerReg, pTimer->u8TimerNumber)); 429 *pValue = 0; 412 430 break; 413 431 } … … 442 460 { 443 461 uint64_t u64Ticks; 444 Log(("read HPET_COUNTER\n"));445 462 if (pThis->u64HpetConfig & HPET_CFG_ENABLE) 446 463 u64Ticks = hpetGetTicks(pThis); … … 449 466 /** @todo: is it correct? */ 450 467 *pValue = (iIndex == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32); 468 Log(("read HPET_COUNTER: %s part value %x\n", (iIndex == HPET_COUNTER) ? "low" : "high", *pValue)); 451 469 break; 452 470 } … … 457 475 default: 458 476 Log(("invalid HPET register read: %x\n", iIndex)); 477 *pValue = 0; 459 478 break; 460 479 } … … 488 507 case HPET_TN_CFG: 489 508 { 490 Log(("write HPET_TN_CFG: %d\n", iTimerNo)); 491 if (iNewValue & HPET_TN_32BIT) 492 { 509 Log(("write HPET_TN_CFG: %d: %x\n", iTimerNo, iNewValue)); 510 if ((iNewValue & HPET_TN_32BIT) != 0) 511 { 512 Log(("setting timer to 32-bit mode\n")); 493 513 pTimer->u64Cmp = (uint32_t)pTimer->u64Cmp; 494 514 pTimer->u64Period = (uint32_t)pTimer->u64Period; … … 497 517 { 498 518 LogRel(("level-triggered config not yet supported\n")); 499 Assert (false);519 AssertFailed(); 500 520 } 501 521 /** We only care about lower 32-bits so far */ … … 574 594 { 575 595 LogRel(("invalid timer register write: %d\n", iTimerReg)); 576 Assert (false);596 AssertFailed(); 577 597 break; 578 598 } … … 636 656 { 637 657 /* Enable main counter and interrupt generation. */ 638 pThis->u64HpetOffset = hpetTicksToNs(pThis ->u64HpetCounter)658 pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter) 639 659 - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)); 640 660 for (i = 0; i < HPET_NUM_TIMERS; i++) … … 745 765 uint32_t iTimer = (iIndex - 0x100) / 0x20; 746 766 uint32_t iTimerReg = (iIndex - 0x100) % 0x20; 747 767 748 768 /* for most 8-byte accesses we just split them, happens under lock anyway. */ 749 769 rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg, &value.u32[0]); … … 756 776 if (iIndex == HPET_COUNTER) 757 777 { 758 /* When reading HPET counter we must read it in a single read, 778 /* When reading HPET counter we must read it in a single read, 759 779 to avoid unexpected time jumps on 32-bit overflow. */ 760 value.u64 = 761 (pThis->u64HpetConfig & HPET_CFG_ENABLE) != 0 780 value.u64 = 781 (pThis->u64HpetConfig & HPET_CFG_ENABLE) != 0 762 782 ? 763 783 hpetGetTicks(pThis) … … 769 789 { 770 790 /* for most 8-byte accesses we just split them, happens under lock anyway. */ 771 791 772 792 rc = hpetConfigRegRead32(pThis, iIndex, &value.u32[0]); 773 793 if (RT_UNLIKELY(rc != VINF_SUCCESS)) … … 1011 1031 pThis->pHpetHlpR3->pfnSetIrq(pThis->CTX_SUFF(pDevIns), irq, PDM_IRQ_LEVEL_FLIP_FLOP); 1012 1032 else 1013 Assert (false);1033 AssertFailed(); 1014 1034 /* @todo: implement IRQs in level-triggered mode */ 1015 1035 } … … 1048 1068 u64Diff = hpetComputeDiff(pTimer, u64CurTick); 1049 1069 1050 Log4(("HPET: periodical: next in %lld\n", hpetTicksToNs( u64Diff)));1051 TMTimerSetNano(pTmTimer, hpetTicksToNs( u64Diff));1070 Log4(("HPET: periodical: next in %lld\n", hpetTicksToNs(pThis, u64Diff))); 1071 TMTimerSetNano(pTmTimer, hpetTicksToNs(pThis, u64Diff)); 1052 1072 } 1053 1073 else if ((pTimer->u64Config & HPET_TN_32BIT) && … … 1057 1077 { 1058 1078 u64Diff = hpetComputeDiff(pTimer, u64CurTick); 1059 TMTimerSetNano(pTmTimer, hpetTicksToNs( u64Diff));1079 TMTimerSetNano(pTmTimer, hpetTicksToNs(pThis, u64Diff)); 1060 1080 pTimer->u8Wrap = 0; 1061 1081 } … … 1122 1142 pThis->u64HpetCounter = 0ULL; 1123 1143 pThis->u64HpetOffset = 0ULL; 1144 1145 uint32_t u32Vendor = 0x8086; 1124 1146 /* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */ 1125 uint32_t u32Vendor = 0x8086;1126 1147 uint32_t u32Caps = 1127 1148 (1 << 15) /* LEG_RT_CAP, LegacyReplacementRoute capable */ | 1128 1149 (1 << 13) /* COUNTER_SIZE_CAP, main counter is 64-bit capable */ | 1129 ((HPET_NUM_TIMERS-1) << 8) /* NUM_TIM_CAP, number of timers -1 */ | 1150 /* Actually ICH9 has 4 timers, but to avoid breaking saved state we'll stick with 3 so far. */ 1151 (HPET_NUM_TIMERS << 8) /* NUM_TIM_CAP, number of timers -1 */ | 1130 1152 1 /* REV_ID, revision, must not be 0 */; 1131 1153 pThis->u64Capabilities = (u32Vendor << 16) | u32Caps; 1132 pThis->u64Capabilities |= ((uint64_t)( HPET_CLK_PERIOD) << 32);1154 pThis->u64Capabilities |= ((uint64_t)(pThis->fIch9 ? HPET_CLK_PERIOD_ICH9 : HPET_CLK_PERIOD) << 32); 1133 1155 1134 1156 /* Notify PIT/RTC devices */ … … 1147 1169 int rc; 1148 1170 HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *); 1149 1150 memset(pThis, 0, sizeof(*pThis));1151 1171 1152 1172 pThis->pDevInsR3 = pDevIns; … … 1218 1238 bool fRCEnabled = false; 1219 1239 bool fR0Enabled = false; 1240 bool fIch9 = false; 1220 1241 PDMHPETREG HpetReg; 1221 1242 1222 /* Only one HPET device now */1243 /* Only one HPET device now, as we use fixed MMIO region. */ 1223 1244 Assert(iInstance == 0); 1224 1245 … … 1226 1247 * Validate configuration. 1227 1248 */ 1228 if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0")) 1249 if (!CFGMR3AreValuesValid(pCfg, 1250 "GCEnabled\0" 1251 "R0Enabled\0" 1252 "ICH9\0")) 1229 1253 return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES; 1230 1254 … … 1239 1263 return PDMDEV_SET_ERROR(pDevIns, rc, 1240 1264 N_("Configuration error: failed to read R0Enabled as boolean")); 1265 rc = CFGMR3QueryBoolDef(pCfg, "ICH9", &fIch9, false); 1266 if (RT_FAILURE(rc)) 1267 return PDMDEV_SET_ERROR(pDevIns, rc, 1268 N_("Configuration error: failed to read ICH9 as boolean")); 1269 1241 1270 /* Initialize the device state */ 1271 memset(pThis, 0, sizeof(*pThis)); 1272 1273 pThis->fIch9 = (uint8_t)fIch9; 1274 1242 1275 rc = hpetInit(pDevIns); 1243 1276 if (RT_FAILURE(rc)) -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r36703 r36837 1072 1072 InsertConfigNode(pDev, "0", &pInst); 1073 1073 InsertConfigInteger(pInst, "Trusted", 1); /* boolean */ 1074 InsertConfigNode(pInst, "Config", &pCfg); 1075 InsertConfigInteger(pCfg, "ICH9", (chipsetType == ChipsetType_ICH9) ? 1 : 0); /* boolean */ 1074 1076 } 1075 1077
Note:
See TracChangeset
for help on using the changeset viewer.