VirtualBox

Changeset 24705 in vbox for trunk/src/VBox/Devices/Network


Ignore:
Timestamp:
Nov 16, 2009 5:13:52 PM (15 years ago)
Author:
vboxsync
Message:

#3987: Virtio: Got rid of indirect function calls (expect pfnCallback), fixed statistic counters.

File:
1 edited

Legend:

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

    r24652 r24705  
    227227
    228228/*****************************************************************************/
    229 RT_C_DECLS_BEGIN
     229#define virtioGetHostFeatures        vnetGetHostFeatures       
     230#define virtioGetHostMinimalFeatures vnetGetHostMinimalFeatures
     231#define virtioSetHostFeatures        vnetSetHostFeatures       
     232#define virtioGetConfig              vnetGetConfig             
     233#define virtioSetConfig              vnetSetConfig             
     234#define virtioReset                  vnetReset                 
     235#define virtioReady                  vnetReady                 
     236
    230237PDMBOTHCBDECL(uint32_t) vnetGetHostFeatures(void *pState);
    231238PDMBOTHCBDECL(uint32_t) vnetGetHostMinimalFeatures(void *pState);
     
    235242PDMBOTHCBDECL(void)     vnetReset(void *pState);
    236243PDMBOTHCBDECL(void)     vnetReady(void *pState);
    237 RT_C_DECLS_END
    238244
    239245/*****************************************************************************/
     
    242248
    243249#ifdef IN_RING3
    244 const struct VirtioPCIDevices
    245 {
    246     uint16_t    uPCIVendorId;
    247     uint16_t    uPCIDeviceId;
    248     uint16_t    uPCISubsystemVendorId;
    249     uint16_t    uPCISubsystemId;
    250     uint16_t    uPCIClass;
    251     unsigned    nQueues;
    252     const char *pcszName;
    253     const char *pcszNameFmt;
    254     uint32_t  (*pfnGetHostFeatures)(void *pvState);
    255     uint32_t  (*pfnGetHostMinimalFeatures)(void *pvState);
    256     void      (*pfnSetHostFeatures)(void *pvState, uint32_t uFeatures);
    257     int       (*pfnGetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data);
    258     int       (*pfnSetConfig)(void *pvState, uint32_t port, uint32_t cb, void *data);
    259     void      (*pfnReset)(void *pvState);
    260     void      (*pfnReady)(void *pvState);
    261 } g_VPCIDevices[] =
    262 {
    263     /*  Vendor  Device SSVendor SubSys             Class   NQ Name          Instance */
    264     { /* Virtio Network Device */
    265         0x1AF4, 0x1000, 0x1AF4, 1 + VIRTIO_NET_ID, 0x0200, VNET_NQUEUES,
    266                                                               "virtio-net", "vnet%d",
    267         vnetGetHostFeatures, vnetGetHostMinimalFeatures, vnetSetHostFeatures,
    268         vnetGetConfig, vnetSetConfig, vnetReset, vnetReady
    269     },
     250
     251#define DEVICE_PCI_VENDOR_ID           0x1AF4
     252#define DEVICE_PCI_DEVICE_ID           0x1000
     253#define DEVICE_PCI_SUBSYSTEM_VENDOR_ID 0x1AF4
     254#define DEVICE_PCI_SUBSYSTEM_ID        1 + VIRTIO_NET_ID
     255#define DEVICE_PCI_CLASS               0x0200
     256#define DEVICE_N_QUEUES                3
     257#define DEVICE_NAME                    "virtio-net"
     258#define DEVICE_NAME_FMT                "vnet%d"
     259#if 0
    270260    { /* Virtio Block Device */
    271261        0x1AF4, 0x1001, 0x1AF4, 1 + VIRTIO_BLK_ID, 0x0180, 2, "virtio-blk", "vblk%d",
    272262        NULL, NULL, NULL, NULL, NULL, NULL, NULL
    273263    },
    274 };
     264#endif
     265
    275266#endif
    276267
     
    295286#define VPCI_STATUS_DRV_OK  0x04
    296287#define VPCI_STATUS_FAILED  0x80
    297 
    298 /** @todo use+extend RTNETIPV4 */
    299 
    300 /** @todo use+extend RTNETTCP */
    301288
    302289#ifndef VBOX_DEVICE_STRUCT_TESTCASE
     
    519506}
    520507
    521 #ifdef IN_RING3
    522508void vpciReset(PVPCISTATE pState)
    523509{
     
    530516        vqueueReset(&pState->Queues[i]);
    531517}
    532 #endif
    533518
    534519
     
    556541        return rc;
    557542
     543    STAM_COUNTER_INC(&pState->StatIntsRaised);
    558544    LogFlow(("%s vpciRaiseInterrupt: u8IntCause=%x\n",
    559545             INSTANCE(pState), u8IntCause));
     
    576562}
    577563
    578 #ifdef IN_RING3
    579564DECLINLINE(uint32_t) vpciGetHostFeatures(PVPCISTATE pState)
    580565{
    581     return g_VPCIDevices[pState->enmDevType].pfnGetHostFeatures(pState)
     566    return virtioGetHostFeatures(pState)
    582567        | VPCI_F_NOTIFY_ON_EMPTY;
    583568}
    584 #endif
    585569
    586570/**
     
    609593        case VPCI_HOST_FEATURES:
    610594            /* Tell the guest what features we support. */
    611 #ifdef IN_RING3
    612595            *pu32 = vpciGetHostFeatures(pState) | VPCI_F_BAD_FEATURE;
    613 #else
    614             rc = VINF_IOM_HC_IOPORT_READ;
    615 #endif
    616596            break;
    617597
     
    649629            if (port >= VPCI_CONFIG)
    650630            {
    651 #ifdef IN_RING3
    652                 rc = g_VPCIDevices[pState->enmDevType].pfnGetConfig(pState, port - VPCI_CONFIG, cb, pu32);
    653 #else
    654                 rc = VINF_IOM_HC_IOPORT_READ;
    655 #endif
     631                rc = virtioGetConfig(pState, port - VPCI_CONFIG, cb, pu32);
    656632            }
    657633            else
     
    696672        case VPCI_GUEST_FEATURES:
    697673            /* Check if the guest negotiates properly, fall back to basics if it does not. */
    698 #ifdef IN_RING3
    699674            if (VPCI_F_BAD_FEATURE & u32)
    700675            {
    701676                Log(("%s WARNING! Guest failed to negotiate properly (guest=%x)\n",
    702677                     INSTANCE(pState), u32));
    703                 pState->uGuestFeatures = g_VPCIDevices[pState->enmDevType].pfnGetHostMinimalFeatures(pState);
     678                pState->uGuestFeatures = virtioGetHostMinimalFeatures(pState);
    704679            }
    705680            /* The guest may potentially desire features we don't support! */
     
    712687            else
    713688                pState->uGuestFeatures = u32;
    714             g_VPCIDevices[pState->enmDevType].pfnSetHostFeatures(pState, pState->uGuestFeatures);
    715 #else
    716             rc = VINF_IOM_HC_IOPORT_WRITE;
    717 #endif
     689            virtioSetHostFeatures(pState, pState->uGuestFeatures);
    718690            break;
    719691
    720692        case VPCI_QUEUE_PFN:
    721 #ifdef IN_RING3
    722693            /*
    723694             * The guest is responsible for allocating the pages for queues,
     
    730701                vqueueInit(&pState->Queues[pState->uQueueSelector], u32);
    731702            else
    732                 g_VPCIDevices[pState->enmDevType].pfnReset(pState);
    733 #else
    734             rc = VINF_IOM_HC_IOPORT_WRITE;
    735 #endif
     703                virtioReset(pState);
    736704            break;
    737705
     
    763731
    764732        case VPCI_STATUS:
    765 #ifdef IN_RING3
    766733            Assert(cb == 1);
    767734            u32 &= 0xFF;
     
    770737            /* Writing 0 to the status port triggers device reset. */
    771738            if (u32 == 0)
    772                 g_VPCIDevices[pState->enmDevType].pfnReset(pState);
     739                virtioReset(pState);
    773740            else if (fHasBecomeReady)
    774                 g_VPCIDevices[pState->enmDevType].pfnReady(pState);
    775 #else
    776             rc = VINF_IOM_HC_IOPORT_WRITE;
    777 #endif
     741                virtioReady(pState);
    778742            break;
    779743
    780744        default:
    781 #ifdef IN_RING3
    782745            if (port >= VPCI_CONFIG)
    783                 rc = g_VPCIDevices[pState->enmDevType].pfnSetConfig(pState, port - VPCI_CONFIG, cb, &u32);
     746                rc = virtioSetConfig(pState, port - VPCI_CONFIG, cb, &u32);
    784747            else
    785748                rc = PDMDeviceDBGFStop(pDevIns, RT_SRC_POS, "%s virtioIOPortOut: no valid port at offset port=%RTiop cb=%08x\n", szInst, port, cb);
    786 #else
    787             rc = VINF_IOM_HC_IOPORT_WRITE;
    788 #endif
    789749            break;
    790750    }
     
    10621022        }
    10631023        else
    1064             pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
     1024            pState->nQueues = DEVICE_N_QUEUES;
    10651025        for (unsigned i = 0; i < pState->nQueues; i++)
    10661026        {
     
    10931053static DECLCALLBACK(void) vpciConfigure(PCIDEVICE& pci, VirtioDeviceType enmType)
    10941054{
    1095     Assert(enmType < (int)RT_ELEMENTS(g_VPCIDevices));
    10961055    /* Configure PCI Device, assume 32-bit mode ******************************/
    1097     PCIDevSetVendorId(&pci, g_VPCIDevices[enmType].uPCIVendorId);
    1098     PCIDevSetDeviceId(&pci, g_VPCIDevices[enmType].uPCIDeviceId);
    1099     vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, g_VPCIDevices[enmType].uPCISubsystemVendorId);
    1100     vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, g_VPCIDevices[enmType].uPCISubsystemId);
     1056    PCIDevSetVendorId(&pci, DEVICE_PCI_VENDOR_ID);
     1057    PCIDevSetDeviceId(&pci, DEVICE_PCI_DEVICE_ID);
     1058    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_VENDOR_ID, DEVICE_PCI_SUBSYSTEM_VENDOR_ID);
     1059    vpciCfgSetU16(pci, VBOX_PCI_SUBSYSTEM_ID, DEVICE_PCI_SUBSYSTEM_ID);
    11011060
    11021061    /* ABI version, must be equal 0 as of 2.6.30 kernel. */
     
    11041063    /* Ethernet adapter */
    11051064    vpciCfgSetU8( pci, VBOX_PCI_CLASS_PROG,           0x00);
    1106     vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, g_VPCIDevices[enmType].uPCIClass);
     1065    vpciCfgSetU16(pci, VBOX_PCI_CLASS_DEVICE, DEVICE_PCI_CLASS);
    11071066    /* Interrupt Pin: INTA# */
    11081067    vpciCfgSetU8( pci, VBOX_PCI_INTERRUPT_PIN,        0x01);
     
    11161075    int rc = VINF_SUCCESS;
    11171076    /* Init handles and log related stuff. */
    1118     RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), g_VPCIDevices[enmDevType].pcszNameFmt, iInstance);
     1077    RTStrPrintf(pState->szInstance, sizeof(pState->szInstance), DEVICE_NAME_FMT, iInstance);
    11191078    pState->enmDevType   = enmDevType;
    11201079
     
    11511110    pState->pLedsConnector = (PPDMILEDCONNECTORS)pBase->pfnQueryInterface(pBase, PDMINTERFACE_LED_CONNECTORS);
    11521111
    1153     pState->nQueues = g_VPCIDevices[pState->enmDevType].nQueues;
     1112    pState->nQueues = DEVICE_N_QUEUES;
    11541113
    11551114#if defined(VBOX_WITH_STATISTICS)
     
    14401399}
    14411400
    1442 #ifdef IN_RING3
    14431401/**
    14441402 * Hardware reset. Revert all registers to initial values.
     
    14581416}
    14591417
     1418#ifdef IN_RING3
    14601419/**
    14611420 * Wakeup the RX thread.
     
    17221681        return rc;
    17231682
     1683    STAM_PROFILE_ADV_START(&pState->StatReceive, a);
    17241684    vpciSetReadLed(&pState->VPCI, true);
    17251685    if (vnetAddressFilter(pState, pvBuf, cb))
     
    17291689    }
    17301690    vpciSetReadLed(&pState->VPCI, false);
     1691    STAM_PROFILE_ADV_STOP(&pState->StatReceive, a);
    17311692
    17321693    return rc;
     
    18281789        else
    18291790        {
     1791            STAM_PROFILE_ADV_START(&pState->StatTransmit, a);
    18301792            /* Assemble a complete frame. */
    18311793            for (unsigned int i = 1; i < elem.nOut && uOffset < VNET_MAX_FRAME_SIZE; i++)
     
    18481810        vqueuePut(&pState->VPCI, pQueue, &elem, sizeof(VNETHDR) + uOffset);
    18491811        vqueueSync(&pState->VPCI, pQueue);
     1812        STAM_PROFILE_ADV_STOP(&pState->StatTransmit, a);
    18501813    }
    18511814    vpciSetWriteLed(&pState->VPCI, false);
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