On 12/07/17 10:59, Artyom Tarasenko wrote: > On Tue, Jul 11, 2017 at 11:53 PM, Mark Cave-Ayland > <mark.cave-ayl...@ilande.co.uk> wrote: >> This switches the sun4u model to being much closer to a real Ultra 5. >> >> Since the existing code previously bypassed the PCI bridge interrupt >> swizzling, reorganise the interrupt mapping functions so that >> pci_pbm_map_irq() is used by the PCI bridges and pci_apb_map_irq() is >> used by the PCI host bridge. >> >> As part of this change we also combine the "onboard" NIC and the ebus into >> a single multi-function device as done on a real Ultra 5. > > While they are combined on a real Ultra 5, it has a different NIC. > Are the guest OSes smart enough to use NE2000 as an onboard device?
Yes, since the ne2000 is the default NIC unless you explicitly change it on the command line - in which case I think it's fairly safe to assume that you know what you're doing ;) At some point I'll come up with a proper hme device as not all OSs enable the ne2000 driver by default by SPARC, which should get networking going for pretty much all SPARC64 OSs. >> Finally we mark the physically unavailable slots (plus slot 0 in busA) as >> reserved to ensure that users can't plug devices into non-existent slots >> which will break interrupt routing. >> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk> >> --- >> hw/pci-host/apb.c | 35 +++++++++++++++++++++++++++-------- >> hw/sparc64/sun4u.c | 25 ++++++++++++++++++++----- >> 2 files changed, 47 insertions(+), 13 deletions(-) >> >> diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c >> index f9badad..5000432 100644 >> --- a/hw/pci-host/apb.c >> +++ b/hw/pci-host/apb.c >> @@ -601,16 +601,35 @@ static uint64_t apb_pci_config_read(void *opaque, >> hwaddr addr, >> /* 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; >> } >> >> @@ -692,7 +711,7 @@ PCIBus *pci_apb_init(hwaddr special_base, >> 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(), >> 0, 32, TYPE_PCI_BUS); >> @@ -726,14 +745,14 @@ PCIBus *pci_apb_init(hwaddr special_base, >> 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); >> diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c >> index 3bb3bf2..b8b96be 100644 >> --- a/hw/sparc64/sun4u.c >> +++ b/hw/sparc64/sun4u.c >> @@ -27,6 +27,7 @@ >> #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" >> @@ -42,6 +43,7 @@ >> #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" >> @@ -448,10 +450,17 @@ static void sun4uv_init(MemoryRegion >> *address_space_mem, >> 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) leaving slots >> + 0-3 are free on busB 4*/ >> + 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; >> @@ -464,14 +473,20 @@ static void sun4uv_init(MemoryRegion >> *address_space_mem, >> serial_hds_isa_init(isa_bus, i, MAX_SERIAL_PORTS); >> parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS); >> >> - pci_dev = pci_create(pci_bus, -1, "ne2k_pci"); >> + pci_dev = pci_create_simple(pci_busA, PCI_DEVFN(2, 0), "VGA"); >> + >> + pci_dev = pci_create_multifunction(pci_busA, PCI_DEVFN(1, 1), true, >> + "ne2k_pci"); >> dev = &pci_dev->qdev; >> qdev_set_nic_properties(dev, &nd_table[0]); >> qdev_init_nofail(dev); >> >> 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"); >> >> -- >> 1.7.10.4 ATB, Mark.