diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-10-19 18:42:51 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-10-19 18:42:51 +0100 |
commit | 063833a6ec2a6747e27c5f9866bb44c7e8de1265 (patch) | |
tree | 259d6e4d4f1c48b6bd515a092b5b81cea54d6cd3 /hw | |
parent | d634fc0499001c5ee49e1004576f9c92ea7c05ff (diff) | |
parent | bcf9e2c2f2b7a610efaafc4bd6d0bee9181c2345 (diff) |
Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-signed' into staging
qemu-sparc update
# gpg: Signature made Thu 19 Oct 2017 07:50:16 BST
# gpg: using RSA key 0x5BC2C56FAE0F321F
# gpg: Good signature from "Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>"
# Primary key fingerprint: CC62 1AB9 8E82 200D 915C C9C4 5BC2 C56F AE0F 321F
* remotes/mcayland/tags/qemu-sparc-signed:
sun4u: fix assert when adding NICs which aren't the in-built model
sun4u: update PCI topology to include simba PCI bridges
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/pci-host/apb.c | 47 | ||||
-rw-r--r-- | hw/sparc64/sun4u.c | 60 |
2 files changed, 79 insertions, 28 deletions
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 1edf57f600..64025cd8cc 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -599,16 +599,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; } @@ -669,6 +688,12 @@ static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp) 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)); } @@ -690,9 +715,9 @@ 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(), + &d->pci_ioport, 0, 32, TYPE_PCI_BUS); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); @@ -725,14 +750,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); @@ -798,8 +823,8 @@ static int pci_pbm_init_device(SysBusDevice *dev) 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); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index 8282651aeb..77a787466a 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" @@ -440,7 +442,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem, 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, @@ -454,10 +457,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) 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; @@ -470,27 +480,43 @@ 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); - 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(pci_busB, -1, "sunhme"); + } } else { - pci_nic_init_nofail(nd, pci_bus, "ne2k_pci", NULL); + pci_dev = pci_create(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"); @@ -531,7 +557,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, /* 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); |