Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 64861)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 64862)
@@ -84,5 +84,5 @@
 static void ich9pcibridgeReset(PPDMDEVINS pDevIns);
 DECLINLINE(PPDMPCIDEV) ich9pciFindBridge(PDEVPCIBUS pBus, uint8_t uBus);
-static void ich9pciBiosInitDevice(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn);
+static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus);
 #endif
 
@@ -1437,7 +1437,6 @@
     uint8_t uBridgeBus = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_SECONDARY_BUS, 1);
 
-    /* Init devices behind the bridge and possibly other bridges as well. */
-    for (int iDev = 0; iDev <= 255; iDev++)
-        ich9pciBiosInitDevice(pPciRoot, uBridgeBus, iDev);
+    /* Init all devices behind the bridge (recursing to further buses). */
+    ich9pciBiosInitAllDevicesOnBus(pPciRoot, uBridgeBus);
 
     /*
@@ -1474,214 +1473,236 @@
 }
 
-static void ich9pciBiosInitDevice(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn)
-{
-    uint16_t uDevClass, uVendor, uDevice;
-    uint8_t uCmd;
-
-    uDevClass  = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
-    uVendor    = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
-    uDevice    = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_DEVICE_ID, 2);
-
-    /* If device is present */
-    if (uVendor == 0xffff)
-        return;
-
-    Log(("BIOS init device: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
-
-    switch (uDevClass)
-    {
-        case 0x0101:
-            /* IDE controller */
-            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x40, 0x8000, 2); /* enable IDE0 */
-            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x42, 0x8000, 2); /* enable IDE1 */
-            goto default_map;
-            break;
-        case 0x0300:
-            /* VGA controller */
-
-            /* NB: Default Bochs VGA LFB address is 0xE0000000. Old guest
-             * software may break if the framebuffer isn't mapped there.
+static void ich9pciBiosInitDeviceBARs(PDEVPCIROOT pPciRoot, uint8_t uBus, uint8_t uDevFn)
+{
+    uint8_t uHeaderType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_HEADER_TYPE, 1) & 0x7f;
+    int cRegions = 0;
+    if (uHeaderType == 0x00)
+        /* Ignore ROM region here, which is included in VBOX_PCI_NUM_REGIONS. */
+        cRegions = VBOX_PCI_NUM_REGIONS - 1;
+    else if (uHeaderType == 0x01)
+        /* PCI bridges have 2 BARs. */
+        cRegions = 2;
+
+    bool fActiveMemRegion = false;
+    bool fActiveIORegion = false;
+    for (int iRegion = 0; iRegion < cRegions; iRegion++)
+    {
+        uint32_t u32Address = ich9pciGetRegionReg(iRegion);
+
+        /* Calculate size - we write all 1s into the BAR, and then evaluate which bits
+           are cleared. */
+        uint8_t u8ResourceType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 1);
+
+        bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
+                      == PCI_ADDRESS_SPACE_BAR64;
+        bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
+        uint64_t cbRegSize64 = 0;
+
+        if (f64Bit)
+        {
+            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
+            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
+            cbRegSize64  =            ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address,   4);
+            cbRegSize64 |= ((uint64_t)ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address+4, 4) << 32);
+            cbRegSize64 &= ~UINT64_C(0x0f);
+            cbRegSize64 = (~cbRegSize64) + 1;
+
+            /* No 64-bit PIO regions possible. */
+#ifndef DEBUG_bird /* EFI triggers this for DevAHCI. */
+            AssertMsg((u8ResourceType & PCI_COMMAND_IOACCESS) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
+#endif
+        }
+        else
+        {
+            uint32_t cbRegSize32;
+            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
+            cbRegSize32 = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 4);
+
+            /* Clear resource information depending on resource type. */
+            if (fIsPio) /* PIO */
+                cbRegSize32 &= ~UINT32_C(0x01);
+            else        /* MMIO */
+                cbRegSize32 &= ~UINT32_C(0x0f);
+
+            /*
+             * Invert all bits and add 1 to get size of the region.
+             * (From PCI implementation note)
              */
