diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-09-04 18:53:46 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-09-04 18:53:46 +0100 |
commit | 53e2c48d3f0db6a1598f49baf0b56dd4975e53a7 (patch) | |
tree | 5ef273021e6de542eac0e107b16c475d0b3e0173 | |
parent | 2b483739791b33c46e6084b51edcf62107058ae1 (diff) | |
parent | e5fd1eb05ec918e9877640d85ec45680cf106632 (diff) |
Merge remote-tracking branch 'remotes/mcayland/tags/qemu-sparc-signed' into staging
qemu-sparc update
# gpg: Signature made Mon 04 Sep 2017 18:45:26 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:
apb: add busA qdev property to PBM PCI bridge
apb: fix endianness for APB and PCI config accesses
apb: fix up PCI bus nomenclature
sun4u: expose fw_cfg and NVRAM on ebus PCI IO address space
sun4u: switch to using qdev to instantiate fw_cfg interface
sun4u: pass PCIDevice into pci_ebus_init() instead of PCIBus
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | hw/pci-host/apb.c | 62 | ||||
-rw-r--r-- | hw/sparc64/sun4u.c | 27 |
2 files changed, 61 insertions, 28 deletions
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 96e5d0b60d..b709456b97 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -155,6 +155,18 @@ typedef struct APBState { unsigned int nr_resets; } APBState; +#define TYPE_PBM_PCI_BRIDGE "pbm-bridge" +#define PBM_PCI_BRIDGE(obj) \ + OBJECT_CHECK(PBMPCIBridge, (obj), TYPE_PBM_PCI_BRIDGE) + +typedef struct PBMPCIBridge { + /*< private >*/ + PCIBridge parent_obj; + + /* Is this busA with in-built devices (ebus)? */ + bool busA; +} PBMPCIBridge; + static inline void pbm_set_request(APBState *s, unsigned int irq_num) { APB_DPRINTF("%s: request irq %d\n", __func__, irq_num); @@ -559,7 +571,7 @@ static uint64_t apb_config_readl (void *opaque, static const MemoryRegionOps apb_config_ops = { .read = apb_config_readl, .write = apb_config_writel, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_BIG_ENDIAN, }; static void apb_pci_config_write(void *opaque, hwaddr addr, @@ -568,7 +580,6 @@ static void apb_pci_config_write(void *opaque, hwaddr addr, APBState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s); - val = qemu_bswap_len(val, size); APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val); pci_data_write(phb->bus, addr, val, size); } @@ -581,7 +592,6 @@ static uint64_t apb_pci_config_read(void *opaque, hwaddr addr, PCIHostState *phb = PCI_HOST_BRIDGE(s); ret = pci_data_read(phb->bus, addr, size); - ret = qemu_bswap_len(ret, size); APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret); return ret; } @@ -634,8 +644,6 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level) static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp) { - pci_bridge_initfn(dev, TYPE_PCI_BUS); - /* * command register: * According to PCI bridge spec, after reset @@ -645,16 +653,28 @@ static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp) * the reset value should be zero unless the boot pin is tied high * (which is true) and thus it should be PCI_COMMAND_MEMORY. */ - pci_set_word(dev->config + PCI_COMMAND, - PCI_COMMAND_MEMORY); + uint16_t cmd = PCI_COMMAND_MEMORY; + PBMPCIBridge *br = PBM_PCI_BRIDGE(dev); + + pci_bridge_initfn(dev, TYPE_PCI_BUS); + + /* If initialising busA, ensure that we allow IO transactions so that + we get the early serial console until OpenBIOS configures the bridge */ + if (br->busA) { + cmd |= PCI_COMMAND_IO; + } + + pci_set_word(dev->config + PCI_COMMAND, cmd); pci_set_word(dev->config + PCI_STATUS, PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM); + + pci_bridge_update_mappings(PCI_BRIDGE(br)); } PCIBus *pci_apb_init(hwaddr special_base, hwaddr mem_base, - qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3, + qemu_irq *ivec_irqs, PCIBus **busA, PCIBus **busB, qemu_irq **pbm_irqs) { DeviceState *dev; @@ -703,20 +723,19 @@ PCIBus *pci_apb_init(hwaddr special_base, /* APB secondary busses */ pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true, - "pbm-bridge"); + TYPE_PBM_PCI_BRIDGE); br = PCI_BRIDGE(pci_dev); - pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1", - pci_apb_map_irq); + pci_bridge_map_irq(br, "pciB", pci_apb_map_irq); qdev_init_nofail(&pci_dev->qdev); - *bus2 = pci_bridge_get_sec_bus(br); + *busB = pci_bridge_get_sec_bus(br); pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true, - "pbm-bridge"); + TYPE_PBM_PCI_BRIDGE); br = PCI_BRIDGE(pci_dev); - pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2", - pci_apb_map_irq); + pci_bridge_map_irq(br, "pciA", pci_apb_map_irq); + qdev_prop_set_bit(DEVICE(pci_dev), "busA", true); qdev_init_nofail(&pci_dev->qdev); - *bus3 = pci_bridge_get_sec_bus(br); + *busA = pci_bridge_get_sec_bus(br); return phb->bus; } @@ -745,7 +764,7 @@ static void pci_pbm_reset(DeviceState *d) static const MemoryRegionOps pci_config_ops = { .read = apb_pci_config_read, .write = apb_pci_config_write, - .endianness = DEVICE_NATIVE_ENDIAN, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int pci_pbm_init_device(SysBusDevice *dev) @@ -836,6 +855,11 @@ static const TypeInfo pbm_host_info = { .class_init = pbm_host_class_init, }; +static Property pbm_pci_properties[] = { + DEFINE_PROP_BOOL("busA", PBMPCIBridge, busA, false), + DEFINE_PROP_END_OF_LIST(), +}; + static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -851,12 +875,14 @@ static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->reset = pci_bridge_reset; dc->vmsd = &vmstate_pci_device; + dc->props = pbm_pci_properties; } static const TypeInfo pbm_pci_bridge_info = { - .name = "pbm-bridge", + .name = TYPE_PBM_PCI_BRIDGE, .parent = TYPE_PCI_BRIDGE, .class_init = pbm_pci_bridge_class_init, + .instance_size = sizeof(PBMPCIBridge), }; static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data) diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index bbdb40c330..5e59269adc 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -224,13 +224,11 @@ static void isa_irq_handler(void *opaque, int n, int level) /* EBUS (Eight bit bus) bridge */ static ISABus * -pci_ebus_init(PCIBus *bus, int devfn, qemu_irq *irqs) +pci_ebus_init(PCIDevice *pci_dev, qemu_irq *irqs) { qemu_irq *isa_irq; - PCIDevice *pci_dev; ISABus *isa_bus; - pci_dev = pci_create_simple(bus, devfn, "ebus"); isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(pci_dev), "isa.0")); isa_irq = qemu_allocate_irqs(isa_irq_handler, irqs, 16); isa_bus_irqs(isa_bus, isa_irq); @@ -428,7 +426,8 @@ static void sun4uv_init(MemoryRegion *address_space_mem, Nvram *nvram; unsigned int i; uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry; - PCIBus *pci_bus, *pci_bus2, *pci_bus3; + PCIBus *pci_bus, *pci_busA, *pci_busB; + PCIDevice *ebus; ISABus *isa_bus; SysBusDevice *s; qemu_irq *ivec_irqs, *pbm_irqs; @@ -447,12 +446,13 @@ static void sun4uv_init(MemoryRegion *address_space_mem, prom_init(hwdef->prom_addr, bios_name); 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_bus2, - &pci_bus3, &pbm_irqs); + 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_bus3 - isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs); + /* XXX Should be pci_busA */ + ebus = pci_create_simple(pci_bus, -1, "ebus"); + isa_bus = pci_ebus_init(ebus, pbm_irqs); i = 0; if (hwdef->console_serial_base) { @@ -492,7 +492,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem, /* Map NVRAM into I/O (ebus) space */ nvram = m48t59_init(NULL, 0, 0, NVRAM_SIZE, 1968, 59); s = SYS_BUS_DEVICE(nvram); - memory_region_add_subregion(get_system_io(), 0x2000, + memory_region_add_subregion(pci_address_space_io(ebus), 0x2000, sysbus_mmio_get_region(s, 0)); initrd_size = 0; @@ -512,7 +512,14 @@ static void sun4uv_init(MemoryRegion *address_space_mem, graphic_width, graphic_height, graphic_depth, (uint8_t *)&nd_table[0].macaddr); - fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT); + dev = qdev_create(NULL, TYPE_FW_CFG_IO); + qdev_prop_set_bit(dev, "dma_enabled", false); + object_property_add_child(OBJECT(ebus), TYPE_FW_CFG, OBJECT(dev), NULL); + qdev_init_nofail(dev); + memory_region_add_subregion(pci_address_space_io(ebus), BIOS_CFG_IOPORT, + &FW_CFG_IO(dev)->comb_iomem); + + fw_cfg = FW_CFG(dev); fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); |