- Timestamp:
- Oct 15, 2020 1:42:24 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/DevHPET.cpp
r82968 r86591 142 142 143 143 /** Extract the timer count from the capabilities. */ 144 #define HPET_CAP_GET_TIMERS(a_u32) ( ((a_u32) >> 8) & 0x1f ) 144 #define HPET_CAP_GET_TIMERS(a_u32) ((((a_u32) >> 8) + 1) & 0x1f) 145 /** Revision ID. */ 146 #define HPET_CAP_GET_REV_ID(a_u32) ((a_u32) & 0xff) 147 /** Counter size. */ 148 #define HPET_CAP_HAS_64BIT_COUNT_SIZE(a_u32) RT_BOOL((a_u32) & RT_BIT(13)) 149 /** Legacy Replacement Route. */ 150 #define HPET_CAP_HAS_LEG_RT(a_u32) RT_BOOL((a_u32) & RT_BIT(15)) 151 145 152 146 153 /** The version of the saved state. */ 147 #define HPET_SAVED_STATE_VERSION 2 154 #define HPET_SAVED_STATE_VERSION 3 155 /** The version of the saved state prior to the off-by-1 timer count fix. */ 156 #define HPET_SAVED_STATE_VERSION_PRE_TIMER 2 148 157 /** Empty saved state */ 149 #define HPET_SAVED_STATE_VERSION_EMPTY 1158 #define HPET_SAVED_STATE_VERSION_EMPTY 1 150 159 151 160 … … 1216 1225 */ 1217 1226 uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u32Capabilities); 1227 AssertReturn(cTimers <= RT_ELEMENTS(pThis->aTimers), VERR_OUT_OF_RANGE); 1218 1228 for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++) 1219 1229 { … … 1249 1259 if (uVersion == HPET_SAVED_STATE_VERSION_EMPTY) 1250 1260 return VINF_SUCCESS; 1251 if (uVersion != HPET_SAVED_STATE_VERSION) 1261 if ( uVersion != HPET_SAVED_STATE_VERSION 1262 && uVersion != HPET_SAVED_STATE_VERSION_PRE_TIMER) 1252 1263 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION; 1253 1264 … … 1287 1298 if (RT_FAILURE(rc)) 1288 1299 return rc; 1289 if (HPET_CAP_GET_TIMERS(RT_LO_U32(u64CapPer)) != cTimers) 1300 1301 /* Older saved state have an off-by-1 timer count bug. */ 1302 uint8_t cCapTimers = HPET_CAP_GET_TIMERS(RT_LO_U32(u64CapPer)); 1303 if ( uVersion <= HPET_SAVED_STATE_VERSION_PRE_TIMER 1304 && cCapTimers > 0 /* Paranoia */) 1305 --cCapTimers; 1306 1307 /* Verify capability reported timer count matches timer count in the saved state field. */ 1308 if (cCapTimers != cTimers) 1290 1309 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Capabilities does not match timer count: cTimers=%#x caps=%#x"), 1291 cTimers, (unsigned)HPET_CAP_GET_TIMERS(u64CapPer)); 1310 cTimers, cCapTimers); 1311 if (HPET_CAP_GET_TIMERS(RT_LO_U32(u64CapPer)) > RT_ELEMENTS(pThis->aTimers)) 1312 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - too many timers in capability register: CAP=%#x => %u times, max %u"), 1313 RT_LO_U32(u64CapPer), (unsigned)HPET_CAP_GET_TIMERS(RT_LO_U32(u64CapPer)), RT_ELEMENTS(pThis->aTimers)); 1314 1292 1315 pThis->u32Capabilities = RT_LO_U32(u64CapPer); 1293 1316 pThis->u32Period = RT_HI_U32(u64CapPer); … … 1455 1478 */ 1456 1479 hpetR3Reset(pDevIns); 1480 1481 uint32_t const fCaps = pThis->u32Capabilities; 1482 LogRel(("HPET: Capabilities=%#RX32 (LegacyRt=%RTbool CounterSize=%s Timers=%u Revision=%#x)\n", 1483 fCaps, HPET_CAP_HAS_LEG_RT(fCaps), HPET_CAP_HAS_64BIT_COUNT_SIZE(fCaps) ? "64-bit" : "32-bit", 1484 HPET_CAP_GET_TIMERS(fCaps), HPET_CAP_GET_REV_ID(fCaps))); 1457 1485 1458 1486 /*
Note:
See TracChangeset
for help on using the changeset viewer.