VirtualBox

Changeset 37536 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 17, 2011 12:41:53 PM (14 years ago)
Author:
vboxsync
Message:

DevHPET: making the number of timers more flexible.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevHPET.cpp

    r37534 r37536  
    107107#define HPET_TN_INT_ROUTE_CAP_SHIFT           32
    108108#define HPET_TN_CFG_BITS_READONLY_OR_RESERVED 0xffff80b1U
     109
     110/** Extract the timer count from the capabilities.
     111 * @todo Check if the mask is correct.  */
     112#define HPET_CAP_GET_TIMERS(a_u64)          ( ((a_u64) >> 8) & 0xf )
    109113
    110114/** The version of the saved state. */
     
    428432    Assert(PDMCritSectIsOwner(&pThis->csLock));
    429433
    430     if (iTimerNo >= HPET_NUM_TIMERS)
     434    if (iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u64Capabilities))
    431435    {
    432436        static unsigned s_cOccurences = 0;
     
    496500    Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
    497501
    498     if (iTimerNo >= HPET_NUM_TIMERS)
     502    if (iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u64Capabilities))
    499503    {
    500504        LogRel(("HPET: using timer above configured range: %d\n", iTimerNo));
     
    753757            pThis->u64HpetConfig = hpetUpdateMasked(u32NewValue, iOldValue, HPET_CFG_WRITE_MASK);
    754758
     759            uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u64Capabilities);
    755760            if (hpetBitJustSet(iOldValue, u32NewValue, HPET_CFG_ENABLE))
    756761            {
     
    759764                pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter)
    760765                                     - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
    761                 for (uint32_t i = 0; i < HPET_NUM_TIMERS; i++)
     766                for (uint32_t i = 0; i < cTimers; i++)
    762767                    if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i]))
    763768                        hpetProgramTimer(&pThis->aTimers[i]);
     
    767772                /* Halt main counter and disable interrupt generation. */
    768773                pThis->u64HpetCounter = hpetGetTicks(pThis);
    769                 for (uint32_t i = 0; i < HPET_NUM_TIMERS; i++)
     774                for (uint32_t i = 0; i < cTimers; i++)
    770775                    TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer));
    771776            }
     
    11151120                    pThis->u64HpetOffset, pThis->u64HpetCounter, RT_HI_U32(pThis->u64Capabilities),
    11161121                    !!(pThis->u64HpetConfig & HPET_CFG_LEGACY) ? "on " : "off",
    1117                     (unsigned)((pThis->u64Capabilities >> 8) & 0x1f));
     1122                    HPET_CAP_GET_TIMERS(pThis->u64Capabilities));
    11181123    pHlp->pfnPrintf(pHlp,
    11191124                    "Timers:\n");
    1120     for (unsigned i = 0; i < HPET_NUM_TIMERS; i++)
     1125    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
    11211126    {
    11221127        pHlp->pfnPrintf(pHlp, " %d: comparator=%016RX64 period(hidden)=%016RX64 cfg=%016RX64\n",
     
    11391144    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
    11401145
    1141     SSMR3PutU8(pSSM, HPET_NUM_TIMERS);
     1146    SSMR3PutU8(pSSM, HPET_CAP_GET_TIMERS(pThis->u64Capabilities));
    11421147
    11431148    return VINF_SSM_DONT_CALL_AGAIN;
     
    11601165     * The state.
    11611166     */
    1162     for (uint32_t iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
     1167    uint32_t const cTimers = HPET_CAP_GET_TIMERS(pThis->u64Capabilities);
     1168    for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
    11631169    {
    11641170        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
     
    12001206    int rc = SSMR3GetU8(pSSM, &cTimers);
    12011207    AssertRCReturn(rc, rc);
    1202     if (cTimers != HPET_NUM_TIMERS)
    1203         return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - wrong number of timers: saved=%#x config=%#x"),
    1204                                 cTimers, HPET_NUM_TIMERS);
     1208    if (cTimers > RT_ELEMENTS(pThis->aTimers))
     1209        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - too many timers: saved=%#x config=%#x"),
     1210                                cTimers, RT_ELEMENTS(pThis->aTimers));
    12051211
    12061212    if (uPass != SSM_PASS_FINAL)
     
    12101216     * The state.
    12111217     */
    1212     for (uint32_t iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
     1218    for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
    12131219    {
    12141220        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
     
    12221228
    12231229    SSMR3GetU64(pSSM, &pThis->u64HpetOffset);
    1224     SSMR3GetU64(pSSM, &pThis->u64Capabilities);
     1230    uint64_t u64Capabilities;
     1231    SSMR3GetU64(pSSM, &u64Capabilities);
    12251232    SSMR3GetU64(pSSM, &pThis->u64HpetConfig);
    12261233    SSMR3GetU64(pSSM, &pThis->u64Isr);
     
    12281235    if (RT_FAILURE(rc))
    12291236        return rc;
     1237    if (HPET_CAP_GET_TIMERS(u64Capabilities) != cTimers)
     1238        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Capabilities does not match timer count: cTimers=%#x caps=%#x"),
     1239                                cTimers, HPET_CAP_GET_TIMERS(u64Capabilities));
     1240    pThis->u64Capabilities = u64Capabilities;
    12301241
    12311242    /*
     
    12331244     */
    12341245    PDMCritSectEnter(&pThis->csLock, VERR_IGNORED);
    1235     for (uint32_t iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
     1246    for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
    12361247    {
    12371248        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
     
    12861297     */
    12871298    TMTimerLock(pThis->aTimers[0].pTimerR3, VERR_IGNORED);
    1288     for (unsigned i = 0; i < HPET_NUM_TIMERS; i++)
     1299    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
    12891300    {
    12901301        HpetTimer *pHpetTimer = &pThis->aTimers[i];
     
    13231334                                                 Actually ICH9 has 4 timers, but to avoid breaking
    13241335                                                 saved state we'll stick with 3 so far. */ /** @todo fix this ICH9 timer count bug. */
     1336                                              /** @todo what about the '-1' bit?? Linux thinks it has 4 timers. */
    13251337                     | 1                      /* REV_ID           - Revision, must not be 0 */
    13261338                     ;
     
    13831395    AssertRCReturn(rc, rc);
    13841396
    1385     /* Init the HPET timers. */
    1386     for (unsigned i = 0; i < HPET_NUM_TIMERS; i++)
     1397    /* Init the HPET timers (init all regardless of how many we expose). */
     1398    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
    13871399    {
    13881400        HpetTimer *pHpetTimer = &pThis->aTimers[i];
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette