Changeset 42635 in vbox for trunk/src/VBox/Devices/PC
- Timestamp:
- Aug 6, 2012 5:34:08 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevHPET.cpp
r42565 r42635 16 16 */ 17 17 18 /* This implementation is based on the (generic) Intel IA-PC HPET specification 19 * and the Intel ICH9 datasheet. 20 */ 21 18 22 /******************************************************************************* 19 23 * Header Files * … … 45 49 46 50 /** The number of timers for PIIX4 / PIIX3. */ 47 #define HPET_NUM_TIMERS_PIIX 3 51 #define HPET_NUM_TIMERS_PIIX 3 /* Minimal implementation. */ 48 52 /** The number of timers for ICH9. */ 49 53 #define HPET_NUM_TIMERS_ICH9 4 … … 71 75 72 76 /* Delivery mode */ 73 /* Via APIC */ 74 #define HPET_TIMER_DELIVERY_APIC 0 75 /* Via FSB */ 76 #define HPET_TIMER_DELIVERY_FSB 1 77 #define HPET_TIMER_DELIVERY_APIC 0 /* Delivery through APIC. */ 78 #define HPET_TIMER_DELIVERY_FSB 1 /* Delivery through FSB. */ 77 79 78 80 #define HPET_TIMER_CAP_FSB_INT_DEL (1 << 15) … … 82 84 #define HPET_CFG_LEGACY 0x002 /* LEG_RT_CNF */ 83 85 84 #define HPET_ID 0x000 85 #define HPET_PERIOD 0x004 86 #define HPET_CFG 0x010 87 #define HPET_STATUS 0x020 88 #define HPET_COUNTER 0x0f0 89 #define HPET_TN_CFG 0x000 90 #define HPET_TN_CMP 0x008 91 #define HPET_TN_ROUTE 0x010 86 /* Register offsets in HPET space. */ 87 #define HPET_ID 0x000 /* Device ID. */ 88 #define HPET_PERIOD 0x004 /* Clock period in femtoseconds. */ 89 #define HPET_CFG 0x010 /* Configuration register. */ 90 #define HPET_STATUS 0x020 /* Status register. */ 91 #define HPET_COUNTER 0x0f0 /* Main HPET counter. */ 92 93 /* Timer N offsets (within each timer's space). */ 94 #define HPET_TN_CFG 0x000 /* Timer N configuration. */ 95 #define HPET_TN_CMP 0x008 /* Timer N comparator. */ 96 #define HPET_TN_ROUTE 0x010 /* Timer N interrupt route. */ 97 92 98 #define HPET_CFG_WRITE_MASK 0x3 93 99 94 #define HPET_TN_INT_TYPE RT_BIT_64(1) 95 #define HPET_TN_ENABLE RT_BIT_64(2) 96 #define HPET_TN_PERIODIC RT_BIT_64(3) 97 #define HPET_TN_PERIODIC_CAP RT_BIT_64(4) 98 #define HPET_TN_SIZE_CAP RT_BIT_64(5) 99 #define HPET_TN_SETVAL RT_BIT_64(6) 100 #define HPET_TN_32BIT RT_BIT_64(8) 101 #define HPET_TN_INT_ROUTE_MASK UINT64_C(0x3e00) 102 #define HPET_TN_CFG_WRITE_MASK UINT64_C(0x3e46) 103 #define HPET_TN_INT_ROUTE_SHIFT 9 104 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32 100 #define HPET_TN_INT_TYPE RT_BIT_64(1) 101 #define HPET_TN_ENABLE RT_BIT_64(2) 102 #define HPET_TN_PERIODIC RT_BIT_64(3) 103 #define HPET_TN_PERIODIC_CAP RT_BIT_64(4) 104 #define HPET_TN_SIZE_CAP RT_BIT_64(5) 105 #define HPET_TN_SETVAL RT_BIT_64(6) 106 #define HPET_TN_32BIT RT_BIT_64(8) 107 #define HPET_TN_INT_ROUTE_MASK UINT64_C(0x3e00) 108 #define HPET_TN_CFG_WRITE_MASK UINT64_C(0x3e46) 109 #define HPET_TN_INT_ROUTE_SHIFT 9 110 #define HPET_TN_INT_ROUTE_CAP_SHIFT 32 111 105 112 #define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U 106 113 107 /** Extract the timer count from the capabilities. 108 * @todo Check if the mask is correct. */ 109 #define HPET_CAP_GET_TIMERS(a_u32) ( ((a_u32) >> 8) & 0xf ) 114 /** Extract the timer count from the capabilities. */ 115 #define HPET_CAP_GET_TIMERS(a_u32) ( ((a_u32) >> 8) & 0x1f ) 110 116 111 117 /** The version of the saved state. */ … … 425 431 Assert(PDMCritSectIsOwner(&pThis->csLock)); 426 432 427 if ( iTimerNo >= RT_ELEMENTS(pThis->aTimers) /* parfait*/428 || iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities))429 { 433 if ( iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities) /* The second check is only to satisfy Parfait; */ 434 || iTimerNo >= RT_ELEMENTS(pThis->aTimers) ) /* in practice, the number of configured timers */ 435 { /* will always be <= aTimers elements. */ 430 436 static unsigned s_cOccurences = 0; 431 437 if (s_cOccurences++ < 10) … … 494 500 Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer))); 495 501 496 if ( iTimerNo >= RT_ELEMENTS(pThis->aTimers) /* parfait */497 || iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities))502 if ( iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities) 503 || iTimerNo >= RT_ELEMENTS(pThis->aTimers) ) /* Parfait - see above. */ 498 504 { 499 505 static unsigned s_cOccurences = 0; … … 1071 1077 uint64_t u64Diff; 1072 1078 1073 if ((pHpetTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0)) 1074 { 1075 hpetAdjustComparator(pHpetTimer, u64CurTick); 1076 1077 u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick); 1078 1079 Log4(("HPET: periodical: next in %llu\n", hpetTicksToNs(pThis, u64Diff))); 1080 TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff)); 1081 } 1082 else if ( hpet32bitTimer(pHpetTimer) 1083 && !(pHpetTimer->u64Config & HPET_TN_PERIODIC)) 1084 { 1079 if (pHpetTimer->u64Config & HPET_TN_PERIODIC) 1080 { 1081 if (u64Period) { 1082 hpetAdjustComparator(pHpetTimer, u64CurTick); 1083 1084 u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick); 1085 1086 Log4(("HPET: periodic: next in %llu\n", hpetTicksToNs(pThis, u64Diff))); 1087 TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff)); 1088 } 1089 } 1090 else if (hpet32bitTimer(pHpetTimer)) 1091 { 1092 /* For 32-bit non-periodic timers, generate wrap-around interrupts. */ 1085 1093 if (pHpetTimer->u8Wrap) 1086 1094 {
Note:
See TracChangeset
for help on using the changeset viewer.