VirtualBox

Changeset 36092 in vbox for trunk/src/VBox/Devices/Bus


Ignore:
Timestamp:
Feb 26, 2011 9:07:51 PM (14 years ago)
Author:
vboxsync
Message:

PCI: simplified BIOS init, fixed routing for nontrivial topologies

File:
1 edited

Legend:

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

    r36079 r36092  
    9696    PCIBUS              aPciBus;
    9797
    98 
    9998    /** I/O APIC irq levels */
    10099    volatile uint32_t   uaPciApicIrqLevels[PCI_APIC_IRQ_PINS];
     
    183182static DECLCALLBACK(uint32_t) ich9pciConfigReadDev(PCIDevice *aDev, uint32_t u32Address, unsigned len);
    184183DECLINLINE(PPCIDEVICE) ich9pciFindBridge(PPCIBUS pBus, uint8_t iBus);
    185 static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions);
     184static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn);
    186185#endif
    187186
     
    697696         * If the target bus is in the range we pass the request on to the bridge.
    698697         */
    699         PPCIDEVICE pBridgeTemp = pBus->papBridgesR3[iBridge];
    700         AssertMsg(pBridgeTemp && pciDevIsPci2PciBridge(pBridgeTemp),
     698        PPCIDEVICE pBridge = pBus->papBridgesR3[iBridge];
     699        AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
    701700                  ("Device is not a PCI bridge but on the list of PCI bridges\n"));
    702 
    703         if (   iBus >= PCIDevGetByte(pBridgeTemp, VBOX_PCI_SECONDARY_BUS)
    704             && iBus <= PCIDevGetByte(pBridgeTemp, VBOX_PCI_SUBORDINATE_BUS))
    705             return pBridgeTemp;
     701        uint32_t uSecondary   = PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
     702        uint32_t uSubordinate = PCIDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
     703        Log2(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
     704        if (iBus >= uSecondary && iBus <= uSubordinate)
     705            return pBridge;
    706706    }
    707707
     
    15291529
    15301530
    1531 static void ich9pciBiosInitBridge(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions)
    1532 {
    1533     ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, pGlobals->uBus, 1);
    1534     /* Temporary until we know how many other bridges are behind this one. */
    1535     ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SUBORDINATE_BUS, 0xff, 1);
    1536 
    1537     /* Add position of this bridge into the array. */
    1538     paBridgePositions[cBridgeDepth+1] = (uDevFn >> 3);
     1531static void ich9pciBiosInitBridge(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
     1532{
     1533    Log(("BIOS init device: %0x2::%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
    15391534
    15401535    /*
     
    15641559    /* Init devices behind the bridge and possibly other bridges as well. */
    15651560    for (int iDev = 0; iDev <= 255; iDev++)
    1566         ich9pciBiosInitDevice(pGlobals, uBus + 1, iDev, cBridgeDepth + 1, paBridgePositions);
    1567 
    1568     /* The number of bridges behind the this one is now available. */
    1569     ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_SUBORDINATE_BUS, pGlobals->uBus, 1);
     1561        ich9pciBiosInitDevice(pGlobals, uBus + 1, iDev);
    15701562
    15711563    /*
     
    16021594}
    16031595
    1604 static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, uint8_t cBridgeDepth, uint8_t *paBridgePositions)
     1596static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
    16051597{
    16061598    uint32_t *paddr;
     
    16431635       case 0x0604:
    16441636            /* PCI-to-PCI bridge. */
    1645             ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_PRIMARY_BUS, uBus, 1);
    1646 
    16471637            AssertMsg(pGlobals->uBus < 255, ("Too many bridges on the bus\n"));
    1648             pGlobals->uBus++;
    1649             ich9pciBiosInitBridge(pGlobals, uBus, uDevFn, cBridgeDepth, paBridgePositions);
     1638            ich9pciBiosInitBridge(pGlobals, uBus, uDevFn);
    16501639            break;
    16511640        default:
     
    17011690    if (iPin != 0)
    17021691    {
    1703         uint8_t uBridgeDevFn = uDevFn;
    17041692        iPin--;
    17051693
    1706         /* We need to go up to the host bus to see which irq this device will assert there. */
    1707         while (cBridgeDepth != 0)
    1708         {
    1709             /* Get the pin the device would assert on the bridge. */
    1710             iPin = ((uBridgeDevFn >> 3) + iPin) & 3;
    1711             uBridgeDevFn = paBridgePositions[cBridgeDepth];
    1712             cBridgeDepth--;
     1694        if (uBus != 0)
     1695        {
     1696            /* Find bus this device attached to. */
     1697            PPCIBUS pBus = &pGlobals->aPciBus;
     1698            while (1)
     1699            {
     1700                PPCIDEVICE pBridge = ich9pciFindBridge(pBus, uBus);
     1701                if (!pBridge)
     1702                {
     1703                    Assert(false);
     1704                    break;
     1705                }
     1706                if (uBus == PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
     1707                {
     1708                    /* OK, found bus this device attached to. */
     1709                    break;
     1710                }
     1711                pBus = PDMINS_2_DATA(pBridge->pDevIns, PPCIBUS);
     1712            }
     1713
     1714            /* We need to go up to the host bus to see which irq pin this
     1715             * device will use there. See logic in ich9pcibridgeSetIrq().
     1716             */
     1717            while (pBus->iBus != 0)
     1718            {
     1719                /* Get the pin the device would assert on the bridge. */
     1720                iPin = ((pBus->aPciDev.devfn >> 3) + iPin) & 3;
     1721                pBus = pBus->aPciDev.Int.s.pBusR3;
     1722            };
    17131723        }
    17141724
    17151725        int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
     1726        Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
     1727             iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
    17161728        ich9pciConfigWrite(pGlobals, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
    17171729    }
    17181730}
     1731
     1732/* Initializes bridges registers used for routing. */
     1733static void ich9pciInitBridgeTopology(PPCIGLOBALS pGlobals, PPCIBUS pBus)
     1734{
     1735    PPCIDEVICE pBridgeDev = &pBus->aPciDev;
     1736    PCIDevSetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS, pGlobals->uBus);
     1737
     1738    /* For simplicity, let's start numbering PCI bridges from 0,
     1739     * not 1, so don't increment count on Host->PCI bridge.
     1740     */
     1741    if (strcmp(pBridgeDev->name, "i82801") != 0)
     1742        pGlobals->uBus++;
     1743
     1744    PCIDevSetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS, pGlobals->uBus);
     1745    for (uint32_t iBridge = 0; iBridge < pBus->cBridges; iBridge++)
     1746    {
     1747        PPCIDEVICE pBridge = pBus->papBridgesR3[iBridge];
     1748        AssertMsg(pBridge && pciDevIsPci2PciBridge(pBridge),
     1749                  ("Device is not a PCI bridge but on the list of PCI bridges\n"));
     1750        PPCIBUS pChildBus = PDMINS_2_DATA(pBridge->pDevIns, PPCIBUS);
     1751        ich9pciInitBridgeTopology(pGlobals, pChildBus);
     1752    }
     1753    PCIDevSetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS, pGlobals->uBus);
     1754    Log2(("ich9pciInitBridgeTopology: for bus %p: primary=%d secondary=%d subordinate=%d\n",
     1755          pBus,
     1756          PCIDevGetByte(pBridgeDev, VBOX_PCI_PRIMARY_BUS),
     1757          PCIDevGetByte(pBridgeDev, VBOX_PCI_SECONDARY_BUS),
     1758          PCIDevGetByte(pBridgeDev, VBOX_PCI_SUBORDINATE_BUS)
     1759          ));
     1760}
     1761
    17191762
    17201763static DECLCALLBACK(int) ich9pciFakePCIBIOS(PPDMDEVINS pDevIns)
     
    17331776    pGlobals->uBus = 0;
    17341777
    1735     /*
     1778    /**
     1779     * Assign bridge topology, for further routing to work.
     1780     */
     1781    PPCIBUS pBus = &pGlobals->aPciBus;
     1782    ich9pciInitBridgeTopology(pGlobals, pBus);
     1783
     1784    /**
    17361785     * Init the devices.
    17371786     */
    17381787    for (i = 0; i < 256; i++)
    17391788    {
    1740         uint8_t aBridgePositions[256];
    1741 
    1742         memset(aBridgePositions, 0, sizeof(aBridgePositions));
    1743         Log2(("PCI: Initializing device %d (%#x)\n",
    1744               i, 0x80000000 | (i << 8)));
    1745         ich9pciBiosInitDevice(pGlobals, 0, i, 0, aBridgePositions);
     1789        ich9pciBiosInitDevice(pGlobals, 0, i);
    17461790    }
    17471791
     
    21282172        AssertMsg(pPciDev->Int.s.pfnBridgeConfigRead && pPciDev->Int.s.pfnBridgeConfigWrite,
    21292173                  ("device is a bridge but does not implement read/write functions\n"));
     2174        Log2(("Setting bridge %d on bus %p\n", pBus->cBridges, pBus));
    21302175        pBus->papBridgesR3[pBus->cBridges] = pPciDev;
    21312176        pBus->cBridges++;
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