VirtualBox

Changeset 37497 in vbox


Ignore:
Timestamp:
Jun 16, 2011 2:34:03 PM (13 years ago)
Author:
vboxsync
Message:

DevHPET: code cleanup in progress...

File:
1 edited

Legend:

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

    r37466 r37497  
    55
    66/*
    7  * Copyright (C) 2009-2010 Oracle Corporation
     7 * Copyright (C) 2009-2011 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2121#define LOG_GROUP LOG_GROUP_DEV_HPET
    2222#include <VBox/vmm/pdmdev.h>
     23#include <VBox/vmm/stam.h>
    2324#include <VBox/log.h>
    24 #include <VBox/vmm/stam.h>
    2525#include <iprt/assert.h>
    2626#include <iprt/asm-math.h>
     
    5555 * 10000000 femtoseconds == 10ns
    5656 */
    57 #define HPET_CLK_PERIOD             10000000UL
     57#define HPET_CLK_PERIOD             UINT32_C(10000000)
    5858
    5959/*
    6060 * 69841279 femtoseconds == 69.84 ns (1 / 14.31818MHz)
    6161 */
    62 #define HPET_CLK_PERIOD_ICH9        69841279UL
     62#define HPET_CLK_PERIOD_ICH9        UINT32_C(69841279)
    6363
    6464/*
     
    111111#define HPET_SAVED_STATE_VERSION       2
    112112
    113 /* Empty saved state */
     113/** Empty saved state */
    114114#define HPET_SAVED_STATE_VERSION_EMPTY 1
    115115
     
    136136    RCPTRTYPE(struct HpetState *)    pHpetRC;
    137137
    138     /* Timer number. */
    139     uint8_t                          u8TimerNumber;
    140      /* Wrap. */
     138    /** Timer index. */
     139    uint8_t                          idxTimer;
     140    /** Wrap. */
    141141    uint8_t                          u8Wrap;
    142     /* Alignment. */
     142    /** Alignment. */
    143143    uint32_t                         alignment0;
    144     /* Memory-mapped, software visible timer registers. */
    145     /* Configuration/capabilities. */
     144
     145    /** @name Memory-mapped, software visible timer registers.
     146     * @{ */
     147    /** Configuration/capabilities. */
    146148    uint64_t                         u64Config;
    147     /* comparator. */
     149    /** Comparator. */
    148150    uint64_t                         u64Cmp;
    149     /* FSB route, not supported now. */
     151    /** FSB route, not supported now. */
    150152    uint64_t                         u64Fsb;
    151 
    152     /* Hidden register state. */
    153     /* Last value written to comparator. */
     153    /** @} */
     154
     155    /** @name Hidden register state.
     156     * @{ */
     157    /** Last value written to comparator. */
    154158    uint64_t                         u64Period;
     159    /** @} */
    155160} HpetTimer;
     161AssertCompileMemberAlignment(HpetTimer, u64Config, sizeof(uint64_t));
    156162
    157163typedef struct HpetState
     
    199205#ifndef VBOX_DEVICE_STRUCT_TESTCASE
    200206
    201 /*
    202  * We shall declare MMIO accessors as extern "C" to avoid name mangling
    203  * and let them be found during R0/RC module init.
    204  * Maybe PDMBOTHCBDECL macro shall have extern "C" part in it.
    205  */
    206 
    207 RT_C_DECLS_BEGIN
    208 PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    209 PDMBOTHCBDECL(int) hpetMMIORead (PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    210 RT_C_DECLS_END
    211 
    212 
    213 /*
    214  * Temporary control to disable locking if problems found
    215  */
    216 static const bool fHpetLocking = true;
    217 
     207
     208/** @todo Use macros so we can get the source position. */
    218209DECLINLINE(int) hpetLock(HpetState* pThis, int rcBusy)
    219210{
    220     if (!fHpetLocking)
    221         return VINF_SUCCESS;
    222 
    223211    return PDMCritSectEnter(&pThis->csLock, rcBusy);
    224212}
     
    226214DECLINLINE(void) hpetUnlock(HpetState* pThis)
    227215{
    228     if (!fHpetLocking)
    229         return;
    230 
    231216    PDMCritSectLeave(&pThis->csLock);
    232217}
    233218
    234 DECLINLINE(bool) hpet32bitTimer(HpetTimer *pTimer)
    235 {
    236     uint64_t u64Cfg = pTimer->u64Config;
     219DECLINLINE(bool) hpet32bitTimer(HpetTimer *pHpetTimer)
     220{
     221    uint64_t u64Cfg = pHpetTimer->u64Config;
    237222
    238223    return ((u64Cfg & HPET_TN_SIZE_CAP) == 0) || ((u64Cfg & HPET_TN_32BIT) != 0);
    239224}
    240225
    241 DECLINLINE(uint64_t) hpetInvalidValue(HpetTimer *pTimer)
    242 {
    243     return hpet32bitTimer(pTimer) ? ~0U : ~0ULL;
     226DECLINLINE(uint64_t) hpetInvalidValue(HpetTimer *pHpetTimer)
     227{
     228    return hpet32bitTimer(pHpetTimer) ? UINT32_MAX : UINT64_MAX;
    244229}
    245230
     
    270255     * with the same speed.
    271256     */
    272     return nsToHpetTicks(pThis, TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer)) +
    273                                 pThis->u64HpetOffset);
     257    return nsToHpetTicks(pThis,
     258                           TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer))
     259                         + pThis->u64HpetOffset);
    274260}
    275261
     
    297283}
    298284
    299 DECLINLINE(uint64_t) hpetComputeDiff(HpetTimer* pTimer,
     285DECLINLINE(uint64_t) hpetComputeDiff(HpetTimer *pHpetTimer,
    300286                                     uint64_t   u64Now)
    301287{
    302288
    303     if (hpet32bitTimer(pTimer))
     289    if (hpet32bitTimer(pHpetTimer))
    304290    {
    305291        uint32_t u32Diff;
    306292
    307         u32Diff = (uint32_t)pTimer->u64Cmp - (uint32_t)u64Now;
     293        u32Diff = (uint32_t)pHpetTimer->u64Cmp - (uint32_t)u64Now;
    308294        u32Diff = ((int32_t)u32Diff > 0) ? u32Diff : (uint32_t)0;
    309295        return (uint64_t)u32Diff;
     
    313299        uint64_t u64Diff;
    314300
    315         u64Diff = pTimer->u64Cmp - u64Now;
     301        u64Diff = pHpetTimer->u64Cmp - u64Now;
    316302        u64Diff = ((int64_t)u64Diff > 0) ?  u64Diff : (uint64_t)0;
    317303        return u64Diff;
     
    320306
    321307
    322 static void hpetAdjustComparator(HpetTimer* pTimer,
    323                                  uint64_t   u64Now)
    324 {
    325   uint64_t u64Period = pTimer->u64Period;
    326   if (   (pTimer->u64Config & HPET_TN_PERIODIC)
    327       && (u64Period != 0))
     308static void hpetAdjustComparator(HpetTimer *pHpetTimer, uint64_t u64Now)
     309{
     310  uint64_t u64Period = pHpetTimer->u64Period;
     311  if (   (pHpetTimer->u64Config & HPET_TN_PERIODIC)
     312      && u64Period != 0)
    328313  {
    329314      /* While loop is suboptimal */
    330       if (hpet32bitTimer(pTimer))
     315      if (hpet32bitTimer(pHpetTimer))
    331316      {
    332           while (hpetTimeAfter32(u64Now, pTimer->u64Cmp))
    333               pTimer->u64Cmp = (uint32_t)(pTimer->u64Cmp + u64Period);
     317          while (hpetTimeAfter32(u64Now, pHpetTimer->u64Cmp))
     318              pHpetTimer->u64Cmp = (uint32_t)(pHpetTimer->u64Cmp + u64Period);
    334319      }
    335320      else
    336321      {
    337           while (hpetTimeAfter64(u64Now, pTimer->u64Cmp))
    338               pTimer->u64Cmp += u64Period;
     322          while (hpetTimeAfter64(u64Now, pHpetTimer->u64Cmp))
     323              pHpetTimer->u64Cmp += u64Period;
    339324      }
    340325  }
    341326}
    342327
    343 static void hpetProgramTimer(HpetTimer *pTimer)
    344 {
     328static void hpetProgramTimer(HpetTimer *pHpetTimer)
     329{
     330    uint64_t u64Ticks = hpetGetTicks(pHpetTimer->CTX_SUFF(pHpet));
    345331    uint64_t u64Diff;
    346332    uint32_t u32TillWrap;
    347     uint64_t u64Ticks = hpetGetTicks(pTimer->CTX_SUFF(pHpet));
    348333
    349334    /* no wrapping on new timers */
    350     pTimer->u8Wrap = 0;
    351 
    352     hpetAdjustComparator(pTimer, u64Ticks);
    353 
    354     u64Diff = hpetComputeDiff(pTimer, u64Ticks);
     335    pHpetTimer->u8Wrap = 0;
     336
     337    hpetAdjustComparator(pHpetTimer, u64Ticks);
     338
     339    u64Diff = hpetComputeDiff(pHpetTimer, u64Ticks);
    355340
    356341    /*
     
    358343     * counter wraps in addition to an interrupt with comparator match.
    359344     */
    360     if (    hpet32bitTimer(pTimer)
    361         && !(pTimer->u64Config & HPET_TN_PERIODIC))
     345    if (    hpet32bitTimer(pHpetTimer)
     346        && !(pHpetTimer->u64Config & HPET_TN_PERIODIC))
    362347    {
    363348        u32TillWrap = 0xffffffff - (uint32_t)u64Ticks + 1;
     
    365350        {
    366351            Log(("wrap on timer %d: till=%u ticks=%lld diff64=%lld\n",
    367                  pTimer->u8TimerNumber, u32TillWrap, u64Ticks, u64Diff));
     352                 pHpetTimer->idxTimer, u32TillWrap, u64Ticks, u64Diff));
    368353            u64Diff = u32TillWrap;
    369             pTimer->u8Wrap = 1;
     354            pHpetTimer->u8Wrap = 1;
    370355        }
    371356    }
     
    378363#endif
    379364
    380     Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pTimer->CTX_SUFF(pHpet), u64Diff)));
    381 
    382     TMTimerSetNano(pTimer->CTX_SUFF(pTimer), hpetTicksToNs(pTimer->CTX_SUFF(pHpet), u64Diff));
    383 }
    384 
    385 static uint32_t getTimerIrq(struct HpetTimer *pTimer)
     365    Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff)));
     366
     367    TMTimerSetNano(pHpetTimer->CTX_SUFF(pTimer), hpetTicksToNs(pHpetTimer->CTX_SUFF(pHpet), u64Diff));
     368}
     369
     370static uint32_t getTimerIrq(struct HpetTimer *pHpetTimer)
    386371{
    387372    /*
     
    393378     * to the different ICs.
    394379     */
    395     if (   (pTimer->u8TimerNumber <= 1)
    396         && (pTimer->CTX_SUFF(pHpet)->u64HpetConfig & HPET_CFG_LEGACY))
    397         return (pTimer->u8TimerNumber == 0) ? 0 : 8;
    398 
    399     return (pTimer->u64Config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
     380    if (   (pHpetTimer->idxTimer <= 1)
     381        && (pHpetTimer->CTX_SUFF(pHpet)->u64HpetConfig & HPET_CFG_LEGACY))
     382        return (pHpetTimer->idxTimer == 0) ? 0 : 8;
     383
     384    return (pHpetTimer->u64Config & HPET_TN_INT_ROUTE_MASK) >> HPET_TN_INT_ROUTE_SHIFT;
    400385}
    401386
     
    405390                              uint32_t  *pValue)
    406391{
    407     HpetTimer *pTimer;
    408 
    409392    if (iTimerNo >= HPET_NUM_TIMERS)
    410393    {
     
    413396    }
    414397
    415     pTimer = &pThis->aTimers[iTimerNo];
    416 
     398    HpetTimer *pHpetTimer = &pThis->aTimers[iTimerNo];
    417399    switch (iTimerReg)
    418400    {
    419401        case HPET_TN_CFG:
    420             Log(("read HPET_TN_CFG on %d\n", pTimer->u8TimerNumber));
    421             *pValue = (uint32_t)(pTimer->u64Config);
     402            Log(("read HPET_TN_CFG on %d\n", pHpetTimer->idxTimer));
     403            *pValue = (uint32_t)(pHpetTimer->u64Config);
    422404            break;
    423405        case HPET_TN_CFG + 4:
    424             Log(("read HPET_TN_CFG+4 on %d\n", pTimer->u8TimerNumber));
    425             *pValue = (uint32_t)(pTimer->u64Config >> 32);
     406            Log(("read HPET_TN_CFG+4 on %d\n", pHpetTimer->idxTimer));
     407            *pValue = (uint32_t)(pHpetTimer->u64Config >> 32);
    426408            break;
    427409        case HPET_TN_CMP:
    428             Log(("read HPET_TN_CMP on %d, cmp=%llx\n", pTimer->u8TimerNumber, pTimer->u64Cmp));
    429             *pValue = (uint32_t)(pTimer->u64Cmp);
     410            Log(("read HPET_TN_CMP on %d, cmp=%llx\n", pHpetTimer->idxTimer, pHpetTimer->u64Cmp));
     411            *pValue = (uint32_t)(pHpetTimer->u64Cmp);
    430412            break;
    431413        case HPET_TN_CMP + 4:
    432             Log(("read HPET_TN_CMP+4 on %d, cmp=%llx\n", pTimer->u8TimerNumber, pTimer->u64Cmp));
    433             *pValue = (uint32_t)(pTimer->u64Cmp >> 32);
     414            Log(("read HPET_TN_CMP+4 on %d, cmp=%llx\n", pHpetTimer->idxTimer, pHpetTimer->u64Cmp));
     415            *pValue = (uint32_t)(pHpetTimer->u64Cmp >> 32);
    434416            break;
    435417        case HPET_TN_ROUTE:
    436             Log(("read HPET_TN_ROUTE on %d\n", pTimer->u8TimerNumber));
    437             *pValue = (uint32_t)(pTimer->u64Fsb >> 32);
     418            Log(("read HPET_TN_ROUTE on %d\n", pHpetTimer->idxTimer));
     419            *pValue = (uint32_t)(pHpetTimer->u64Fsb >> 32);
    438420            break;
    439421        default:
    440             LogRel(("invalid HPET register read %d on %d\n", iTimerReg, pTimer->u8TimerNumber));
     422            LogRel(("invalid HPET register read %d on %d\n", iTimerReg, pHpetTimer->idxTimer));
    441423            *pValue = 0;
    442424            break;
     
    493475}
    494476
    495 static int hpetTimerRegWrite32(HpetState* pThis,
     477static int hpetTimerRegWrite32(HpetState *pThis,
    496478                               uint32_t   iTimerNo,
    497479                               uint32_t   iTimerReg,
    498480                               uint32_t   iNewValue)
    499481{
    500     HpetTimer * pTimer;
    501     uint64_t    iOldValue = 0;
    502482    uint32_t    u32Temp;
    503483    int         rc;
     
    508488        return VINF_SUCCESS;
    509489    }
    510     pTimer = &pThis->aTimers[iTimerNo];
    511 
     490
     491    HpetTimer *pHpetTimer = &pThis->aTimers[iTimerNo];
    512492    rc = hpetTimerRegRead32(pThis, iTimerNo, iTimerReg, &u32Temp);
    513493    if (RT_FAILURE(rc))
    514494        return rc;
    515     iOldValue = u32Temp;
     495    uint64_t iOldValue = u32Temp;
    516496
    517497    switch (iTimerReg)
     
    523503            Log(("write HPET_TN_CFG: %d: %x\n", iTimerNo, iNewValue));
    524504
    525             if ((pTimer->u64Config & HPET_TN_PERIODIC_CAP) != 0)
     505            if ((pHpetTimer->u64Config & HPET_TN_PERIODIC_CAP) != 0)
    526506                u64Mask |= HPET_TN_PERIODIC;
    527507
    528             if ((pTimer->u64Config & HPET_TN_SIZE_CAP) != 0)
     508            if ((pHpetTimer->u64Config & HPET_TN_SIZE_CAP) != 0)
    529509                u64Mask |= HPET_TN_32BIT;
    530510            else
     
    534514            {
    535515                Log(("setting timer %d to 32-bit mode\n", iTimerNo));
    536                 pTimer->u64Cmp    = (uint32_t)pTimer->u64Cmp;
    537                 pTimer->u64Period = (uint32_t)pTimer->u64Period;
     516                pHpetTimer->u64Cmp    = (uint32_t)pHpetTimer->u64Cmp;
     517                pHpetTimer->u64Period = (uint32_t)pHpetTimer->u64Period;
    538518            }
    539519            if ((iNewValue & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
     
    542522                AssertFailed();
    543523            }
    544             /** We only care about lower 32-bits so far */
    545             pTimer->u64Config =
    546                     hpetUpdateMasked(iNewValue, iOldValue, u64Mask);
    547             break;
    548         }
     524            /* We only care about lower 32-bits so far */
     525            pHpetTimer->u64Config = hpetUpdateMasked(iNewValue, iOldValue, u64Mask);
     526            break;
     527        }
     528
    549529        case HPET_TN_CFG + 4: /* Interrupt capabilities */
    550530        {
     
    552532            break;
    553533        }
     534
    554535        case HPET_TN_CMP: /* lower bits of comparator register */
    555536        {
    556537            Log(("write HPET_TN_CMP on %d: %x\n", iTimerNo, iNewValue));
    557             if (pTimer->u64Config & HPET_TN_PERIODIC)
     538            if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
    558539            {
    559                 iNewValue &= hpetInvalidValue(pTimer) >> 1;
    560                 pTimer->u64Period = (pTimer->u64Period & 0xffffffff00000000ULL)
    561                                   | iNewValue;
     540                iNewValue &= hpetInvalidValue(pHpetTimer) >> 1;
     541                pHpetTimer->u64Period = (pHpetTimer->u64Period & UINT64_C(0xffffffff00000000))
     542                                      | iNewValue;
    562543            }
    563544
    564             pTimer->u64Cmp = (pTimer->u64Cmp & 0xffffffff00000000ULL)
    565                            | iNewValue;
    566 
    567             pTimer->u64Config &= ~HPET_TN_SETVAL;
    568             Log2(("after HPET_TN_CMP cmp=%llx per=%llx\n", pTimer->u64Cmp, pTimer->u64Period));
     545            pHpetTimer->u64Cmp = (pHpetTimer->u64Cmp & UINT64_C(0xffffffff00000000))
     546                               | iNewValue;
     547
     548            pHpetTimer->u64Config &= ~HPET_TN_SETVAL;
     549            Log2(("after HPET_TN_CMP cmp=%llx per=%llx\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period));
    569550
    570551            if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
    571                 hpetProgramTimer(pTimer);
    572             break;
    573         }
     552                hpetProgramTimer(pHpetTimer);
     553            break;
     554        }
     555
    574556        case HPET_TN_CMP + 4: /* upper bits of comparator register */
    575557        {
    576558            Log(("write HPET_TN_CMP + 4 on %d: %x\n", iTimerNo, iNewValue));
    577             if (hpet32bitTimer(pTimer))
     559            if (hpet32bitTimer(pHpetTimer))
    578560                break;
    579561
    580             if (pTimer->u64Config & HPET_TN_PERIODIC)
    581             {
    582                 pTimer->u64Period = (pTimer->u64Period & UINT64_C(0xffffffff))
    583                                    | ((uint64_t)iNewValue << 32);
    584             }
    585 
    586             pTimer->u64Cmp = (pTimer->u64Cmp & UINT64_C(0xffffffff))
    587                            | ((uint64_t)iNewValue << 32);
    588 
    589             Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx\n", pTimer->u64Cmp, pTimer->u64Period));
    590 
    591             pTimer->u64Config &= ~HPET_TN_SETVAL;
     562            if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
     563                pHpetTimer->u64Period = (pHpetTimer->u64Period & UINT64_C(0xffffffff))
     564                                      | ((uint64_t)iNewValue << 32);
     565
     566            pHpetTimer->u64Cmp = (pHpetTimer->u64Cmp & UINT64_C(0xffffffff))
     567                               | ((uint64_t)iNewValue << 32);
     568
     569            Log2(("after HPET_TN_CMP+4 cmp=%llx per=%llx\n", pHpetTimer->u64Cmp, pHpetTimer->u64Period));
     570
     571            pHpetTimer->u64Config &= ~HPET_TN_SETVAL;
    592572
    593573            if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
    594                 hpetProgramTimer(pTimer);
    595             break;
    596         }
     574                hpetProgramTimer(pHpetTimer);
     575            break;
     576        }
     577
    597578        case HPET_TN_ROUTE:
    598579        {
     
    600581            break;
    601582        }
     583
    602584        case HPET_TN_ROUTE + 4:
    603585        {
     
    605587            break;
    606588        }
     589
    607590        default:
    608591        {
     
    612595        }
    613596    }
     597
    614598    return VINF_SUCCESS;
    615599}
     
    643627            break;
    644628        }
     629
    645630        case HPET_CFG:
    646631        {
    647             uint32_t i, iOldValue;
    648 
    649             Log(("write HPET_CFG: %x\n", iNewValue));
    650 
    651             iOldValue = (uint32_t)(pThis->u64HpetConfig);
     632            uint32_t const iOldValue = (uint32_t)(pThis->u64HpetConfig);
     633            Log(("write HPET_CFG: %x (old %x)\n", iNewValue, iOldValue));
    652634
    653635            /*
     
    656638             */
    657639            if (hpetBitJustSet(iOldValue, iNewValue, HPET_CFG_LEGACY))
    658             {
    659640                rc = hpetLegacyMode(pThis, true);
    660             }
    661641            else if (hpetBitJustCleared(iOldValue, iNewValue, HPET_CFG_LEGACY))
    662             {
    663642                rc = hpetLegacyMode(pThis, false);
    664             }
    665643            if (rc != VINF_SUCCESS)
    666644                return rc;
     
    671649                /* Enable main counter and interrupt generation. */
    672650                pThis->u64HpetOffset = hpetTicksToNs(pThis, pThis->u64HpetCounter)
    673                         - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
    674                 for (i = 0; i < HPET_NUM_TIMERS; i++)
     651                                     - TMTimerGet(pThis->aTimers[0].CTX_SUFF(pTimer));
     652                for (uint32_t i = 0; i < HPET_NUM_TIMERS; i++)
    675653                    if (pThis->aTimers[i].u64Cmp != hpetInvalidValue(&pThis->aTimers[i]))
    676654                        hpetProgramTimer(&pThis->aTimers[i]);
     
    680658                /* Halt main counter and disable interrupt generation. */
    681659                pThis->u64HpetCounter = hpetGetTicks(pThis);
    682                 for (i = 0; i < HPET_NUM_TIMERS; i++)
     660                for (uint32_t i = 0; i < HPET_NUM_TIMERS; i++)
    683661                    TMTimerStop(pThis->aTimers[i].CTX_SUFF(pTimer));
    684662            }
    685663            break;
    686664        }
     665
    687666        case HPET_CFG + 4:
    688667        {
     
    690669            pThis->u64HpetConfig = hpetUpdateMasked((uint64_t)iNewValue << 32,
    691670                                                    pThis->u64HpetConfig,
    692                                                     0xffffffff00000000ULL);
    693             break;
    694         }
     671                                                    UINT64_C(0xffffffff00000000));
     672            break;
     673        }
     674
    695675        case HPET_STATUS:
    696676        {
     
    700680            break;
    701681        }
     682
    702683        case HPET_STATUS + 4:
    703684        {
     
    707688            break;
    708689        }
     690
    709691        case HPET_COUNTER:
    710692        {
    711             pThis->u64HpetCounter = (pThis->u64HpetCounter & 0xffffffff00000000ULL) | iNewValue;
     693            pThis->u64HpetCounter = (pThis->u64HpetCounter & UINT64_C(0xffffffff00000000)) | iNewValue;
    712694            Log(("write HPET_COUNTER: %#x -> %llx\n",
    713695                 iNewValue, pThis->u64HpetCounter));
    714696            break;
    715697        }
     698
    716699        case HPET_COUNTER + 4:
    717700        {
    718             pThis->u64HpetCounter = (pThis->u64HpetCounter & 0xffffffffULL)
    719                     | (((uint64_t)iNewValue) << 32);
     701            pThis->u64HpetCounter = (pThis->u64HpetCounter & UINT64_C(0xffffffff))
     702                                  | (((uint64_t)iNewValue) << 32);
    720703            Log(("write HPET_COUNTER + 4: %#x -> %llx\n",
    721704                 iNewValue, pThis->u64HpetCounter));
    722705            break;
    723706        }
     707
    724708        default:
    725709            LogRel(("invalid HPET config write: %x\n", iIndex));
     
    829813                                 unsigned   cb)
    830814{
    831     HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState*);
    832     int rc = VINF_SUCCESS;
    833     uint32_t iIndex = (uint32_t)(GCPhysAddr - HPET_BASE);
     815    HpetState  *pThis = PDMINS_2_DATA(pDevIns, HpetState*);
     816    int         rc    = VINF_SUCCESS;
     817    uint32_t    iIndex = (uint32_t)(GCPhysAddr - HPET_BASE);
    834818
    835819    LogFlow(("hpetMMIOWrite (%d): %llx (%x) <- %x\n",
     
    858842            break;
    859843        }
     844
    860845        case 8:
    861846        {
    862             union
    863             {
    864                 uint32_t u32[2];
    865                 uint64_t u64;
    866             } value;
    867 
    868847            /* Unaligned accesses not allowed */
    869848            if (iIndex % 8 != 0)
     
    873852                break;
    874853            }
     854
     855
     856            // for 8-byte accesses we just split them, happens under lock anyway
     857            union
     858            {
     859                uint32_t u32[2];
     860                uint64_t u64;
     861            } value;
    875862            value.u64 = *(uint64_t*)pv;
    876             // for 8-byte accesses we just split them, happens under lock anyway
    877863            if (iIndex >= 0x100 && iIndex < 0x400)
    878864            {
     
    881867
    882868                rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg, value.u32[0]);
    883                 if (RT_UNLIKELY(rc != VINF_SUCCESS))
    884                     break;
    885                 rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, value.u32[1]);
     869                if (RT_LIKELY(rc == VINF_SUCCESS))
     870                    rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, value.u32[1]);
    886871            }
    887872            else
    888873            {
    889874                rc = hpetConfigRegWrite32(pThis, iIndex, value.u32[0]);
    890                 if (RT_UNLIKELY(rc != VINF_SUCCESS))
    891                     break;
    892                 rc = hpetConfigRegWrite32(pThis, iIndex+4, value.u32[1]);
     875                if (RT_LIKELY(rc == VINF_SUCCESS))
     876                    rc = hpetConfigRegWrite32(pThis, iIndex+4, value.u32[1]);
    893877            }
    894878            break;
     
    898882            AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
    899883            rc = VERR_INTERNAL_ERROR;
     884            break;
    900885    }
    901886
    902887    hpetUnlock(pThis);
    903 
    904888    return rc;
    905889}
     
    907891#ifdef IN_RING3
    908892
    909 static int hpetSaveTimer(HpetTimer *pTimer,
    910                          PSSMHANDLE pSSM)
    911 {
    912     TMR3TimerSave(pTimer->pTimerR3, pSSM);
    913     SSMR3PutU8  (pSSM,              pTimer->u8Wrap);
    914     SSMR3PutU64 (pSSM,              pTimer->u64Config);
    915     SSMR3PutU64 (pSSM,              pTimer->u64Cmp);
    916     SSMR3PutU64 (pSSM,              pTimer->u64Fsb);
    917     SSMR3PutU64 (pSSM,              pTimer->u64Period);
    918 
    919     return VINF_SUCCESS;
    920 }
    921 
    922 static int hpetLoadTimer(HpetTimer *pTimer,
    923                          PSSMHANDLE pSSM)
    924 {
    925     TMR3TimerLoad(pTimer->pTimerR3, pSSM);
    926     SSMR3GetU8(pSSM,                &pTimer->u8Wrap);
    927     SSMR3GetU64(pSSM,               &pTimer->u64Config);
    928     SSMR3GetU64(pSSM,               &pTimer->u64Cmp);
    929     SSMR3GetU64(pSSM,               &pTimer->u64Fsb);
    930     SSMR3GetU64(pSSM,               &pTimer->u64Period);
    931 
    932     return VINF_SUCCESS;
     893/** @todo move the saved state stuff down before the timer.  */
     894
     895static int hpetSaveTimer(HpetTimer *pHpetTimer, PSSMHANDLE pSSM)
     896{
     897    TMR3TimerSave(pHpetTimer->pTimerR3, pSSM);
     898    SSMR3PutU8(pSSM,  pHpetTimer->u8Wrap);
     899    SSMR3PutU64(pSSM, pHpetTimer->u64Config);
     900    SSMR3PutU64(pSSM, pHpetTimer->u64Cmp);
     901    SSMR3PutU64(pSSM, pHpetTimer->u64Fsb);
     902    return SSMR3PutU64(pSSM, pHpetTimer->u64Period);
     903}
     904
     905static int hpetLoadTimer(HpetTimer *pHpetTimer, PSSMHANDLE pSSM)
     906{
     907    TMR3TimerLoad(pHpetTimer->pTimerR3, pSSM);
     908    SSMR3GetU8(pSSM,  &pHpetTimer->u8Wrap);
     909    SSMR3GetU64(pSSM, &pHpetTimer->u64Config);
     910    SSMR3GetU64(pSSM, &pHpetTimer->u64Cmp);
     911    SSMR3GetU64(pSSM, &pHpetTimer->u64Fsb);
     912    return SSMR3GetU64(pSSM, &pHpetTimer->u64Period);
    933913}
    934914
     
    992972{
    993973    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
    994     uint32_t   iTimer;
    995     int        rc;
    996974
    997975    if (uVersion == HPET_SAVED_STATE_VERSION_EMPTY)
     
    1003981    uint8_t u8NumTimers;
    1004982
    1005     rc = SSMR3GetU8(pSSM, &u8NumTimers);          AssertRCReturn(rc, rc);
     983    int rc = SSMR3GetU8(pSSM, &u8NumTimers);
     984    AssertRCReturn(rc, rc);
    1006985    if (u8NumTimers != HPET_NUM_TIMERS)
    1007986        return SSMR3SetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - wrong number of timers: saved=%#x config=%#x"), u8NumTimers, HPET_NUM_TIMERS);
     
    1010989        return VINF_SUCCESS;
    1011990
    1012     for (iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
     991    for (uint32_t iTimer = 0; iTimer < HPET_NUM_TIMERS; iTimer++)
    1013992    {
    1014993        rc = hpetLoadTimer(&pThis->aTimers[iTimer], pSSM);
     
    10251004}
    10261005
    1027 static void hpetIrqUpdate(struct HpetTimer *pTimer)
    1028 {
    1029     uint32_t irq    = getTimerIrq(pTimer);
    1030     HpetState* pThis = pTimer->CTX_SUFF(pHpet);
     1006static void hpetIrqUpdate(struct HpetTimer *pHpetTimer)
     1007{
     1008    uint32_t   irq   = getTimerIrq(pHpetTimer);
     1009    HpetState *pThis = pHpetTimer->CTX_SUFF(pHpet);
    10311010
    10321011    /** @todo: is it correct? */
    1033     if (   !!(pTimer->u64Config & HPET_TN_ENABLE)
     1012    if (   !!(pHpetTimer->u64Config & HPET_TN_ENABLE)
    10341013        && !!(pThis->u64HpetConfig & HPET_CFG_ENABLE))
    10351014    {
     
    10371016
    10381017        /* ISR bits are only set in level-triggered mode */
    1039         if ((pTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
    1040             pThis->u64Isr |= (uint64_t)(1 << pTimer->u8TimerNumber);
     1018        if ((pHpetTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_LEVEL)
     1019            pThis->u64Isr |= (uint64_t)(1 << pHpetTimer->idxTimer);
    10411020
    10421021        /* We trigger flip/flop in edge-triggered mode and do nothing in level-triggered mode yet */
    1043         if ((pTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_EDGE)
     1022        if ((pHpetTimer->u64Config & HPET_TN_INT_TYPE) == HPET_TIMER_TYPE_EDGE)
    10441023            pThis->pHpetHlpR3->pfnSetIrq(pThis->CTX_SUFF(pDevIns), irq, PDM_IRQ_LEVEL_FLIP_FLOP);
    10451024        else
     
    10561035 * @param   pvUser          Pointer to the HPET timer state.
    10571036 */
    1058 static DECLCALLBACK(void) hpetTimer(PPDMDEVINS pDevIns,
    1059                                     PTMTIMER   pTmTimer,
    1060                                     void *     pvUser)
     1037static DECLCALLBACK(void) hpetTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    10611038{
    10621039    HpetState *pThis      = PDMINS_2_DATA(pDevIns, HpetState *);
    1063     HpetTimer *pTimer    = (HpetTimer *)pvUser;
    1064     uint64_t   u64Period  = pTimer->u64Period;
    1065     uint64_t   u64CurTick = hpetGetTicks(pThis); /** @todo this should be done AFTER locking the HPET. */
     1040    HpetTimer *pHpetTimer = (HpetTimer *)pvUser;
     1041    uint64_t   u64Period  = pHpetTimer->u64Period;
     1042    uint64_t   u64CurTick = hpetGetTicks(pThis);
    10661043    uint64_t   u64Diff;
    1067     int        rc;
    1068 
    1069     if (pTimer == NULL)
    1070         return;
    10711044
    10721045    /* Lock in R3 must either block or succeed */
    1073     rc = hpetLock(pThis, VERR_IGNORED);
    1074 
     1046    int rc = hpetLock(pThis, VERR_IGNORED);
    10751047    AssertLogRelRCReturnVoid(rc);
    10761048
    1077     if ((pTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0))
    1078     {
    1079         hpetAdjustComparator(pTimer, u64CurTick);
    1080 
    1081         u64Diff = hpetComputeDiff(pTimer, u64CurTick);
    1082 
    1083         Log4(("HPET: periodical: next in %lld\n", hpetTicksToNs(pThis, u64Diff)));
    1084         TMTimerSetNano(pTmTimer, hpetTicksToNs(pThis, u64Diff));
    1085     }
    1086     else if (    hpet32bitTimer(pTimer)
    1087              && !(pTimer->u64Config & HPET_TN_PERIODIC))
    1088     {
    1089         if (pTimer->u8Wrap)
    1090         {
    1091             u64Diff = hpetComputeDiff(pTimer, u64CurTick);
    1092             TMTimerSetNano(pTmTimer, hpetTicksToNs(pThis, u64Diff));
    1093             pTimer->u8Wrap = 0;
     1049    if ((pHpetTimer->u64Config & HPET_TN_PERIODIC) && (u64Period != 0))
     1050    {
     1051        hpetAdjustComparator(pHpetTimer, u64CurTick);
     1052
     1053        u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick);
     1054
     1055        Log4(("HPET: periodical: next in %llu\n", hpetTicksToNs(pThis, u64Diff)));
     1056        TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
     1057    }
     1058    else if (    hpet32bitTimer(pHpetTimer)
     1059             && !(pHpetTimer->u64Config & HPET_TN_PERIODIC))
     1060    {
     1061        if (pHpetTimer->u8Wrap)
     1062        {
     1063            u64Diff = hpetComputeDiff(pHpetTimer, u64CurTick);
     1064            TMTimerSetNano(pTimer, hpetTicksToNs(pThis, u64Diff));
     1065            pHpetTimer->u8Wrap = 0;
    10941066        }
    10951067    }
    10961068
    10971069    /* Should it really be under lock, does it really matter? */
    1098     hpetIrqUpdate(pTimer);
     1070    hpetIrqUpdate(pHpetTimer);
    10991071
    11001072    hpetUnlock(pThis);
     
    11421114    for (i = 0; i < HPET_NUM_TIMERS; i++)
    11431115    {
    1144         HpetTimer *pTimer = &pThis->aTimers[i];
    1145         pTimer->u8TimerNumber = i;
     1116        HpetTimer *pHpetTimer = &pThis->aTimers[i];
     1117        pHpetTimer->idxTimer = i;
    11461118        /* capable of periodic operations and 64-bits */
    11471119        if (pThis->fIch9)
    1148             pTimer->u64Config = (i == 0) ?
    1149                     (HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP)
    1150                     :
    1151                     0;
     1120            pHpetTimer->u64Config = (i == 0)
     1121                                  ? (HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP)
     1122                                  : 0;
    11521123        else
    1153             pTimer->u64Config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
     1124            pHpetTimer->u64Config = HPET_TN_PERIODIC_CAP | HPET_TN_SIZE_CAP;
    11541125
    11551126        /* We can do all IRQs */
    11561127        uint32_t u32RoutingCap = 0xffffffff;
    1157         pTimer->u64Config |= ((uint64_t)u32RoutingCap) << 32;
    1158         pTimer->u64Period = 0ULL;
    1159         pTimer->u8Wrap = 0;
    1160         pTimer->u64Cmp = hpetInvalidValue(pTimer);
    1161     }
    1162     pThis->u64HpetCounter = 0ULL;
    1163     pThis->u64HpetOffset = 0ULL;
     1128        pHpetTimer->u64Config |= ((uint64_t)u32RoutingCap) << 32;
     1129        pHpetTimer->u64Period  = 0;
     1130        pHpetTimer->u8Wrap    = 0;
     1131        pHpetTimer->u64Cmp     = hpetInvalidValue(pHpetTimer);
     1132    }
     1133    pThis->u64HpetCounter = 0;
     1134    pThis->u64HpetOffset  = 0;
    11641135
    11651136    uint32_t u32Vendor = 0x8086;
     
    11891160
    11901161    pThis->pDevInsR3 = pDevIns;
    1191     pThis->pDevInsR0  = PDMDEVINS_2_R0PTR(pDevIns);
    1192     pThis->pDevInsRC  = PDMDEVINS_2_RCPTR(pDevIns);
     1162    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     1163    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    11931164
    11941165    for (unsigned i = 0; i < HPET_NUM_TIMERS; i++)
    11951166    {
    1196         HpetTimer *pTimer = &pThis->aTimers[i];
    1197 
    1198         pTimer->pHpetR3 = pThis;
    1199         pTimer->pHpetR0 = PDMINS_2_DATA_R0PTR(pDevIns);
    1200         pTimer->pHpetRC = PDMINS_2_DATA_RCPTR(pDevIns);
    1201 
    1202         int rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetTimer, pTimer,
    1203                                         TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "HPET Timer",
     1167        HpetTimer *pHpetTimer = &pThis->aTimers[i];
     1168
     1169        pHpetTimer->pHpetR3 = pThis;
     1170        pHpetTimer->pHpetR0 = PDMINS_2_DATA_R0PTR(pDevIns);
     1171        pHpetTimer->pHpetRC = PDMINS_2_DATA_RCPTR(pDevIns);
     1172
     1173        int rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetTimer, pHpetTimer,
     1174                                        TMTIMER_FLAGS_NO_CRIT_SECT, "HPET Timer",
    12041175                                        &pThis->aTimers[i].pTimerR3);
    12051176        if (RT_FAILURE(rc))
     
    12071178        pThis->aTimers[i].pTimerRC = TMTimerRCPtr(pThis->aTimers[i].pTimerR3);
    12081179        pThis->aTimers[i].pTimerR0 = TMTimerR0Ptr(pThis->aTimers[i].pTimerR3);
     1180        TMR3TimerSetCritSect(pThis->aTimers[i].pTimerR3, &pThis->csLock);
    12091181    }
    12101182
     
    12231195static DECLCALLBACK(void) hpetInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    12241196{
    1225     HpetState   *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
    1226     int i;
     1197    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
    12271198
    12281199    pHlp->pfnPrintf(pHlp,
     
    12361207    pHlp->pfnPrintf(pHlp,
    12371208                    "Timers:\n");
    1238     for (i = 0; i < HPET_NUM_TIMERS; i++)
     1209    for (unsigned i = 0; i < HPET_NUM_TIMERS; i++)
    12391210    {
    12401211        pHlp->pfnPrintf(pHlp, " %d: comparator=%016RX64 period(hidden)=%016RX64 cfg=%016RX64\n",
    1241                         pThis->aTimers[i].u8TimerNumber,
     1212                        pThis->aTimers[i].idxTimer,
    12421213                        pThis->aTimers[i].u64Cmp,
    12431214                        pThis->aTimers[i].u64Period,
     
    12541225    HpetState   *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
    12551226    int          rc;
    1256     bool         fRCEnabled = false;
    1257     bool         fR0Enabled = false;
    1258     bool         fIch9      = false;
    1259     PDMHPETREG   HpetReg;
    12601227
    12611228    /* Only one HPET device now, as we use fixed MMIO region. */
     
    12721239
    12731240    /* Query configuration. */
     1241    bool fRCEnabled;
    12741242    rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fRCEnabled, true);
    12751243    if (RT_FAILURE(rc))
     
    12771245                                N_("Configuration error: Querying \"GCEnabled\" as a bool failed"));
    12781246
     1247    bool fR0Enabled;
    12791248    rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
    12801249    if (RT_FAILURE(rc))
    12811250        return PDMDEV_SET_ERROR(pDevIns, rc,
    12821251                                N_("Configuration error: failed to read R0Enabled as boolean"));
     1252
     1253    bool fIch9;
    12831254    rc = CFGMR3QueryBoolDef(pCfg, "ICH9", &fIch9, false);
    12841255    if (RT_FAILURE(rc))
     
    12871258
    12881259    /* Initialize the device state */
    1289     memset(pThis, 0, sizeof(*pThis));
    1290 
    12911260    pThis->fIch9 = (uint8_t)fIch9;
    12921261
     
    13021271     * Register the HPET and get helpers.
    13031272     */
    1304     HpetReg.u32Version  = PDM_HPETREG_VERSION;
     1273    PDMHPETREG HpetReg;
     1274    HpetReg.u32Version = PDM_HPETREG_VERSION;
    13051275    rc = PDMDevHlpHPETRegister(pDevIns, &HpetReg, &pThis->pHpetHlpR3);
    1306     if (RT_FAILURE(rc))
    1307     {
    1308         AssertMsgRC(rc, ("Cannot HPETRegister: %Rrc\n", rc));
    1309         return rc;
    1310     }
     1276    AssertRCReturn(rc, rc);
    13111277
    13121278    /*
     
    13431309        }
    13441310    }
     1311
    13451312    if (fR0Enabled)
    13461313    {
     
    14281395
    14291396#endif /* IN_RING3 */
    1430 
    1431 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
     1397#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
     1398
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