VirtualBox

Changeset 303 in vbox for trunk/src


Ignore:
Timestamp:
Jan 25, 2007 2:55:10 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
17851
Message:

Completed physical monitoring of ring descriptor table. (disabled)
Currently in an experimental stage, so don't complain.

File:
1 edited

Legend:

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

    r252 r303  
    7272
    7373/* Enable this to catch writes to the ring descriptors instead of using excessive polling */
    74 //#define PCNET_NO_POLLING
     74/* #define PCNET_NO_POLLING */
    7575
    7676/* Enable to handle frequent io reads in the guest context */
     
    120120{
    121121    PCIDEVICE                           PciDev;
     122#ifndef PCNET_NO_POLLING
    122123    /** Poll timer (address for host context) */
    123124    PTMTIMERHC                          pTimerPollHC;
    124125    /** Poll timer (address for guest context) */
    125126    PTMTIMERGC                          pTimerPollGC;
    126 
     127#endif
    127128    /** Register Address Pointer */
    128129    uint32_t                            u32RAP;
     
    217218    PDMCRITSECT                         CritSect;
    218219
     220#ifdef PCNET_NO_POLLING
     221    RTGCPHYS                            TRDAPhysOld;
     222    uint32_t                            cbTRDAOld;
     223
     224    RTGCPHYS                            RDRAPhysOld;
     225    uint32_t                            cbRDRAOld;
     226
     227    DECLGCCALLBACKMEMBER(int, pfnEMInterpretInstructionGC, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize));
     228    DECLR0CALLBACKMEMBER(int, pfnEMInterpretInstructionR0, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize));
     229#endif
     230
    219231    bool                                fGCEnabled;
    220232    bool                                fR0Enabled;
     
    247259    STAMCOUNTER                         StatTXRingWrite;
    248260    STAMCOUNTER                         StatRingWriteHC;
     261    STAMCOUNTER                         StatRingWriteR0;
    249262    STAMCOUNTER                         StatRingWriteGC;
     263
     264    STAMCOUNTER                         StatRingWriteFailedHC;
     265    STAMCOUNTER                         StatRingWriteFailedR0;
     266    STAMCOUNTER                         StatRingWriteFailedGC;
     267
     268    STAMCOUNTER                         StatRingWriteOutsideRangeHC;
     269    STAMCOUNTER                         StatRingWriteOutsideRangeR0;
     270    STAMCOUNTER                         StatRingWriteOutsideRangeGC;
    250271# endif
    251272#endif /* VBOX_WITH_STATISTICS */
     
    921942                                  RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    922943#ifndef IN_RING3
    923 DECLEXPORT(int) pcnetHandleRingWriteGC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
    924                                        RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
     944DECLEXPORT(int) pcnetHandleRingWrite(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
     945                                     RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
    925946#endif
    926947__END_DECLS
     
    933954static void     pcnetPollRxTx(PCNetState *pData);
    934955static void     pcnetPollTimer(PCNetState *pData);
     956static void     pcnetUpdateIrq(PCNetState *pData);
    935957static uint32_t pcnetBCRReadU16(PCNetState *pData, uint32_t u32RAP);
    936958static int      pcnetBCRWriteU16(PCNetState *pData, uint32_t u32RAP, uint32_t val);
     
    951973 * @param   pvUser      User argument.
    952974 */
    953 DECLEXPORT(int) pcnetHandleRingWriteGC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
    954                                        RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
    955 {
    956     PPDMDEVINS  pDevIns = (PPDMDEVINS)pvUser;
    957     PCNetState *pData   = PDMINS2DATA(pDevIns, PCNetState *);
     975DECLEXPORT(int) pcnetHandleRingWrite(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame,
     976                                     RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser)
     977{
     978    PCNetState *pData   = (PCNetState *)pvUser;
    958979
    959980    Log(("#%d pcnetHandleRingWriteGC: write to %08x\n", PCNETSTATE_2_DEVINS(pData)->iInstance, GCPhysFault));
    960     STAM_COUNTER_INC(&CTXSUFF(pData->StatRingWrite)); NOREF(pData);
     981
     982    uint32_t cb;
     983    int rc = CTXALLSUFF(pData->pfnEMInterpretInstruction)(pVM, pRegFrame, pvFault, &cb);
     984    if (VBOX_SUCCESS(rc) && cb)
     985    {
     986        if (GCPhysFault >= pData->GCTDRA && GCPhysFault + cb < pcnetTdraAddr(pData, 0))
     987        {
     988            int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);
     989            if (VBOX_SUCCESS(rc))
     990            {
     991                STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWrite)); ;
     992
     993                /* Check if we can do something now */
     994                pcnetPollRxTx(pData);
     995
     996                PDMCritSectLeave(&pData->CritSect);
     997                return VINF_SUCCESS;
     998            }
     999        }
     1000        else
     1001        {
     1002            STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteOutsideRange)); ;
     1003            return VINF_SUCCESS;    /* outside of the ring range */
     1004        }
     1005    }
     1006    STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteFailed)); ;
    9611007    return VINF_IOM_HC_MMIO_WRITE; /* handle in ring3 */
    9621008}
     
    10031049        AssertReleaseRC(rc);
    10041050        /* Check if we can do something now */
    1005         pcnetPollTimer(pData);
     1051        pcnetPollRxTx(pData);
     1052        pcnetUpdateIrq(pData);
    10061053        PDMCritSectLeave(&pData->CritSect);
    10071054    }
     
    11431190#ifdef IN_RING3
    11441191#ifdef PCNET_NO_POLLING
    1145 static void pcnetUpdateRingHandlers(PCNetState *pData,
    1146                                     RTGCPHYS oldrdra, uint16_t oldrcvrl,
    1147                                     RTGCPHYS oldtdra, uint16_t oldxmtrl)
     1192static void pcnetUpdateRingHandlers(PCNetState *pData)
    11481193{
    11491194    PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData);
     1195
     1196    Log(("pcnetUpdateRingHandlers TD %VGp size %x -> %VGp size %x\n", pData->TRDAPhysOld, pData->cbTRDAOld, pData->GCTDRA, pcnetTdraAddr(pData, 0)));
     1197    Log(("pcnetUpdateRingHandlers RX %VGp size %x -> %VGp size %x\n", pData->RDRAPhysOld, pData->cbRDRAOld, pData->GCRDRA, pcnetRdraAddr(pData, 0)));
     1198
    11501199#if 0
    1151     if (oldrdra != 0 && pData->GCRDRA != oldrdra)
     1200    if (pData->RDRAPhysOld != 0 && pData->GCRDRA != pData->RDRAPhysOld)
    11521201        PGMHandlerPhysicalDeregister(pDevIns->pDevHlp->pfnGetVM(pDevIns),
    1153                                      oldrdra & ~PAGE_OFFSET_MASK);
    1154     if (   oldtdra != 0 && pData->GCTDRA != oldtdra
     1202                                     pData->RDRAPhysOld & ~PAGE_OFFSET_MASK);
     1203    if (   pData->TRDAPhysOld != 0 && pData->GCTDRA != pData->TRDAPhysOld
    11551204        && (pData->GCRDRA & ~PAGE_OFFSET_MASK) != (pData->GCTDRA & ~PAGE_OFFSET_MASK))
    11561205#endif
     
    11641213                                          RT_ALIGN(pcnetRdraAddr(pData, 0), PAGE_SIZE) - 1,
    11651214                                          pcnetHandleRingWrite, pDevIns,
    1166                                           g_DevicePCNet.szR0Mod, "pcnetHandleRingWriteGC",
     1215                                          g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite",
    11671216                                          pData->pDevInsHC->pvInstanceDataHC,
    1168                                           g_DevicePCNet.szGCMod, "pcnetHandleRingWriteGC",
     1217                                          g_DevicePCNet.szGCMod, "pcnetHandleRingWrite",
    11691218                                          pData->pDevInsHC->pvInstanceDataGC,
    11701219                                          "PCNet receive ring write access handler");
    11711220        AssertRC(rc);
    1172     }
    1173 #endif
    1174     if (pData->GCTDRA != oldtdra || CSR_XMTRL(pData) != oldxmtrl)
    1175     {
    1176         if (oldtdra != 0)
     1221
     1222        pData->RDRAPhysOld = pData->GCRDRA;
     1223        pData->cbRDRAOld   = pcnetRdraAddr(pData, 0);
     1224    }
     1225#endif
     1226    if (pData->GCTDRA != pData->TRDAPhysOld || CSR_XMTRL(pData) != pData->cbTRDAOld)
     1227    {
     1228        if (pData->TRDAPhysOld != 0)
    11771229            PGMHandlerPhysicalDeregister(pDevIns->pDevHlp->pfnGetVM(pDevIns),
    1178                                          oldtdra & ~PAGE_OFFSET_MASK);
     1230                                         pData->TRDAPhysOld & ~PAGE_OFFSET_MASK);
     1231
    11791232        int rc;
     1233
    11801234        rc = PGMR3HandlerPhysicalRegister(pDevIns->pDevHlp->pfnGetVM(pDevIns),
    11811235                                          PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
     
    11831237                                          RT_ALIGN(pcnetTdraAddr(pData, 0), PAGE_SIZE) - 1,
    11841238                                          pcnetHandleRingWrite, pDevIns,
    1185                                           g_DevicePCNet.szR0Mod, "pcnetHandleRingWriteGC",
     1239                                          g_DevicePCNet.szR0Mod, "pcnetHandleRingWrite",
    11861240                                          pData->pDevInsHC->pvInstanceDataHC,
    1187                                           g_DevicePCNet.szGCMod, "pcnetHandleRingWriteGC",
     1241                                          g_DevicePCNet.szGCMod, "pcnetHandleRingWrite",
    11881242                                          pData->pDevInsHC->pvInstanceDataGC,
    11891243                                          "PCNet transmit ring write access handler");
    11901244        AssertRC(rc);
     1245
     1246        pData->TRDAPhysOld = pData->GCTDRA;
     1247        pData->cbTRDAOld   = pcnetTdraAddr(pData, 0);
    11911248    }
    11921249}
     
    11961253{
    11971254    PPDMDEVINS pDevIns = PCNETSTATE_2_DEVINS(pData);
    1198 #ifdef PCNET_NO_POLLING
    1199     RTGCPHYS oldrdra  = pData->GCRDRA,    oldtdra  = pData->GCTDRA;
    1200     uint16_t oldrcvrl = CSR_RCVRL(pData), oldxmtrl = CSR_XMTRL(pData);
    1201 #endif
    12021255    Log(("#%d pcnetInit: init_addr=0x%08x\n", PCNETSTATE_2_DEVINS(pData)->iInstance,
    12031256         PHYSADDR(pData, CSR_IADR(pData))));
     
    12491302
    12501303#ifdef PCNET_NO_POLLING
    1251     pcnetUpdateRingHandlers(pData, oldrdra, oldrcvrl, oldtdra, oldxmtrl);
     1304    pcnetUpdateRingHandlers(pData);
    12521305#endif
    12531306
     
    20852138         * but so far I have not seen any guest depending on these values. The 2ms
    20862139         * interval is the default polling interval of the PCNet card (65536/33MHz). */
     2140#ifdef PCNET_NO_POLLING
     2141        pcnetPollRxTx(pData);
     2142#else
    20872143        uint64_t u64Now = TMTimerGet(pData->CTXSUFF(pTimerPoll));
    20882144        if (RT_UNLIKELY(u64Now - pData->u64LastPoll > 200000))
     
    20952151            TMTimerSet(pData->CTXSUFF(pTimerPoll),
    20962152                       TMTimerGet(pData->CTXSUFF(pTimerPoll)) + 2000000);
     2153#endif
    20972154    }
    20982155    STAM_PROFILE_ADV_STOP(&pData->StatPollTimer, a);
     
    34323489    SSMR3PutMem(pSSMHandle, &pData->MacConfigured, sizeof(pData->MacConfigured));
    34333490    SSMR3PutBool(pSSMHandle, pData->fAm79C973);
     3491#ifdef PCNET_NO_POLLING
     3492    return VINF_SUCCESS;
     3493#else
    34343494    return TMR3TimerSave(pData->CTXSUFF(pTimerPoll), pSSMHandle);
     3495#endif
    34353496}
    34363497
     
    34663527    Assert(!memcmp(&Mac, &pData->MacConfigured, sizeof(Mac)));
    34673528    SSMR3GetBool(pSSMHandle, &pData->fAm79C973);
     3529#ifndef PCNET_NO_POLLING
    34683530    TMR3TimerLoad(pData->CTXSUFF(pTimerPoll), pSSMHandle);
     3531#endif
    34693532
    34703533    pData->iLog2DescSize = BCR_SWSTYLE(pData)
     
    37083771    PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *);
    37093772    pData->pDevInsGC     = PDMDEVINS_2_GCPTR(pDevIns);
    3710     pData->pTimerPollGC  = TMTimerGCPtr(pData->pTimerPollHC);
    37113773    pData->pXmitQueueGC  = PDMQueueGCPtr(pData->pXmitQueueHC);
    37123774    pData->pCanRxQueueGC = PDMQueueGCPtr(pData->pCanRxQueueHC);
     3775#ifdef PCNET_NO_POLLING
     3776    *(RTHCUINTPTR *)&pData->pfnEMInterpretInstructionGC += offDelta;
     3777#else
     3778    pData->pTimerPollGC  = TMTimerGCPtr(pData->pTimerPollHC);
     3779#endif
    37133780}
    37143781
     
    38733940        return rc;
    38743941
     3942#ifdef PCNET_NO_POLLING
     3943    rc = PDMR3GetSymbolR0Lazy(pDevIns->pDevHlp->pfnGetVM(pDevIns), NULL, "EMInterpretInstruction", (void **)&pData->pfnEMInterpretInstructionR0);
     3944    if (VBOX_SUCCESS(rc))
     3945    {
     3946        /*
     3947         * Resolve the GC handler.
     3948         */
     3949        RTGCPTR pfnHandlerGC;
     3950        rc = PDMR3GetSymbolGCLazy(pDevIns->pDevHlp->pfnGetVM(pDevIns), NULL, "EMInterpretInstruction", (RTGCPTR *)&pData->pfnEMInterpretInstructionGC);
     3951    }
     3952    if (VBOX_FAILURE(rc))
     3953    {
     3954        AssertMsgFailed(("PDMR3GetSymbolGCLazy -> %Vrc\n", rc));
     3955        return rc;
     3956    }
     3957#else
    38753958    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimer,
    38763959                                "PCNet Poll Timer", &pData->pTimerPollHC);
     
    38803963        return rc;
    38813964    }
     3965#endif
    38823966    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore,
    38833967                                "PCNet Restore Timer", &pData->pTimerRestore);
     
    39964080    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRCVRingWrite,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of receive ring writes",          "/Devices/PCNet%d/Ring/RCVWrites", iInstance);
    39974081    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTXRingWrite,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of transmit ring writes",         "/Devices/PCNet%d/Ring/TXWrites", iInstance);
    3998     PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteHC,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored ring page writes",   "/Devices/PCNet%d/Ring/HCWrites", iInstance);
    3999     PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteGC,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored ring page writes",   "/Devices/PCNet%d/Ring/GCWrites", iInstance);
     4082    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteHC,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored ring page writes",   "/Devices/PCNet%d/Ring/HC/Writes", iInstance);
     4083    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteR0,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored ring page writes",   "/Devices/PCNet%d/Ring/R0/Writes", iInstance);
     4084    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteGC,        STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored ring page writes",   "/Devices/PCNet%d/Ring/GC/Writes", iInstance);
     4085    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedHC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of failed ring page writes",   "/Devices/PCNet%d/Ring/HC/Failed", iInstance);
     4086    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedR0,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of failed ring page writes",   "/Devices/PCNet%d/Ring/R0/Failed", iInstance);
     4087    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedGC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of failed ring page writes",   "/Devices/PCNet%d/Ring/GC/Failed", iInstance);
     4088    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeHC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored writes outside ring range",   "/Devices/PCNet%d/Ring/HC/Outside", iInstance);
     4089    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeR0,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored writes outside ring range",   "/Devices/PCNet%d/Ring/R0/Outside", iInstance);
     4090    PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideRangeGC,  STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of monitored writes outside ring range",   "/Devices/PCNet%d/Ring/GC/Outside", iInstance);
    40004091# endif /* PCNET_NO_POLLING */
    40014092#endif
Note: See TracChangeset for help on using the changeset viewer.

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