Changeset 64862 in vbox for trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
- Timestamp:
- Dec 14, 2016 12:23:23 PM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
r64707 r64862 84 84 static void ich9pcibridgeReset(PPDMDEVINS pDevIns); 85 85 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus); 86 static void ich9pciBiosInit Device(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn);86 static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus); 87 87 #endif 88 88 … … 1437 1437 uint8_t uBridgeBus = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, 1); 1438 1438 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); 1442 1441 1443 1442 /* … … 1474 1473 } 1475 1474 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. 1475 static 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) 1504 1530 */ 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) 1531 1553 { 1532 uint32_t u32Address = ich9pciGetRegionReg(iRegion);1533 1534 /* Calculate size - we write all 1s into the BAR, and then evaluate which bits1535 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 1543 1554 if (f64Bit) 1544 1555 { 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)); 1556 1566 } 1557 1567 else 1558 1568 { 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); 1631 1575 } 1632 1576 } 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 1656 1578 { 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 1603 static 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) 1659 1659 { 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); 1662 1672 } 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) 1664 1678 { 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 }; 1669 1683 } 1670 1684 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); 1686 1707 } 1687 1708 } … … 1780 1801 1781 1802 /* 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); 1786 1806 1787 1807 return VINF_SUCCESS; … … 2189 2209 break; 2190 2210 } 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) */ 2192 2220 default: 2193 2221 if (fWritable) … … 2318 2346 uint32_t u32High = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion+1)); 2319 2347 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); 2321 2349 iRegion++; 2322 2350 } 2323 2351 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); 2325 2353 } 2326 2354 } … … 2362 2390 PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SECONDARY_BUS), 2363 2391 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); 2364 2400 devpciR3InfoPciBus(pBusSub, pHlp, iIndentLvl + 1, fRegisters); 2365 2401 }
Note:
See TracChangeset
for help on using the changeset viewer.