-
-            /*
-             * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But
-             * only the framebuffer (i.e., a memory region) is explicitly registered via
-             * ich9pciSetRegionAddress, so don't forget to enable I/O decoding.
-             */
-            uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 1);
-            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND,
-                                       uCmd | PCI_COMMAND_IOACCESS,
-                                       1);
-            goto default_map;
-            break;
-        case 0x0604:
-            /* PCI-to-PCI bridge. */
-            ich9pciBiosInitBridge(pPciRoot, uBus, uDevFn);
-            break;
-        default:
-        default_map:
-        {
-            /* default memory mappings */
-            bool fActiveMemRegion = false;
-            bool fActiveIORegion = false;
-            /*
-             * We ignore ROM region here.
-             */
-            for (int iRegion = 0; iRegion < VBOX_PCI_NUM_REGIONS - 1; iRegion++)
+            if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
+                cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
+            else
+                cbRegSize32 = (~cbRegSize32) + 1;
+
+            cbRegSize64 = cbRegSize32;
+        }
+        Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
+
+        if (cbRegSize64)
+        {
+            /* Try 32-bit base first. */
+            uint32_t* paddr = fIsPio ? &pPciRoot->uPciBiosIo : &pPciRoot->uPciBiosMmio;
+            uint64_t  uNew = *paddr;
+            /* Align starting address to region size. */
+            uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
+            if (fIsPio)
+                uNew &= UINT32_C(0xffff);
+            /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
+            if (   !uNew
+                || (uNew <= UINT32_C(0xffffffff) && uNew + cbRegSize64 - 1 >= UINT32_C(0xfec00000))
+                || uNew >= _4G)
             {
-                uint32_t u32Address = ich9pciGetRegionReg(iRegion);
-
-                /* Calculate size - we write all 1s into the BAR, and then evaluate which bits
-                   are cleared. */
-                uint8_t u8ResourceType = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 1);
-
-                bool f64Bit =    (u8ResourceType & ((uint8_t)(PCI_ADDRESS_SPACE_BAR64 | PCI_ADDRESS_SPACE_IO)))
-                              == PCI_ADDRESS_SPACE_BAR64;
-                bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
-                uint64_t cbRegSize64 = 0;
-
                 if (f64Bit)
                 {
-                    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
-                    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
-                    cbRegSize64  =            ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address,   4);
-                    cbRegSize64 |= ((uint64_t)ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address+4, 4) << 32);
-                    cbRegSize64 &= ~UINT64_C(0x0f);
-                    cbRegSize64 = (~cbRegSize64) + 1;
-
-                    /* No 64-bit PIO regions possible. */
-#ifndef DEBUG_bird /* EFI triggers this for DevAHCI. */
-                    AssertMsg((u8ResourceType & PCI_COMMAND_IOACCESS) == 0, ("type=%#x rgn=%d\n", u8ResourceType, iRegion));
-#endif
+                    /* Map a 64-bit region above 4GB. */
+                    Assert(!fIsPio);
+                    uNew = pPciRoot->uPciBiosMmio64;
+                    /* Align starting address to region size. */
+                    uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
+                    LogFunc(("Start address of 64-bit MMIO region %u/%u is %#llx\n", iRegion, iRegion + 1, uNew));
+                    ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
+                    fActiveMemRegion = true;
+                    pPciRoot->uPciBiosMmio64 = uNew + cbRegSize64;
+                    Log2Func(("New 64-bit address is %#llx\n", pPciRoot->uPciBiosMmio64));
                 }
                 else
                 {
-                    uint32_t cbRegSize32;
-                    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
-                    cbRegSize32 = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, u32Address, 4);
-
-                    /* Clear resource information depending on resource type. */
-                    if (fIsPio) /* PIO */
-                        cbRegSize32 &= ~UINT32_C(0x01);
-                    else        /* MMIO */
-                        cbRegSize32 &= ~UINT32_C(0x0f);
-
-                    /*
-                     * Invert all bits and add 1 to get size of the region.
-                     * (From PCI implementation note)
-                     */
-                    if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
-                        cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
-                    else
-                        cbRegSize32 = (~cbRegSize32) + 1;
-
-                    cbRegSize64 = cbRegSize32;
-                }
-                Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
-
-                if (cbRegSize64)
-                {
-                    /* Try 32-bit base first. */
-                    uint32_t* paddr = fIsPio ? &pPciRoot->uPciBiosIo : &pPciRoot->uPciBiosMmio;
-                    uint64_t  uNew = *paddr;
-                    /* Align starting address to region size. */
-                    uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
-                    if (fIsPio)
-                        uNew &= UINT32_C(0xffff);
-                    /* Unconditionally exclude I/O-APIC/HPET/ROM. Pessimistic, but better than causing a mess. */
-                    if (   !uNew
-                        || (uNew <= UINT32_C(0xffffffff) && uNew + cbRegSize64 - 1 >= UINT32_C(0xfec00000))
-                        || uNew >= _4G)
-                    {
-                        if (f64Bit)
-                        {
-                            /* Map a 64-bit region above 4GB. */
-                            Assert(!fIsPio);
-                            uNew = pPciRoot->uPciBiosMmio64;
-                            /* Align starting address to region size. */
-                            uNew = (uNew + cbRegSize64 - 1) & ~(cbRegSize64 - 1);
-                            LogFunc(("Start address of 64-bit MMIO region %u/%u is %#llx\n", iRegion, iRegion + 1, uNew));
-                            ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
-                            fActiveMemRegion = true;
-                            pPciRoot->uPciBiosMmio64 = uNew + cbRegSize64;
-                            Log2Func(("New 64-bit address is %#llx\n", pPciRoot->uPciBiosMmio64));
-                        }
-                        else
-                        {
-                            LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n",
-                                    iRegion, uBus, uDevFn >> 3, uDevFn & 7, uVendor, uDevice)); /** @todo make this a VM start failure later. */
-                            /* Undo the mapping mess caused by the size probing. */
-                            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0), 4);
-                        }
-                    }
-                    else
-                    {
-                        LogFunc(("Start address of %s region %u is %#x\n", (fIsPio ? "I/O" : "MMIO"), iRegion, uNew));
-                        ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
-                        if (fIsPio)
-                            fActiveIORegion = true;
-                        else
-                            fActiveMemRegion = true;
-                        *paddr = uNew + cbRegSize64;
-                        Log2Func(("New 32-bit address is %#x\n", *paddr));
-                    }
-
-                    if (f64Bit)
-                        iRegion++; /* skip next region */
+                    uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
+                    uint16_t uDevice = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_DEVICE_ID, 2);
+                    LogRel(("PCI: no space left for BAR%u of device %u/%u/%u (vendor=%#06x device=%#06x)\n",
+                            iRegion, uBus, uDevFn >> 3, uDevFn & 7, uVendor, uDevice)); /** @todo make this a VM start failure later. */
+                    /* Undo the mapping mess caused by the size probing. */
+                    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, u32Address, UINT32_C(0), 4);
                 }
             }
