VirtualBox

Changeset 64373 in vbox for trunk/src/VBox/Devices/Samples


Ignore:
Timestamp:
Oct 23, 2016 7:03:39 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111478
Message:

PDM,Devices: Support for multiple PCI devices/function in a single PDM device.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Samples/DevPlayground.cpp

    r64354 r64373  
    4141*********************************************************************************************************************************/
    4242/**
    43  * Device Instance Data.
     43 * Playground device per function (sub-device) data.
     44 */
     45typedef struct VBOXPLAYGROUNDDEVICEFUNCTION
     46{
     47    /** The PCI devices. */
     48    PDMPCIDEV   PciDev;
     49    /** The function number. */
     50    uint8_t     iFun;
     51    /** Device function name. */
     52    char        szName[31];
     53} VBOXPLAYGROUNDDEVICEFUNCTION;
     54/** Pointer to a PCI function of the playground device. */
     55typedef VBOXPLAYGROUNDDEVICEFUNCTION *PVBOXPLAYGROUNDDEVICEFUNCTION;
     56
     57/**
     58 * Playground device instance data.
    4459 */
    4560typedef struct VBOXPLAYGROUNDDEVICE
    4661{
    47     /** The PCI device. */
    48     PCIDEVICE           PciDev;
     62    /** PCI device functions. */
     63    VBOXPLAYGROUNDDEVICEFUNCTION aPciFuns[8];
    4964} VBOXPLAYGROUNDDEVICE;
     65/** Pointer to the instance data of a playground device instance. */
    5066typedef VBOXPLAYGROUNDDEVICE *PVBOXPLAYGROUNDDEVICE;
    5167
     
    8096 * @callback_method_impl{FNPCIIOREGIONMAP}
    8197 */
    82 static DECLCALLBACK(int)
    83 devPlaygroundMap(PPCIDEVICE pPciDev, int iRegion, RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
    84 {
    85     RT_NOREF(enmType, cb);
     98static DECLCALLBACK(int) devPlaygroundMap(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, uint32_t iRegion,
     99                                          RTGCPHYS GCPhysAddress, RTGCPHYS cb, PCIADDRESSSPACE enmType)
     100{
     101    RT_NOREF(pPciDev, enmType, cb);
    86102
    87103    switch (iRegion)
     
    92108            if (GCPhysAddress == NIL_RTGCPHYS)
    93109                return VINF_SUCCESS; /* We ignore the unmap notification. */
    94             return PDMDevHlpMMIOExMap(pPciDev->pDevIns, pPciDev, iRegion, GCPhysAddress);
     110            return PDMDevHlpMMIOExMap(pDevIns, pPciDev, iRegion, GCPhysAddress);
    95111
    96112        default:
     
    131147     */
    132148    PVBOXPLAYGROUNDDEVICE pThis = PDMINS_2_DATA(pDevIns, PVBOXPLAYGROUNDDEVICE);
    133     PCIDevSetVendorId(&pThis->PciDev, 0x80ee);
    134     PCIDevSetDeviceId(&pThis->PciDev, 0xde4e);
    135     PCIDevSetClassBase(&pThis->PciDev, 0x07);   /* communications device */
    136     PCIDevSetClassSub(&pThis->PciDev, 0x80);    /* other communications device */
    137149
    138150    /*
     
    144156     * PCI device setup.
    145157     */
    146     int rc = PDMDevHlpPCIRegister(pDevIns, &pThis->PciDev);
    147     if (RT_FAILURE(rc))
    148         return rc;
    149 
    150     /* First region. */
    151     RTGCPHYS const cbFirst = 8*_1G64;
    152     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0, cbFirst,
    153                                       (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
    154                                       devPlaygroundMap);
    155     AssertLogRelRCReturn(rc, rc);
    156     rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pThis->PciDev, 0, cbFirst,
    157                                     IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR0",
    158                                     NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
    159                                     NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
    160                                     NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
    161     AssertLogRelRCReturn(rc, rc);
    162 
    163     /* Second region. */
    164     RTGCPHYS const cbSecond = 256*_1G64;
    165     rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, cbSecond,
    166                                       (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
    167                                       devPlaygroundMap);
    168     AssertLogRelRCReturn(rc, rc);
    169     rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pThis->PciDev, 2, cbSecond,
    170                                     IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR2",
    171                                     NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
    172                                     NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
    173                                     NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
    174     AssertLogRelRCReturn(rc, rc);
     158    uint32_t iPciDevNo = PDMPCIDEVREG_DEV_NO_FIRST_UNUSED;
     159    for (uint32_t iPciFun = 0; iPciFun < RT_ELEMENTS(pThis->aPciFuns); iPciFun++)
     160    {
     161        PVBOXPLAYGROUNDDEVICEFUNCTION pFun = &pThis->aPciFuns[iPciFun];
     162        RTStrPrintf(pFun->szName, sizeof(pThis->aPciFuns[iPciFun].PciDev), "playground%u", iPciFun);
     163        pFun->iFun = iPciFun;
     164
     165        PCIDevSetVendorId( &pFun->PciDev, 0x80ee);
     166        PCIDevSetDeviceId( &pFun->PciDev, 0xde4e);
     167        PCIDevSetClassBase(&pFun->PciDev, 0x07);   /* communications device */
     168        PCIDevSetClassSub( &pFun->PciDev, 0x80);   /* other communications device */
     169        int rc = PDMDevHlpPCIRegisterEx(pDevIns, &pFun->PciDev, iPciFun, 0 /*fFlags*/, iPciDevNo, iPciFun,
     170                                        pThis->aPciFuns[iPciFun].szName);
     171        AssertLogRelRCReturn(rc, rc);
     172
     173        /* First region. */
     174        RTGCPHYS const cbFirst = iPciFun == 0 ? 8*_1G64 : iPciFun * _4K;
     175        rc = PDMDevHlpPCIIORegionRegisterEx(pDevIns, &pFun->PciDev, 0, cbFirst,
     176                                            (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
     177                                            devPlaygroundMap);
     178        AssertLogRelRCReturn(rc, rc);
     179        rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pFun->PciDev, 0, cbFirst,
     180                                        IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR0",
     181                                        NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
     182                                        NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
     183                                        NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
     184        AssertLogRelRCReturn(rc, rc);
     185
     186        /* Second region. */
     187        RTGCPHYS const cbSecond = iPciFun == 0  ? 256*_1G64 : iPciFun * _32K;
     188        rc = PDMDevHlpPCIIORegionRegisterEx(pDevIns, &pFun->PciDev, 2, cbSecond,
     189                                            (PCIADDRESSSPACE)(PCI_ADDRESS_SPACE_MEM | PCI_ADDRESS_SPACE_BAR64),
     190                                            devPlaygroundMap);
     191        AssertLogRelRCReturn(rc, rc);
     192        rc = PDMDevHlpMMIOExPreRegister(pDevIns, &pFun->PciDev, 2, cbSecond,
     193                                        IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU, "PG-BAR2",
     194                                        NULL /*pvUser*/,  devPlaygroundMMIOWrite, devPlaygroundMMIORead, NULL /*pfnFill*/,
     195                                        NIL_RTR0PTR /*pvUserR0*/, NULL /*pszWriteR0*/, NULL /*pszReadR0*/, NULL /*pszFillR0*/,
     196                                        NIL_RTRCPTR /*pvUserRC*/, NULL /*pszWriteRC*/, NULL /*pszReadRC*/, NULL /*pszFillRC*/);
     197        AssertLogRelRCReturn(rc, rc);
     198
     199        /* Subsequent function should use the same major as the previous one. */
     200        iPciDevNo = PDMPCIDEVREG_DEV_NO_SAME_AS_PREV;
     201    }
    175202
    176203    return VINF_SUCCESS;
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