VirtualBox

Ignore:
Timestamp:
Dec 14, 2016 12:23:23 PM (8 years ago)
Author:
vboxsync
Message:

DevPciIch9: Improve BiosInit logic, handling bridges better (set up their BARs if present and recurse after setting up all devices on a bus, making the BAR allocations waste less space due to required alignment for bridge I/O and memory ranges). Add I/O and memory range information to "info pci".

File:
1 edited

Legend:

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

    r64707 r64862  
    8484static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
    8585DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus);
    86 static void ich9pciBiosInitDevice(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn);
     86static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus);
    8787#endif
    8888
     
    14371437    uint8_t uBridgeBus = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, 1);
    14381438
    1439     /* Init devices behind the bridge and possibly other bridges as well. */
    1440     for (int iDev = 0; iDev <= 255; iDev++)
    1441         ich9pciBiosInitDevice(pPciRoot, uBridgeBus, iDev);
     1439    /* Init all devices behind the bridge (recursing to further buses). */
     1440    ich9pciBiosInitAllDevicesOnBus(pPciRoot, uBridgeBus);
    14421441
    14431442    /*
     
    14741473}
    14751474
    1476 static void ich9pciBiosInitDevice(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn)
    1477 {
    1478     uint16_t uDevClass, uVendor, uDevice;
    1479     uint8_t uCmd;
    1480 
    1481     uDevClass  = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
    1482     uVendor    = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
    1483     uDevice    = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_DEVICE_ID, 2);
    1484 
    1485     /* If device is present */
    1486     if (uVendor == 0xffff)
    1487         return;
    1488 
    1489     Log(("BIOS init device: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
    1490 
    1491     switch (uDevClass)
    1492     {
    1493         case 0x0101:
    1494             /* IDE controller */
    1495             ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x40, 0x8000, 2); /* enable IDE0 */
    1496             ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x42, 0x8000, 2); /* enable IDE1 */
    1497             goto default_map;
    1498             break;
    1499         case 0x0300:
    1500             /* VGA controller */
    1501 
    1502             /* NB: Default Bochs VGA LFB address is 0xE0000000. Old guest
    1503              * software may break if the framebuffer isn't mapped there.
     1475static void ich9pciBiosInitDeviceBARs(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn)
     1476{
     1477    uint8_t uHeaderType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_HEADER_TYPE, 1) & 0x7f;
     1478    int cRegions = 0;
     1479    if (uHeaderType == 0x00)
     1480        /* Ignore ROM region here, which is included in VBOX_PCI_NUM_REGIONS. */
     1481        cRegions = VBOX_PCI_NUM_REGIONS - 1;
     1482    else if (uHeaderType == 0x01)
     1483        /* PCI bridges have 2 BARs. */
     1484        cRegions = 2;
     1485
     1486    bool fActiveMemRegion = false;
     1487    bool fActiveIORegion = false;
     1488    for (int iRegion = 0; iRegion < cRegions; iRegion++)
     1489    {
     1490        uint32_t u32Address = ich9pciGetRegionReg(iRegion);
     1491
     1492        /* Calculate size - we write all 1s into the BAR, and then evaluate which bits
     1493           are cleared. */
     1494        uint8_t u8ResourceType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 1);
     1495
     1496        bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
     1497                      == PCI_ADDRESS_SPACE_BAR64;
     1498        bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
     1499        uint64_t cbRegSize64 = 0;
     1500
     1501        if (f64Bit)
     1502        {
     1503            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
     1504            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
     1505            cbRegSize64  =            ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address,   4);
     1506            cbRegSize64 |= ((uint64_t)ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address+4, 4) << 32);
     1507            cbRegSize64 &= ~UINT64_C(0x0f);
     1508            cbRegSize64 = (~cbRegSize64) + 1;
     1509
     1510            /* No 64-bit PIO regions possible. */
     1511#ifndef DEBUG_bird /* EFI triggers this for DevAHCI. */
     1512            AssertMsg((u8ResourceType & PCI_COMMAND_IOACCESS) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
     1513#endif
     1514        }
     1515        else
     1516        {
     1517            uint32_t cbRegSize32;
     1518            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
     1519            cbRegSize32 = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 4);
     1520
     1521            /* Clear resource information depending on resource type. */
     1522            if (fIsPio) /* PIO */
     1523                cbRegSize32 &= ~UINT32_C(0x01);
     1524            else        /* MMIO */
     1525                cbRegSize32 &= ~UINT32_C(0x0f);
     1526
     1527            /*
     1528             * Invert all bits and add 1 to get size of the region.
     1529             * (From PCI implementation note)
    15041530             */
    1505 
    1506             /*
    1507              * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But
    1508              * only the framebuffer (i.e., a memory region) is explicitly registered via
    1509              * ich9pciSetRegionAddress, so don't forget to enable I/O decoding.
    1510              */
    1511             uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 1);
    1512             ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND,
    1513                                        uCmd | PCI_COMMAND_IOACCESS,
    1514                                        1);
    1515             goto default_map;
    1516             break;
    1517         case 0x0604:
    1518             /* PCI-to-PCI bridge. */
    1519             ich9pciBiosInitBridge(pPciRoot, uBus, uDevFn);
    1520             break;
    1521         default:
    1522         default_map:
    1523         {
    1524             /* default memory mappings */
    1525             bool fActiveMemRegion = false;
    1526             bool fActiveIORegion = false;
    1527             /*
    1528              * We ignore ROM region here.
    1529              */
    1530             for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS - 1; iRegion++)
     1531            if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
     1532                cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
     1533            else
     1534                cbRegSize32 = (~cbRegSize32) + 1;
     1535
     1536            cbRegSize64 = cbRegSize32;
     1537        }
     1538        Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
     1539
     1540        if (cbRegSize64)
     1541        {
     1542            /* Try 32-bit base first. */
     1543            uint32_t* paddr = fIsPio ? &pPciRoot->uPciBiosIo : &pPciRoot->uPciBiosMmio;
     1544            uint64_t  uNew = *paddr;
     1545            /* Align starting address to region size. */
     1546            uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
     1547            if (fIsPio)
     1548                uNew &= UINT32_C(0xffff);
     1549            /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
     1550            if (   !uNew
     1551                || (uNew <= UINT32_C(0xffffffff) && uNew + cbRegSize64 - 1 >= UINT32_C(0xfec00000))
     1552                || uNew >= _4G)
    15311553            {
    1532                 uint32_t u32Address = ich9pciGetRegionReg(iRegion);
    1533 
    1534                 /* Calculate size - we write all 1s into the BAR, and then evaluate which bits
    1535                    are cleared. */
    1536                 uint8_t u8ResourceType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 1);
    1537 
    1538                 bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
    1539                               == PCI_ADDRESS_SPACE_BAR64;
    1540                 bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
    1541                 uint64_t cbRegSize64 = 0;
    1542 
    15431554                if (f64Bit)
    15441555                {
    1545                     ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
    1546                     ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
    1547                     cbRegSize64  =            ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address,   4);
    1548                     cbRegSize64 |= ((uint64_t)ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address+4, 4) << 32);
    1549                     cbRegSize64 &= ~UINT64_C(0x0f);
    1550                     cbRegSize64 = (~cbRegSize64) + 1;
    1551 
    1552                     /* No 64-bit PIO regions possible. */
    1553 #ifndef DEBUG_bird /* EFI triggers this for DevAHCI. */
    1554                     AssertMsg((u8ResourceType & PCI_COMMAND_IOACCESS) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
    1555 #endif
     1556                    /* Map a 64-bit region above 4GB. */
     1557                    Assert(!fIsPio);
     1558                    uNew = pPciRoot->uPciBiosMmio64;
     1559                    /* Align starting address to region size. */
     1560                    uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
     1561                    LogFunc(("Start address of 64-bit MMIO region %u/%u is %#llx\n", iRegion, iRegion + 1, uNew));
     1562                    ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
     1563                    fActiveMemRegion = true;
     1564                    pPciRoot->uPciBiosMmio64 = uNew + cbRegSize64;
     1565                    Log2Func(("New 64-bit address is %#llx\n", pPciRoot->uPciBiosMmio64));
    15561566                }
    15571567                else
    15581568                {
    1559                     uint32_t cbRegSize32;
    1560                     ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
    1561                     cbRegSize32 = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 4);
    1562 
    1563                     /* Clear resource information depending on resource type. */
    1564                     if (fIsPio) /* PIO */
    1565                         cbRegSize32 &= ~UINT32_C(0x01);
    1566                     else        /* MMIO */
    1567                         cbRegSize32 &= ~UINT32_C(0x0f);
    1568 
    1569                     /*
    1570                      * Invert all bits and add 1 to get size of the region.
    1571                      * (From PCI implementation note)
    1572                      */
    1573                     if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
    1574                         cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
    1575                     else
    1576                         cbRegSize32 = (~cbRegSize32) + 1;
    1577 
    1578                     cbRegSize64 = cbRegSize32;
    1579                 }
    1580                 Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
    1581 
    1582                 if (cbRegSize64)
    1583                 {
    1584                     /* Try 32-bit base first. */
    1585                     uint32_t* paddr = fIsPio ? &pPciRoot->uPciBiosIo : &pPciRoot->uPciBiosMmio;
    1586                     uint64_t  uNew = *paddr;
    1587                     /* Align starting address to region size. */
    1588                     uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
    1589                     if (fIsPio)
    1590                         uNew &= UINT32_C(0xffff);
    1591                     /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
    1592                     if (   !uNew
    1593                         || (uNew <= UINT32_C(0xffffffff) && uNew + cbRegSize64 - 1 >= UINT32_C(0xfec00000))
    1594                         || uNew >= _4G)
    1595                     {
    1596                         if (f64Bit)
    1597                         {
    1598                             /* Map a 64-bit region above 4GB. */
    1599                             Assert(!fIsPio);
    1600                             uNew = pPciRoot->uPciBiosMmio64;
    1601                             /* Align starting address to region size. */
    1602                             uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
    1603                             LogFunc(("Start address of 64-bit MMIO region %u/%u is %#llx\n", iRegion, iRegion + 1, uNew));
    1604                             ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
    1605                             fActiveMemRegion = true;
    1606                             pPciRoot->uPciBiosMmio64 = uNew + cbRegSize64;
    1607                             Log2Func(("New 64-bit address is %#llx\n", pPciRoot->uPciBiosMmio64));
    1608                         }
    1609                         else
    1610                         {
    1611                             LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n",
    1612                                     iRegion, uBus, uDevFn >> 3, uDevFn & 7, uVendor, uDevice)); /** @todo make this a VM start failure later. */
    1613                             /* Undo the mapping mess caused by the size probing. */
    1614                             ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0), 4);
    1615                         }
    1616                     }
    1617                     else
    1618                     {
    1619                         LogFunc(("Start address of %s region %u is %#x\n", (fIsPio ? "I/O" : "MMIO"), iRegion, uNew));
    1620                         ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
    1621                         if (fIsPio)
    1622                             fActiveIORegion = true;
    1623                         else
    1624                             fActiveMemRegion = true;
    1625                         *paddr = uNew + cbRegSize64;
    1626                         Log2Func(("New 32-bit address is %#x\n", *paddr));
    1627                     }
    1628 
    1629                     if (f64Bit)
    1630                         iRegion++; /* skip next region */
     1569                    uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
     1570                    uint16_t uDevice = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_DEVICE_ID, 2);
     1571                    LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n",
     1572                            iRegion, uBus, uDevFn >> 3, uDevFn & 7, uVendor, uDevice)); /** @todo make this a VM start failure later. */
     1573                    /* Undo the mapping mess caused by the size probing. */
     1574                    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0), 4);
    16311575                }
    16321576            }
    1633 
    1634             /* Update the command word appropriately. */
    1635             uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
    1636             if (fActiveMemRegion)
    1637                 uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
    1638             if (fActiveIORegion)
    1639                 uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */
    1640             ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
    1641             break;
    1642         }
    1643     }
    1644 
    1645     /* map the interrupt */
    1646     uint32_t iPin = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_PIN, 1);
    1647     if (iPin != 0)
    1648     {
    1649         iPin--;
    1650 
    1651         if (uBus != 0)
    1652         {
    1653             /* Find bus this device attached to. */
    1654             PDEVPCIBUS pBus = &pPciRoot->PciBus;
    1655             while (1)
     1577            else
    16561578            {
    1657                 PPDMPCIDEV pBridge = ich9pciFindBridge(pBus, uBus);
    1658                 if (!pBridge)
     1579                LogFunc(("Start address of %s region %u is %#x\n", (fIsPio ? "I/O" : "MMIO"), iRegion, uNew));
     1580                ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
     1581                if (fIsPio)
     1582                    fActiveIORegion = true;
     1583                else
     1584                    fActiveMemRegion = true;
     1585                *paddr = uNew + cbRegSize64;
     1586                Log2Func(("New 32-bit address is %#x\n", *paddr));
     1587            }
     1588
     1589            if (f64Bit)
     1590                iRegion++; /* skip next region */
     1591        }
     1592    }
     1593
     1594    /* Update the command word appropriately. */
     1595    uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
     1596    if (fActiveMemRegion)
     1597        uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
     1598    if (fActiveIORegion)
     1599        uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */
     1600    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
     1601}
     1602
     1603static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus)
     1604{
     1605    /* First pass: assign resources to all devices and map the interrupt. */
     1606    for (uint32_t uDevFn = 0; uDevFn < 256; uDevFn++)
     1607    {
     1608        /* check if device is present */
     1609        uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
     1610        if (uVendor == 0xffff)
     1611            continue;
     1612
     1613        Log(("BIOS init device: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
     1614
     1615        /* default memory mappings */
     1616        ich9pciBiosInitDeviceBARs(pPciRoot, uBus, uDevFn);
     1617        uint16_t uDevClass = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
     1618        switch (uDevClass)
     1619        {
     1620            case 0x0101:
     1621                /* IDE controller */
     1622                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x40, 0x8000, 2); /* enable IDE0 */
     1623                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x42, 0x8000, 2); /* enable IDE1 */
     1624                break;
     1625            case 0x0300:
     1626            {
     1627                /* VGA controller */
     1628
     1629                /* NB: Default Bochs VGA LFB address is 0xE0000000. Old guest
     1630                 * software may break if the framebuffer isn't mapped there.
     1631                 */
     1632
     1633                /*
     1634                 * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But
     1635                 * only the framebuffer (i.e., a memory region) is explicitly registered via
     1636                 * ich9pciSetRegionAddress, so don't forget to enable I/O decoding.
     1637                 */
     1638                uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 1);
     1639                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND,
     1640                                           uCmd | PCI_COMMAND_IOACCESS,
     1641                                           1);
     1642                break;
     1643            }
     1644            default:
     1645                break;
     1646        }
     1647
     1648        /* map the interrupt */
     1649        uint32_t iPin = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_PIN, 1);
     1650        if (iPin != 0)
     1651        {
     1652            iPin--;
     1653
     1654            if (uBus != 0)
     1655            {
     1656                /* Find bus this device attached to. */
     1657                PDEVPCIBUS pBus = &pPciRoot->PciBus;
     1658                while (1)
    16591659                {
    1660                     Assert(false);
    1661                     break;
     1660                    PPDMPCIDEV pBridge = ich9pciFindBridge(pBus, uBus);
     1661                    if (!pBridge)
     1662                    {
     1663                        Assert(false);
     1664                        break;
     1665                    }
     1666                    if (uBus == PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
     1667                    {
     1668                        /* OK, found bus this device attached to. */
     1669                        break;
     1670                    }
     1671                    pBus = PDMINS_2_DATA(pBridge->Int.s.CTX_SUFF(pDevIns), PDEVPCIBUS);
    16621672                }
    1663                 if (uBus == PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
     1673
     1674                /* We need to go up to the host bus to see which irq pin this
     1675                 * device will use there. See logic in ich9pcibridgeSetIrq().
     1676                 */
     1677                while (pBus->iBus != 0)
    16641678                {
    1665                     /* OK, found bus this device attached to. */
    1666                     break;
    1667                 }
    1668                 pBus = PDMINS_2_DATA(pBridge->Int.s.CTX_SUFF(pDevIns), PDEVPCIBUS);
     1679                    /* Get the pin the device would assert on the bridge. */
     1680                    iPin = ((pBus->PciDev.uDevFn >> 3) + iPin) & 3;
     1681                    pBus = pBus->PciDev.Int.s.pBusR3;
     1682                };
    16691683            }
    16701684
    1671             /* We need to go up to the host bus to see which irq pin this
    1672              * device will use there. See logic in ich9pcibridgeSetIrq().
    1673              */
    1674             while (pBus->iBus != 0)
    1675             {
    1676                 /* Get the pin the device would assert on the bridge. */
    1677                 iPin = ((pBus->PciDev.uDevFn >> 3) + iPin) & 3;
    1678                 pBus = pBus->PciDev.Int.s.pBusR3;
    1679             };
    1680         }
    1681 
    1682         int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
    1683         Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
    1684              iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
    1685         ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
     1685            int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
     1686            Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
     1687                 iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
     1688            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
     1689        }
     1690    }
     1691
     1692    /* Second pass: handle bridges recursively. */
     1693    for (uint32_t uDevFn = 0; uDevFn < 256; uDevFn++)
     1694    {
     1695        /* check if device is present */
     1696        uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
     1697        if (uVendor == 0xffff)
     1698            continue;
     1699
     1700        /* only handle PCI-to-PCI bridges */
     1701        uint16_t uDevClass = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
     1702        if (uDevClass != 0x0604)
     1703            continue;
     1704
     1705        Log(("BIOS init bridge: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
     1706        ich9pciBiosInitBridge(pPciRoot, uBus, uDevFn);
    16861707    }
    16871708}
     
    17801801
    17811802    /*
    1782      * Init the devices.
    1783      */
    1784     for (uint32_t i = 0; i < 256; i++)
    1785         ich9pciBiosInitDevice(pPciRoot, 0, i);
     1803     * Init all devices on bus 0 (recursing to further buses).
     1804     */
     1805    ich9pciBiosInitAllDevicesOnBus(pPciRoot, 0);
    17861806
    17871807    return VINF_SUCCESS;
     
    21892209                            break;
    21902210                        }
    2191                         /* fall thru (bridge) */
     2211                        else if (uAddress < VBOX_PCI_BASE_ADDRESS_2 || uAddress > VBOX_PCI_BASE_ADDRESS_5+3)
     2212                        {
     2213                            /* PCI bridges have only BAR0, BAR1 and ROM */
     2214                            uint32_t iRegion = fRom ? VBOX_PCI_ROM_SLOT : (uAddress - VBOX_PCI_BASE_ADDRESS_0) >> 2;
     2215                            devpciR3WriteBarByte(pPciDev, iRegion, uAddress & 0x3, bVal);
     2216                            fUpdateMappings = true;
     2217                            break;
     2218                        }
     2219                        /* fall thru (bridge config space which isn't a BAR) */
    21922220                    default:
    21932221                        if (fWritable)
     
    23182346                        uint32_t u32High = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion+1));
    23192347                        uint64_t u64Addr = RT_MAKE_U64(uAddr, u32High);
    2320                         pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion);
     2348                        pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion - 1);
    23212349                        iRegion++;
    23222350                    }
    23232351                    else
    2324                         pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion);
     2352                        pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion - 1);
    23252353                }
    23262354            }
     
    23622390                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SECONDARY_BUS),
    23632391                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SUBORDINATE_BUS));
     2392            devpciR3InfoIndent(pHlp, iIndentLvl);
     2393            pHlp->pfnPrintf(pHlp, "behind bridge: I/O %#06x..%#06x\n",
     2394                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_BASE) & 0xf0 << 8,
     2395                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_LIMIT) & 0xf0 << 8 | 0xfff);
     2396            devpciR3InfoIndent(pHlp, iIndentLvl);
     2397            pHlp->pfnPrintf(pHlp, "behind bridge: memory %#010x..%#010x\n",
     2398                            PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_BASE) << 16,
     2399                            PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_LIMIT) << 16 | 0xffff);
    23642400            devpciR3InfoPciBus(pBusSub, pHlp, iIndentLvl + 1, fRegisters);
    23652401        }
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