/* The APB host has an IRQ line for each IRQ line of each slot.  */
 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
 {
-    return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
+    /* Return the irq as swizzled by the PBM */
+    return irq_num;
 }
 
 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
 {
+    PBMPCIBridge *br = PBM_PCI_BRIDGE(pci_bridge_get_device(
+                           PCI_BUS(qdev_get_parent_bus(DEVICE(pci_dev)))));
+
     int bus_offset;
-    if (pci_dev->devfn & 1)
-        bus_offset = 16;
-    else
-        bus_offset = 0;
+    if (br->busA) {
+        bus_offset = 0x0;
+
+        /* The on-board devices have fixed (legacy) OBIO intnos */
+        switch (PCI_SLOT(pci_dev->devfn)) {
+        case 1:
+            /* Onboard NIC */
+            return 0x21;
+        case 3:
+            /* Onboard IDE */
+            return 0x20;
+
+        default:
+            /* Normal intno, fall through */
+            break;
+        }
+    } else {
+        bus_offset = 0x10;
+    }
     return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
 }
 
                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                  PCI_STATUS_DEVSEL_MEDIUM);
 
+    /* Allow 32-bit IO addresses */
+    pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
+    pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
+    pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
+    pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
+
     pci_bridge_update_mappings(PCI_BRIDGE(br));
 }
 
     d = APB_DEVICE(dev);
     phb = PCI_HOST_BRIDGE(dev);
     phb->bus = pci_register_bus(DEVICE(phb), "pci",
-                                pci_apb_set_irq, pci_pbm_map_irq, d,
+                                pci_apb_set_irq, pci_apb_map_irq, d,
                                 &d->pci_mmio,
-                                get_system_io(),
+                                &d->pci_ioport,
                                 0, 32, TYPE_PCI_BUS);
     qdev_init_nofail(dev);
     s = SYS_BUS_DEVICE(dev);
     pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
                                    TYPE_PBM_PCI_BRIDGE);
     br = PCI_BRIDGE(pci_dev);
-    pci_bridge_map_irq(br, "pciB", pci_apb_map_irq);
+    pci_bridge_map_irq(br, "pciB", pci_pbm_map_irq);
     qdev_init_nofail(&pci_dev->qdev);
     *busB = pci_bridge_get_sec_bus(br);
 
     pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
                                    TYPE_PBM_PCI_BRIDGE);
     br = PCI_BRIDGE(pci_dev);
-    pci_bridge_map_irq(br, "pciA", pci_apb_map_irq);
+    pci_bridge_map_irq(br, "pciA", pci_pbm_map_irq);
     qdev_prop_set_bit(DEVICE(pci_dev), "busA", true);
     qdev_init_nofail(&pci_dev->qdev);
     *busA = pci_bridge_get_sec_bus(br);
     sysbus_init_mmio(dev, &s->pci_config);
 
     /* pci_ioport */
-    memory_region_init_alias(&s->pci_ioport, OBJECT(s), "apb-pci-ioport",
-                             get_system_io(), 0, 0x10000);
+    memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
+
     /* at region 2 */
     sysbus_init_mmio(dev, &s->pci_ioport);
 
 
 #include "cpu.h"
 #include "hw/hw.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "hw/pci-host/apb.h"
 #include "hw/i386/pc.h"
 #include "hw/char/serial.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/sysbus.h"
 #include "hw/ide.h"
+#include "hw/ide/pci.h"
 #include "hw/loader.h"
 #include "elf.h"
 #include "qemu/cutils.h"
     DeviceState *dev;
     FWCfgState *fw_cfg;
     NICInfo *nd;
-    int onboard_nic_idx;
+    MACAddr macaddr;
+    bool onboard_nic;
 
     /* init CPUs */
     cpu = sparc64_cpu_devinit(machine->cpu_model, hwdef->default_cpu_model,
     ivec_irqs = qemu_allocate_irqs(sparc64_cpu_set_ivec_irq, cpu, IVEC_MAX);
     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_busA,
                            &pci_busB, &pbm_irqs);
-    pci_vga_init(pci_bus);
 
-    /* XXX Should be pci_busA */
-    ebus = pci_create_simple(pci_bus, -1, "ebus");
+    /* Only in-built Simba PBMs can exist on the root bus, slot 0 on busA is
+       reserved (leaving no slots free after on-board devices) however slots
+       0-3 are free on busB */
+    pci_bus->slot_reserved_mask = 0xfffffffc;
+    pci_busA->slot_reserved_mask = 0xfffffff1;
+    pci_busB->slot_reserved_mask = 0xfffffff0;
+
+    ebus = pci_create_multifunction(pci_busA, PCI_DEVFN(1, 0), true, "ebus");
+    qdev_init_nofail(DEVICE(ebus));
+
     isa_bus = pci_ebus_init(ebus, pbm_irqs);
 
     i = 0;
     serial_hds_isa_init(isa_bus, i, MAX_SERIAL_PORTS);
     parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);
 
-    onboard_nic_idx = -1;
+    pci_dev = pci_create_simple(pci_busA, PCI_DEVFN(2, 0), "VGA");
+
+    memset(&macaddr, 0, sizeof(MACAddr));
+    onboard_nic = false;
     for (i = 0; i < nb_nics; i++) {
         nd = &nd_table[i];
 
-        if (onboard_nic_idx == -1 &&
-                (!nd->model || strcmp(nd->model, "sunhme") == 0)) {
-            pci_dev = pci_create(pci_bus, -1, "sunhme");
-            dev = &pci_dev->qdev;
-            qdev_set_nic_properties(dev, nd);
-            qdev_init_nofail(dev);
-
-            onboard_nic_idx = i;
+        if (!nd->model || strcmp(nd->model, "sunhme") == 0) {
+            if (!onboard_nic) {
+                pci_dev = pci_create_multifunction(pci_busA, PCI_DEVFN(1, 1),
+                                                   true, "sunhme");
+                memcpy(&macaddr, &nd->macaddr.a, sizeof(MACAddr));
+                onboard_nic = true;
+            } else {
+                pci_dev = pci_create_simple(pci_busB, -1, "sunhme");
+            }
         } else {
-            pci_nic_init_nofail(nd, pci_bus, "ne2k_pci", NULL);
+            pci_dev = pci_create_simple(pci_busB, -1, nd->model);
         }
+
+        dev = &pci_dev->qdev;
+        qdev_set_nic_properties(dev, nd);
+        qdev_init_nofail(dev);
+    }
+
+    /* If we don't have an onboard NIC, grab a default MAC address so that
+     * we have a valid machine id */
+    if (!onboard_nic) {
+        qemu_macaddr_default_if_unset(&macaddr);
     }
-    onboard_nic_idx = MAX(onboard_nic_idx, 0);
 
     ide_drive_get(hd, ARRAY_SIZE(hd));
 
-    pci_cmd646_ide_init(pci_bus, hd, 1);
+    pci_dev = pci_create(pci_busA, PCI_DEVFN(3, 0), "cmd646-ide");
+    qdev_prop_set_uint32(&pci_dev->qdev, "secondary", 1);
+    qdev_init_nofail(&pci_dev->qdev);
+    pci_ide_create_devs(pci_dev, hd);
 
     isa_create_simple(isa_bus, "i8042");
 
                            /* XXX: need an option to load a NVRAM image */
                            0,
                            graphic_width, graphic_height, graphic_depth,
-                           (uint8_t *)&nd_table[onboard_nic_idx].macaddr);
+                           (uint8_t *)&macaddr);
 
     dev = qdev_create(NULL, TYPE_FW_CFG_IO);
     qdev_prop_set_bit(dev, "dma_enabled", false);