VirtualBox

Changeset 81034 in vbox


Ignore:
Timestamp:
Sep 26, 2019 8:04:13 PM (5 years ago)
Author:
vboxsync
Message:

DevPci: Share more of the setirq code for bridges and added cycle (bogus data) detection. bugref:9218

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Bus/DevPCI.cpp

    r81033 r81034  
    15111511     * of our parent passing the device which asserted the interrupt instead of the device of the bridge.
    15121512     */
    1513 #if 1
    1514     PDEVPCIBUSCC const  pBridgeBusCC  = PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC); /* For keep using our own pcihlp.  */
    1515     PPDMDEVINS const    pBridgeDevIns = pDevIns;                                 /* ditto */
    1516 
    1517     PDEVPCIBUS          pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    1518     PPDMDEVINS          pDevInsBus;
    1519     PPDMPCIDEV          pPciDevBus    = pDevIns->apPciDevs[0];
    1520     uint8_t             uDevFnBridge  = pPciDevBus->uDevFn;
    1521     int                 iIrqPinBridge = ((pPciDev->uDevFn >> 3) + iIrq) & 3;
    1522 
    1523     /* Walk the chain until we reach the host bus. */
    1524     Assert(pBus->iBus != 0);
    1525     for (;;)
    1526     {
    1527         /* Get the parent. */
    1528         pDevInsBus = pBridgeBusCC->CTX_SUFF(pPciHlp)->pfnGetBusByNo(pBridgeDevIns, pPciDevBus->Int.s.idxPdmBus);
    1529         AssertLogRelReturnVoid(pDevInsBus);
    1530 
    1531         pBus       = PDMINS_2_DATA(pDevInsBus, PDEVPCIBUS);
    1532         pPciDevBus = pDevInsBus->apPciDevs[0];
    1533         if (pBus->iBus == 0)
    1534             break;
    1535 
    1536         uDevFnBridge  = pPciDevBus->uDevFn;
    1537         iIrqPinBridge = ((uDevFnBridge >> 3) + iIrqPinBridge) & 3;
    1538     }
    1539 
     1513    PDEVPCIBUS pBus;
     1514    uint8_t    uDevFnBridge;
     1515    int        iIrqPinBridge;
     1516    PPDMDEVINS pDevInsBus = devpcibridgeCommonSetIrqRootWalk(pDevIns, pPciDev, iIrq, &pBus, &uDevFnBridge, &iIrqPinBridge);
     1517    AssertReturnVoid(pDevInsBus);
    15401518    AssertMsg(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
    15411519    Assert(pDevInsBus->pReg == &g_DevicePCI);
     1520
    15421521    pciSetIrqInternal(pDevInsBus, DEVPCIBUS_2_DEVPCIROOT(pBus), PDMINS_2_DATA_CC(pDevInsBus, PDEVPCIBUSCC),
    15431522                      uDevFnBridge, pPciDev, iIrqPinBridge, iLevel, uTagSrc);
    1544 #else  /* (old code for reference) */
    1545     PDEVPCIBUS   pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    1546     PDEVPCIBUSCC pBusCC        = PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC);
    1547     PPDMPCIDEV   pPciDevBus    = pPciDev;
    1548     int          iIrqPinBridge = iIrq;
    1549     uint8_t      uDevFnBridge  = 0;
    1550 
    1551     /* Walk the chain until we reach the host bus. */
    1552     do
    1553     {
    1554         uDevFnBridge  = pBus->PciDev.uDevFn;
    1555         iIrqPinBridge = ((pPciDevBus->uDevFn >> 3) + iIrqPinBridge) & 3;
    1556 
    1557         /* Get the parent. */
    1558         pBus = pBus->PciDev.Int.s.CTX_SUFF(pBus);
    1559         pPciDevBus = &pBus->PciDev;
    1560     } while (pBus->iBus != 0);
    1561 
    1562     AssertMsg(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
    1563     pciSetIrqInternal(pDevIns, DEVPCIBUS_2_DEVPCIROOT(pBus), pBusCC, uDevFnBridge, pPciDev, iIrqPinBridge, iLevel, uTagSrc);
    1564 #endif
    15651523}
    15661524
  • trunk/src/VBox/Devices/Bus/DevPciIch9.cpp

    r81033 r81034  
    133133}
    134134
     135/**
     136 * Worker for ich9pcibridgeSetIrq and pcibridgeSetIrq that walks up to the root
     137 * bridges and permutates iIrq accordingly.
     138 *
     139 * See ich9pciBiosInitAllDevicesOnBus for corresponding configuration code.
     140 */
     141DECLHIDDEN(PPDMDEVINS) devpcibridgeCommonSetIrqRootWalk(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq,
     142                                                        PDEVPCIBUS *ppBus, uint8_t *puDevFnBridge, int *piIrqPinBridge)
     143{
     144    PDEVPCIBUSCC const  pBridgeBusCC   = PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC); /* For keep using our own pcihlp.  */
     145    PPDMDEVINS const    pBridgeDevIns  = pDevIns;                                 /* ditto */
     146
     147    PDEVPCIBUS          pBus           = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
     148    PPDMDEVINS          pDevInsBus;
     149    PPDMPCIDEV          pPciDevBus     = pDevIns->apPciDevs[0];
     150    uint8_t             uDevFnBridge   = pPciDevBus->uDevFn;
     151    int                 iIrqPinBridge  = ((pPciDev->uDevFn >> 3) + iIrq) & 3;
     152    uint64_t            bmSeen[256/64] = { 0, 0, 0, 0 };
     153    ASMBitSet(bmSeen, RT_MIN(pPciDevBus->Int.s.idxPdmBus, 255));
     154
     155    /* Walk the chain until we reach the host bus. */
     156    Assert(pBus->iBus != 0);
     157    for (;;)
     158    {
     159        /* Get the parent. */
     160        pDevInsBus = pBridgeBusCC->CTX_SUFF(pPciHlp)->pfnGetBusByNo(pBridgeDevIns, pPciDevBus->Int.s.idxPdmBus);
     161        AssertLogRelReturn(pDevInsBus, NULL);
     162
     163        pBus       = PDMINS_2_DATA(pDevInsBus, PDEVPCIBUS);
     164        pPciDevBus = pDevInsBus->apPciDevs[0];
     165        if (pBus->iBus == 0)
     166        {
     167            *ppBus          = pBus;
     168            *puDevFnBridge  = uDevFnBridge;
     169            *piIrqPinBridge = iIrqPinBridge;
     170            return pDevInsBus;
     171        }
     172
     173        uDevFnBridge  = pPciDevBus->uDevFn;
     174        iIrqPinBridge = ((uDevFnBridge >> 3) + iIrqPinBridge) & 3;
     175
     176        /* Make sure that we cannot end up in a loop here: */
     177        AssertMsgReturn(ASMBitTestAndSet(bmSeen, RT_MIN(pPciDevBus->Int.s.idxPdmBus, 255)),
     178                        ("idxPdmBus=%u\n", pPciDevBus->Int.s.idxPdmBus),
     179                        NULL);
     180    }
     181
     182}
     183
    135184static void ich9pcibridgeSetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc)
    136185{
     
    144193     * See ich9pciBiosInitAllDevicesOnBus for corresponding configuration code.
    145194     */
    146 #if 1
    147 /** @todo r=bird: move the lookup code into a separate function and check for
    148  *        loops in the parent bus references.  */
    149     PDEVPCIBUSCC const  pBridgeBusCC  = PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC); /* For keep using our own pcihlp.  */
    150     PPDMDEVINS const    pBridgeDevIns = pDevIns;                                 /* ditto */
    151 
    152     PDEVPCIBUS          pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    153     PPDMDEVINS          pDevInsBus;
    154     PPDMPCIDEV          pPciDevBus    = pDevIns->apPciDevs[0];
    155     uint8_t             uDevFnBridge  = pPciDevBus->uDevFn;
    156     int                 iIrqPinBridge = ((pPciDev->uDevFn >> 3) + iIrq) & 3;
    157 
    158     /* Walk the chain until we reach the host bus. */
    159     Assert(pBus->iBus != 0);
    160     for (;;)
    161     {
    162         /* Get the parent. */
    163         pDevInsBus = pBridgeBusCC->CTX_SUFF(pPciHlp)->pfnGetBusByNo(pBridgeDevIns, pPciDevBus->Int.s.idxPdmBus);
    164         AssertLogRelReturnVoid(pDevInsBus);
    165 
    166         pBus       = PDMINS_2_DATA(pDevInsBus, PDEVPCIBUS);
    167         pPciDevBus = pDevInsBus->apPciDevs[0];
    168         if (pBus->iBus == 0)
    169             break;
    170 
    171         uDevFnBridge  = pPciDevBus->uDevFn;
    172         iIrqPinBridge = ((uDevFnBridge >> 3) + iIrqPinBridge) & 3;
    173     }
    174 
     195    PDEVPCIBUS pBus;
     196    uint8_t    uDevFnBridge;
     197    int        iIrqPinBridge;
     198    PPDMDEVINS pDevInsBus = devpcibridgeCommonSetIrqRootWalk(pDevIns, pPciDev, iIrq, &pBus, &uDevFnBridge, &iIrqPinBridge);
     199    AssertReturnVoid(pDevInsBus);
    175200    AssertMsg(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
    176     Assert(pDevInsBus->pReg == &g_DevicePciIch9);
     201    Assert(pDevInsBus->pReg == &g_DevicePciIch9); /* ASSUMPTION: Same style root bus.  Need callback interface to mix types. */
    177202
    178203    /*
     
    186211    ich9pciSetIrqInternal(pDevInsBus, DEVPCIBUS_2_DEVPCIROOT(pBus), PDMINS_2_DATA_CC(pDevInsBus, PDEVPCIBUSCC),
    187212                          uDevFnBridge, pPciDev, iIrqPinVector, iLevel, uTagSrc);
    188 #else  /* (old code for reference) */
    189     PDEVPCIBUS     pBus          = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
    190     PPDMPCIDEV     pPciDevBus    = pPciDev;
    191     int            iIrqPinBridge = iIrq;
    192     uint8_t        uDevFnBridge  = 0;
    193 
    194     /* Walk the chain until we reach the host bus. */
    195     do
    196     {
    197         uDevFnBridge  = pBus->PciDev.uDevFn;
    198         iIrqPinBridge = ((pPciDevBus->uDevFn >> 3) + iIrqPinBridge) & 3;
    199 
    200         /* Get the parent. */
    201         pBus = pBus->PciDev.Int.s.CTX_SUFF(pBus);
    202         pPciDevBus = &pBus->PciDev;
    203     } while (pBus->iBus != 0);
    204 
    205     AssertMsgReturnVoid(pBus->iBus == 0, ("This is not the host pci bus iBus=%d\n", pBus->iBus));
    206 
    207     /*
    208      * For MSI/MSI-X enabled devices the iIrq doesn't denote the pin but rather a vector which is completely
    209      * orthogonal to the pin based approach. The vector is not subject to the pin based routing with PCI bridges.
    210      */
    211     int iIrqPinVector = iIrqPinBridge;
    212     if (   MsiIsEnabled(pPciDev)
    213         || MsixIsEnabled(pPciDev))
    214         iIrqPinVector = iIrq;
    215     ich9pciSetIrqInternal(pDevIns, DEVPCIBUS_2_DEVPCIROOT(pBus), PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC),
    216                           uDevFnBridge, pPciDev, iIrqPinVector, iLevel, uTagSrc);
    217 #endif
    218213}
    219214
     
    10051000
    10061001/**
    1007  * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3}
     1002 * @interface_method_impl{PDMPCIBUSREGR3,pfnRegisterR3}
    10081003 */
    10091004DECLCALLBACK(int) devpciR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
     
    10171012
    10181013/**
    1019  * @interface_method_impl{PDMPCIBUSREG,pfnRegisterR3}
     1014 * @interface_method_impl{PDMPCIBUSREGR3,pfnRegisterR3}
    10201015 */
    10211016DECLCALLBACK(int) devpcibridgeR3CommonRegisterDevice(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
  • trunk/src/VBox/Devices/Bus/DevPciInternal.h

    r81033 r81034  
    198198    PDMINS_2_DATA_CC(pDevIns, PDEVPCIBUSCC)->CTX_SUFF(pPciHlp)->pfnUnlock(pDevIns)
    199199
     200
     201DECLHIDDEN(PPDMDEVINS)     devpcibridgeCommonSetIrqRootWalk(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq,
     202                                                            PDEVPCIBUS *ppBus, uint8_t *puDevFnBridge, int *piIrqPinBridge);
    200203
    201204#ifdef IN_RING3
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