-
-            /* Update the command word appropriately. */
-            uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
-            if (fActiveMemRegion)
-                uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
-            if (fActiveIORegion)
-                uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */
-            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
-            break;
-        }
-    }
-
-    /* map the interrupt */
-    uint32_t iPin = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_PIN, 1);
-    if (iPin != 0)
-    {
-        iPin--;
-
-        if (uBus != 0)
-        {
-            /* Find bus this device attached to. */
-            PDEVPCIBUS pBus = &pPciRoot->PciBus;
-            while (1)
+            else
             {
-                PPDMPCIDEV pBridge = ich9pciFindBridge(pBus, uBus);
-                if (!pBridge)
+                LogFunc(("Start address of %s region %u is %#x\n", (fIsPio ? "I/O" : "MMIO"), iRegion, uNew));
+                ich9pciBiosInitSetRegionAddress(pPciRoot, uBus, uDevFn, iRegion, uNew);
+                if (fIsPio)
+                    fActiveIORegion = true;
+                else
+                    fActiveMemRegion = true;
+                *paddr = uNew + cbRegSize64;
+                Log2Func(("New 32-bit address is %#x\n", *paddr));
+            }
+
+            if (f64Bit)
+                iRegion++; /* skip next region */
+        }
+    }
+
+    /* Update the command word appropriately. */
+    uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
+    if (fActiveMemRegion)
+        uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
+    if (fActiveIORegion)
+        uCmd |= PCI_COMMAND_IOACCESS; /* Enable I/O space access. */
+    ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, uCmd, 2);
+}
+
+static void ich9pciBiosInitAllDevicesOnBus(PDEVPCIROOT pPciRoot, uint8_t uBus)
+{
+    /* First pass: assign resources to all devices and map the interrupt. */
+    for (uint32_t uDevFn = 0; uDevFn < 256; uDevFn++)
+    {
+        /* check if device is present */
+        uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
+        if (uVendor == 0xffff)
+            continue;
+
+        Log(("BIOS init device: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
+
+        /* default memory mappings */
+        ich9pciBiosInitDeviceBARs(pPciRoot, uBus, uDevFn);
+        uint16_t uDevClass = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
+        switch (uDevClass)
+        {
+            case 0x0101:
+                /* IDE controller */
+                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x40, 0x8000, 2); /* enable IDE0 */
+                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, 0x42, 0x8000, 2); /* enable IDE1 */
+                break;
+            case 0x0300:
+            {
+                /* VGA controller */
+
+                /* NB: Default Bochs VGA LFB address is 0xE0000000. Old guest
+                 * software may break if the framebuffer isn't mapped there.
+                 */
+
+                /*
+                 * Legacy VGA I/O ports are implicitly decoded by a VGA class device. But
+                 * only the framebuffer (i.e., a memory region) is explicitly registered via
+                 * ich9pciSetRegionAddress, so don't forget to enable I/O decoding.
+                 */
+                uint8_t uCmd = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND, 1);
+                ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_COMMAND,
+                                           uCmd | PCI_COMMAND_IOACCESS,
+                                           1);
+                break;
+            }
+            default:
+                break;
+        }
+
+        /* map the interrupt */
+        uint32_t iPin = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_PIN, 1);
+        if (iPin != 0)
+        {
+            iPin--;
+
+            if (uBus != 0)
+            {
+                /* Find bus this device attached to. */
+                PDEVPCIBUS pBus = &pPciRoot->PciBus;
+                while (1)
                 {
-                    Assert(false);
-                    break;
+                    PPDMPCIDEV pBridge = ich9pciFindBridge(pBus, uBus);
+                    if (!pBridge)
+                    {
+                        Assert(false);
+                        break;
+                    }
+                    if (uBus == PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
+                    {
+                        /* OK, found bus this device attached to. */
+                        break;
+                    }
+                    pBus = PDMINS_2_DATA(pBridge->Int.s.CTX_SUFF(pDevIns), PDEVPCIBUS);
                 }
-                if (uBus == PDMPciDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS))
+
+                /* We need to go up to the host bus to see which irq pin this
+                 * device will use there. See logic in ich9pcibridgeSetIrq().
+                 */
+                while (pBus->iBus != 0)
                 {
-                    /* OK, found bus this device attached to. */
-                    break;
-                }
-                pBus = PDMINS_2_DATA(pBridge->Int.s.CTX_SUFF(pDevIns), PDEVPCIBUS);
+                    /* Get the pin the device would assert on the bridge. */
+                    iPin = ((pBus->PciDev.uDevFn >> 3) + iPin) & 3;
+                    pBus = pBus->PciDev.Int.s.pBusR3;
+                };
             }
 
