VirtualBox

Changeset 44546 in vbox for trunk


Ignore:
Timestamp:
Feb 5, 2013 2:43:08 PM (12 years ago)
Author:
vboxsync
Message:

DevE1000: Changed e1kRegLookup to use binary search for the part of g_aE1kRegMap where that is possible, only resorting to linear lookup for the remainder. Added individual register read and write statistics counters.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DevE1000.cpp

    r44542 r44546  
    612612} E1kRegIndex;
    613613
    614 #define E1K_NUM_OF_32BIT_REGS MTA_IDX
     614#define E1K_NUM_OF_32BIT_REGS           MTA_IDX
     615/** The number of registers with strictly increasing offset. */
     616#define E1K_NUM_OF_BINARY_SEARCHABLE    (WUPL_IDX + 1)
    615617
    616618
     
    12231225    STAMCOUNTER                         StatTxPathRegular;
    12241226    STAMCOUNTER                         StatPHYAccesses;
    1225 
     1227    STAMCOUNTER                         aStatRegWrites[E1K_NUM_OF_REGS];
     1228    STAMCOUNTER                         aStatRegReads[E1K_NUM_OF_REGS];
    12261229#endif /* VBOX_WITH_STATISTICS */
    12271230
     
    13141317 * Register map table.
    13151318 *
    1316  * Override fn_read and fn_write to get register-specific behavior.
    1317  */
    1318 const static struct E1kRegMap_st
     1319 * Override pfnRead and pfnWrite to get register-specific behavior.
     1320 */
     1321static const struct E1kRegMap_st
    13191322{
    13201323    /** Register offset in the register space. */
     
    13341337    /** Full name. */
    13351338    const char *name;
    1336 } s_e1kRegMap[E1K_NUM_OF_REGS] =
     1339} g_aE1kRegMap[E1K_NUM_OF_REGS] =
    13371340{
    13381341    /* offset  size     read mask   write mask  read callback            write callback            abbrev      full name                     */
     
    14691472    { 0x09800, 0x003fc, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "FFVT"    , "Flexible Filter Value Table" },
    14701473    { 0x10000, 0x10000, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadUnimplemented, e1kRegWriteUnimplemented, "PBM"     , "Packet Buffer Memory (n)" },
    1471     { 0x00040, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA           , e1kRegWriteRA           , "RA"      , "Receive Address (64-bit) (n) (82542)" },
    1472     { 0x00200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA          , e1kRegWriteMTA          , "MTA"     , "Multicast Table Array (n) (82542)" },
    1473     { 0x00600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA         , e1kRegWriteVFTA         , "VFTA"    , "VLAN Filter Table Array (n) (82542)" }
     1474    { 0x00040, 0x00080, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadRA           , e1kRegWriteRA           , "RA82542" , "Receive Address (64-bit) (n) (82542)" },
     1475    { 0x00200, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadMTA          , e1kRegWriteMTA          , "MTA82542", "Multicast Table Array (n) (82542)" },
     1476    { 0x00600, 0x00200, 0xFFFFFFFF, 0xFFFFFFFF, e1kRegReadVFTA         , e1kRegWriteVFTA         , "VFTA82542", "VLAN Filter Table Array (n) (82542)" }
    14741477};
    14751478
     
    28442847{
    28452848    E1K_INC_ISTAT_CNT(pThis->uStatIntICS);
    2846     return e1kRaiseInterrupt(pThis, VINF_IOM_R3_MMIO_WRITE, value & s_e1kRegMap[ICS_IDX].writable);
     2849    return e1kRaiseInterrupt(pThis, VINF_IOM_R3_MMIO_WRITE, value & g_aE1kRegMap[ICS_IDX].writable);
    28472850}
    28482851
     
    52985301static int e1kRegWriteMTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value)
    52995302{
    5300     AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);
    5301     pThis->auMTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auMTA[0])] = value;
     5303    AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);
     5304    pThis->auMTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auMTA[0])] = value;
    53025305
    53035306    return VINF_SUCCESS;
     
    53165319static int e1kRegReadMTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value)
    53175320{
    5318     AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);
    5319     *pu32Value = pThis->auMTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auMTA[0])];
     5321    AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->auMTA), VERR_DEV_IO_ERROR);
     5322    *pu32Value = pThis->auMTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auMTA[0])];
    53205323
    53215324    return VINF_SUCCESS;
     
    53335336static int e1kRegWriteRA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value)
    53345337{
    5335     AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);
    5336     pThis->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])] = value;
     5338    AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);
     5339    pThis->aRecAddr.au32[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])] = value;
    53375340
    53385341    return VINF_SUCCESS;
     
    53515354static int e1kRegReadRA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value)
    53525355{
    5353     AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);
    5354     *pu32Value = pThis->aRecAddr.au32[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])];
     5356    AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->aRecAddr.au32), VERR_DEV_IO_ERROR);
     5357    *pu32Value = pThis->aRecAddr.au32[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->aRecAddr.au32[0])];
    53555358
    53565359    return VINF_SUCCESS;
     
    53685371static int e1kRegWriteVFTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value)
    53695372{
    5370     AssertReturn(offset - s_e1kRegMap[index].offset < sizeof(pThis->auVFTA), VINF_SUCCESS);
    5371     pThis->auVFTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])] = value;
     5373    AssertReturn(offset - g_aE1kRegMap[index].offset < sizeof(pThis->auVFTA), VINF_SUCCESS);
     5374    pThis->auVFTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])] = value;
    53725375
    53735376    return VINF_SUCCESS;
     
    53865389static int e1kRegReadVFTA(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t *pu32Value)
    53875390{
    5388     AssertReturn(offset - s_e1kRegMap[index].offset< sizeof(pThis->auVFTA), VERR_DEV_IO_ERROR);
    5389     *pu32Value = pThis->auVFTA[(offset - s_e1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])];
     5391    AssertReturn(offset - g_aE1kRegMap[index].offset< sizeof(pThis->auVFTA), VERR_DEV_IO_ERROR);
     5392    *pu32Value = pThis->auVFTA[(offset - g_aE1kRegMap[index].offset)/sizeof(pThis->auVFTA[0])];
    53905393
    53915394    return VINF_SUCCESS;
     
    54075410{
    54085411    E1kLog(("%s At %08X read (00000000) attempt from unimplemented register %s (%s)\n",
    5409             pThis->szPrf, offset, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
     5412            pThis->szPrf, offset, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    54105413    *pu32Value = 0;
    54115414
     
    54575460{
    54585461    AssertReturn(index < E1K_NUM_OF_32BIT_REGS, VERR_DEV_IO_ERROR);
    5459     *pu32Value = pThis->auRegs[index] & s_e1kRegMap[index].readable;
     5462    *pu32Value = pThis->auRegs[index] & g_aE1kRegMap[index].readable;
    54605463
    54615464    return VINF_SUCCESS;
     
    54775480{
    54785481    E1kLog(("%s At %08X write attempt (%08X) to  unimplemented register %s (%s)\n",
    5479             pThis->szPrf, offset, value, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
     5482            pThis->szPrf, offset, value, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    54805483
    54815484    return VINF_SUCCESS;
     
    55015504{
    55025505    AssertReturn(index < E1K_NUM_OF_32BIT_REGS, VERR_DEV_IO_ERROR);
    5503     pThis->auRegs[index] = (value & s_e1kRegMap[index].writable) |
    5504             (pThis->auRegs[index] & ~s_e1kRegMap[index].writable);
     5506    pThis->auRegs[index] = (value & g_aE1kRegMap[index].writable)
     5507                         | (pThis->auRegs[index] & ~g_aE1kRegMap[index].writable);
    55055508
    55065509    return VINF_SUCCESS;
     
    55185521static int e1kRegLookup(PE1KSTATE pThis, uint32_t offReg)
    55195522{
     5523#if 0
    55205524    int index;
    55215525
    55225526    for (index = 0; index < E1K_NUM_OF_REGS; index++)
    55235527    {
    5524         if (s_e1kRegMap[index].offset <= offReg && offReg < s_e1kRegMap[index].offset + s_e1kRegMap[index].size)
     5528        if (g_aE1kRegMap[index].offset <= offReg && offReg < g_aE1kRegMap[index].offset + g_aE1kRegMap[index].size)
    55255529        {
    55265530            return index;
    55275531        }
    55285532    }
     5533#else
     5534    int iStart = 0;
     5535    int iEnd   = E1K_NUM_OF_BINARY_SEARCHABLE;
     5536    for (;;)
     5537    {
     5538        int i = (iEnd - iStart) / 2 + iStart;
     5539        uint32_t offCur = g_aE1kRegMap[i].offset;
     5540        if (offReg < offCur)
     5541        {
     5542            if (i == iStart)
     5543                break;
     5544            iEnd = i;
     5545        }
     5546        else if (offReg >= offCur + g_aE1kRegMap[i].size)
     5547        {
     5548            i++;
     5549            if (i == iEnd)
     5550                break;
     5551            iStart = i;
     5552        }
     5553        else
     5554            return i;
     5555        Assert(iEnd > iStart);
     5556    }
     5557
     5558    for (unsigned i = E1K_NUM_OF_BINARY_SEARCHABLE; i < RT_ELEMENTS(g_aE1kRegMap); i++)
     5559        if (offReg - g_aE1kRegMap[i].offset < g_aE1kRegMap[i].size)
     5560            return i;
     5561
     5562# ifdef VBOX_STRICT
     5563    for (unsigned i = 0; i < RT_ELEMENTS(g_aE1kRegMap); i++)
     5564        Assert(offReg - g_aE1kRegMap[i].offset >= g_aE1kRegMap[i].size);
     5565# endif
     5566
     5567#endif
    55295568
    55305569    return -1;
     
    55795618    if (index != -1)
    55805619    {
    5581         if (s_e1kRegMap[index].readable)
     5620        if (g_aE1kRegMap[index].readable)
    55825621        {
    55835622            /* Make the mask correspond to the bits we are about to read. */
    5584             shift = (offReg - s_e1kRegMap[index].offset) % sizeof(uint32_t) * 8;
     5623            shift = (offReg - g_aE1kRegMap[index].offset) % sizeof(uint32_t) * 8;
    55855624            mask <<= shift;
    55865625            if (!mask)
     
    55985637            //pThis->iStatIntLost += pThis->iStatIntLostOne;
    55995638            //pThis->iStatIntLostOne = 0;
    5600             rc = s_e1kRegMap[index].pfnRead(pThis, offReg & 0xFFFFFFFC, index, &u32);
     5639            rc = g_aE1kRegMap[index].pfnRead(pThis, offReg & 0xFFFFFFFC, index, &u32);
    56015640            u32 &= mask;
    56025641            //e1kCsLeave(pThis);
    56035642            E1kLog2(("%s At %08X read  %s          from %s (%s)\n",
    5604                     pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
     5643                    pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    56055644            /* Shift back the result. */
    56065645            u32 >>= shift;
    56075646        }
    56085647        else
    5609         {
    56105648            E1kLog(("%s At %08X read (%s) attempt from write-only register %s (%s)\n",
    5611                     pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
    5612         }
     5649                    pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf), g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
     5650        if (IOM_SUCCESS(rc))
     5651            STAM_COUNTER_INC(&pThis->aStatRegReads[index]);
    56135652    }
    56145653    else
    5615     {
    56165654        E1kLog(("%s At %08X read (%s) attempt from non-existing register\n",
    56175655                pThis->szPrf, offReg, e1kU32toHex(u32, mask, buf)));
    5618     }
    56195656
    56205657    memcpy(pv, &u32, cb);
     
    56395676    int         rc     = VINF_SUCCESS;
    56405677    int         index  = e1kRegLookup(pThis, offReg);
    5641     uint32_t    u32;
    56425678
    56435679    /*
     
    56595695        return VINF_SUCCESS;
    56605696    }
    5661     u32 = *(uint32_t*)pv;
     5697
     5698    uint32_t u32 = *(uint32_t const *)pv;
    56625699    if (index != -1)
    56635700    {
    5664         if (s_e1kRegMap[index].writable)
     5701        if (g_aE1kRegMap[index].writable)
    56655702        {
    56665703            /*
     
    56695706             */
    56705707            E1kLog2(("%s At %08X write          %08X  to  %s (%s)\n",
    5671                      pThis->szPrf, offReg, u32, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
     5708                     pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
    56725709            //rc = e1kCsEnter(pThis, VERR_SEM_BUSY, RT_SRC_POS);
    56735710            if (RT_UNLIKELY(rc != VINF_SUCCESS))
     
    56765713            //pThis->iStatIntLost += pThis->iStatIntLostOne;
    56775714            //pThis->iStatIntLostOne = 0;
    5678             rc = s_e1kRegMap[index].pfnWrite(pThis, offReg, index, u32);
     5715            rc = g_aE1kRegMap[index].pfnWrite(pThis, offReg, index, u32);
    56795716            //e1kCsLeave(pThis);
    56805717        }
    56815718        else
    5682         {
    56835719            E1kLog(("%s At %08X write attempt (%08X) to  read-only register %s (%s)\n",
    5684                     pThis->szPrf, offReg, u32, s_e1kRegMap[index].abbrev, s_e1kRegMap[index].name));
    5685         }
     5720                    pThis->szPrf, offReg, u32, g_aE1kRegMap[index].abbrev, g_aE1kRegMap[index].name));
     5721        if (IOM_SUCCESS(rc))
     5722            STAM_COUNTER_INC(&pThis->aStatRegWrites[index]);
    56865723    }
    56875724    else
    5688     {
    56895725        E1kLog(("%s At %08X write attempt (%08X) to  non-existing register\n",
    56905726                pThis->szPrf, offReg, u32));
    5691     }
    56925727    return rc;
    56935728}
     
    58695904    {
    58705905        E1kLog2(("%s %8.8s = %08x\n", pThis->szPrf,
    5871                 s_e1kRegMap[i].abbrev, pThis->auRegs[i]));
     5906                g_aE1kRegMap[i].abbrev, pThis->auRegs[i]));
    58725907    }
    58735908# ifdef E1K_INT_STATS
     
    68696904
    68706905    for (i = 0; i < E1K_NUM_OF_32BIT_REGS; ++i)
    6871         pHlp->pfnPrintf(pHlp, "%8.8s = %08x\n", s_e1kRegMap[i].abbrev, pThis->auRegs[i]);
     6906        pHlp->pfnPrintf(pHlp, "%8.8s = %08x\n", g_aE1kRegMap[i].abbrev, pThis->auRegs[i]);
    68726907
    68736908    for (i = 0; i < RT_ELEMENTS(pThis->aRecAddr.array); i++)
     
    73277362
    73287363    /*
     7364     * Internal validations.
     7365     */
     7366    for (uint32_t iReg = 1; iReg < E1K_NUM_OF_BINARY_SEARCHABLE; iReg++)
     7367        AssertLogRelMsgReturn(   g_aE1kRegMap[iReg].offset > g_aE1kRegMap[iReg - 1].offset
     7368                              &&    g_aE1kRegMap[iReg].offset + g_aE1kRegMap[iReg].size
     7369                                 >= g_aE1kRegMap[iReg - 1].offset + g_aE1kRegMap[iReg - 1].size,
     7370                              ("%s@%#xLB%#x vs %s@%#xLB%#x\n",
     7371                               g_aE1kRegMap[iReg].abbrev,      g_aE1kRegMap[iReg].offset,     g_aE1kRegMap[iReg].size,
     7372                               g_aE1kRegMap[iReg - 1].abbrev,  g_aE1kRegMap[iReg - 1].offset, g_aE1kRegMap[iReg - 1].size),
     7373                               VERR_INTERNAL_ERROR_4);
     7374
     7375    /*
    73297376     * Validate configuration.
    73307377     */
     
    76247671    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatTxPathRegular,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Regular descriptor path",            "/Devices/E1k%d/TxPath/Normal", iInstance);
    76257672    PDMDevHlpSTAMRegisterF(pDevIns, &pThis->StatPHYAccesses,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Number of PHY accesses",             "/Devices/E1k%d/PHYAccesses", iInstance);
     7673    for (unsigned iReg = 0; iReg < E1K_NUM_OF_REGS; iReg++)
     7674    {
     7675        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegReads[iReg],   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
     7676                               g_aE1kRegMap[iReg].name, "/Devices/E1k%d/Regs/%s-Reads", iInstance, g_aE1kRegMap[iReg].abbrev);
     7677        PDMDevHlpSTAMRegisterF(pDevIns, &pThis->aStatRegWrites[iReg],   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,
     7678                               g_aE1kRegMap[iReg].name, "/Devices/E1k%d/Regs/%s-Writes", iInstance, g_aE1kRegMap[iReg].abbrev);
     7679    }
    76267680#endif /* VBOX_WITH_STATISTICS */
    76277681
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