VirtualBox

Changeset 80108 in vbox


Ignore:
Timestamp:
Aug 1, 2019 8:24:22 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
132548
Message:

Implemented virtio_pci_cfg_cap interface of VirtIO 1.0 spec, section 4.1.4.7. (See #9440, Comment #40)

Location:
trunk/src/VBox/Devices
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp

    r80059 r80108  
    8383                                                    | VIRTIOSCSI_F_T10_PI  \
    8484
     85typedef struct VIRTIO_PCI_DEV_CAP_T
     86{
     87    uint32_t    uTestField1;
     88    uint32_t    uTestField2;
     89} VIRTIO_PCI_DEV_CAP_T, *PVIRTIO_PCI_DEV_CAP_T;
     90
    8591/**
    8692 * State of a target attached to the VirtIO SCSI Host
     
    143149    /* virtioState must be first member */
    144150    VIRTIOSTATE                     virtioState;
     151
     152    VIRTIO_PCI_DEV_CAP_T            devSpecificCap;
    145153
    146154    /* SCSI target instances data */
     
    180188    /** The event semaphore the processing thread waits on. */
    181189    SUPSEMEVENT                     hEvtProcess;
    182 
    183     PVIRTIOCALLBACKS                pVirtioCallbacks;
    184190
    185191    /** Number of ports detected */
     
    971977    PVIRTIOSTATE pVirtio = &(pThis->virtioState);
    972978
     979    virtioSetHostFeatures(pVirtio, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED);
     980
    973981    pThis->IBase.pfnQueryInterface = virtioScsiR3DeviceQueryInterface;
    974     rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams, &pThis->pVirtioCallbacks,
     982
     983    rc = virtioConstruct(pDevIns, pVirtio, iInstance, pVirtioPciParams,
    975984                         VIRTIOSCSI_NAME_FMT, VIRTIOSCSI_N_QUEUES, VIRTIOSCSI_REGION_PCI_CAP,
    976985                         virtioScsiR3DevCapRead, virtioScsiR3DevCapWrite,
    977                         0 /* cbDevSpecificCap */,
    978                         0 /* uNotifyOffMultiplier */);
     986                         sizeof(VIRTIO_PCI_DEV_CAP_T ) /* cbDevSpecificCap */,
     987                         false /* fHaveDevSpecificCap */, 0 /* uNotifyOffMultiplier */);
    979988
    980989
     
    982991        return PDMDEV_SET_ERROR(pDevIns, rc, N_("virtio-scsi: failed to initialize VirtIO"));
    983992
    984     pThis->pVirtioCallbacks->pfnSetHostFeatures(pVirtio, VIRTIOSCSI_HOST_SCSI_FEATURES_OFFERED);
    985993
    986994    rc = PDMDevHlpPCIIORegionRegister(pDevIns, VIRTIOSCSI_REGION_MEM_IO, 32,
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r80058 r80108  
    424424}
    425425
    426 
    427426/**
    428427 * Raise interrupt.
     
    432431 * @param   u8IntCause  Interrupt cause bit mask to set in PCI ISR port.
    433432 */
     433__attribute__((unused))
    434434int virtioRaiseInterrupt(VIRTIOSTATE *pState, int rcBusy, uint8_t u8IntCause)
    435435{
    436436    RT_NOREF2(pState, u8IntCause);
    437437    RT_NOREF_PV(rcBusy);
    438 /* PK TODO: Adapt to VirtIO 1.0
    439     STAM_COUNTER_INC(&pState->StatIntsRaised);
    440438    LogFlow(("%s virtioRaiseInterrupt: u8IntCause=%x\n",
    441439             INSTANCE(pState), u8IntCause));
     
    443441    pState->uISR |= u8IntCause;
    444442    PDMDevHlpPCISetIrq(pState->CTX_SUFF(pDevIns), 0, 1);
    445 */
    446443    return VINF_SUCCESS;
    447444}
     
    459456}
    460457
    461 DECLINLINE(uint32_t) virtioGetHostFeatures(PVIRTIOSTATE pState,
    462                                          PFNGETHOSTFEATURES pfnGetHostFeatures)
    463 {
    464     return pfnGetHostFeatures(pState) /*| VIRTIO_F_NOTIFY_ON_EMPTY */;
    465 }
    466 
    467458
    468459#ifdef IN_RING3
    469 
    470 
    471460/**
    472461 * Saves the state of device.
     
    645634            AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n"));
    646635        }
    647         else /* Guest WRITE pCommonCfg->uDeviceFeature */
     636        else /* Guest READ pCommonCfg->uDeviceFeature */
    648637        {
    649638            switch(pVirtio->uFeaturesOfferedSelect)
    650639            {
    651640                case 0:
    652                     pVirtio->uFeaturesOffered = *(uint32_t *)pv;
    653                     LOG_ACCESSOR(uFeaturesOffered, uint32_t);
     641                    *(uint32_t *)pv = pVirtio->uFeaturesOffered & 0xffffffff;
     642                    LogFunc(("Guest read  0x%8x from LO DWORD of uFeaturesOffered\n", *(uint32_t *)pv));
    654643                    break;
    655644                case 1:
    656                     pVirtio->uFeaturesOffered = (uint64_t)(*(uint32_t *)pv) << 32;
    657                     LOG_ACCESSOR(uFeaturesOffered, uint32_t);
     645                    *(uint32_t *)pv = (pVirtio->uFeaturesOffered >> 32) & 0xffffffff;
     646                    LogFunc(("Guest read  0x%8x from HI DWORD of uFeaturesOffered\n", *(uint32_t *)pv));
    658647                    break;
    659648                default:
    660                     Log(("Guest selected out of range pVirtio->uDeviceFeature (%d), returning 0\n",
     649                    Log(("Guest read uDeviceFeature with out of range selector (%d), returning 0\n",
    661650                        pVirtio->uFeaturesOfferedSelect));
    662651            }
     
    671660                case 0:
    672661                    pVirtio->uFeaturesAccepted = *(uint32_t *)pv;
    673                     LOG_ACCESSOR(uFeaturesAccepted, uint32_t);
     662                    LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
    674663                    break;
    675664                case 1:
    676665                    pVirtio->uFeaturesAccepted = (uint64_t)(*(uint32_t *)pv) << 32;
    677                     LOG_ACCESSOR(uFeaturesAccepted, uint32_t);
     666                    LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
    678667                    break;
    679668            }
     
    685674                case 0:
    686675                    *(uint32_t *)pv = pVirtio->uFeaturesAccepted & 0xffffffff;
    687                     LOG_ACCESSOR(uFeaturesAccepted, uint32_t);
     676                    LogFunc(("Guest read  0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
    688677                    break;
    689678                case 1:
    690679                    *(uint32_t *)pv = (pVirtio->uFeaturesAccepted >> 32) & 0xffffffff;
    691                     LOG_ACCESSOR(uFeaturesAccepted, uint32_t);
     680                    LogFunc(("Guest read  0x%8x from HI DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
    692681                    break;
    693682            }
     
    712701            pVirtio->uDeviceStatus = *(uint8_t *)pv;
    713702            LogFunc(("Driver wrote uDeviceStatus:\n"));
    714             showDeviceStatus(pVirtio->uDeviceStatus);
     703            logDeviceStatus(pVirtio->uDeviceStatus);
    715704            if (pVirtio->uDeviceStatus == 0)
    716705                virtioResetDevice(pVirtio);
     
    720709            LogFunc(("Driver read uDeviceStatus:\n"));
    721710            *(uint32_t *)pv = pVirtio->uDeviceStatus;
    722             showDeviceStatus(pVirtio->uDeviceStatus);
     711            logDeviceStatus(pVirtio->uDeviceStatus);
    723712        }
    724713    }
     
    799788//    LogFlowFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
    800789//#endif
     790
     791    /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */
     792
    801793    off_t uoff = 0;
    802794    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg,  uoff);
    803795    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    VIRTIO_PCI_ISR_CAP_T,    pIsrCap,     uoff);
    804 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    805     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap,  uoff);
    806 #endif
    807     /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */
    808 
     796
     797    if (pVirtio->fHaveDevSpecificCap)
     798    {
     799        MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap,  uoff);
     800        if (pDeviceCap)
     801            rc = pVirtio->virtioCallbacks.pfnVirtioDevCapRead(pDevIns, GCPhysAddr, pv, cb);
     802        return rc;
     803    }
    809804    if (pCommonCfg)
    810805        virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uoff, pv);
     
    814809        LogFunc(("Read 0x%s from pIsrCap\n", *(uint8_t *)pv));
    815810    }
    816 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    817     else if (pDeviceCap)
    818         rc = pThis->pfnVirtioDevCapRead(pDevIns, GCPhysAddr, pv, cb);
    819 #endif
     811    else {
     812
     813        AssertMsgFailed(("virtio: Write outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb));
     814        Log(("pCommonCfg=%p, pIsrCap=%p, uoff=%d\n",
     815                pCommonCfg, pIsrCap, uoff));
     816    }
     817    return rc;
     818}
     819
     820/**
     821 * Memory mapped I/O Handler for PCI Capabilities write operations.
     822 *
     823 * @returns VBox status code.
     824 *
     825 * @param   pDevIns     The device instance.
     826 * @param   pvUser      User argument.
     827 * @param   GCPhysAddr  Physical address (in GC) where the write starts.
     828 * @param   pv          Where to fetch the result.
     829 * @param   cb          Number of bytes to write.
     830 */
     831PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
     832{
     833
     834    RT_NOREF(pvUser);
     835    PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     836    int rc = VINF_SUCCESS;
     837
     838//#ifdef LOG_ENABLED
     839//    LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
     840//#endif
     841    off_t uoff = 0;
     842
     843    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg,  uoff);
     844    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    VIRTIO_PCI_ISR_CAP_T,    pIsrCap,     uoff);
     845    if (pVirtio->fHaveDevSpecificCap)
     846    {
     847        MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap,  uoff);
     848        if (pDeviceCap)
     849            rc = pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, GCPhysAddr, pv, cb);
     850        return rc;
     851    }
     852    if (pCommonCfg)
     853        virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uoff, pv);
     854    else if (pIsrCap)
     855    {
     856        pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1;
     857        pVirtio->fDeviceConfigInterrupt = !!(*((uint8_t *)pv) & 2);
     858        Log(("pIsrCap... setting fQueueInterrupt=%d fDeviceConfigInterrupt=%d\n",
     859              pVirtio->fQueueInterrupt, pVirtio->fDeviceConfigInterrupt));
     860    }
    820861    else
    821         AssertMsgFailed(("virtio: Write outside of capabilities region\n"));
     862    {
     863        AssertMsgFailed(("virtio: Write outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb));
     864        Log(("pCommonCfg=%p, pIsrCap=%p, uoff=%d\n",
     865                pCommonCfg, pIsrCap, uoff));
     866    }
    822867
    823868    return rc;
    824869}
    825 #if TBD
     870
     871
     872/**
     873 * @callback_method_impl{FNPCIIOREGIONMAP}
     874 */
     875static DECLCALLBACK(int) virtioR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
     876                                     RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     877{
     878    RT_NOREF3(pPciDev, iRegion, enmType);
     879    PVIRTIOSTATE  pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     880    int rc = VINF_SUCCESS;
     881
     882    Assert(cb >= 32);
     883
     884    if (iRegion == pVirtio->uVirtioCapRegion)
     885    {
     886        /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */
     887        rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
     888                           IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
     889                           virtioR3MmioWrite, virtioR3MmioRead,
     890                           "virtio-scsi MMIO");
     891
     892        if (RT_FAILURE(rc))
     893        {
     894            LogFunc(("virtio: PCI Capabilities failed to map GCPhysAddr=%RGp cb=%RGp, region=%d\n",
     895                    GCPhysAddress, cb, iRegion));
     896            return rc;
     897        }
     898        LogFunc(("virtio: PCI Capabilities mapped at GCPhysAddr=%RGp cb=%RGp, region=%d\n",
     899                GCPhysAddress, cb, iRegion));
     900        pVirtio->GCPhysPciCapBase = GCPhysAddress;
     901        pVirtio->pGcPhysCommonCfg = (PVIRTIO_PCI_COMMON_CFG_T)(GCPhysAddress + pVirtio->uCommonCfgOffset);
     902        pVirtio->pGcPhysNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)(GCPhysAddress + pVirtio->uNotifyCapOffset);
     903        pVirtio->pGcPhysIsrCap    = (PVIRTIO_PCI_ISR_CAP_T)(   GCPhysAddress + pVirtio->uIsrCapOffset);
     904        pVirtio->pGcPhysPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)(   GCPhysAddress + pVirtio->uPciCfgCapOffset);
     905        pVirtio->pGcPhysDeviceCap = (PVIRTIO_PCI_DEVICE_CAP_T)(GCPhysAddress + pVirtio->uDeviceCapOffset);
     906    }
     907    return rc;
     908}
     909
    826910/**
    827911  * Callback function for reading from the PCI configuration space.
     
    841925{
    842926    PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
    843     int rc = VINF_SUCCESS;
    844 
    845     LogFunc(("uAddress: %d, uPciConfigDataOffset: %d\n", uAddress, pVirtio->uPciConfigDataOffset));
    846 
    847     if (uAddress == pVirtio->uPciConfigDataOffset)
    848         Log(("Read uPciConfigDataOffset\n"));
    849     rc = pVirtio->pfnPciConfigReadOld(pDevIns, pPciDev, uAddress, cb);
    850     return rc;
    851 
     927
     928    if (uAddress == pVirtio->uPciCfgDataOff)
     929    {
     930        /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability
     931         * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space
     932         * (the virtio_pci_cfg_cap capability), and access data items. */
     933        uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength;
     934        uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset;
     935        uint8_t  uBar    = pVirtio->pPciCfgCap->pciCap.uBar;
     936        uint32_t pv = 0;
     937        if (uBar == pVirtio->uVirtioCapRegion)
     938            (void)virtioR3MmioRead(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->GCPhysPciCapBase + uOffset),
     939                                    &pv, uLength);
     940        else
     941        {
     942            LogFunc(("Guest read virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring"));
     943            return 0;
     944        }
     945        LogFunc(("virtio: Guest read  virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%d, length=%d, result=%d\n",
     946                uBar, uOffset, uLength, pv));
     947        return pv;
     948    }
     949    return pVirtio->pfnPciConfigReadOld(pDevIns, pPciDev, uAddress, cb);
    852950}
    853951
     
    872970{
    873971    PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
    874     VBOXSTRICTRC strictRc;
    875 
    876     LogFunc(("uAddress: %d, uPciConfigDataOffset: %d\n", uAddress, pVirtio->uPciConfigDataOffset));
    877     if (uAddress == pVirtio->uPciConfigDataOffset)
    878         Log(("Wrote uPciConfigDataOffset\n"));
    879     strictRc = pVirtio->pfnPciConfigWriteOld(pDevIns, pPciDev, uAddress, u32Value, cb);
    880     return strictRc;
    881 }
    882 #endif
    883 /**
    884  * Memory mapped I/O Handler for PCI Capabilities write operations.
    885  *
    886  * @returns VBox status code.
    887  *
    888  * @param   pDevIns     The device instance.
    889  * @param   pvUser      User argument.
    890  * @param   GCPhysAddr  Physical address (in GC) where the write starts.
    891  * @param   pv          Where to fetch the result.
    892  * @param   cb          Number of bytes to write.
    893  */
    894 PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
    895 {
    896 
    897     RT_NOREF(pvUser);
    898     PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
    899     int rc = VINF_SUCCESS;
    900 
    901 #ifdef LOG_ENABLED
    902 //    LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
    903 #endif
    904     off_t uoff = 0;
    905 
    906     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg,  uoff);
    907     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    VIRTIO_PCI_ISR_CAP_T,    pIsrCap,     uoff);
    908 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    909     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, VIRTIO_PCI_DEVICE_CAP_T, pDeviceCap,  uoff);
    910 #endif
    911 
    912     if (pCommonCfg)
    913         virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uoff, pv);
    914     else if (pIsrCap)
    915     {
    916         pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1;
    917         pVirtio->fDeviceConfigInterrupt = !!(*((uint8_t *)pv) & 2);
    918         Log(("pIsrCap... setting fQueueInterrupt=%d fDeviceConfigInterrupt=%d\n",
    919               pVirtio->fQueueInterrupt, pVirtio->fDeviceConfigInterrupt));
    920     }
    921 #if HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    922     else if (pDeviceCap)
    923         rc = pThis->pfnVirtioDevCapWrite(pDevIns, GCPhysAddr, pv, cb);
    924 #endif
    925     else
    926         AssertMsgFailed(("virtio: Write outside of capabilities region\n"));
    927 
    928     return rc;
    929 }
    930 
    931 
    932 /**
    933  * @callback_method_impl{FNPCIIOREGIONMAP}
    934  */
    935 static DECLCALLBACK(int) virtioR3Map(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
    936                                      RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    937 {
    938     RT_NOREF3(pPciDev, iRegion, enmType);
    939     PVIRTIOSTATE  pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
    940     int rc = VINF_SUCCESS;
    941 
    942     Assert(cb >= 32);
    943 
    944     /* We use the assigned size here, because we currently only support page aligned MMIO ranges. */
    945     rc = PDMDevHlpMMIORegister(pDevIns, GCPhysAddress, cb, NULL /*pvUser*/,
    946                            IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
    947                            virtioR3MmioWrite, virtioR3MmioRead,
    948                            "virtio-scsi MMIO");
    949 
    950     LogFunc(("virtio: PCI Capabilities mapped at GCPhysAddr=%RGp cb=%RGp, region=%d\n", GCPhysAddress, cb, iRegion));
    951 
    952     if (RT_SUCCESS(rc))
    953     {
    954         pVirtio->GCPhysPciCapBase = GCPhysAddress;
    955         pVirtio->pGcPhysCommonCfg = (PVIRTIO_PCI_COMMON_CFG_T)(GCPhysAddress + pVirtio->uCommonCfgOffset);
    956         pVirtio->pGcPhysNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)(GCPhysAddress + pVirtio->uNotifyCapOffset);
    957         pVirtio->pGcPhysIsrCap    = (PVIRTIO_PCI_ISR_CAP_T)(GCPhysAddress + pVirtio->uIsrCapOffset);
    958         pVirtio->pGcPhysPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)(GCPhysAddress + pVirtio->uPciCfgCapOffset);
    959 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    960         pVirtio->pGcPhysDeviceCap = (PVIRTIO_PCI_DEVICE_CAP_T)(GCPhysAddress + pVirtio->uuDeviceCapOffset);
    961 #endif
    962     }
    963     return rc;
    964 }
    965 
     972
     973    if (uAddress == pVirtio->uPciCfgDataOff)
     974    {
     975        /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability
     976         * whereby the guest driver can specify a bar, offset, and length via the PCI configuration space
     977         * (the virtio_pci_cfg_cap capability), and access data items. */
     978        uint32_t uLength = pVirtio->pPciCfgCap->pciCap.uLength;
     979        uint32_t uOffset = pVirtio->pPciCfgCap->pciCap.uOffset;
     980        uint8_t  uBar    = pVirtio->pPciCfgCap->pciCap.uBar;
     981        if (uBar == pVirtio->uVirtioCapRegion)
     982            (void)virtioR3MmioWrite(pDevIns, NULL, (RTGCPHYS)((uint32_t)pVirtio->GCPhysPciCapBase + uOffset),
     983                                    (void *)&u32Value, uLength);
     984        else
     985        {
     986            LogFunc(("Guest wrote virtio_pci_cfg_cap.pci_cfg_data using unconfigured BAR. Ignoring"));
     987            return VINF_SUCCESS;
     988        }
     989        LogFunc(("Guest wrote  virtio_pci_cfg_cap.pci_cfg_data, bar=%d, offset=%x, length=%x, value=%d\n",
     990                uBar, uOffset, uLength, u32Value));
     991        return VINF_SUCCESS;
     992    }
     993    return pVirtio->pfnPciConfigWriteOld(pDevIns, pPciDev, uAddress, u32Value, cb);
     994}
    966995
    967996/**
     
    9781007
    9791008/**
    980  * Get VirtIO available host-side features
     1009 * Get VirtIO accepted host-side features
    9811010 *
    9821011 * @returns feature bits selected or 0 if selector out of range.
     
    9861015 */
    9871016
     1017__attribute__((unused))
    9881018static uint64_t virtioGetHostFeatures(PVIRTIOSTATE pVirtio)
    9891019{
    990     return pVirtio->uFeaturesOffered;
     1020    return pVirtio->uFeaturesAccepted;
    9911021}
    9921022
     
    10011031 */
    10021032
    1003 static int virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered)
     1033void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered)
    10041034{
    10051035    pVirtio->uFeaturesOffered = VIRTIO_F_VERSION_1 | uFeaturesOffered;
    1006     return VINF_SUCCESS;
    10071036}
    10081037
     
    10551084
    10561085int   virtioConstruct(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, int iInstance, PVIRTIOPCIPARAMS pPciParams,
    1057                     PPVIRTIOCALLBACKS ppVirtioCallbacks, const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioRegion,
     1086                    const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioCapRegion,
    10581087                    PFNVIRTIODEVCAPREAD devCapReadCallback, PFNVIRTIODEVCAPWRITE devCapWriteCallback,
    1059                     uint16_t cbDevSpecificCap, uint32_t uNotifyOffMultiplier)
     1088                    uint16_t cbDevSpecificCap, bool fHaveDevSpecificCap,  uint32_t uNotifyOffMultiplier)
    10601089{
    10611090    pVirtio->nQueues = nQueues;
     
    10641093    /* Init handles and log related stuff. */
    10651094    RTStrPrintf(pVirtio->szInstance, sizeof(pVirtio->szInstance), pcszNameFmt, iInstance);
    1066 
    1067     VIRTIOCALLBACKS virtioCallbacks;
    1068     virtioCallbacks.pfnSetHostFeatures = virtioSetHostFeatures;
    1069     virtioCallbacks.pfnGetHostFeatures = virtioGetHostFeatures;
    1070     virtioCallbacks.pfnReset = virtioReset;
    1071     *ppVirtioCallbacks = &virtioCallbacks;
    10721095
    10731096    pVirtio->pDevInsR3 = pDevIns;
     
    10751098    pVirtio->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    10761099    pVirtio->uDeviceStatus = 0;
    1077     pVirtio->pfnVirtioDevCapRead     = devCapReadCallback;
    1078     pVirtio->pfnVirtioDevCapWrite    = devCapWriteCallback;
     1100    pVirtio->uVirtioCapRegion = uVirtioCapRegion;
     1101    pVirtio->fHaveDevSpecificCap = fHaveDevSpecificCap;
     1102    pVirtio->virtioCallbacks.pfnVirtioDevCapRead = devCapReadCallback;
     1103    pVirtio->virtioCallbacks.pfnVirtioDevCapWrite = devCapWriteCallback;
    10791104
    10801105    /* Set PCI config registers (assume 32-bit mode) */
     
    10991124    pVirtio->IBase = pDevIns->IBase;
    11001125
     1126
     1127    PDMDevHlpPCISetConfigCallbacks(pDevIns, &pVirtio->dev,
     1128                virtioPciConfigRead,  &pVirtio->pfnPciConfigReadOld,
     1129                virtioPciConfigWrite, &pVirtio->pfnPciConfigWriteOld);
     1130
    11011131    /** Construct & map PCI vendor-specific capabilities for virtio host negotiation with guest driver */
    11021132
     
    11091139    uint8_t uCfgCapOffset = 0x40;
    11101140    PVIRTIO_PCI_NOTIFY_CAP_T pNotifyCap;
    1111     PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap;
    1112 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    1113     PVIRTIO_PCI_CAP_T pDeviceCap;
    1114 #endif
     1141    PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap, pDeviceCap;
    11151142    uint32_t cbVirtioCaps = 0;
    11161143
    1117     /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CAP_T) */
     1144    /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T)
     1145     * as a mandatory but suboptimal alternative interface to host device capabilities, facilitating
     1146     * access the memory of any BAR. If the guest uses it (the VirtIO driver on Linux doesn't),
     1147     * Unlike Common, Notify, ISR and Device capabilities, it is accessed directly via PCI Config region.
     1148     * therefore does not contribute to the capabilities region (BAR) the other capabilities use.
     1149     */
    11181150    pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1119     pVirtio->uPciConfigDataOffset = 0x40 + sizeof(VIRTIO_PCI_CAP_T);
     1151    pVirtio->uPciCfgDataOff = uCfgCapOffset + RT_OFFSETOF(VIRTIO_PCI_CFG_CAP_T, uPciCfgData);
    11201152    PVIRTIO_PCI_CAP_T pCfg = (PVIRTIO_PCI_CAP_T)pVirtio->pPciCfgCap;
    11211153    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
     
    11231155    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CFG_CAP_T);
    11241156    pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG;
    1125     pCfg->uBar     = uVirtioRegion;
    1126     pCfg->uOffset  = pVirtio->uPciCfgCapOffset = 0;
    1127     pCfg->uLength  = sizeof(VIRTIO_PCI_CFG_CAP_T);
     1157    pCfg->uBar     = uVirtioCapRegion;
     1158    pCfg->uOffset  = 4;
     1159    pCfg->uLength  = 4;  /* Initially make non-zero 4-byte aligned so Linux Virtio impl's scan doesn't reject this cap */
    11281160    cbVirtioCaps  += pCfg->uLength;
    11291161
    1130     /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/
     1162    /* Following capability mapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/
    11311163    pCfg = pCommonCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    11321164    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
     
    11341166    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    11351167    pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG;
    1136     pCfg->uBar     = uVirtioRegion;
    1137     pCfg->uOffset  = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset + sizeof(VIRTIO_PCI_CFG_CAP_T);
     1168    pCfg->uBar     = uVirtioCapRegion;
     1169    pCfg->uOffset  = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset
     1170                                               + pVirtio->pPciCfgCap->pciCap.uLength;
    11381171    pCfg->uLength  = sizeof(VIRTIO_PCI_COMMON_CFG_T);
    11391172    cbVirtioCaps  += pCfg->uLength;
    11401173
    1141     /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/
     1174    /* Following capability mapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/
    11421175    pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    11431176    pCfg = (PVIRTIO_PCI_CAP_T)pNotifyCap;
     
    11461179    pCfg->uCapLen  = sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    11471180    pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG;
    1148     pCfg->uBar     = uVirtioRegion;
     1181    pCfg->uBar     = uVirtioCapRegion;
    11491182    pCfg->uOffset  = pVirtio->uNotifyCapOffset = pCommonCfg->uOffset + sizeof(VIRTIO_PCI_COMMON_CFG_T);
    11501183    pCfg->uLength  = sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
     
    11521185    cbVirtioCaps  += pCfg->uLength;
    11531186
    1154     /* Capability will be mapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T)  */
     1187    /* Following capability mapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T)  */
    11551188    pCfg = pIsrCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    11561189    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1157     pCfg->uCapNext = (uint8_t)(fMsiSupport || cbDevSpecificCap ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0);
     1190    pCfg->uCapNext = (uint8_t)(fMsiSupport || pVirtio->fHaveDevSpecificCap
     1191                               ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0);
    11581192    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    11591193    pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG;
    1160     pCfg->uBar     = uVirtioRegion;
     1194    pCfg->uBar     = uVirtioCapRegion;
    11611195    pCfg->uOffset  = pVirtio->uIsrCapOffset = pNotifyCap->pciCap.uOffset + sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    11621196    pCfg->uLength  = sizeof(VIRTIO_PCI_ISR_CAP_T);
    11631197    cbVirtioCaps  += pCfg->uLength;
    11641198
    1165 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    1166     /* Capability will be mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/
    1167     pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1168     pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1169     pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0);
    1170     pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    1171     pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG;
    1172     pCfg->uBar     = uVirtioRegion;
    1173     pCfg->uOffset  = uDeviceCapOffset->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T);
    1174     pCfg->uLength  = cbDevSpecificCap;
    1175     cbVirtioCaps  += pCfg->uLength;
    1176 #endif
     1199    if (pVirtio->fHaveDevSpecificCap)
     1200    {
     1201        /* Following capability mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/
     1202        pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
     1203        pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
     1204        pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0);
     1205        pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
     1206        pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG;
     1207        pCfg->uBar     = uVirtioCapRegion;
     1208        pCfg->uOffset  = pVirtio->uDeviceCapOffset = pIsrCap->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T);
     1209        pCfg->uLength  = cbDevSpecificCap;
     1210        cbVirtioCaps  += pCfg->uLength;
     1211    }
    11771212
    11781213    /* Set offset to first capability and enable PCI dev capabilities */
     
    11931228            PCIDevSetCapabilityList(&pVirtio->dev, 0x40);
    11941229    }
    1195 /*
    1196     PDMDevHlpPCISetConfigCallbacks(pDevIns, &pVirtio->dev,
    1197                 virtioPciConfigRead,  &pVirtio->pfnPciConfigReadOld,
    1198                 virtioPciConfigWrite, &pVirtio->pfnPciConfigWriteOld);
    1199 */
    1200     rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioRegion, cbVirtioCaps,
     1230
     1231    rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, cbVirtioCaps,
    12011232                                      PCI_ADDRESS_SPACE_MEM, virtioR3Map);
    12021233    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r80058 r80108  
    3434/** @} */
    3535
    36 
    3736/** Reserved Feature Bits */
    3837#define VIRTIO_F_RING_INDIRECT_DESC         RT_BIT_64(28)
     
    6261#define VIRTIO_STATUS_FAILED                0x80    /** Fatal: Something wrong, guest gave up    */
    6362#define VIRTIO_STATUS_DEVICE_NEEDS_RESET    0x40    /** Device experienced unrecoverable error   */
    64 
    6563
    6664#define VIRTIO_MAX_NQUEUES                  256     /** Max queues we allow guest to create      */
     
    157155    uint16_t  uQueueMsixVector;       /** RW (driver selects MSI-X queue vector)      */
    158156    uint16_t  uQueueEnable;           /** RW (driver controls usability of queue)     */
    159     uint16_t  uQueueNotifyOff;        /** RO (offset uto virtqueue; see spec)          */
     157    uint16_t  uQueueNotifyOff;        /** RO (offset uto virtqueue; see spec)         */
    160158    uint64_t  uQueueDesc;             /** RW (driver writes desc table phys addr)     */
    161159    uint64_t  uQueueAvail;            /** RW (driver writes avail ring phys addr)     */
     
    163161} VIRTIO_PCI_COMMON_CFG_T, *PVIRTIO_PCI_COMMON_CFG_T;
    164162
     163/* The following two types are opaque here. The device-specific capabilities are handled
     164 * through a callback to the consumer host device driver, where the corresponding
     165 * struct is declared, since it cannot be defined in the host-generic section of
     166 * the VirtIO specification. */
     167
     168typedef void * PVIRTIO_PCI_DEVICE_CAP_T;
     169typedef struct virtio_pci_device_cap
     170{
     171} VIRTIO_PCI_DEVICE_CAP_T;
     172
    165173typedef struct virtio_pci_notify_cap
    166174{
     
    175183 * and implement this struct and the macro
    176184 */
    177 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    178 typedef struct virtio_pci_dev_cfg     VIRTIO_PCI_DEVICE_CAP_T, *PVIRTIO_PCI_DEVICE_CAP_T;
    179 #endif
    180 
    181185typedef struct virtio_pci_cfg_cap {
    182186        struct virtio_pci_cap pciCap;
     
    280284typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
    281285
     286/** @name VirtIO port I/O callbacks.
     287 * @{ */
     288typedef struct VIRTIOCALLBACKS
     289{
     290     DECLCALLBACKMEMBER(int,      pfnVirtioDevCapRead)
     291                                      (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead);
     292     DECLCALLBACKMEMBER(int,      pfnVirtioDevCapWrite)
     293                                      (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite);
     294} VIRTIOCALLBACKS, *PVIRTALCALLBACKS;
     295/** @} */
     296
    282297/**
    283298 * The core (/common) state of the VirtIO PCI device
     
    287302typedef struct VIRTIOSTATE
    288303{
    289     PDMPCIDEV              dev;
    290     PDMCRITSECT            cs;                     /**< Critical section - what is it protecting? */
     304    PDMPCIDEV                    dev;
     305    PDMCRITSECT                  cs;                     /**< Critical section - what is it protecting? */
    291306    /* Read-only part, never changes after initialization. */
    292     char                   szInstance[8];          /**< Instance name, e.g. VNet#1. */
    293 
     307    char                         szInstance[8];          /**< Instance name, e.g. VNet#1. */
     308
     309    bool                         fHaveDevSpecificCap;
    294310#if HC_ARCH_BITS != 64
    295     uint32_t               padding1;
     311    uint32_t                     padding1;
    296312#endif
    297313
    298314    /** Status LUN: Base interface. */
    299     PDMIBASE               IBase;
     315    PDMIBASE                     IBase;
    300316
    301317    /** Status LUN: LED port interface. */
    302     PDMILEDPORTS           ILed;
     318    PDMILEDPORTS                 ILed;
    303319
    304320    /* Read/write part, protected with critical section. */
    305321    /** Status LED. */
    306     PDMLED                 led;
    307 
     322    PDMLED                       led;
     323
     324    VIRTIOCALLBACKS              virtioCallbacks;
    308325
    309326    /** Status LUN: LED connector (peer). */
    310327    R3PTRTYPE(PPDMILEDCONNECTORS) pLedsConnector;
    311328
    312     PPDMDEVINSR3                pDevInsR3;              /**< Device instance - R3. */
    313     PPDMDEVINSR0                pDevInsR0;              /**< Device instance - R0. */
    314     PPDMDEVINSRC                pDevInsRC;              /**< Device instance - RC. */
    315 
    316     /** Base address of PCI capabilities */
    317     RTGCPHYS                    GCPhysPciCapBase;
    318 
    319 
    320     /** Callbacks when guest driver reads or writes VirtIO device-specific capabilities(s) */
    321 
    322     PFNVIRTIODEVCAPWRITE         pfnVirtioDevCapWrite;
    323     PFNVIRTIODEVCAPREAD          pfnVirtioDevCapRead;
    324     PFNPCICONFIGREAD             pfnPciConfigReadOld;
    325     PFNPCICONFIGWRITE            pfnPciConfigWriteOld;
    326 
    327     uint8_t                      uPciConfigDataOffset;
     329    PPDMDEVINSR3                 pDevInsR3;              /**< Device instance - R3. */
     330    PPDMDEVINSR0                 pDevInsR0;              /**< Device instance - R0. */
     331    PPDMDEVINSRC                 pDevInsRC;              /**< Device instance - RC. */
     332
     333
     334    uint8_t                      uPciCfgDataOff;
    328335#if HC_ARCH_BITS == 64
    329336    uint32_t                     padding2;
     
    364371    uint64_t                     uQueueUsed[MAX_QUEUES];
    365372
     373    /** Base address of PCI capabilities */
     374    RTGCPHYS                     GCPhysPciCapBase;
     375
     376    uint8_t                      uVirtioCapRegion;      /* Client assigned  Virtio dedicated capabilities region*/
     377
     378    /** Callbacks when guest driver reads or writes VirtIO device-specific capabilities(s) */
     379    PFNPCICONFIGREAD             pfnPciConfigReadOld;
     380    PFNPCICONFIGWRITE            pfnPciConfigWriteOld;
     381
     382
    366383    uint32_t                     uNotifyCapOffset;
    367384    uint32_t                     uIsrCapOffset;
     
    376393    PVIRTIO_PCI_ISR_CAP_T        pGcPhysIsrCap;         /** Pointer to MMIO mapped struct */
    377394    PVIRTIO_PCI_CFG_CAP_T        pGcPhysPciCfgCap;      /** Pointer to MMIO mapped struct */
    378 #ifdef HAVE_VIRTIO_DEVICE_SPECIFIC_CAP
    379395    PVIRTIO_PCI_DEVICE_CAP_T     pGcPhysDeviceCap;      /** Pointer to MMIO mapped struct */
    380 #endif
    381396
    382397    bool fDeviceConfigInterrupt;
     
    385400} VIRTIOSTATE, *PVIRTIOSTATE;
    386401
    387 /** @name VirtIO port I/O callbacks.
    388  * @{ */
    389 typedef struct VIRTIOIOCALLBACKS
    390 {
    391      DECLCALLBACKMEMBER(uint64_t, pfnGetHostFeatures)(PVIRTIOSTATE pVirtio);
    392      DECLCALLBACKMEMBER(int,      pfnSetHostFeatures)(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered);
    393      DECLCALLBACKMEMBER(int,      pfnReset)(PVIRTIOSTATE pVirtio);
    394 /*   DECLCALLBACKMEMBER(uint32_t, pfnGetHostMinimalFeatures)(void *pvState); */
    395 /*   DECLCALLBACKMEMBER(int,      pfnGetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData); */
    396 /*   DECLCALLBACKMEMBER(int,      pfnSetConfig)(void *pvState, uint32_t offCfg, uint32_t cb, void *pvData); */
    397 /*   DECLCALLBACKMEMBER(void,     pfnReady)(void *pvState); */
    398 } VIRTIOCALLBACKS, *PVIRTIOCALLBACKS, **PPVIRTIOCALLBACKS;
    399 /** @} */
    400 
    401402void    virtioRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
    402403void   *virtioQueryInterface(struct PDMIBASE *pInterface, const char *pszIID);
    403404
    404405int     virtioConstruct(PPDMDEVINS pDevIns, PVIRTIOSTATE pVirtio, int iInstance, PVIRTIOPCIPARAMS pPciParams,
    405                     PPVIRTIOCALLBACKS ppVirtioCallbacks, const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioRegion,
     406                    const char *pcszNameFmt, uint32_t nQueues, uint32_t uVirtioCapRegion,
    406407                    PFNVIRTIODEVCAPREAD devCapReadCallback, PFNVIRTIODEVCAPWRITE devCapWriteCallback,
    407                     uint16_t cbDevSpecificCap, uint32_t uNotifyOffMultiplier);
     408                    uint16_t cbDevSpecificCap, bool fHaveDevSpecificCap, uint32_t uNotifyOffMultiplier);
    408409
    409410int     virtioDestruct(PVIRTIOSTATE pVirtio);
     
    415416int     virtioRaiseInterrupt(PVIRTIOSTATE pVirtio, int rcBusy, uint8_t uint8_tIntCause);
    416417void    virtioNotify(PVIRTIOSTATE pVirtio);
     418void    virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered);
    417419
    418420PVQUEUE virtioAddQueue(PVIRTIOSTATE pVirtio, unsigned uSize, PFNVIRTIOQUEUECALLBACK pfnCallback, const char *pcszName);
     
    424426void    vringSetNotification( PVIRTIOSTATE pVirtio, PVIRTQUEUE pVirtQueue, bool fEnabled);
    425427
    426 DECLINLINE(void) showDeviceStatus(uint8_t status)
     428DECLINLINE(void) logDeviceStatus(uint8_t status)
    427429{
    428430    if (status & VIRTIO_STATUS_ACKNOWLEDGE)
    429         Log(("                        ACKNOWLEDGE\n"));
     431        Log(("                         ACKNOWLEDGE\n"));
    430432    if (status & VIRTIO_STATUS_DRIVER)
    431         Log(("                        DRIVER\n"));
     433        Log(("                         DRIVER\n"));
    432434    if (status & VIRTIO_STATUS_DRIVER_OK)
    433         Log(("                        DRIVER_OK\n"));
     435        Log(("                         DRIVER_OK\n"));
    434436    if (status & VIRTIO_STATUS_FEATURES_OK)
    435         Log(("                        FEATURES_OK\n"));
     437        Log(("                         FEATURES_OK\n"));
    436438    if (status & VIRTIO_STATUS_FAILED)
    437         Log(("                        FAILED\n"));
     439        Log(("                         FAILED\n"));
    438440    if (status & VIRTIO_STATUS_DEVICE_NEEDS_RESET)
    439         Log(("                        ACKNOWLEDGE\n"));
     441        Log(("                         ACKNOWLEDGE\n"));
    440442    if (status == 0)
    441         Log(("                        RESET\n"));
     443        Log(("                         RESET\n"));
    442444    Log(("\n"));
    443445}
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