VirtualBox

Changeset 81963 in vbox for trunk/src


Ignore:
Timestamp:
Nov 18, 2019 8:31:38 PM (5 years ago)
Author:
vboxsync
Message:

DevHPET: Stats. bugref:9218

File:
1 edited

Legend:

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

    r81961 r81963  
    230230    uint64_t                    u64Period;
    231231    /** @} */
     232
     233    STAMCOUNTER                 StatSetIrq;
     234    STAMCOUNTER                 StatSetTimer;
    232235} HPETTIMER;
    233236AssertCompileMemberAlignment(HPETTIMER, u64Config, sizeof(uint64_t));
     
    263266    /** @}  */
    264267
    265     /** Global device lock. */
    266     PDMCRITSECT                 CritSect;
    267 
    268268    /** Whether we emulate ICH9 HPET (different frequency & timer count). */
    269269    bool                        fIch9;
     
    271271    uint8_t                     abPadding0[7];
    272272
    273     /** The handle of the MMIO region.   */
     273    /** Global device lock. */
     274    PDMCRITSECT                 CritSect;
     275
     276    /** The handle of the MMIO region. */
    274277    IOMMMIOHANDLE               hMmio;
     278
     279    STAMCOUNTER                 StatCounterRead4Byte;
     280    STAMCOUNTER                 StatCounterRead8Byte;
     281    STAMCOUNTER                 StatCounterWriteLow;
     282    STAMCOUNTER                 StatCounterWriteHigh;
    275283} HPET;
    276284/** Pointer to the shared HPET device state. */
     
    328336{
    329337    uint64_t u64Cfg = pHpetTimer->u64Config;
    330 
    331338    return ((u64Cfg & HPET_TN_SIZE_CAP) == 0) || ((u64Cfg & HPET_TN_32BIT) != 0);
    332339}
     
    344351DECLINLINE(uint64_t) nsToHpetTicks(PCHPET pThis, uint64_t u64Value)
    345352{
     353    //return ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, RT_MAX(pThis->u32Period, 1 /* no div/zero */));
    346354    return ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, pThis->u32Period);
    347355}
     
    467475    {
    468476        Log4(("HPET: next IRQ in %lld ticks (%lld ns)\n", u64Diff, hpetTicksToNs(pThis, u64Diff)));
     477        STAM_REL_COUNTER_INC(&pHpetTimer->StatSetTimer);
    469478        PDMDevHlpTimerSetNano(pDevIns, pHpetTimer->hTimer, hpetTicksToNs(pThis, u64Diff));
    470479    }
     
    496505    RT_NOREF(pDevIns);
    497506
    498     if (   iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities)  /* The second check is only to satisfy Parfait; */
    499         || iTimerNo >= RT_ELEMENTS(pThis->aTimers) )                /* in practice, the number of configured timers */
    500     {                                                               /* will always be <= aTimers elements. */
     507    uint32_t u32Value;
     508    if (   iTimerNo < HPET_CAP_GET_TIMERS(pThis->u32Capabilities)
     509        && iTimerNo < RT_ELEMENTS(pThis->aTimers) )
     510    {
     511        PCHPETTIMER pHpetTimer = &pThis->aTimers[iTimerNo];
     512        switch (iTimerReg)
     513        {
     514            case HPET_TN_CFG:
     515                u32Value = (uint32_t)pHpetTimer->u64Config;
     516                Log(("read HPET_TN_CFG on %d: %#x\n", iTimerNo, u32Value));
     517                break;
     518
     519            case HPET_TN_CFG + 4:
     520                u32Value = (uint32_t)(pHpetTimer->u64Config >> 32);
     521                Log(("read HPET_TN_CFG+4 on %d: %#x\n", iTimerNo, u32Value));
     522                break;
     523
     524            case HPET_TN_CMP:
     525                u32Value = (uint32_t)pHpetTimer->u64Cmp;
     526                Log(("read HPET_TN_CMP on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
     527                break;
     528
     529            case HPET_TN_CMP + 4:
     530                u32Value = (uint32_t)(pHpetTimer->u64Cmp >> 32);
     531                Log(("read HPET_TN_CMP+4 on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
     532                break;
     533
     534            case HPET_TN_ROUTE:
     535                u32Value = (uint32_t)(pHpetTimer->u64Fsb >> 32); /** @todo Looks wrong, but since it's not supported, who cares. */
     536                Log(("read HPET_TN_ROUTE on %d: %#x\n", iTimerNo, u32Value));
     537                break;
     538
     539            default:
     540            {
     541                LogRelMax(10, ("HPET: Invalid HPET register read %d on %d\n", iTimerReg, pHpetTimer->idxTimer));
     542                u32Value = 0;
     543                break;
     544            }
     545        }
     546    }
     547    else
     548    {
    501549        LogRelMax(10, ("HPET: Using timer above configured range: %d\n", iTimerNo));
    502         *pu32Value = 0;
    503         return;
    504     }
    505 
    506     PCHPETTIMER pHpetTimer = &pThis->aTimers[iTimerNo];
    507     uint32_t u32Value;
    508     switch (iTimerReg)
    509     {
    510         case HPET_TN_CFG:
    511             u32Value = (uint32_t)pHpetTimer->u64Config;
    512             Log(("read HPET_TN_CFG on %d: %#x\n", iTimerNo, u32Value));
    513             break;
    514 
    515         case HPET_TN_CFG + 4:
    516             u32Value = (uint32_t)(pHpetTimer->u64Config >> 32);
    517             Log(("read HPET_TN_CFG+4 on %d: %#x\n", iTimerNo, u32Value));
    518             break;
    519 
    520         case HPET_TN_CMP:
    521             u32Value = (uint32_t)pHpetTimer->u64Cmp;
    522             Log(("read HPET_TN_CMP on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
    523             break;
    524 
    525         case HPET_TN_CMP + 4:
    526             u32Value = (uint32_t)(pHpetTimer->u64Cmp >> 32);
    527             Log(("read HPET_TN_CMP+4 on %d: %#x (%#llx)\n", pHpetTimer->idxTimer, u32Value, pHpetTimer->u64Cmp));
    528             break;
    529 
    530         case HPET_TN_ROUTE:
    531             u32Value = (uint32_t)(pHpetTimer->u64Fsb >> 32); /** @todo Looks wrong, but since it's not supported, who cares. */
    532             Log(("read HPET_TN_ROUTE on %d: %#x\n", iTimerNo, u32Value));
    533             break;
    534 
    535         default:
    536         {
    537             LogRelMax(10, ("HPET: Invalid HPET register read %d on %d\n", iTimerReg, pHpetTimer->idxTimer));
    538             u32Value = 0;
    539             break;
    540         }
     550        u32Value = 0;
    541551    }
    542552    *pu32Value = u32Value;
     
    716726        case HPET_COUNTER + 4:
    717727        {
     728            STAM_REL_COUNTER_INC(&pThis->StatCounterRead4Byte);
    718729            DEVHPET_LOCK_BOTH_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ);
    719730
     
    728739            /** @todo is it correct? */
    729740            u32Value = (idxReg == HPET_COUNTER) ? (uint32_t)u64Ticks : (uint32_t)(u64Ticks >> 32);
    730             Log(("read HPET_COUNTER: %s part value %x (%#llx)\n",
    731                  (idxReg == HPET_COUNTER) ? "low" : "high", u32Value, u64Ticks));
     741            Log(("read HPET_COUNTER: %s part value %x (%#llx)\n", (idxReg == HPET_COUNTER) ? "low" : "high", u32Value, u64Ticks));
    732742            break;
    733743        }
     
    874884        case HPET_COUNTER:
    875885        {
     886            STAM_REL_COUNTER_INC(&pThis->StatCounterWriteLow);
    876887            DEVHPET_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    877888            pThis->u64HpetCounter = RT_MAKE_U64(u32NewValue, RT_HI_U32(pThis->u64HpetCounter));
     
    883894        case HPET_COUNTER + 4:
    884895        {
     896            STAM_REL_COUNTER_INC(&pThis->StatCounterWriteHigh);
    885897            DEVHPET_LOCK_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_WRITE);
    886898            pThis->u64HpetCounter = RT_MAKE_U64(RT_LO_U32(pThis->u64HpetCounter), u32NewValue);
     
    943955            /* When reading HPET counter we must read it in a single read,
    944956               to avoid unexpected time jumps on 32-bit overflow. */
     957            STAM_REL_COUNTER_INC(&pThis->StatCounterRead8Byte);
    945958            DEVHPET_LOCK_BOTH_RETURN(pDevIns, pThis, VINF_IOM_R3_MMIO_READ);
    946959            if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
     
    10841097            AssertReturnVoid(pThisCC);
    10851098            pThisCC->pHpetHlp->pfnSetIrq(pDevIns, irq, PDM_IRQ_LEVEL_FLIP_FLOP);
     1099            STAM_REL_COUNTER_INC(&pHpetTimer->StatSetIrq);
    10861100        }
    10871101        else
     
    11191133            {
    11201134                Log4(("HPET: periodic: next in %llu\n", hpetTicksToNs(pThis, u64Diff)));
    1121                 PDMDevHlpTimerSetNano(pDevIns, pHpetTimer->hTimer, hpetTicksToNs(pThis, u64Diff));
     1135                STAM_REL_COUNTER_INC(&pHpetTimer->StatSetTimer);
    11221136            }
    11231137            else
     
    14661480
    14671481    /*
    1468      * Register SSM state and info item.
     1482     * Register SSM state, info item and statistics.
    14691483     */
    14701484    rc = PDMDevHlpSSMRegister3(pDevIns, HPET_SAVED_STATE_VERSION, sizeof(*pThis), hpetR3LiveExec, hpetR3SaveExec, hpetR3LoadExec);
     
    14721486
    14731487    PDMDevHlpDBGFInfoRegister(pDevIns, "hpet", "Display HPET status. (no arguments)", hpetR3Info);
     1488
     1489    /* Statistics: */
     1490    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCounterRead4Byte, STAMTYPE_COUNTER,
     1491                          "CounterRead4Byte", STAMUNIT_OCCURENCES, "HPET_COUNTER 32-bit reads");
     1492    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCounterRead8Byte, STAMTYPE_COUNTER,
     1493                          "CounterRead8Byte", STAMUNIT_OCCURENCES, "HPET_COUNTER 64-bit reads");
     1494    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCounterWriteLow,  STAMTYPE_COUNTER,
     1495                          "CounterWriteLow",  STAMUNIT_OCCURENCES, "Low HPET_COUNTER writes");
     1496    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatCounterWriteHigh, STAMTYPE_COUNTER,
     1497                          "CounterWriteHigh", STAMUNIT_OCCURENCES, "High HPET_COUNTER writes");
     1498    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
     1499    {
     1500        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aTimers[i].StatSetIrq, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS,
     1501                               STAMUNIT_OCCURENCES, "Number of times the IRQ has been set.",  "timer%u/SetIrq", i);
     1502        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aTimers[i].StatSetTimer, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS,
     1503                               STAMUNIT_OCCURENCES, "Number of times the timer has be programmed.",  "timer%u/SetTimer", i);
     1504    }
    14741505
    14751506    return VINF_SUCCESS;
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