-            /* We need to go up to the host bus to see which irq pin this
-             * device will use there. See logic in ich9pcibridgeSetIrq().
-             */
-            while (pBus->iBus != 0)
-            {
-                /* Get the pin the device would assert on the bridge. */
-                iPin = ((pBus->PciDev.uDevFn >> 3) + iPin) & 3;
-                pBus = pBus->PciDev.Int.s.pBusR3;
-            };
-        }
-
-        int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
-        Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
-             iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
-        ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
+            int iIrq = aPciIrqs[ich9pciSlotGetPirq(uBus, uDevFn, iPin)];
+            Log(("Using pin %d and IRQ %d for device %02x:%02x.%d\n",
+                 iPin, iIrq, uBus, uDevFn>>3, uDevFn&7));
+            ich9pciBiosInitWriteConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_INTERRUPT_LINE, iIrq, 1);
+        }
+    }
+
+    /* Second pass: handle bridges recursively. */
+    for (uint32_t uDevFn = 0; uDevFn < 256; uDevFn++)
+    {
+        /* check if device is present */
+        uint16_t uVendor = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
+        if (uVendor == 0xffff)
+            continue;
+
+        /* only handle PCI-to-PCI bridges */
+        uint16_t uDevClass = ich9pciBiosInitReadConfig(pPciRoot, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
+        if (uDevClass != 0x0604)
+            continue;
+
+        Log(("BIOS init bridge: %02x:%02x.%d\n", uBus, uDevFn >> 3, uDevFn & 7));
+        ich9pciBiosInitBridge(pPciRoot, uBus, uDevFn);
     }
 }
