VirtualBox

Changeset 80148 in vbox for trunk/src/VBox/Devices/VirtIO


Ignore:
Timestamp:
Aug 6, 2019 6:36:58 AM (5 years ago)
Author:
vboxsync
Message:

Changed how MMIO items are accessed, simplified and fixed PCI CFG CAPs, finished host side Virtio library callbacks implemented, and starting toget device specific configuration negotiation (see #9440, Comment 41

Location:
trunk/src/VBox/Devices/VirtIO
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.cpp

    r80108 r80148  
    3636#endif
    3737
    38 /* These ACCESSOR macros handle the most basic kinds of MMIO accesses to fields
    39  * virtio 1.0 spec's virtio_pci_common_cfg  avoiding a lot of visual bloat.
    40  */
    41 
    42  /**
    43   * If the physical address and access length is within the mapped capability struct
    44   * the ptrByType will be set to the mapped capability start. Otherwise ptrByType will be NULL.
    45   *
    46   * Implied parameters:
    47   *     GPhysAddr   - Physical address accessed (via MMIO callback)
    48   *     cb          - Number of bytes to access
    49   *
    50   * Actual Parameters:
    51   *     [IN]  pCapStruct - Pointer to MMIO mapped capability struct
    52   *     [IN]  type       - Capability struct type
    53   *     [OUT] result     - A pointer of type capType that will be set to a mapped capability
    54   *                       if phys. addr / access len is within it's span.
    55   *     [OUT] offset     - The offset of the physical address into the capability if applicable.
    56   */
    57 
    58 #define MATCH_VIRTIO_CAP_STRUCT(pCapStruct, type, result, offset) \
    59         type *result = NULL; \
    60         if (   GCPhysAddr >= (RTGCPHYS)pCapStruct \
    61             && GCPhysAddr < ((RTGCPHYS)pCapStruct + sizeof(type)) \
    62             && cb <= sizeof(type)) \
    63         { \
    64             offset = GCPhysAddr - (RTGCPHYS)pCapStruct; \
    65             result = (type *)pCapStruct; \
    66         }
    67 
    68 #define LOG_ACCESSOR(member, type) \
    69         LogFunc(("Guest %s 0x%x %s %s\n", fWrite ? "wrote" : "read ", \
    70                  *(type *)pv, fWrite ? "  to" : "from", #member));
    71 
    72 #define LOG_INDEXED_ACCESSOR(member, type, idx) \
    73         LogFunc(("Guest %s 0x%x %s %s[%d]\n", fWrite ? "wrote" : "read ", \
    74                  *(type *)pv, fWrite ? "  to" : "from", #member, idx));
    75 
    76 #define ACCESSOR(member, type) \
     38
     39/**
     40* Returns true if physical address and access length are within the mapped capability struct.
     41*
     42* Actual Parameters:
     43*     [IN]  pPhysCapStruct - Pointer to MMIO mapped capability struct
     44*     [IN]  pCfgCap        - Pointer to capability in PCI configuration area
     45*     [OUT] fMatched       - True if GCPhysAddr is within the physically mapped capability.
     46*
     47* Implied parameters:
     48*     [IN]  GCPhysAddr     - Physical address accessed (via MMIO callback)
     49*     [IN]  cb             - Number of bytes to access
     50*     [OUT] result          - true or false
     51*
     52*/
     53#define MATCH_VIRTIO_CAP_STRUCT(pGcPhysCapData, pCfgCap, fMatched) \
     54        bool fMatched = false; \
     55        if (pGcPhysCapData && pCfgCap && GCPhysAddr >= (RTGCPHYS)pGcPhysCapData \
     56            && GCPhysAddr < ((RTGCPHYS)pGcPhysCapData + ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
     57            && cb <= ((PVIRTIO_PCI_CAP_T)pCfgCap)->uLength) \
     58                fMatched = true;
     59
     60/**
     61 * This macro resolves to boolean true if uoff is within the specified member offset and length.
     62 *
     63 * Actual Parameters:
     64 *     [IN] member      - Member of VIRTIO_PCI_COMMON_CFG_T
     65 *
     66 * Implied Parameters:
     67 *     [IN]  uoff        - Offset into VIRTIO_PCI_COMMON_CFG_T
     68 *     [IN]  cb          - Number of bytes to access
     69 *     [OUT] result      - true or false
     70 */
     71#define COMMON_CFG(member) \
     72           (uoff >= RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
     73        &&  uoff < (uint32_t)(RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member) \
     74                             + RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member)) \
     75        &&   cb <= RT_SIZEOFMEMB(VIRTIO_PCI_COMMON_CFG_T, member) \
     76                  - (uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member)))
     77
     78#define LOG_ACCESSOR(member) \
     79        LogFunc(("Guest %s %s[%d:%d]: %.*Rhxs\n", \
     80                  fWrite ? "wrote" : "read ", #member, foff, foff + cb, cb, pv));
     81
     82#define LOG_INDEXED_ACCESSOR(member, idx) \
     83        LogFunc(("Guest %s %s[%d][%d:%d]: %.*Rhxs\n", \
     84                  fWrite ? "wrote" : "read ", #member, idx, foff, foff + cb, cb, pv));
     85
     86#define ACCESSOR(member) \
    7787    { \
     88        uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    7889        if (fWrite) \
    79         { \
    80             pVirtio->member = *(type *)pv; \
    81         } \
     90            memcpy(((char *)&pVirtio->member) + uoff, (const char *)pv, cb); \
     91        else \
     92            memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \
     93        LOG_ACCESSOR(member); \
     94    }
     95
     96#define ACCESSOR_WITH_IDX(member, idx) \
     97    { \
     98        uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
     99        if (fWrite) \
     100            memcpy(((char *)(pVirtio->member + idx)) + uoff, (const char *)pv, cb); \
     101        else \
     102            memcpy((char *)pv, (const char *)(((char *)(pVirtio->member + idx)) + uoff), cb); \
     103        LOG_INDEXED_ACCESSOR(member, idx); \
     104    }
     105
     106#define ACCESSOR_READONLY(member) \
     107    { \
     108        uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
     109        if (fWrite) \
     110            LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
    82111        else \
    83112        { \
    84             *(type *)pv = pVirtio->member; \
     113            memcpy((char *)pv, (const char *)(((char *)&pVirtio->member) + uoff), cb); \
     114            LOG_ACCESSOR(member); \
    85115        } \
    86         LOG_ACCESSOR(member, type); \
    87     }
    88 #define ACCESSOR_WITH_IDX(member, type, idx) \
     116    }
     117
     118#define ACCESSOR_READONLY_WITH_IDX(member, idx) \
    89119    { \
     120        uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, member); \
    90121        if (fWrite) \
    91         { \
    92             pVirtio->member[idx] = *(type *)pv; \
    93         } \
     122            LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \
    94123        else \
    95124        { \
    96             *(type *)pv = pVirtio->member[idx]; \
    97         } \
    98         LOG_INDEXED_ACCESSOR(member, type, idx); \
    99     }
    100 
    101 #define ACCESSOR_READONLY(member, type) \
    102     { \
    103         if (fWrite) \
    104         { \
    105             LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s\n", #member)); \
    106             AssertMsgFailed(("bad access\n")); \
    107         } \
    108         else \
    109         { \
    110             *(type *)pv = pVirtio->member; \
    111             LOG_ACCESSOR(member, type); \
    112         } \
    113     }
    114 
    115 #define ACCESSOR_READONLY_WITH_IDX(member, type, idx) \
    116     { \
    117         if (fWrite) \
    118         { \
    119             LogFunc(("Guest attempted to write readonly virtio_pci_common_cfg.%s[%d]\n", #member, idx)); \
    120             AssertMsgFailed(("bad access\n")); \
    121         } \
    122         else \
    123         { \
    124             *(type *)pv = pVirtio->member[idx]; \
    125             LOG_INDEXED_ACCESSOR(member, type, idx); \
     125            memcpy((char *)pv, ((char *)(pVirtio->member + idx)) + uoff, cb); \
     126            LOG_INDEXED_ACCESSOR(member, idx); \
    126127        } \
    127128    }
     
    625626 * @param   cb          Number of bytes to read or write
    626627 */
    627 int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, void const *pv)
     628
     629
     630int virtioCommonCfgAccessed(PVIRTIOSTATE pVirtio, int fWrite, off_t uoff, unsigned cb, void const *pv)
    628631{
    629632    int rv = VINF_SUCCESS;
    630     if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeature))
    631     {
    632         if (fWrite) /* Guest WRITE pCommonCfg->uDeviceFeature */
    633         {
    634             AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n"));
    635         }
    636         else /* Guest READ pCommonCfg->uDeviceFeature */
    637         {
    638             switch(pVirtio->uFeaturesOfferedSelect)
     633    uint64_t val;
     634    if (COMMON_CFG(uDeviceFeatures))
     635    {
     636        if (fWrite) /* Guest WRITE pCommonCfg>uDeviceFeatures */
     637            Log(("Guest attempted to write readonly virtio_pci_common_cfg.device_feature\n"));
     638        else /* Guest READ pCommonCfg->uDeviceFeatures */
     639        {
     640            uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatures);
     641            switch(pVirtio->uDeviceFeaturesSelect)
    639642            {
    640643                case 0:
    641                     *(uint32_t *)pv = pVirtio->uFeaturesOffered & 0xffffffff;
    642                     LogFunc(("Guest read  0x%8x from LO DWORD of uFeaturesOffered\n", *(uint32_t *)pv));
     644                    val = pVirtio->uDeviceFeatures & 0xffffffff;
     645                    memcpy((void *)pv, (const void *)&val, cb);
     646                    LogFunc(("Guest read  uDeviceFeatures(LO)[%d:%d]: %.*Rhxs\n",
     647                              foff, foff + cb, cb, pv));
    643648                    break;
    644649                case 1:
    645                     *(uint32_t *)pv = (pVirtio->uFeaturesOffered >> 32) & 0xffffffff;
    646                     LogFunc(("Guest read  0x%8x from HI DWORD of uFeaturesOffered\n", *(uint32_t *)pv));
     650                    val = (pVirtio->uDeviceFeatures >> 32) & 0xffffffff;
     651                    memcpy((void *)pv, (const void *)&val, cb);
     652                    LogFunc(("Guest read  uDeviceFeatures(HI)[%d:%d]: %.*Rhxs\n",
     653                              foff, foff + cb, cb, pv));
    647654                    break;
    648655                default:
    649                     Log(("Guest read uDeviceFeature with out of range selector (%d), returning 0\n",
    650                         pVirtio->uFeaturesOfferedSelect));
     656                    Log(("Guest read uDeviceFeatures with out of range selector (%d), returning 0\n",
     657                          pVirtio->uDeviceFeaturesSelect));
    651658            }
    652659        }
    653660    }
    654     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeature))
    655     {
    656         if (fWrite) /* Guest WRITE pCommonCfg->uDriverFeature */
    657         {
    658             switch(pVirtio->uFeaturesOfferedSelect)
     661    else if (COMMON_CFG(uDriverFeatures))
     662    {
     663        if (fWrite) /* Guest WRITE pCommonCfg->udriverFeatures */
     664        {
     665            uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
     666            switch(pVirtio->uDriverFeaturesSelect)
    659667            {
    660668                case 0:
    661                     pVirtio->uFeaturesAccepted = *(uint32_t *)pv;
    662                     LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
     669                    memcpy(&pVirtio->uDriverFeatures, pv, cb);
     670                    LogFunc(("Guest wrote uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n",
     671                              foff, foff + cb, cb, pv));
    663672                    break;
    664673                case 1:
    665                     pVirtio->uFeaturesAccepted = (uint64_t)(*(uint32_t *)pv) << 32;
    666                     LogFunc(("Guest wrote 0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
     674                    memcpy(((char *)&pVirtio->uDriverFeatures) + sizeof(uint32_t), pv, cb);
     675                    LogFunc(("Guest wrote uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n",
     676                              foff, foff + cb, cb, pv));
    667677                    break;
    668678            }
    669679        }
    670         else /* Guest READ pCommonCfg->uDriverFeature */
    671         {
    672             switch(pVirtio->uFeaturesOfferedSelect)
     680        else /* Guest READ pCommonCfg->udriverFeatures */
     681        {
     682            uint32_t foff = uoff - RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatures);
     683            switch(pVirtio->uDriverFeaturesSelect)
    673684            {
    674685                case 0:
    675                     *(uint32_t *)pv = pVirtio->uFeaturesAccepted & 0xffffffff;
    676                     LogFunc(("Guest read  0x%8x from LO DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
     686                    val = pVirtio->uDriverFeatures & 0xffffffff;
     687                    memcpy((void *)pv, (const void *)&val, cb);
     688                    LogFunc(("Guest read  uDriverFeatures(LO)[%d:%d]: %.*Rhxs\n",
     689                              foff, foff + cb, cb, pv));
    677690                    break;
    678691                case 1:
    679                     *(uint32_t *)pv = (pVirtio->uFeaturesAccepted >> 32) & 0xffffffff;
    680                     LogFunc(("Guest read  0x%8x from HI DWORD of uFeaturesAccepted\n", *(uint32_t *)pv));
     692                    val = (pVirtio->uDriverFeatures >> 32) & 0xffffffff;
     693                    memcpy((void *)pv, (const void *)&val, cb);
     694                    LogFunc(("Guest read  uDriverFeatures(HI)[%d:%d]: %.*Rhxs\n",
     695                              foff, foff + cb, cb, pv));
    681696                    break;
     697                default:
     698                    Log(("Guest read uDriverFeatures with out of range selector (%d), returning 0\n",
     699                         pVirtio->uDriverFeaturesSelect));
    682700            }
    683701        }
    684702    }
    685     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uNumQueues))
     703    else if (COMMON_CFG(uNumQueues))
    686704    {
    687705        if (fWrite)
    688         {
    689             AssertMsgFailed(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n"));
    690         }
     706            Log(("Guest attempted to write readonly virtio_pci_common_cfg.num_queues\n"));
    691707        else
    692708        {
     
    695711        }
    696712    }
    697     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceStatus))
     713    else if (COMMON_CFG(uDeviceStatus))
    698714    {
    699715        if (fWrite) /* Guest WRITE pCommonCfg->uDeviceStatus */
     
    712728        }
    713729    }
    714     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uMsixConfig))
    715     {
    716         ACCESSOR(uMsixConfig, uint32_t);
    717     }
    718     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDeviceFeatureSelect))
    719     {
    720         ACCESSOR(uFeaturesOfferedSelect, uint32_t);
    721     }
    722     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uDriverFeatureSelect))
    723     {
    724         ACCESSOR(uFeaturesAcceptedSelect, uint32_t);
    725     }
    726     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uConfigGeneration))
    727     {
    728         ACCESSOR_READONLY(uConfigGeneration, uint8_t);
    729     }
    730     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueSelect))
    731     {
    732         ACCESSOR(uQueueSelect, uint16_t);
    733     }
    734     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueSize))
    735     {
    736         ACCESSOR_WITH_IDX(uQueueSize, uint16_t, pVirtio->uQueueSelect);
    737     }
    738     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueMsixVector))
    739     {
    740         ACCESSOR_WITH_IDX(uQueueMsixVector, uint16_t, pVirtio->uQueueSelect);
    741     }
    742     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueEnable))
    743     {
    744         ACCESSOR_WITH_IDX(uQueueEnable, uint16_t, pVirtio->uQueueSelect);
    745     }
    746     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueNotifyOff))
    747     {
    748         ACCESSOR_READONLY_WITH_IDX(uQueueNotifyOff, uint16_t, pVirtio->uQueueSelect);
    749     }
    750     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueDesc))
    751     {
    752         ACCESSOR_WITH_IDX(uQueueDesc, uint64_t, pVirtio->uQueueSelect);
    753     }
    754     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueAvail))
    755     {
    756         ACCESSOR_WITH_IDX(uQueueAvail, uint64_t, pVirtio->uQueueSelect);
    757     }
    758     else if (uoff == RT_OFFSETOF(VIRTIO_PCI_COMMON_CFG_T, uQueueUsed))
    759     {
    760         ACCESSOR_WITH_IDX(uQueueUsed, uint64_t, pVirtio->uQueueSelect);
     730    else if (COMMON_CFG(uMsixConfig))
     731    {
     732        ACCESSOR(uMsixConfig);
     733    }
     734    else if (COMMON_CFG(uDeviceFeaturesSelect))
     735    {
     736        ACCESSOR(uDeviceFeaturesSelect);
     737    }
     738    else if (COMMON_CFG(uDriverFeaturesSelect))
     739    {
     740        ACCESSOR(uDriverFeaturesSelect);
     741    }
     742    else if (COMMON_CFG(uConfigGeneration))
     743    {
     744        ACCESSOR_READONLY(uConfigGeneration);
     745    }
     746    else if (COMMON_CFG(uQueueSelect))
     747    {
     748        ACCESSOR(uQueueSelect);
     749    }
     750    else if (COMMON_CFG(uQueueSize))
     751    {
     752        ACCESSOR_WITH_IDX(uQueueSize, pVirtio->uQueueSelect);
     753    }
     754    else if (COMMON_CFG(uQueueMsixVector))
     755    {
     756        ACCESSOR_WITH_IDX(uQueueMsixVector, pVirtio->uQueueSelect);
     757    }
     758    else if (COMMON_CFG(uQueueEnable))
     759    {
     760        ACCESSOR_WITH_IDX(uQueueEnable, pVirtio->uQueueSelect);
     761    }
     762    else if (COMMON_CFG(uQueueNotifyOff))
     763    {
     764        ACCESSOR_READONLY_WITH_IDX(uQueueNotifyOff, pVirtio->uQueueSelect);
     765    }
     766    else if (COMMON_CFG(uQueueDesc))
     767    {
     768        ACCESSOR_WITH_IDX(uQueueDesc, pVirtio->uQueueSelect);
     769    }
     770    else if (COMMON_CFG(uQueueAvail))
     771    {
     772        ACCESSOR_WITH_IDX(uQueueAvail, pVirtio->uQueueSelect);
     773    }
     774    else if (COMMON_CFG(uQueueUsed))
     775    {
     776        ACCESSOR_WITH_IDX(uQueueUsed, pVirtio->uQueueSelect);
    761777    }
    762778    else
    763779    {
    764 
    765         AssertMsgFailed(("virtio: Bad common cfg offset   \n"));
     780        LogFunc(("Bad access by guest to virtio_pci_common_cfg: uoff=%d, cb=%d\n", uoff, cb));
     781        rv = VERR_ACCESS_DENIED;
    766782    }
    767783    return rv;
     
    786802
    787803//#ifdef LOG_ENABLED
    788 //    LogFlowFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
     804//    LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
    789805//#endif
    790806
    791     /* Note: The notify capability is handled differently as per VirtIO 1.0 spec 4.1.4.4 */
    792 
    793     off_t uoff = 0;
    794     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, VIRTIO_PCI_COMMON_CFG_T, pCommonCfg,  uoff);
    795     MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    VIRTIO_PCI_ISR_CAP_T,    pIsrCap,     uoff);
    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     }
    804     if (pCommonCfg)
    805         virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uoff, pv);
    806     else if (pIsrCap)
     807    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap,     fDevSpecific);
     808    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, pVirtio->pCommonCfgCap,  fCommonCfg);
     809    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    pVirtio->pIsrCap,        fIsrCap);
     810
     811    if (fDevSpecific)
     812    {
     813        uint32_t uDevSpecificDataOffset = GCPhysAddr - pVirtio->pGcPhysDeviceCap;
     814        rc = pVirtio->virtioCallbacks.pfnVirtioDevCapRead(pDevIns, uDevSpecificDataOffset, pv, cb);
     815    }
     816    else
     817    if (fCommonCfg)
     818    {
     819        uint32_t uCommonCfgDataOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg;
     820        virtioCommonCfgAccessed(pVirtio, 0 /* fWrite */, uCommonCfgDataOffset, cb, pv);
     821    }
     822    else
     823    if (fIsrCap)
    807824    {
    808825        *(uint8_t *)pv = pVirtio->fQueueInterrupt | pVirtio->fDeviceConfigInterrupt << 1;
     
    811828    else {
    812829
    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));
     830        AssertMsgFailed(("virtio: Read outside of capabilities region: GCPhysAddr=%RGp cb=%RGp\n", GCPhysAddr, cb));
    816831    }
    817832    return rc;
     
    831846PDMBOTHCBDECL(int) virtioR3MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
    832847{
    833 
    834848    RT_NOREF(pvUser);
    835849    PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
     
    839853//    LogFunc(("pVirtio=%#p GCPhysAddr=%RGp pv=%#p{%.*Rhxs} cb=%u\n", pVirtio, GCPhysAddr, pv, cb, pv, cb));
    840854//#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    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysDeviceCap, pVirtio->pDeviceCap,     fDevSpecific);
     857    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysCommonCfg, pVirtio->pCommonCfgCap,  fCommonCfg);
     858    MATCH_VIRTIO_CAP_STRUCT(pVirtio->pGcPhysIsrCap,    pVirtio->pIsrCap,        fIsrCap);
     859
     860    if (fDevSpecific)
     861    {
     862        uint32_t uDevSpecificDataOffset = GCPhysAddr - pVirtio->pGcPhysDeviceCap;
     863        rc = pVirtio->virtioCallbacks.pfnVirtioDevCapWrite(pDevIns, uDevSpecificDataOffset, pv, cb);
     864    }
     865    else
     866    if (fCommonCfg)
     867    {
     868        uint32_t uCommonCfgDataOffset = GCPhysAddr - pVirtio->pGcPhysCommonCfg;
     869        virtioCommonCfgAccessed(pVirtio, 1 /* fWrite */, uCommonCfgDataOffset, cb, pv);
     870    }
     871    else
     872    if (fIsrCap)
    855873    {
    856874        pVirtio->fQueueInterrupt = (*(uint8_t *)pv) & 1;
     
    861879    else
    862880    {
    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     }
    867 
     881       LogFunc(("virtio: Write outside of capabilities region:\nGCPhysAddr=%RGp cb=%RGp,", GCPhysAddr, cb));
     882    }
    868883    return rc;
    869884}
     
    899914                GCPhysAddress, cb, iRegion));
    900915        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);
     916        pVirtio->pGcPhysCommonCfg = GCPhysAddress + pVirtio->pCommonCfgCap->uOffset;
     917        pVirtio->pGcPhysNotifyCap = GCPhysAddress + pVirtio->pNotifyCap->pciCap.uOffset;
     918        pVirtio->pGcPhysIsrCap    = GCPhysAddress + pVirtio->pIsrCap->uOffset;
     919        if (pVirtio->fHaveDevSpecificCap)
     920            pVirtio->pGcPhysDeviceCap = GCPhysAddress + pVirtio->pDeviceCap->uOffset;
    906921    }
    907922    return rc;
     
    926941    PVIRTIOSTATE pVirtio = PDMINS_2_DATA(pDevIns, PVIRTIOSTATE);
    927942
    928     if (uAddress == pVirtio->uPciCfgDataOff)
     943    if (uAddress == (uint64_t)&pVirtio->pPciCfgCap->uPciCfgData)
    929944    {
    930945        /* VirtIO 1.0 spec section 4.1.4.7 describes a required alternative access capability
     
    10181033static uint64_t virtioGetHostFeatures(PVIRTIOSTATE pVirtio)
    10191034{
    1020     return pVirtio->uFeaturesAccepted;
     1035    return pVirtio->uDriverFeatures;
    10211036}
    10221037
     
    10281043 *
    10291044 * @param   pState              Virtio state
    1030  * @param   uFeaturesOffered    Feature bits (0-63) to set
    1031  */
    1032 
    1033 void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered)
    1034 {
    1035     pVirtio->uFeaturesOffered = VIRTIO_F_VERSION_1 | uFeaturesOffered;
     1045 * @param   uDeviceFeatures    Feature bits (0-63) to set
     1046 */
     1047
     1048void virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uDeviceFeatures)
     1049{
     1050    pVirtio->uDeviceFeatures = VIRTIO_F_VERSION_1 | uDeviceFeatures;
    10361051}
    10371052
     
    10981113    pVirtio->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    10991114    pVirtio->uDeviceStatus = 0;
     1115    pVirtio->cbDevSpecificCap = cbDevSpecificCap;
    11001116    pVirtio->uVirtioCapRegion = uVirtioCapRegion;
    11011117    pVirtio->fHaveDevSpecificCap = fHaveDevSpecificCap;
     
    11371153#endif
    11381154
    1139     uint8_t uCfgCapOffset = 0x40;
    1140     PVIRTIO_PCI_NOTIFY_CAP_T pNotifyCap;
    1141     PVIRTIO_PCI_CAP_T pCommonCfg, pIsrCap, pDeviceCap;
    1142     uint32_t cbVirtioCaps = 0;
     1155#define CFGADDR2IDX(addr) ((uint64_t)addr - (uint64_t)&pVirtio->dev.abConfig)
    11431156
    11441157    /* The following capability mapped via VirtIO 1.0: struct virtio_pci_cfg_cap (VIRTIO_PCI_CFG_CAP_T)
     
    11481161     * therefore does not contribute to the capabilities region (BAR) the other capabilities use.
    11491162     */
    1150     pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1151     pVirtio->uPciCfgDataOff = uCfgCapOffset + RT_OFFSETOF(VIRTIO_PCI_CFG_CAP_T, uPciCfgData);
    1152     PVIRTIO_PCI_CAP_T pCfg = (PVIRTIO_PCI_CAP_T)pVirtio->pPciCfgCap;
     1163    PVIRTIO_PCI_CAP_T pCfg;
     1164
     1165    /* Common capability (VirtIO 1.0 spec) */
     1166    pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[0x40];
     1167    pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG;
    11531168    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1154     pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_CFG_CAP_T);
     1169    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
     1170    pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen;
     1171    pCfg->uBar     = uVirtioCapRegion;
     1172    pCfg->uOffset  = 0;
     1173    pCfg->uLength  = sizeof(VIRTIO_PCI_COMMON_CFG_T);
     1174    pVirtio->pCommonCfgCap = pCfg;
     1175
     1176    /* Notify capability (VirtIO 1.0 spec) */
     1177    pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext];
     1178    pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG;
     1179    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
     1180    pCfg->uCapLen  = sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
     1181    pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen;
     1182    pCfg->uBar     = uVirtioCapRegion;
     1183    pCfg->uOffset  = pVirtio->pCommonCfgCap->uOffset + pVirtio->pCommonCfgCap->uLength;
     1184    pCfg->uLength  = 4; /* This needs to be calculated differently */
     1185    pVirtio->pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)pCfg;
     1186    pVirtio->pNotifyCap->uNotifyOffMultiplier = uNotifyOffMultiplier;
     1187
     1188    /* ISR capability (VirtIO 1.0 spec) */
     1189    pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext];
     1190    pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG;
     1191    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
     1192    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
     1193    pCfg->uCapNext = CFGADDR2IDX(pCfg) + pCfg->uCapLen;
     1194    pCfg->uBar     = uVirtioCapRegion;
     1195    pCfg->uOffset  = pVirtio->pNotifyCap->pciCap.uOffset + pVirtio->pNotifyCap->pciCap.uLength;
     1196    pCfg->uLength  = sizeof(uint32_t);
     1197    pVirtio->pIsrCap = pCfg;
     1198
     1199    /* PCI Cfg capability (VirtIO 1.0 spec) */
     1200    pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext];
     1201    pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG;
     1202    pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    11551203    pCfg->uCapLen  = sizeof(VIRTIO_PCI_CFG_CAP_T);
    1156     pCfg->uCfgType = VIRTIO_PCI_CAP_PCI_CFG;
     1204    pCfg->uCapNext = (fMsiSupport || pVirtio->fHaveDevSpecificCap) ? CFGADDR2IDX(pCfg) + pCfg->uCapLen : 0;
    11571205    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 */
    1160     cbVirtioCaps  += pCfg->uLength;
    1161 
    1162     /* Following capability mapped via VirtIO 1.0: struct virtio_pci_common_cfg (VIRTIO_PCI_COMMON_CFG_T)*/
    1163     pCfg = pCommonCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1164     pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1165     pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T);
    1166     pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    1167     pCfg->uCfgType = VIRTIO_PCI_CAP_COMMON_CFG;
    1168     pCfg->uBar     = uVirtioCapRegion;
    1169     pCfg->uOffset  = pVirtio->uCommonCfgOffset = pVirtio->pPciCfgCap->pciCap.uOffset
    1170                                                + pVirtio->pPciCfgCap->pciCap.uLength;
    1171     pCfg->uLength  = sizeof(VIRTIO_PCI_COMMON_CFG_T);
    1172     cbVirtioCaps  += pCfg->uLength;
    1173 
    1174     /* Following capability mapped via VirtIO 1.0: struct virtio_pci_notify_cap (VIRTIO_PCI_NOTIFY_CAP_T)*/
    1175     pNotifyCap = (PVIRTIO_PCI_NOTIFY_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1176     pCfg = (PVIRTIO_PCI_CAP_T)pNotifyCap;
    1177     pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1178     pCfg->uCapNext = uCfgCapOffset += sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    1179     pCfg->uCapLen  = sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    1180     pCfg->uCfgType = VIRTIO_PCI_CAP_NOTIFY_CFG;
    1181     pCfg->uBar     = uVirtioCapRegion;
    1182     pCfg->uOffset  = pVirtio->uNotifyCapOffset = pCommonCfg->uOffset + sizeof(VIRTIO_PCI_COMMON_CFG_T);
    1183     pCfg->uLength  = sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    1184     pNotifyCap->uNotifyOffMultiplier = uNotifyOffMultiplier;
    1185     cbVirtioCaps  += pCfg->uLength;
    1186 
    1187     /* Following capability mapped via VirtIO 1.0: uint8_t (VIRTIO_PCI_ISR_CAP_T)  */
    1188     pCfg = pIsrCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
    1189     pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1190     pCfg->uCapNext = (uint8_t)(fMsiSupport || pVirtio->fHaveDevSpecificCap
    1191                                ? (uCfgCapOffset += sizeof(VIRTIO_PCI_ISR_CAP_T)) : 0);
    1192     pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    1193     pCfg->uCfgType = VIRTIO_PCI_CAP_ISR_CFG;
    1194     pCfg->uBar     = uVirtioCapRegion;
    1195     pCfg->uOffset  = pVirtio->uIsrCapOffset = pNotifyCap->pciCap.uOffset + sizeof(VIRTIO_PCI_NOTIFY_CAP_T);
    1196     pCfg->uLength  = sizeof(VIRTIO_PCI_ISR_CAP_T);
    1197     cbVirtioCaps  += pCfg->uLength;
     1206    pCfg->uOffset  = pVirtio->pIsrCap->uOffset + pVirtio->pIsrCap->uLength;
     1207    pCfg->uLength  = 4;  /* Initialize a non-zero 4-byte aligned so Linux virtio_pci module recognizes this cap */
     1208    pVirtio->pPciCfgCap = (PVIRTIO_PCI_CFG_CAP_T)pCfg;
    11981209
    11991210    if (pVirtio->fHaveDevSpecificCap)
    12001211    {
    12011212        /* Following capability mapped via VirtIO 1.0: struct virtio_pci_dev_cap (VIRTIODEVCAP)*/
    1202         pCfg = pDeviceCap = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[uCfgCapOffset];
     1213        pCfg = (PVIRTIO_PCI_CAP_T)&pVirtio->dev.abConfig[pCfg->uCapNext];
     1214        pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG;
    12031215        pCfg->uCapVndr = VIRTIO_PCI_CAP_ID_VENDOR;
    1204         pCfg->uCapNext = (uint8_t)(fMsiSupport ? (uCfgCapOffset += sizeof(VIRTIO_PCI_CAP_T)) : 0);
    12051216        pCfg->uCapLen  = sizeof(VIRTIO_PCI_CAP_T);
    1206         pCfg->uCfgType = VIRTIO_PCI_CAP_DEVICE_CFG;
     1217        pCfg->uCapNext = fMsiSupport ? CFGADDR2IDX(pCfg) + pCfg->uCapLen : 0;
    12071218        pCfg->uBar     = uVirtioCapRegion;
    1208         pCfg->uOffset  = pVirtio->uDeviceCapOffset = pIsrCap->uOffset + sizeof(VIRTIO_PCI_ISR_CAP_T);
     1219        pCfg->uOffset  = pVirtio->pIsrCap->uOffset + pVirtio->pIsrCap->uLength;
    12091220        pCfg->uLength  = cbDevSpecificCap;
    1210         cbVirtioCaps  += pCfg->uLength;
     1221        pVirtio->pDeviceCap = pCfg;
    12111222    }
    12121223
     
    12191230        PDMMSIREG aMsiReg;
    12201231        RT_ZERO(aMsiReg);
    1221         aMsiReg.iMsixCapOffset  = uCfgCapOffset;
     1232        aMsiReg.iMsixCapOffset  = pCfg->uCapNext;
    12221233        aMsiReg.iMsixNextOffset = 0;
    12231234        aMsiReg.iMsixBar        = 0;
     
    12291240    }
    12301241
    1231     rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, cbVirtioCaps,
     1242    rc = PDMDevHlpPCIIORegionRegister(pDevIns, uVirtioCapRegion, 4096,
    12321243                                      PCI_ADDRESS_SPACE_MEM, virtioR3Map);
    12331244    if (RT_FAILURE(rc))
  • trunk/src/VBox/Devices/VirtIO/Virtio_1_0.h

    r80108 r80148  
    141141
    142142    /* Per device fields */
    143     uint32_t  uDeviceFeatureSelect;   /** RW (driver selects device features)         */
    144     uint32_t  uDeviceFeature;         /** RO (device reports features to driver)      */
    145     uint32_t  uDriverFeatureSelect;   /** RW (driver selects driver features)         */
    146     uint32_t  uDriverFeature;         /** RW (driver accepts device features)         */
     143    uint32_t  uDeviceFeaturesSelect;   /** RW (driver selects device features)         */
     144    uint32_t  uDeviceFeatures;         /** RO (device reports features to driver)      */
     145    uint32_t  uDriverFeaturesSelect;   /** RW (driver selects driver features)         */
     146    uint32_t  uDriverFeatures;         /** RW (driver accepts device features)         */
    147147    uint16_t  uMsixConfig;            /** RW (driver sets MSI-X config vector)        */
    148148    uint16_t  uNumQueues;             /** RO (device specifies max queues)            */
     
    177177} VIRTIO_PCI_NOTIFY_CAP_T, *PVIRTIO_PCI_NOTIFY_CAP_T;
    178178
    179 typedef uint8_t VIRTIO_PCI_ISR_CAP_T, *PVIRTIO_PCI_ISR_CAP_T;
    180 
    181179/*
    182180 * If the client of this library has any device-specific capabilities, it must define
     
    278276 */
    279277
    280 typedef DECLCALLBACK(int)   FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite);
     278 /**
     279 * VirtIO Device-specific capabilities read callback
     280 * (other VirtIO capabilities and features are handled in VirtIO implementation)
     281 *
     282 * @param   pDevIns     The device instance.
     283 * @param   offset      Offset within device specific capabilities struct
     284 * @param   pvBuf       Buffer in which to save read data
     285 * @param   cbWrite     Number of bytes to write
     286 */
     287typedef DECLCALLBACK(int)   FNVIRTIODEVCAPWRITE(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite);
    281288typedef FNVIRTIODEVCAPWRITE *PFNVIRTIODEVCAPWRITE;
    282289
    283 typedef DECLCALLBACK(int)   FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead);
     290/**
     291 * VirtIO Device-specific capabilities read callback
     292 * (other VirtIO capabilities and features are handled in VirtIO implementation)
     293 *
     294 * @param   pDevIns     The device instance.
     295 * @param   offset      Offset within device specific capabilities struct
     296 * @param   pvBuf       Buffer in which to save read data
     297 * @param   cbRead      Number of bytes to read
     298 */
     299typedef DECLCALLBACK(int)   FNVIRTIODEVCAPREAD(PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead);
    284300typedef FNVIRTIODEVCAPREAD *PFNVIRTIODEVCAPREAD;
    285301
     
    289305{
    290306     DECLCALLBACKMEMBER(int,      pfnVirtioDevCapRead)
    291                                       (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbRead);
     307                                      (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbRead);
    292308     DECLCALLBACKMEMBER(int,      pfnVirtioDevCapWrite)
    293                                       (PPDMDEVINS pDevIns, RTGCPHYS GCPhysAddr, const void *pvBuf, size_t cbWrite);
     309                                      (PPDMDEVINS pDevIns, uint32_t uOffset, const void *pvBuf, size_t cbWrite);
    294310} VIRTIOCALLBACKS, *PVIRTALCALLBACKS;
    295311/** @} */
     
    307323    char                         szInstance[8];          /**< Instance name, e.g. VNet#1. */
    308324
    309     bool                         fHaveDevSpecificCap;
    310325#if HC_ARCH_BITS != 64
    311326    uint32_t                     padding1;
     
    352367    VQUEUE                       Queues[VIRTIO_MAX_NQUEUES];
    353368
    354     uint32_t                     uFeaturesOfferedSelect;     /** Select hi/lo 32-bit uFeaturesOffered to r/w */
    355     uint64_t                     uFeaturesOffered;           /** Host features offered */
    356     uint32_t                     uFeaturesAcceptedSelect;    /** Selects hi/lo 32-bit uFeaturesAccepted to r/w*/
    357     uint64_t                     uFeaturesAccepted;          /** Host features accepted by guest */
     369    uint32_t                     uDeviceFeaturesSelect;     /** Select hi/lo 32-bit uDeviceFeatures to r/w */
     370    uint64_t                     uDeviceFeatures;           /** Host features offered */
     371    uint32_t                     uDriverFeaturesSelect;     /** Selects hi/lo 32-bit uDriverFeatures to r/w*/
     372    uint64_t                     uDriverFeatures;           /** Host features accepted by guest */
    358373
    359374    uint32_t                     uMsixConfig;
     
    371386    uint64_t                     uQueueUsed[MAX_QUEUES];
    372387
    373     /** Base address of PCI capabilities */
    374     RTGCPHYS                     GCPhysPciCapBase;
    375388
    376389    uint8_t                      uVirtioCapRegion;      /* Client assigned  Virtio dedicated capabilities region*/
     
    380393    PFNPCICONFIGWRITE            pfnPciConfigWriteOld;
    381394
    382 
    383     uint32_t                     uNotifyCapOffset;
    384     uint32_t                     uIsrCapOffset;
    385     uint32_t                     uPciCfgCapOffset;
    386     uint32_t                     uDeviceCapOffset;
    387     uint32_t                     uCommonCfgOffset;
     395    bool                         fHaveDevSpecificCap;
     396    uint32_t                     cbDevSpecificCap;
    388397
    389398    PVIRTIO_PCI_CFG_CAP_T        pPciCfgCap;            /** Pointer to struct in configuration area */
    390 
    391     PVIRTIO_PCI_COMMON_CFG_T     pGcPhysCommonCfg;      /** Pointer to MMIO mapped struct */
    392     PVIRTIO_PCI_NOTIFY_CAP_T     pGcPhysNotifyCap;      /** Pointer to MMIO mapped struct */
    393     PVIRTIO_PCI_ISR_CAP_T        pGcPhysIsrCap;         /** Pointer to MMIO mapped struct */
    394     PVIRTIO_PCI_CFG_CAP_T        pGcPhysPciCfgCap;      /** Pointer to MMIO mapped struct */
    395     PVIRTIO_PCI_DEVICE_CAP_T     pGcPhysDeviceCap;      /** Pointer to MMIO mapped struct */
     399    PVIRTIO_PCI_NOTIFY_CAP_T     pNotifyCap;            /** Pointer to struct in configuration area */
     400    PVIRTIO_PCI_CAP_T            pCommonCfgCap;         /** Pointer to struct in configuration area */
     401    PVIRTIO_PCI_CAP_T            pIsrCap;               /** Pointer to struct in configuration area */
     402    PVIRTIO_PCI_CAP_T            pDeviceCap;            /** Pointer to struct in configuration area */
     403
     404    /** Base address of PCI capabilities */
     405    RTGCPHYS                     GCPhysPciCapBase;
     406    RTGCPHYS                     pGcPhysCommonCfg;      /** Pointer to MMIO mapped capability data */
     407    RTGCPHYS                     pGcPhysNotifyCap;      /** Pointer to MMIO mapped capability data */
     408    RTGCPHYS                     pGcPhysIsrCap;         /** Pointer to MMIO mapped capability data */
     409    RTGCPHYS                     pGcPhysDeviceCap;      /** Pointer to MMIO mapped capability data */
    396410
    397411    bool fDeviceConfigInterrupt;
     
    416430int     virtioRaiseInterrupt(PVIRTIOSTATE pVirtio, int rcBusy, uint8_t uint8_tIntCause);
    417431void    virtioNotify(PVIRTIOSTATE pVirtio);
    418 void    virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uFeaturesOffered);
     432void    virtioSetHostFeatures(PVIRTIOSTATE pVirtio, uint64_t uDeviceFeatures);
    419433
    420434PVQUEUE virtioAddQueue(PVIRTIOSTATE pVirtio, unsigned uSize, PFNVIRTIOQUEUECALLBACK pfnCallback, const char *pcszName);
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