@@ -1780,8 +1801,7 @@
 
     /*
-     * Init the devices.
-     */
-    for (uint32_t i = 0; i < 256; i++)
-        ich9pciBiosInitDevice(pPciRoot, 0, i);
+     * Init all devices on bus 0 (recursing to further buses).
+     */
+    ich9pciBiosInitAllDevicesOnBus(pPciRoot, 0);
 
     return VINF_SUCCESS;
@@ -2189,5 +2209,13 @@
                             break;
                         }
-                        /* fall thru (bridge) */
+                        else if (uAddress < VBOX_PCI_BASE_ADDRESS_2 || uAddress > VBOX_PCI_BASE_ADDRESS_5+3)
+                        {
+                            /* PCI bridges have only BAR0, BAR1 and ROM */
+                            uint32_t iRegion = fRom ? VBOX_PCI_ROM_SLOT : (uAddress - VBOX_PCI_BASE_ADDRESS_0) >> 2;
+                            devpciR3WriteBarByte(pPciDev, iRegion, uAddress & 0x3, bVal);
+                            fUpdateMappings = true;
+                            break;
+                        }
+                        /* fall thru (bridge config space which isn't a BAR) */
                     default:
                         if (fWritable)
@@ -2318,9 +2346,9 @@
                         uint32_t u32High = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion+1));
                         uint64_t u64Addr = RT_MAKE_U64(uAddr, u32High);
-                        pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion);
+                        pHlp->pfnPrintf(pHlp, "%RX64..%RX64\n", u64Addr, u64Addr + cbRegion - 1);
                         iRegion++;
                     }
                     else
-                        pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion);
+                        pHlp->pfnPrintf(pHlp, "%x..%x\n", uAddr, uAddr + (uint32_t)cbRegion - 1);
                 }
             }
@@ -2362,4 +2390,12 @@
                             PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SECONDARY_BUS),
                             PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_SUBORDINATE_BUS));
+            devpciR3InfoIndent(pHlp, iIndentLvl);
+            pHlp->pfnPrintf(pHlp, "behind bridge: I/O %#06x..%#06x\n",
+                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_BASE) & 0xf0 << 8,
+                            PDMPciDevGetByte(&pBusSub->PciDev, VBOX_PCI_IO_LIMIT) & 0xf0 << 8 | 0xfff);
+            devpciR3InfoIndent(pHlp, iIndentLvl);
+            pHlp->pfnPrintf(pHlp, "behind bridge: memory %#010x..%#010x\n",
+                            PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_BASE) << 16,
+                            PDMPciDevGetWord(&pBusSub->PciDev, VBOX_PCI_MEMORY_LIMIT) << 16 | 0xffff);
             devpciR3InfoPciBus(pBusSub, pHlp, iIndentLvl + 1, fRegisters);
         }
