From 4d309c96635b7a961e3e86e2605a97ef945aeee2 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:45 +0000 Subject: uninorth: trivial style fixups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes sure we keep patchew/checkpatch happy during the remainder of this patchset. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 66991da975..710818e355 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -272,7 +272,6 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, UNINState *d; /* Uninorth AGP bus */ - dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); @@ -302,16 +301,23 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) { - d->config[0x0C] = 0x08; // cache_line_size - d->config[0x0D] = 0x10; // latency_timer - d->config[0x34] = 0x00; // capabilities_pointer + /* cache_line_size */ + d->config[0x0C] = 0x08; + /* latency_timer */ + d->config[0x0D] = 0x10; + /* capabilities_pointer */ + d->config[0x34] = 0x00; } static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) { - d->config[0x0C] = 0x08; // cache_line_size - d->config[0x0D] = 0x10; // latency_timer - // d->config[0x34] = 0x80; // capabilities_pointer + /* cache_line_size */ + d->config[0x0C] = 0x08; + /* latency_timer */ + d->config[0x0D] = 0x10; + /* capabilities_pointer + d->config[0x34] = 0x80; */ + /* * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI * memory space with base 0x80000000, size 0x10000000 for Apple's @@ -333,9 +339,12 @@ static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp) { - d->config[0x0C] = 0x08; // cache_line_size - d->config[0x0D] = 0x10; // latency_timer - d->config[0x34] = 0x00; // capabilities_pointer + /* cache_line_size */ + d->config[0x0C] = 0x08; + /* latency_timer */ + d->config[0x0D] = 0x10; + /* capabilities_pointer */ + d->config[0x34] = 0x00; } static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) -- cgit v1.2.3 From 3e0204e15e93e0358339a0feff8f0ec7fe513e20 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:46 +0000 Subject: uninorth: remove second set of uninorth token registers Commit 593c181160: "PPC: Newworld: Add second uninorth control register set" added a second set of uninorth registers at 0xf3000000. Testing MacOS 9.2 to MacOS X 10.4 reveals no accesses to this address and I can't find any reference to it in Apple's Core99.cpp source so I'm assuming that this was the result of another bug that has now been fixed. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'hw') diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 2f5b6f651a..39944203a4 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -147,7 +147,6 @@ static void ppc_core99_init(MachineState *machine) qemu_irq *pic, **openpic_irqs; MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *unin_memory = g_new(MemoryRegion, 1); - MemoryRegion *unin2_memory = g_new(MemoryRegion, 1); int linux_boot, i, j, k; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; @@ -282,9 +281,6 @@ static void ppc_core99_init(MachineState *machine) memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory); - memory_region_init_io(unin2_memory, NULL, &unin_ops, token, "unin", 0x1000); - memory_region_add_subregion(get_system_memory(), 0xf3000000, unin2_memory); - openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); openpic_irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB); -- cgit v1.2.3 From 0203459943ebcb366f68ff65f2191c18ee7533d9 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:47 +0000 Subject: uninorth: QOMify PCI and AGP host bridges Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 79 ++++++++++++++++++++------------------------------ 1 file changed, 32 insertions(+), 47 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 710818e355..1d4d3f5705 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -129,72 +129,61 @@ static const MemoryRegionOps unin_data_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static int pci_unin_main_init_device(SysBusDevice *dev) +static void pci_unin_main_init(Object *obj) { - PCIHostState *h; + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Use values found on a real PowerMac */ /* Uninorth main bus */ - h = PCI_HOST_BRIDGE(dev); - memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - dev, "pci-conf-idx", 0x1000); - memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, dev, + obj, "pci-conf-idx", 0x1000); + memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, "pci-conf-data", 0x1000); - sysbus_init_mmio(dev, &h->conf_mem); - sysbus_init_mmio(dev, &h->data_mem); - - return 0; + sysbus_init_mmio(sbd, &h->conf_mem); + sysbus_init_mmio(sbd, &h->data_mem); } - -static int pci_u3_agp_init_device(SysBusDevice *dev) +static void pci_u3_agp_init(Object *obj) { - PCIHostState *h; + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Uninorth U3 AGP bus */ - h = PCI_HOST_BRIDGE(dev); - memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - dev, "pci-conf-idx", 0x1000); - memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, dev, + obj, "pci-conf-idx", 0x1000); + memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, "pci-conf-data", 0x1000); - sysbus_init_mmio(dev, &h->conf_mem); - sysbus_init_mmio(dev, &h->data_mem); - - return 0; + sysbus_init_mmio(sbd, &h->conf_mem); + sysbus_init_mmio(sbd, &h->data_mem); } -static int pci_unin_agp_init_device(SysBusDevice *dev) +static void pci_unin_agp_init(Object *obj) { - PCIHostState *h; + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Uninorth AGP bus */ - h = PCI_HOST_BRIDGE(dev); - memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - dev, "pci-conf-idx", 0x1000); + obj, "pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, - dev, "pci-conf-data", 0x1000); - sysbus_init_mmio(dev, &h->conf_mem); - sysbus_init_mmio(dev, &h->data_mem); - return 0; + obj, "pci-conf-data", 0x1000); + sysbus_init_mmio(sbd, &h->conf_mem); + sysbus_init_mmio(sbd, &h->data_mem); } -static int pci_unin_internal_init_device(SysBusDevice *dev) +static void pci_unin_internal_init(Object *obj) { - PCIHostState *h; + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Uninorth internal bus */ - h = PCI_HOST_BRIDGE(dev); - memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - dev, "pci-conf-idx", 0x1000); + obj, "pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, - dev, "pci-conf-data", 0x1000); - sysbus_init_mmio(dev, &h->conf_mem); - sysbus_init_mmio(dev, &h->data_mem); - return 0; + obj, "pci-conf-data", 0x1000); + sysbus_init_mmio(sbd, &h->conf_mem); + sysbus_init_mmio(sbd, &h->data_mem); } PCIBus *pci_pmac_init(qemu_irq *pic, @@ -461,10 +450,8 @@ static const TypeInfo unin_internal_pci_host_info = { static void pci_unin_main_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - sbc->init = pci_unin_main_init_device; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -472,15 +459,14 @@ static const TypeInfo pci_unin_main_info = { .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(UNINState), + .instance_init = pci_unin_main_init, .class_init = pci_unin_main_class_init, }; static void pci_u3_agp_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - sbc->init = pci_u3_agp_init_device; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -488,15 +474,14 @@ static const TypeInfo pci_u3_agp_info = { .name = TYPE_U3_AGP_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(UNINState), + .instance_init = pci_u3_agp_init, .class_init = pci_u3_agp_class_init, }; static void pci_unin_agp_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - sbc->init = pci_unin_agp_init_device; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -504,15 +489,14 @@ static const TypeInfo pci_unin_agp_info = { .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(UNINState), + .instance_init = pci_unin_agp_init, .class_init = pci_unin_agp_class_init, }; static void pci_unin_internal_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - sbc->init = pci_unin_internal_init_device; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -520,6 +504,7 @@ static const TypeInfo pci_unin_internal_info = { .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(UNINState), + .instance_init = pci_unin_internal_init, .class_init = pci_unin_internal_class_init, }; -- cgit v1.2.3 From 72941bb76aeeb63d24850bb7fdbb126b7190fd13 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:48 +0000 Subject: uninorth: remove stray PCIBus realize from mac_newworld.c After QOMification this is clearly no longer needed (and possibly hasn't been for some time). Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 1 - 1 file changed, 1 deletion(-) (limited to 'hw') diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 39944203a4..4ff1c293a8 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -350,7 +350,6 @@ static void ppc_core99_init(MachineState *machine) pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); machine_arch = ARCH_MAC99; } - object_property_set_bool(OBJECT(pci_bus), true, "realized", &error_abort); machine->usb |= defaults_enabled() && !machine->usb_disabled; -- cgit v1.2.3 From 5d2eaa02501c9a75a221caa443553d3cc6077cfd Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:49 +0000 Subject: uninorth: move uninorth definitions into uninorth.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland [dwg: Added hw/hw.h #include as suggested by Philippe Mathieu-Daudé] Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 1d4d3f5705..600d675573 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -26,31 +26,11 @@ #include "hw/ppc/mac.h" #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" +#include "hw/pci-host/uninorth.h" #include "trace.h" static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e }; -#define TYPE_UNI_NORTH_PCI_HOST_BRIDGE "uni-north-pci-pcihost" -#define TYPE_UNI_NORTH_AGP_HOST_BRIDGE "uni-north-agp-pcihost" -#define TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE "uni-north-internal-pci-pcihost" -#define TYPE_U3_AGP_HOST_BRIDGE "u3-agp-pcihost" - -#define UNI_NORTH_PCI_HOST_BRIDGE(obj) \ - OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_PCI_HOST_BRIDGE) -#define UNI_NORTH_AGP_HOST_BRIDGE(obj) \ - OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_AGP_HOST_BRIDGE) -#define UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj) \ - OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE) -#define U3_AGP_HOST_BRIDGE(obj) \ - OBJECT_CHECK(UNINState, (obj), TYPE_U3_AGP_HOST_BRIDGE) - -typedef struct UNINState { - PCIHostState parent_obj; - - MemoryRegion pci_mmio; - MemoryRegion pci_hole; -} UNINState; - static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) { return (irq_num + (pci_dev->devfn >> 3)) & 3; -- cgit v1.2.3 From 0f4b5415c31ed1fee02f5826fe0d2d585806fa95 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:50 +0000 Subject: uninorth: alter pci_pmac_init() and pci_pmac_u3_init() to return uninorth device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for moving the device wiring into the New World machine. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 16 ++++++++-------- hw/ppc/mac.h | 10 ++++++---- hw/ppc/mac_newworld.c | 10 ++++++++-- 3 files changed, 22 insertions(+), 14 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 600d675573..b081e3c153 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -166,9 +166,9 @@ static void pci_unin_internal_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } -PCIBus *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io) +UNINState *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -228,12 +228,12 @@ PCIBus *pci_pmac_init(qemu_irq *pic, sysbus_mmio_map(s, 1, 0xf4c00000); #endif - return h->bus; + return d; } -PCIBus *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io) +UNINState *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io) { DeviceState *dev; SysBusDevice *s; @@ -265,7 +265,7 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, pci_create_simple(h->bus, 11 << 3, "u3-agp"); - return h->bus; + return d; } static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index a02f797598..fcf13cb757 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -31,6 +31,8 @@ #include "hw/ide/internal.h" #include "hw/input/adb.h" #include "hw/misc/mos6522.h" +#include "hw/pci/pci_host.h" +#include "hw/pci-host/uninorth.h" /* SMP is not enabled, for now */ #define MAX_CPUS 1 @@ -86,12 +88,12 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, MemoryRegion *address_space_io); /* UniNorth PCI */ -PCIBus *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io); -PCIBus *pci_pmac_u3_init(qemu_irq *pic, +UNINState *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space_mem, MemoryRegion *address_space_io); +UNINState *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem, + MemoryRegion *address_space_io); /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 4ff1c293a8..ccf34ee36c 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -151,6 +151,7 @@ static void ppc_core99_init(MachineState *machine) MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; + UNINState *uninorth_pci; PCIBus *pci_bus; NewWorldMacIOState *macio; MACIOIDEState *macio_ide; @@ -344,10 +345,12 @@ static void ppc_core99_init(MachineState *machine) if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io()); + uninorth_pci = pci_pmac_u3_init(pic, get_system_memory(), + get_system_io()); machine_arch = ARCH_MAC99_U3; } else { - pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io()); + uninorth_pci = pci_pmac_init(pic, get_system_memory(), + get_system_io()); machine_arch = ARCH_MAC99; } @@ -360,6 +363,9 @@ static void ppc_core99_init(MachineState *machine) tbfreq = TBFREQ; } + /* init basic PC hardware */ + pci_bus = PCI_HOST_BRIDGE(uninorth_pci)->bus; + /* MacIO */ macio = NEWWORLD_MACIO(pci_create(pci_bus, -1, TYPE_NEWWORLD_MACIO)); dev = DEVICE(macio); -- cgit v1.2.3 From a5ed75fe2e6625b2ab9ed0694d7a5c95a74b84f7 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:54 +0000 Subject: heathrow: remove obsolete heathow_init() function Instead wire up heathrow to the CPU and grackle PCI host using qdev GPIOs. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/intc/heathrow_pic.c | 23 +++++------------------ hw/ppc/mac.h | 4 ---- hw/ppc/mac_oldworld.c | 20 ++++++++++++-------- 3 files changed, 17 insertions(+), 30 deletions(-) (limited to 'hw') diff --git a/hw/intc/heathrow_pic.c b/hw/intc/heathrow_pic.c index 393fdd7326..b8b997deca 100644 --- a/hw/intc/heathrow_pic.c +++ b/hw/intc/heathrow_pic.c @@ -172,27 +172,14 @@ static void heathrow_init(Object *obj) HeathrowState *s = HEATHROW(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - memory_region_init_io(&s->mem, OBJECT(s), &heathrow_ops, s, - "heathrow-pic", 0x1000); - sysbus_init_mmio(sbd, &s->mem); -} - -DeviceState *heathrow_pic_init(int nb_cpus, qemu_irq **irqs, - qemu_irq **pic_irqs) -{ - DeviceState *d; - HeathrowState *s; - - d = qdev_create(NULL, TYPE_HEATHROW); - qdev_init_nofail(d); - - s = HEATHROW(d); /* only 1 CPU */ - s->irqs = irqs[0]; + qdev_init_gpio_out(DEVICE(obj), s->irqs, 1); - *pic_irqs = qemu_allocate_irqs(heathrow_set_irq, s, HEATHROW_NUM_IRQS); + qdev_init_gpio_in(DEVICE(obj), heathrow_set_irq, HEATHROW_NUM_IRQS); - return d; + memory_region_init_io(&s->mem, OBJECT(s), &heathrow_ops, s, + "heathrow-pic", 0x1000); + sysbus_init_mmio(sbd, &s->mem); } static void heathrow_class_init(ObjectClass *oc, void *data) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index fcf13cb757..d661515e9d 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -77,10 +77,6 @@ void macio_ide_register_dma(MACIOIDEState *ide); void macio_init(PCIDevice *dev, MemoryRegion *pic_mem); -/* Heathrow PIC */ -DeviceState *heathrow_pic_init(int nb_cpus, qemu_irq **irqs, - qemu_irq **pic_irqs); - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 10e291ca22..9bd4ece16d 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -84,7 +84,7 @@ static void ppc_heathrow_init(MachineState *machine) PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; - qemu_irq *pic, **heathrow_irqs; + qemu_irq *pic; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); @@ -227,16 +227,15 @@ static void ppc_heathrow_init(MachineState *machine) memory_region_add_subregion(sysmem, 0xfe000000, isa); /* XXX: we register only 1 output pin for heathrow PIC */ - heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); - heathrow_irqs[0] = - g_malloc0(smp_cpus * sizeof(qemu_irq) * 1); + pic_dev = qdev_create(NULL, TYPE_HEATHROW); + qdev_init_nofail(pic_dev); + /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: - heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); - heathrow_irqs[i][0] = - ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; + qdev_connect_gpio_out(pic_dev, 0, + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]); break; default: error_report("Bus model not supported on OldWorld Mac machine"); @@ -244,6 +243,11 @@ static void ppc_heathrow_init(MachineState *machine) } } + pic = g_new0(qemu_irq, HEATHROW_NUM_IRQS); + for (i = 0; i < HEATHROW_NUM_IRQS; i++) { + pic[i] = qdev_get_gpio_in(pic_dev, i); + } + /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); @@ -256,7 +260,7 @@ static void ppc_heathrow_init(MachineState *machine) error_report("Only 6xx bus is supported on heathrow machine"); exit(1); } - pic_dev = heathrow_pic_init(1, heathrow_irqs, &pic); + pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory(), get_system_io()); -- cgit v1.2.3 From b0318ec10b2a97cac0cdce50a693a11f882c8549 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:55 +0000 Subject: grackle: general tidy-up and QOMify This is the first step towards removing the old-style pci_grackle_init() function. Following on from the previous commit we can now pass the heathrow device as an object link and wire up the heathrow IRQs via qdev GPIOs. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/grackle.c | 96 +++++++++++++++++++++++++++++++++------------------ hw/ppc/mac.h | 2 +- hw/ppc/mac_oldworld.c | 2 +- 3 files changed, 64 insertions(+), 36 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 033588b7d2..f8935246c3 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -27,6 +27,8 @@ #include "hw/pci/pci_host.h" #include "hw/ppc/mac.h" #include "hw/pci/pci.h" +#include "hw/intc/heathrow_pic.h" +#include "qapi/error.h" #include "trace.h" #define GRACKLE_PCI_HOST_BRIDGE(obj) \ @@ -35,6 +37,8 @@ typedef struct GrackleState { PCIHostState parent_obj; + HeathrowState *pic; + qemu_irq irqs[4]; MemoryRegion pci_mmio; MemoryRegion pci_hole; } GrackleState; @@ -47,13 +51,22 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num) static void pci_grackle_set_irq(void *opaque, int irq_num, int level) { - qemu_irq *pic = opaque; + GrackleState *s = opaque; trace_grackle_set_irq(irq_num, level); - qemu_set_irq(pic[irq_num + 0x15], level); + qemu_set_irq(s->irqs[irq_num], level); } -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, +static void grackle_init_irqs(GrackleState *s) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s->irqs); i++) { + s->irqs[i] = qdev_get_gpio_in(DEVICE(s->pic), 0x15 + i); + } +} + +PCIBus *pci_grackle_init(uint32_t base, DeviceState *pic_dev, MemoryRegion *address_space_mem, MemoryRegion *address_space_io) { @@ -63,60 +76,75 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, GrackleState *d; dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); phb = PCI_HOST_BRIDGE(dev); d = GRACKLE_PCI_HOST_BRIDGE(dev); - memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL); - memory_region_init_alias(&d->pci_hole, OBJECT(s), "pci-hole", &d->pci_mmio, - 0x80000000ULL, 0x7e000000ULL); memory_region_add_subregion(address_space_mem, 0x80000000ULL, &d->pci_hole); + sysbus_mmio_map(s, 0, base); + sysbus_mmio_map(s, 1, base + 0x00200000); + + return phb->bus; +} + +static void grackle_realize(DeviceState *dev, Error **errp) +{ + GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(dev); + PCIHostState *phb = PCI_HOST_BRIDGE(dev); + phb->bus = pci_register_root_bus(dev, NULL, pci_grackle_set_irq, pci_grackle_map_irq, - pic, - &d->pci_mmio, - address_space_io, + s, + &s->pci_mmio, + get_system_io(), 0, 4, TYPE_PCI_BUS); pci_create_simple(phb->bus, 0, "grackle"); - qdev_init_nofail(dev); - - sysbus_mmio_map(s, 0, base); - sysbus_mmio_map(s, 1, base + 0x00200000); - - return phb->bus; + grackle_init_irqs(s); } -static int pci_grackle_init_device(SysBusDevice *dev) +static void grackle_init(Object *obj) { - PCIHostState *phb; + GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + PCIHostState *phb = PCI_HOST_BRIDGE(obj); - phb = PCI_HOST_BRIDGE(dev); + memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL); + memory_region_init_alias(&s->pci_hole, OBJECT(s), "pci-hole", &s->pci_mmio, + 0x80000000ULL, 0x7e000000ULL); - memory_region_init_io(&phb->conf_mem, OBJECT(dev), &pci_host_conf_le_ops, - dev, "pci-conf-idx", 0x1000); - memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops, - dev, "pci-data-idx", 0x1000); - sysbus_init_mmio(dev, &phb->conf_mem); - sysbus_init_mmio(dev, &phb->data_mem); + memory_region_init_io(&phb->conf_mem, obj, &pci_host_conf_le_ops, + DEVICE(obj), "pci-conf-idx", 0x1000); + memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, + DEVICE(obj), "pci-data-idx", 0x1000); - return 0; + object_property_add_link(obj, "pic", TYPE_HEATHROW, + (Object **) &s->pic, + qdev_prop_allow_set_link_before_realize, + 0, NULL); + + sysbus_init_mmio(sbd, &phb->conf_mem); + sysbus_init_mmio(sbd, &phb->data_mem); } -static void grackle_pci_host_realize(PCIDevice *d, Error **errp) +static void grackle_pci_realize(PCIDevice *d, Error **errp) { d->config[0x09] = 0x01; } static void grackle_pci_class_init(ObjectClass *klass, void *data) { - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->realize = grackle_pci_host_realize; + k->realize = grackle_pci_realize; k->vendor_id = PCI_VENDOR_ID_MOTOROLA; k->device_id = PCI_DEVICE_ID_MOTOROLA_MPC106; k->revision = 0x00; @@ -139,26 +167,26 @@ static const TypeInfo grackle_pci_info = { }, }; -static void pci_grackle_class_init(ObjectClass *klass, void *data) +static void grackle_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = pci_grackle_init_device; + dc->realize = grackle_realize; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } -static const TypeInfo grackle_pci_host_info = { +static const TypeInfo grackle_host_info = { .name = TYPE_GRACKLE_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(GrackleState), - .class_init = pci_grackle_class_init, + .instance_init = grackle_init, + .class_init = grackle_class_init, }; static void grackle_register_types(void) { type_register_static(&grackle_pci_info); - type_register_static(&grackle_pci_host_info); + type_register_static(&grackle_host_info); } type_init(grackle_register_types) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index d661515e9d..695557b8bf 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -79,7 +79,7 @@ void macio_init(PCIDevice *dev, /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, +PCIBus *pci_grackle_init(uint32_t base, DeviceState *pic_dev, MemoryRegion *address_space_mem, MemoryRegion *address_space_io); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 9bd4ece16d..d48abfef07 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -261,7 +261,7 @@ static void ppc_heathrow_init(MachineState *machine) exit(1); } - pci_bus = pci_grackle_init(0xfec00000, pic, + pci_bus = pci_grackle_init(0xfec00000, pic_dev, get_system_memory(), get_system_io()); pci_vga_init(pci_bus); -- cgit v1.2.3 From a773e64a8fd2a3ef97d6e405dbfb28c17660136d Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:56 +0000 Subject: grackle: remove deprecated pci_grackle_init() function Instead wire up the grackle device inside the Mac Old World machine. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/grackle.c | 28 +--------------------------- hw/ppc/mac.h | 3 --- hw/ppc/mac_oldworld.c | 21 ++++++++++++++++++--- 3 files changed, 19 insertions(+), 33 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index f8935246c3..e4583d493b 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -66,33 +66,6 @@ static void grackle_init_irqs(GrackleState *s) } } -PCIBus *pci_grackle_init(uint32_t base, DeviceState *pic_dev, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io) -{ - DeviceState *dev; - SysBusDevice *s; - PCIHostState *phb; - GrackleState *d; - - dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); - object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", - &error_abort); - qdev_init_nofail(dev); - - s = SYS_BUS_DEVICE(dev); - phb = PCI_HOST_BRIDGE(dev); - d = GRACKLE_PCI_HOST_BRIDGE(dev); - - memory_region_add_subregion(address_space_mem, 0x80000000ULL, - &d->pci_hole); - - sysbus_mmio_map(s, 0, base); - sysbus_mmio_map(s, 1, base + 0x00200000); - - return phb->bus; -} - static void grackle_realize(DeviceState *dev, Error **errp) { GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(dev); @@ -132,6 +105,7 @@ static void grackle_init(Object *obj) sysbus_init_mmio(sbd, &phb->conf_mem); sysbus_init_mmio(sbd, &phb->data_mem); + sysbus_init_mmio(sbd, &s->pci_hole); } static void grackle_pci_realize(PCIDevice *d, Error **errp) diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 695557b8bf..93f25d7acb 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -79,9 +79,6 @@ void macio_init(PCIDevice *dev, /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" -PCIBus *pci_grackle_init(uint32_t base, DeviceState *pic_dev, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io); /* UniNorth PCI */ UNINState *pci_pmac_init(qemu_irq *pic, diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index d48abfef07..f0246f43d3 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -34,6 +34,7 @@ #include "net/net.h" #include "hw/isa/isa.h" #include "hw/pci/pci.h" +#include "hw/pci/pci_host.h" #include "hw/boards.h" #include "hw/nvram/fw_cfg.h" #include "hw/char/escc.h" @@ -55,6 +56,8 @@ #define NDRV_VGA_FILENAME "qemu_vga.ndrv" +#define GRACKLE_BASE 0xfec00000 + static void fw_cfg_boot_set(void *opaque, const char *boot_device, Error **errp) { @@ -94,6 +97,7 @@ static void ppc_heathrow_init(MachineState *machine) PCIBus *pci_bus; OldWorldMacIOState *macio; MACIOIDEState *macio_ide; + SysBusDevice *s; DeviceState *dev, *pic_dev; BusState *adb_bus; int bios_size, ndrv_size; @@ -261,9 +265,20 @@ static void ppc_heathrow_init(MachineState *machine) exit(1); } - pci_bus = pci_grackle_init(0xfec00000, pic_dev, - get_system_memory(), - get_system_io()); + /* Grackle PCI host bridge */ + dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(s, 0, GRACKLE_BASE); + sysbus_mmio_map(s, 1, GRACKLE_BASE + 0x200000); + /* PCI hole */ + memory_region_add_subregion(get_system_memory(), 0x80000000ULL, + sysbus_mmio_get_region(s, 2)); + + pci_bus = PCI_HOST_BRIDGE(dev)->bus; + pci_vga_init(pci_bus); for (i = 0; i < nb_nics; i++) { -- cgit v1.2.3 From a94e5f998bf353e848a9ae7c679b06fff36b4698 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:57 +0000 Subject: grackle: move PCI IO (ISA) memory region into the grackle device This simplifies the Old World machine to simply mapping the ISA memory region into the main address space. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/grackle.c | 7 ++++++- hw/ppc/mac_oldworld.c | 9 +++------ 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index e4583d493b..4810a4de79 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -41,6 +41,7 @@ typedef struct GrackleState { qemu_irq irqs[4]; MemoryRegion pci_mmio; MemoryRegion pci_hole; + MemoryRegion pci_io; } GrackleState; /* Don't know if this matches real hardware, but it agrees with OHW. */ @@ -76,7 +77,7 @@ static void grackle_realize(DeviceState *dev, Error **errp) pci_grackle_map_irq, s, &s->pci_mmio, - get_system_io(), + &s->pci_io, 0, 4, TYPE_PCI_BUS); pci_create_simple(phb->bus, 0, "grackle"); @@ -90,6 +91,9 @@ static void grackle_init(Object *obj) PCIHostState *phb = PCI_HOST_BRIDGE(obj); memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL); + memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, + "pci-isa-mmio", 0x00200000); + memory_region_init_alias(&s->pci_hole, OBJECT(s), "pci-hole", &s->pci_mmio, 0x80000000ULL, 0x7e000000ULL); @@ -106,6 +110,7 @@ static void grackle_init(Object *obj) sysbus_init_mmio(sbd, &phb->conf_mem); sysbus_init_mmio(sbd, &phb->data_mem); sysbus_init_mmio(sbd, &s->pci_hole); + sysbus_init_mmio(sbd, &s->pci_io); } static void grackle_pci_realize(PCIDevice *d, Error **errp) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index f0246f43d3..f9e63b8d83 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -91,7 +91,6 @@ static void ppc_heathrow_init(MachineState *machine) int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); - MemoryRegion *isa = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; @@ -225,11 +224,6 @@ static void ppc_heathrow_init(MachineState *machine) } } - /* Register 2 MB of ISA IO space */ - memory_region_init_alias(isa, NULL, "isa_mmio", - get_system_io(), 0, 0x00200000); - memory_region_add_subregion(sysmem, 0xfe000000, isa); - /* XXX: we register only 1 output pin for heathrow PIC */ pic_dev = qdev_create(NULL, TYPE_HEATHROW); qdev_init_nofail(pic_dev); @@ -276,6 +270,9 @@ static void ppc_heathrow_init(MachineState *machine) /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); + /* Register 2 MB of ISA IO space */ + memory_region_add_subregion(get_system_memory(), 0xfe000000, + sysbus_mmio_get_region(s, 3)); pci_bus = PCI_HOST_BRIDGE(dev)->bus; -- cgit v1.2.3 From ab1244b53d8781e1f2c3dcbdd890afe1b817ca02 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:58 +0000 Subject: mac_oldworld: remove pics IRQ array and wire up macio to heathrow directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce constants for the pre-defined Old World IRQs to help keep things readable. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/mac.h | 8 ++++++++ hw/ppc/mac_oldworld.c | 27 ++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-) (limited to 'hw') diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 93f25d7acb..c5a33e96cb 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -47,6 +47,14 @@ #define ESCC_CLOCK 3686400 +/* Old World IRQs */ +#define OLDWORLD_CUDA_IRQ 0x12 +#define OLDWORLD_ESCCB_IRQ 0x10 +#define OLDWORLD_ESCCA_IRQ 0xf +#define OLDWORLD_IDE0_IRQ 0xd +#define OLDWORLD_IDE0_DMA_IRQ 0x2 +#define OLDWORLD_IDE1_IRQ 0xe +#define OLDWORLD_IDE1_DMA_IRQ 0x3 /* MacIO */ #define TYPE_MACIO_IDE "macio-ide" diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index f9e63b8d83..2bbcefa076 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -87,7 +87,6 @@ static void ppc_heathrow_init(MachineState *machine) PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; - qemu_irq *pic; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); @@ -241,11 +240,6 @@ static void ppc_heathrow_init(MachineState *machine) } } - pic = g_new0(qemu_irq, HEATHROW_NUM_IRQS); - for (i = 0; i < HEATHROW_NUM_IRQS; i++) { - pic[i] = qdev_get_gpio_in(pic_dev, i); - } - /* Timebase Frequency */ if (kvm_enabled()) { tbfreq = kvmppc_get_tbfreq(); @@ -287,13 +281,20 @@ static void ppc_heathrow_init(MachineState *machine) /* MacIO */ macio = OLDWORLD_MACIO(pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO)); dev = DEVICE(macio); - qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */ - qdev_connect_gpio_out(dev, 1, pic[0x10]); /* ESCC-B */ - qdev_connect_gpio_out(dev, 2, pic[0x0F]); /* ESCC-A */ - qdev_connect_gpio_out(dev, 3, pic[0x0D]); /* IDE-0 */ - qdev_connect_gpio_out(dev, 4, pic[0x02]); /* IDE-0 DMA */ - qdev_connect_gpio_out(dev, 5, pic[0x0E]); /* IDE-1 */ - qdev_connect_gpio_out(dev, 6, pic[0x03]); /* IDE-1 DMA */ + qdev_connect_gpio_out(dev, 0, + qdev_get_gpio_in(pic_dev, OLDWORLD_CUDA_IRQ)); + qdev_connect_gpio_out(dev, 1, + qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCB_IRQ)); + qdev_connect_gpio_out(dev, 2, + qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCA_IRQ)); + qdev_connect_gpio_out(dev, 3, + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ)); + qdev_connect_gpio_out(dev, 4, + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ)); + qdev_connect_gpio_out(dev, 5, + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ)); + qdev_connect_gpio_out(dev, 6, + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ)); qdev_prop_set_uint64(dev, "frequency", tbfreq); object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic", &error_abort); -- cgit v1.2.3 From 20d2514ad88057b8ef400cc4f1484d9160a9781a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 22:01:59 +0000 Subject: mac_oldworld: move wiring of macio IRQs to macio_oldworld_realize() Since the macio device has a link to the PIC device, we can now wire up the IRQs directly via qdev GPIOs rather than having to use an intermediate array. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/macio.c | 37 ++++++++++++++++++++++--------------- hw/ppc/mac_oldworld.c | 14 -------------- 2 files changed, 22 insertions(+), 29 deletions(-) (limited to 'hw') diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index a0cefe5719..dac7bcd15e 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -152,10 +152,9 @@ static void macio_oldworld_realize(PCIDevice *d, Error **errp) { MacIOState *s = MACIO(d); OldWorldMacIOState *os = OLDWORLD_MACIO(d); + DeviceState *pic_dev = DEVICE(os->pic); Error *err = NULL; SysBusDevice *sysbus_dev; - int i; - int cur_irq = 0; macio_common_realize(d, &err); if (err) { @@ -164,11 +163,14 @@ static void macio_oldworld_realize(PCIDevice *d, Error **errp) } sysbus_dev = SYS_BUS_DEVICE(&s->cuda); - sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); + sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, + OLDWORLD_CUDA_IRQ)); sysbus_dev = SYS_BUS_DEVICE(&s->escc); - sysbus_connect_irq(sysbus_dev, 0, os->irqs[cur_irq++]); - sysbus_connect_irq(sysbus_dev, 1, os->irqs[cur_irq++]); + sysbus_connect_irq(sysbus_dev, 0, qdev_get_gpio_in(pic_dev, + OLDWORLD_ESCCB_IRQ)); + sysbus_connect_irq(sysbus_dev, 1, qdev_get_gpio_in(pic_dev, + OLDWORLD_ESCCA_IRQ)); object_property_set_bool(OBJECT(&os->nvram), true, "realized", &err); if (err) { @@ -186,15 +188,22 @@ static void macio_oldworld_realize(PCIDevice *d, Error **errp) sysbus_mmio_get_region(sysbus_dev, 0)); /* IDE buses */ - for (i = 0; i < ARRAY_SIZE(os->ide); i++) { - qemu_irq irq0 = os->irqs[cur_irq++]; - qemu_irq irq1 = os->irqs[cur_irq++]; + macio_realize_ide(s, &os->ide[0], + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ), + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ), + 0x16, &err); + if (err) { + error_propagate(errp, err); + return; + } - macio_realize_ide(s, &os->ide[i], irq0, irq1, 0x16 + (i * 4), &err); - if (err) { - error_propagate(errp, err); - return; - } + macio_realize_ide(s, &os->ide[1], + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ), + qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ), + 0x1a, &err); + if (err) { + error_propagate(errp, err); + return; } } @@ -219,8 +228,6 @@ static void macio_oldworld_init(Object *obj) DeviceState *dev; int i; - qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs)); - object_property_add_link(obj, "pic", TYPE_HEATHROW, (Object **) &os->pic, qdev_prop_allow_set_link_before_realize, diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 2bbcefa076..4608bab014 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -281,20 +281,6 @@ static void ppc_heathrow_init(MachineState *machine) /* MacIO */ macio = OLDWORLD_MACIO(pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO)); dev = DEVICE(macio); - qdev_connect_gpio_out(dev, 0, - qdev_get_gpio_in(pic_dev, OLDWORLD_CUDA_IRQ)); - qdev_connect_gpio_out(dev, 1, - qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCB_IRQ)); - qdev_connect_gpio_out(dev, 2, - qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCA_IRQ)); - qdev_connect_gpio_out(dev, 3, - qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ)); - qdev_connect_gpio_out(dev, 4, - qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ)); - qdev_connect_gpio_out(dev, 5, - qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ)); - qdev_connect_gpio_out(dev, 6, - qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ)); qdev_prop_set_uint64(dev, "frequency", tbfreq); object_property_set_link(OBJECT(macio), OBJECT(pic_dev), "pic", &error_abort); -- cgit v1.2.3 From 132e9906d64beb8873ca5efe028a052dec6c4550 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:51 +0000 Subject: uninorth: move PCI mmio memory region initialisation into init function Whilst we are here, rename the memory regions to better reflect whether they belong to either a PCI or an AGP bus. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index b081e3c153..5b8fc3aa16 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -111,29 +111,39 @@ static const MemoryRegionOps unin_data_ops = { static void pci_unin_main_init(Object *obj) { + UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Use values found on a real PowerMac */ /* Uninorth main bus */ memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - obj, "pci-conf-idx", 0x1000); + obj, "unin-pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, - "pci-conf-data", 0x1000); + "unin-pci-conf-data", 0x1000); + + memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", + 0x100000000ULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } static void pci_u3_agp_init(Object *obj) { + UNINState *s = U3_AGP_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); /* Uninorth U3 AGP bus */ memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - obj, "pci-conf-idx", 0x1000); + obj, "unin-pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, - "pci-conf-data", 0x1000); + "unin-pci-conf-data", 0x1000); + + memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", + 0x100000000ULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } @@ -145,9 +155,9 @@ static void pci_unin_agp_init(Object *obj) /* Uninorth AGP bus */ memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - obj, "pci-conf-idx", 0x1000); + obj, "unin-agp-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, - obj, "pci-conf-data", 0x1000); + obj, "unin-agp-conf-data", 0x1000); sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } @@ -159,9 +169,9 @@ static void pci_unin_internal_init(Object *obj) /* Uninorth internal bus */ memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, - obj, "pci-conf-idx", 0x1000); + obj, "unin-pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, - obj, "pci-conf-data", 0x1000); + obj, "unin-pci-conf-data", 0x1000); sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } @@ -182,7 +192,6 @@ UNINState *pci_pmac_init(qemu_irq *pic, s = SYS_BUS_DEVICE(dev); h = PCI_HOST_BRIDGE(s); d = UNI_NORTH_PCI_HOST_BRIDGE(dev); - memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL); memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, 0x80000000ULL, 0x10000000ULL); memory_region_add_subregion(address_space_mem, 0x80000000ULL, @@ -247,7 +256,6 @@ UNINState *pci_pmac_u3_init(qemu_irq *pic, h = PCI_HOST_BRIDGE(dev); d = U3_AGP_HOST_BRIDGE(dev); - memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL); memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, 0x80000000ULL, 0x70000000ULL); memory_region_add_subregion(address_space_mem, 0x80000000ULL, -- cgit v1.2.3 From 0b065209549fdd503fe109b09d78500bb05c9f7f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:52 +0000 Subject: uninorth: introduce temporary pic_irqs device property This is in preparation for moving the PCI bus wiring inside the uninorth host bridge devices. In the future it will be possible to remove this once the PICs have been switched to use qdev GPIOs. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 5b8fc3aa16..fc59698f06 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -188,6 +188,7 @@ UNINState *pci_pmac_init(qemu_irq *pic, /* Use values found on a real PowerMac */ /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); h = PCI_HOST_BRIDGE(s); @@ -199,7 +200,7 @@ UNINState *pci_pmac_init(qemu_irq *pic, h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - pic, + d->pic_irqs, &d->pci_mmio, address_space_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); @@ -220,6 +221,7 @@ UNINState *pci_pmac_init(qemu_irq *pic, /* Uninorth AGP bus */ pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf0800000); @@ -251,6 +253,7 @@ UNINState *pci_pmac_u3_init(qemu_irq *pic, /* Uninorth AGP bus */ dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); h = PCI_HOST_BRIDGE(dev); @@ -263,7 +266,7 @@ UNINState *pci_pmac_u3_init(qemu_irq *pic, h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - pic, + d->pic_irqs, &d->pci_mmio, address_space_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); @@ -436,10 +439,16 @@ static const TypeInfo unin_internal_pci_host_info = { }, }; +static Property pci_unin_main_properties[] = { + DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), + DEFINE_PROP_END_OF_LIST(), +}; + static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->props = pci_unin_main_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -451,10 +460,16 @@ static const TypeInfo pci_unin_main_info = { .class_init = pci_unin_main_class_init, }; +static Property pci_u3_agp_properties[] = { + DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), + DEFINE_PROP_END_OF_LIST(), +}; + static void pci_u3_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->props = pci_u3_agp_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -466,10 +481,16 @@ static const TypeInfo pci_u3_agp_info = { .class_init = pci_u3_agp_class_init, }; +static Property pci_unin_agp_class_properties[] = { + DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), + DEFINE_PROP_END_OF_LIST(), +}; + static void pci_unin_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->props = pci_unin_agp_class_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } -- cgit v1.2.3 From 32cde6154cd252bfa23d05f43a165797e2430ff4 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:53 +0000 Subject: uninorth: move PCI host bridge bus initialisation into device realize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the IO address space is fixed to use the standard system IO address space then we can also use the opportunity to remove the address_space_io parameter from pci_pmac_init() and pci_pmac_u3_init(). Note we also move the default mac99 PCI bus to the end of the initialisation list so that it becomes the default destination for any devices specified via -device without an explicit PCI bus provided. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 117 ++++++++++++++++++++++++++++--------------------- hw/ppc/mac.h | 6 +-- hw/ppc/mac_newworld.c | 6 +-- 3 files changed, 72 insertions(+), 57 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index fc59698f06..426b3c4e33 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -109,6 +109,27 @@ static const MemoryRegionOps unin_data_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void pci_unin_main_realize(DeviceState *dev, Error **errp) +{ + UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); + PCIHostState *h = PCI_HOST_BRIDGE(dev); + + h->bus = pci_register_root_bus(dev, NULL, + pci_unin_set_irq, pci_unin_map_irq, + s->pic_irqs, + &s->pci_mmio, + get_system_io(), + PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); + + pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); + + /* DEC 21154 bridge */ +#if 0 + /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ + pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); +#endif +} + static void pci_unin_main_init(Object *obj) { UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); @@ -129,6 +150,21 @@ static void pci_unin_main_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } +static void pci_u3_agp_realize(DeviceState *dev, Error **errp) +{ + UNINState *s = U3_AGP_HOST_BRIDGE(dev); + PCIHostState *h = PCI_HOST_BRIDGE(dev); + + h->bus = pci_register_root_bus(dev, NULL, + pci_unin_set_irq, pci_unin_map_irq, + s->pic_irqs, + &s->pci_mmio, + get_system_io(), + PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); + + pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); +} + static void pci_u3_agp_init(Object *obj) { UNINState *s = U3_AGP_HOST_BRIDGE(obj); @@ -148,6 +184,19 @@ static void pci_u3_agp_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } +static void pci_unin_agp_realize(DeviceState *dev, Error **errp) +{ + UNINState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); + PCIHostState *h = PCI_HOST_BRIDGE(dev); + + h->bus = pci_register_root_bus(dev, NULL, + pci_unin_set_irq, pci_unin_map_irq, + s->pic_irqs, + &s->pci_mmio, + get_system_io(), + PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); +} + static void pci_unin_agp_init(Object *obj) { SysBusDevice *sbd = SYS_BUS_DEVICE(obj); @@ -177,49 +226,14 @@ static void pci_unin_internal_init(Object *obj) } UNINState *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io) + MemoryRegion *address_space_mem) { DeviceState *dev; SysBusDevice *s; - PCIHostState *h; UNINState *d; /* Use values found on a real PowerMac */ - /* Uninorth main bus */ - dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - h = PCI_HOST_BRIDGE(s); - d = UNI_NORTH_PCI_HOST_BRIDGE(dev); - memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, - 0x80000000ULL, 0x10000000ULL); - memory_region_add_subregion(address_space_mem, 0x80000000ULL, - &d->pci_hole); - - h->bus = pci_register_root_bus(dev, NULL, - pci_unin_set_irq, pci_unin_map_irq, - d->pic_irqs, - &d->pci_mmio, - address_space_io, - PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); - -#if 0 - pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north"); -#endif - - sysbus_mmio_map(s, 0, 0xf2800000); - sysbus_mmio_map(s, 1, 0xf2c00000); - - /* DEC 21154 bridge */ -#if 0 - /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ - pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); -#endif - /* Uninorth AGP bus */ - pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); @@ -239,16 +253,28 @@ UNINState *pci_pmac_init(qemu_irq *pic, sysbus_mmio_map(s, 1, 0xf4c00000); #endif + /* Uninorth main bus */ + dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + d = UNI_NORTH_PCI_HOST_BRIDGE(dev); + memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, + 0x80000000ULL, 0x10000000ULL); + memory_region_add_subregion(address_space_mem, 0x80000000ULL, + &d->pci_hole); + + sysbus_mmio_map(s, 0, 0xf2800000); + sysbus_mmio_map(s, 1, 0xf2c00000); + return d; } UNINState *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io) + MemoryRegion *address_space_mem) { DeviceState *dev; SysBusDevice *s; - PCIHostState *h; UNINState *d; /* Uninorth AGP bus */ @@ -256,7 +282,6 @@ UNINState *pci_pmac_u3_init(qemu_irq *pic, qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); - h = PCI_HOST_BRIDGE(dev); d = U3_AGP_HOST_BRIDGE(dev); memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, @@ -264,18 +289,9 @@ UNINState *pci_pmac_u3_init(qemu_irq *pic, memory_region_add_subregion(address_space_mem, 0x80000000ULL, &d->pci_hole); - h->bus = pci_register_root_bus(dev, NULL, - pci_unin_set_irq, pci_unin_map_irq, - d->pic_irqs, - &d->pci_mmio, - address_space_io, - PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); - sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); - pci_create_simple(h->bus, 11 << 3, "u3-agp"); - return d; } @@ -448,6 +464,7 @@ static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = pci_unin_main_realize; dc->props = pci_unin_main_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -469,6 +486,7 @@ static void pci_u3_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = pci_u3_agp_realize; dc->props = pci_u3_agp_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -490,6 +508,7 @@ static void pci_unin_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = pci_unin_agp_realize; dc->props = pci_unin_agp_class_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index c5a33e96cb..1ab2a3b354 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -90,11 +90,9 @@ void macio_init(PCIDevice *dev, /* UniNorth PCI */ UNINState *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io); + MemoryRegion *address_space_mem); UNINState *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem, - MemoryRegion *address_space_io); + MemoryRegion *address_space_mem); /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index ccf34ee36c..3367d7bb93 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -345,12 +345,10 @@ static void ppc_core99_init(MachineState *machine) if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - uninorth_pci = pci_pmac_u3_init(pic, get_system_memory(), - get_system_io()); + uninorth_pci = pci_pmac_u3_init(pic, get_system_memory()); machine_arch = ARCH_MAC99_U3; } else { - uninorth_pci = pci_pmac_init(pic, get_system_memory(), - get_system_io()); + uninorth_pci = pci_pmac_init(pic, get_system_memory()); machine_arch = ARCH_MAC99; } -- cgit v1.2.3 From c1d66d378c6dd1f112b753c98a308688dd0af24e Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:54 +0000 Subject: uninorth: fix PCI and AGP bus mixup Somewhere in the history of time, the initialisation of the PCI buses for the AGP and PCI host bridges got mixed up in that the PCI host bridge was creating an instance of the AGP PCI bus, and the AGP PCI bus was missing. Swap the PCI host bridge over to use the correct PCI bus (including setting the kMacRISCPCIAddressSelect register used by MacOS X) and add the missing reference to the AGP PCI bus. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 426b3c4e33..1f6752c294 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -121,7 +121,7 @@ static void pci_unin_main_realize(DeviceState *dev, Error **errp) get_system_io(), PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); - pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); + pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); /* DEC 21154 bridge */ #if 0 @@ -195,6 +195,8 @@ static void pci_unin_agp_realize(DeviceState *dev, Error **errp) &s->pci_mmio, get_system_io(), PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); + + pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); } static void pci_unin_agp_init(Object *obj) @@ -303,16 +305,6 @@ static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) d->config[0x0D] = 0x10; /* capabilities_pointer */ d->config[0x34] = 0x00; -} - -static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) -{ - /* cache_line_size */ - d->config[0x0C] = 0x08; - /* latency_timer */ - d->config[0x0D] = 0x10; - /* capabilities_pointer - d->config[0x34] = 0x80; */ /* * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI @@ -325,6 +317,16 @@ static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) d->config[0x4b] = 0x1; } +static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) +{ + /* cache_line_size */ + d->config[0x0C] = 0x08; + /* latency_timer */ + d->config[0x0D] = 0x10; + /* capabilities_pointer + d->config[0x34] = 0x80; */ +} + static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) { /* cache line size */ -- cgit v1.2.3 From 1ff861d289bf2bef65cb5ef20303583bd72ec930 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:55 +0000 Subject: uninorth: enable internal PCI host bridge Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 1f6752c294..ccde332fa9 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -213,6 +213,21 @@ static void pci_unin_agp_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } +static void pci_unin_internal_realize(DeviceState *dev, Error **errp) +{ + UNINState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); + PCIHostState *h = PCI_HOST_BRIDGE(dev); + + h->bus = pci_register_root_bus(dev, NULL, + pci_unin_set_irq, pci_unin_map_irq, + s->pic_irqs, + &s->pci_mmio, + get_system_io(), + PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); + + pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); +} + static void pci_unin_internal_init(Object *obj) { SysBusDevice *sbd = SYS_BUS_DEVICE(obj); @@ -244,16 +259,12 @@ UNINState *pci_pmac_init(qemu_irq *pic, sysbus_mmio_map(s, 1, 0xf0c00000); /* Uninorth internal bus */ -#if 0 - /* XXX: not needed for now */ - pci_create_simple(h->bus, PCI_DEVFN(14, 0), - "uni-north-internal-pci"); dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf4800000); sysbus_mmio_map(s, 1, 0xf4c00000); -#endif /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); @@ -523,10 +534,17 @@ static const TypeInfo pci_unin_agp_info = { .class_init = pci_unin_agp_class_init, }; +static Property pci_unin_internal_class_properties[] = { + DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), + DEFINE_PROP_END_OF_LIST(), +}; + static void pci_unin_internal_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = pci_unin_internal_realize; + dc->props = pci_unin_internal_class_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } -- cgit v1.2.3 From 7b19318bee746628b8cd9795d7a944c26779d60f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:56 +0000 Subject: uninorth: remove obsolete pci_pmac_init() function Instead wire up the PCI/AGP host bridges in mac_newworld.c. Now this is complete it is possible to move the initialisation of the PCI hole alias into pci_unin_main_init(). Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 46 +++++----------------------------------------- hw/ppc/mac_newworld.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 42 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index ccde332fa9..8e4e9b3d35 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -146,8 +146,13 @@ static void pci_unin_main_init(Object *obj) memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 0x100000000ULL); + memory_region_init_alias(&s->pci_hole, OBJECT(s), + "unin-pci-hole", &s->pci_mmio, + 0x80000000ULL, 0x10000000ULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); + sysbus_init_mmio(sbd, &s->pci_hole); } static void pci_u3_agp_realize(DeviceState *dev, Error **errp) @@ -242,47 +247,6 @@ static void pci_unin_internal_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } -UNINState *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem) -{ - DeviceState *dev; - SysBusDevice *s; - UNINState *d; - - /* Use values found on a real PowerMac */ - /* Uninorth AGP bus */ - dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(s, 0, 0xf0800000); - sysbus_mmio_map(s, 1, 0xf0c00000); - - /* Uninorth internal bus */ - dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - sysbus_mmio_map(s, 0, 0xf4800000); - sysbus_mmio_map(s, 1, 0xf4c00000); - - /* Uninorth main bus */ - dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - d = UNI_NORTH_PCI_HOST_BRIDGE(dev); - memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, - 0x80000000ULL, 0x10000000ULL); - memory_region_add_subregion(address_space_mem, 0x80000000ULL, - &d->pci_hole); - - sysbus_mmio_map(s, 0, 0xf2800000); - sysbus_mmio_map(s, 1, 0xf2c00000); - - return d; -} - UNINState *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space_mem) { diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 3367d7bb93..3033fc0d7e 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -348,7 +348,35 @@ static void ppc_core99_init(MachineState *machine) uninorth_pci = pci_pmac_u3_init(pic, get_system_memory()); machine_arch = ARCH_MAC99_U3; } else { - uninorth_pci = pci_pmac_init(pic, get_system_memory()); + /* Use values found on a real PowerMac */ + /* Uninorth AGP bus */ + dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(s, 0, 0xf0800000); + sysbus_mmio_map(s, 1, 0xf0c00000); + + /* Uninorth internal bus */ + dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); + qdev_init_nofail(dev); + s = SYS_BUS_DEVICE(dev); + sysbus_mmio_map(s, 0, 0xf4800000); + sysbus_mmio_map(s, 1, 0xf4c00000); + + /* Uninorth main bus */ + dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); + qdev_init_nofail(dev); + uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev); + s = SYS_BUS_DEVICE(dev); + /* PCI hole */ + memory_region_add_subregion(get_system_memory(), 0x80000000ULL, + sysbus_mmio_get_region(s, 2)); + sysbus_mmio_map(s, 0, 0xf2800000); + sysbus_mmio_map(s, 1, 0xf2c00000); + machine_arch = ARCH_MAC99; } -- cgit v1.2.3 From 8ce3f743c78f422ff87da76553c9421391f3adbf Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:57 +0000 Subject: uninorth: remove obsolete pci_pmac_u3_init() function Instead wire up the PCI/AGP host bridges in mac_newworld.c. Now this is complete it is possible to move the initialisation of the PCI hole alias into pci_u3_agp_init(). Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 30 +++++------------------------- hw/ppc/mac_newworld.c | 13 ++++++++++++- 2 files changed, 17 insertions(+), 26 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 8e4e9b3d35..ec6e529d66 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -185,8 +185,13 @@ static void pci_u3_agp_init(Object *obj) memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 0x100000000ULL); + memory_region_init_alias(&s->pci_hole, OBJECT(s), + "unin-pci-hole", &s->pci_mmio, + 0x80000000ULL, 0x70000000ULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); + sysbus_init_mmio(sbd, &s->pci_hole); } static void pci_unin_agp_realize(DeviceState *dev, Error **errp) @@ -247,31 +252,6 @@ static void pci_unin_internal_init(Object *obj) sysbus_init_mmio(sbd, &h->data_mem); } -UNINState *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem) -{ - DeviceState *dev; - SysBusDevice *s; - UNINState *d; - - /* Uninorth AGP bus */ - dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); - qdev_init_nofail(dev); - s = SYS_BUS_DEVICE(dev); - d = U3_AGP_HOST_BRIDGE(dev); - - memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio, - 0x80000000ULL, 0x70000000ULL); - memory_region_add_subregion(address_space_mem, 0x80000000ULL, - &d->pci_hole); - - sysbus_mmio_map(s, 0, 0xf0800000); - sysbus_mmio_map(s, 1, 0xf0c00000); - - return d; -} - static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) { /* cache_line_size */ diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 3033fc0d7e..2360b24a12 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -345,7 +345,18 @@ static void ppc_core99_init(MachineState *machine) if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) { /* 970 gets a U3 bus */ - uninorth_pci = pci_pmac_u3_init(pic, get_system_memory()); + /* Uninorth AGP bus */ + dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); + qdev_prop_set_ptr(dev, "pic-irqs", pic); + qdev_init_nofail(dev); + uninorth_pci = U3_AGP_HOST_BRIDGE(dev); + s = SYS_BUS_DEVICE(dev); + /* PCI hole */ + memory_region_add_subregion(get_system_memory(), 0x80000000ULL, + sysbus_mmio_get_region(s, 2)); + sysbus_mmio_map(s, 0, 0xf0800000); + sysbus_mmio_map(s, 1, 0xf0c00000); + machine_arch = ARCH_MAC99_U3; } else { /* Use values found on a real PowerMac */ -- cgit v1.2.3 From e7755cc1142db474bfa47247a92c59996af0502a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:58 +0000 Subject: uninorth: use object link to pass OpenPIC object to uninorth Now that the OpenPIC is wired up via the board, we can now remove our temporary PIC qdev pointer property and replace it with an object link instead. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 73 +++++++++++++++++++++++++++++--------------------- hw/ppc/mac_newworld.c | 12 ++++++--- 2 files changed, 51 insertions(+), 34 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index ec6e529d66..e2278fd0f0 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -38,10 +38,10 @@ static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) static void pci_unin_set_irq(void *opaque, int irq_num, int level) { - qemu_irq *pic = opaque; + UNINState *s = opaque; trace_unin_set_irq(unin_irq_line[irq_num], level); - qemu_set_irq(pic[unin_irq_line[irq_num]], level); + qemu_set_irq(s->irqs[irq_num], level); } static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) @@ -109,6 +109,15 @@ static const MemoryRegionOps unin_data_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; +static void pci_unin_init_irqs(UNINState *s) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(s->irqs); i++) { + s->irqs[i] = qdev_get_gpio_in(DEVICE(s->pic), unin_irq_line[i]); + } +} + static void pci_unin_main_realize(DeviceState *dev, Error **errp) { UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); @@ -116,12 +125,13 @@ static void pci_unin_main_realize(DeviceState *dev, Error **errp) h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - s->pic_irqs, + s, &s->pci_mmio, get_system_io(), PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); + pci_unin_init_irqs(s); /* DEC 21154 bridge */ #if 0 @@ -150,6 +160,11 @@ static void pci_unin_main_init(Object *obj) "unin-pci-hole", &s->pci_mmio, 0x80000000ULL, 0x10000000ULL); + object_property_add_link(obj, "pic", TYPE_OPENPIC, + (Object **) &s->pic, + qdev_prop_allow_set_link_before_realize, + 0, NULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); sysbus_init_mmio(sbd, &s->pci_hole); @@ -162,12 +177,13 @@ static void pci_u3_agp_realize(DeviceState *dev, Error **errp) h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - s->pic_irqs, + s, &s->pci_mmio, get_system_io(), PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); + pci_unin_init_irqs(s); } static void pci_u3_agp_init(Object *obj) @@ -189,6 +205,11 @@ static void pci_u3_agp_init(Object *obj) "unin-pci-hole", &s->pci_mmio, 0x80000000ULL, 0x70000000ULL); + object_property_add_link(obj, "pic", TYPE_OPENPIC, + (Object **) &s->pic, + qdev_prop_allow_set_link_before_realize, + 0, NULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); sysbus_init_mmio(sbd, &s->pci_hole); @@ -201,16 +222,18 @@ static void pci_unin_agp_realize(DeviceState *dev, Error **errp) h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - s->pic_irqs, + s, &s->pci_mmio, get_system_io(), PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); + pci_unin_init_irqs(s); } static void pci_unin_agp_init(Object *obj) { + UNINState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -219,6 +242,12 @@ static void pci_unin_agp_init(Object *obj) obj, "unin-agp-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, obj, "unin-agp-conf-data", 0x1000); + + object_property_add_link(obj, "pic", TYPE_OPENPIC, + (Object **) &s->pic, + qdev_prop_allow_set_link_before_realize, + 0, NULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } @@ -230,16 +259,18 @@ static void pci_unin_internal_realize(DeviceState *dev, Error **errp) h->bus = pci_register_root_bus(dev, NULL, pci_unin_set_irq, pci_unin_map_irq, - s->pic_irqs, + s, &s->pci_mmio, get_system_io(), PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); + pci_unin_init_irqs(s); } static void pci_unin_internal_init(Object *obj) { + UNINState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -248,6 +279,12 @@ static void pci_unin_internal_init(Object *obj) obj, "unin-pci-conf-idx", 0x1000); memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, obj, "unin-pci-conf-data", 0x1000); + + object_property_add_link(obj, "pic", TYPE_OPENPIC, + (Object **) &s->pic, + qdev_prop_allow_set_link_before_realize, + 0, NULL); + sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); } @@ -412,17 +449,11 @@ static const TypeInfo unin_internal_pci_host_info = { }, }; -static Property pci_unin_main_properties[] = { - DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), - DEFINE_PROP_END_OF_LIST(), -}; - static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = pci_unin_main_realize; - dc->props = pci_unin_main_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -434,17 +465,11 @@ static const TypeInfo pci_unin_main_info = { .class_init = pci_unin_main_class_init, }; -static Property pci_u3_agp_properties[] = { - DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), - DEFINE_PROP_END_OF_LIST(), -}; - static void pci_u3_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = pci_u3_agp_realize; - dc->props = pci_u3_agp_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -456,17 +481,11 @@ static const TypeInfo pci_u3_agp_info = { .class_init = pci_u3_agp_class_init, }; -static Property pci_unin_agp_class_properties[] = { - DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), - DEFINE_PROP_END_OF_LIST(), -}; - static void pci_unin_agp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = pci_unin_agp_realize; - dc->props = pci_unin_agp_class_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } @@ -478,17 +497,11 @@ static const TypeInfo pci_unin_agp_info = { .class_init = pci_unin_agp_class_init, }; -static Property pci_unin_internal_class_properties[] = { - DEFINE_PROP_PTR("pic-irqs", UNINState, pic_irqs), - DEFINE_PROP_END_OF_LIST(), -}; - static void pci_unin_internal_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = pci_unin_internal_realize; - dc->props = pci_unin_internal_class_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 2360b24a12..e05aa26c3d 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -347,7 +347,8 @@ static void ppc_core99_init(MachineState *machine) /* 970 gets a U3 bus */ /* Uninorth AGP bus */ dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); qdev_init_nofail(dev); uninorth_pci = U3_AGP_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); @@ -362,7 +363,8 @@ static void ppc_core99_init(MachineState *machine) /* Use values found on a real PowerMac */ /* Uninorth AGP bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf0800000); @@ -370,7 +372,8 @@ static void ppc_core99_init(MachineState *machine) /* Uninorth internal bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); sysbus_mmio_map(s, 0, 0xf4800000); @@ -378,7 +381,8 @@ static void ppc_core99_init(MachineState *machine) /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); - qdev_prop_set_ptr(dev, "pic-irqs", pic); + object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", + &error_abort); qdev_init_nofail(dev); uninorth_pci = UNI_NORTH_PCI_HOST_BRIDGE(dev); s = SYS_BUS_DEVICE(dev); -- cgit v1.2.3 From e226efbb262468241c2c8828373a84ffd93992ac Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:30:59 +0000 Subject: uninorth: move PCI IO (ISA) memory region into the uninorth device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do this for both the uninorth main and uninorth u3 AGP buses, using the main PCI bus for each machine (this ensures the IO addresses still match those used by OpenBIOS). Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 14 ++++++++++---- hw/ppc/mac_newworld.c | 12 ++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index e2278fd0f0..3a29a4410e 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -127,7 +127,7 @@ static void pci_unin_main_realize(DeviceState *dev, Error **errp) pci_unin_set_irq, pci_unin_map_irq, s, &s->pci_mmio, - get_system_io(), + &s->pci_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); @@ -155,6 +155,8 @@ static void pci_unin_main_init(Object *obj) memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 0x100000000ULL); + memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, + "unin-pci-isa-mmio", 0x00800000); memory_region_init_alias(&s->pci_hole, OBJECT(s), "unin-pci-hole", &s->pci_mmio, @@ -168,6 +170,7 @@ static void pci_unin_main_init(Object *obj) sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); sysbus_init_mmio(sbd, &s->pci_hole); + sysbus_init_mmio(sbd, &s->pci_io); } static void pci_u3_agp_realize(DeviceState *dev, Error **errp) @@ -179,7 +182,7 @@ static void pci_u3_agp_realize(DeviceState *dev, Error **errp) pci_unin_set_irq, pci_unin_map_irq, s, &s->pci_mmio, - get_system_io(), + &s->pci_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); @@ -200,6 +203,8 @@ static void pci_u3_agp_init(Object *obj) memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", 0x100000000ULL); + memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, + "unin-pci-isa-mmio", 0x00800000); memory_region_init_alias(&s->pci_hole, OBJECT(s), "unin-pci-hole", &s->pci_mmio, @@ -213,6 +218,7 @@ static void pci_u3_agp_init(Object *obj) sysbus_init_mmio(sbd, &h->conf_mem); sysbus_init_mmio(sbd, &h->data_mem); sysbus_init_mmio(sbd, &s->pci_hole); + sysbus_init_mmio(sbd, &s->pci_io); } static void pci_unin_agp_realize(DeviceState *dev, Error **errp) @@ -224,7 +230,7 @@ static void pci_unin_agp_realize(DeviceState *dev, Error **errp) pci_unin_set_irq, pci_unin_map_irq, s, &s->pci_mmio, - get_system_io(), + &s->pci_io, PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); @@ -261,7 +267,7 @@ static void pci_unin_internal_realize(DeviceState *dev, Error **errp) pci_unin_set_irq, pci_unin_map_irq, s, &s->pci_mmio, - get_system_io(), + &s->pci_io, PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index e05aa26c3d..bd7ffdb0fb 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -145,7 +145,6 @@ static void ppc_core99_init(MachineState *machine) CPUPPCState *env = NULL; char *filename; qemu_irq *pic, **openpic_irqs; - MemoryRegion *isa = g_new(MemoryRegion, 1); MemoryRegion *unin_memory = g_new(MemoryRegion, 1); int linux_boot, i, j, k; MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); @@ -273,11 +272,6 @@ static void ppc_core99_init(MachineState *machine) } } - /* Register 8 MB of ISA IO space */ - memory_region_init_alias(isa, NULL, "isa_mmio", - get_system_io(), 0, 0x00800000); - memory_region_add_subregion(get_system_memory(), 0xf2000000, isa); - /* UniN init: XXX should be a real device */ memory_region_init_io(unin_memory, NULL, &unin_ops, token, "unin", 0x1000); memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory); @@ -355,6 +349,9 @@ static void ppc_core99_init(MachineState *machine) /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); + /* Register 8 MB of ISA IO space */ + memory_region_add_subregion(get_system_memory(), 0xf2000000, + sysbus_mmio_get_region(s, 3)); sysbus_mmio_map(s, 0, 0xf0800000); sysbus_mmio_map(s, 1, 0xf0c00000); @@ -389,6 +386,9 @@ static void ppc_core99_init(MachineState *machine) /* PCI hole */ memory_region_add_subregion(get_system_memory(), 0x80000000ULL, sysbus_mmio_get_region(s, 2)); + /* Register 8 MB of ISA IO space */ + memory_region_add_subregion(get_system_memory(), 0xf2000000, + sysbus_mmio_get_region(s, 3)); sysbus_mmio_map(s, 0, 0xf2800000); sysbus_mmio_map(s, 1, 0xf2c00000); -- cgit v1.2.3 From c90c393c2dca764bf2a062b3769ac0de32f5fe28 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Tue, 6 Mar 2018 20:31:00 +0000 Subject: uninorth: rename UNINState to UNINHostState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing UNINState actually represents the PCI/AGP host bridge stage so rename it accordingly. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/pci-host/uninorth.c | 32 ++++++++++++++++---------------- hw/ppc/mac.h | 8 ++++---- hw/ppc/mac_newworld.c | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) (limited to 'hw') diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 3a29a4410e..fada0ffd5f 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -38,7 +38,7 @@ static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) static void pci_unin_set_irq(void *opaque, int irq_num, int level) { - UNINState *s = opaque; + UNINHostState *s = opaque; trace_unin_set_irq(unin_irq_line[irq_num], level); qemu_set_irq(s->irqs[irq_num], level); @@ -81,7 +81,7 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) static void unin_data_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) { - UNINState *s = opaque; + UNINHostState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s); trace_unin_data_write(addr, len, val); pci_data_write(phb->bus, @@ -92,7 +92,7 @@ static void unin_data_write(void *opaque, hwaddr addr, static uint64_t unin_data_read(void *opaque, hwaddr addr, unsigned len) { - UNINState *s = opaque; + UNINHostState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s); uint32_t val; @@ -109,7 +109,7 @@ static const MemoryRegionOps unin_data_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void pci_unin_init_irqs(UNINState *s) +static void pci_unin_init_irqs(UNINHostState *s) { int i; @@ -120,7 +120,7 @@ static void pci_unin_init_irqs(UNINState *s) static void pci_unin_main_realize(DeviceState *dev, Error **errp) { - UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); + UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); PCIHostState *h = PCI_HOST_BRIDGE(dev); h->bus = pci_register_root_bus(dev, NULL, @@ -142,7 +142,7 @@ static void pci_unin_main_realize(DeviceState *dev, Error **errp) static void pci_unin_main_init(Object *obj) { - UNINState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); + UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -175,7 +175,7 @@ static void pci_unin_main_init(Object *obj) static void pci_u3_agp_realize(DeviceState *dev, Error **errp) { - UNINState *s = U3_AGP_HOST_BRIDGE(dev); + UNINHostState *s = U3_AGP_HOST_BRIDGE(dev); PCIHostState *h = PCI_HOST_BRIDGE(dev); h->bus = pci_register_root_bus(dev, NULL, @@ -191,7 +191,7 @@ static void pci_u3_agp_realize(DeviceState *dev, Error **errp) static void pci_u3_agp_init(Object *obj) { - UNINState *s = U3_AGP_HOST_BRIDGE(obj); + UNINHostState *s = U3_AGP_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -223,7 +223,7 @@ static void pci_u3_agp_init(Object *obj) static void pci_unin_agp_realize(DeviceState *dev, Error **errp) { - UNINState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); + UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); PCIHostState *h = PCI_HOST_BRIDGE(dev); h->bus = pci_register_root_bus(dev, NULL, @@ -239,7 +239,7 @@ static void pci_unin_agp_realize(DeviceState *dev, Error **errp) static void pci_unin_agp_init(Object *obj) { - UNINState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); + UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -260,7 +260,7 @@ static void pci_unin_agp_init(Object *obj) static void pci_unin_internal_realize(DeviceState *dev, Error **errp) { - UNINState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); + UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); PCIHostState *h = PCI_HOST_BRIDGE(dev); h->bus = pci_register_root_bus(dev, NULL, @@ -276,7 +276,7 @@ static void pci_unin_internal_realize(DeviceState *dev, Error **errp) static void pci_unin_internal_init(Object *obj) { - UNINState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); + UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -466,7 +466,7 @@ static void pci_unin_main_class_init(ObjectClass *klass, void *data) static const TypeInfo pci_unin_main_info = { .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, - .instance_size = sizeof(UNINState), + .instance_size = sizeof(UNINHostState), .instance_init = pci_unin_main_init, .class_init = pci_unin_main_class_init, }; @@ -482,7 +482,7 @@ static void pci_u3_agp_class_init(ObjectClass *klass, void *data) static const TypeInfo pci_u3_agp_info = { .name = TYPE_U3_AGP_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, - .instance_size = sizeof(UNINState), + .instance_size = sizeof(UNINHostState), .instance_init = pci_u3_agp_init, .class_init = pci_u3_agp_class_init, }; @@ -498,7 +498,7 @@ static void pci_unin_agp_class_init(ObjectClass *klass, void *data) static const TypeInfo pci_unin_agp_info = { .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, - .instance_size = sizeof(UNINState), + .instance_size = sizeof(UNINHostState), .instance_init = pci_unin_agp_init, .class_init = pci_unin_agp_class_init, }; @@ -514,7 +514,7 @@ static void pci_unin_internal_class_init(ObjectClass *klass, void *data) static const TypeInfo pci_unin_internal_info = { .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, - .instance_size = sizeof(UNINState), + .instance_size = sizeof(UNINHostState), .instance_init = pci_unin_internal_init, .class_init = pci_unin_internal_class_init, }; diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 1ab2a3b354..892dd03789 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -89,10 +89,10 @@ void macio_init(PCIDevice *dev, #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" /* UniNorth PCI */ -UNINState *pci_pmac_init(qemu_irq *pic, - MemoryRegion *address_space_mem); -UNINState *pci_pmac_u3_init(qemu_irq *pic, - MemoryRegion *address_space_mem); +UNINHostState *pci_pmac_init(qemu_irq *pic, + MemoryRegion *address_space_mem); +UNINHostState *pci_pmac_u3_init(qemu_irq *pic, + MemoryRegion *address_space_mem); /* Mac NVRAM */ #define TYPE_MACIO_NVRAM "macio-nvram" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index bd7ffdb0fb..29bd3838bf 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -150,7 +150,7 @@ static void ppc_core99_init(MachineState *machine) MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1); hwaddr kernel_base, initrd_base, cmdline_base = 0; long kernel_size, initrd_size; - UNINState *uninorth_pci; + UNINHostState *uninorth_pci; PCIBus *pci_bus; NewWorldMacIOState *macio; MACIOIDEState *macio_ide; -- cgit v1.2.3 From 8a4fd427fe8236bb4f6993702112f058b5d80507 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 29 Mar 2018 18:34:22 +1100 Subject: spapr: Introduce pseries-2.13 machine type Signed-off-by: David Gibson --- hw/ppc/spapr.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 92194a9a53..b92dad2273 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3984,19 +3984,38 @@ static const TypeInfo spapr_machine_info = { } \ type_init(spapr_machine_register_##suffix) +/* + * pseries-2.13 + */ +static void spapr_machine_2_13_instance_options(MachineState *machine) +{ +} + +static void spapr_machine_2_13_class_options(MachineClass *mc) +{ + /* Defaults for the latest behaviour inherited from the base class */ +} + +DEFINE_SPAPR_MACHINE(2_13, "2.13", true); + /* * pseries-2.12 */ +#define SPAPR_COMPAT_2_12 \ + HW_COMPAT_2_12 + static void spapr_machine_2_12_instance_options(MachineState *machine) { + spapr_machine_2_13_instance_options(machine); } static void spapr_machine_2_12_class_options(MachineClass *mc) { - /* Defaults for the latest behaviour inherited from the base class */ + spapr_machine_2_13_class_options(mc); + SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_12); } -DEFINE_SPAPR_MACHINE(2_12, "2.12", true); +DEFINE_SPAPR_MACHINE(2_12, "2.12", false); static void spapr_machine_2_12_sxxm_instance_options(MachineState *machine) { -- cgit v1.2.3 From 1d36c75a9ebf6bddbdb46693052a48ef134f3699 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Wed, 11 Apr 2018 19:46:06 +0200 Subject: spapr: drop useless sanity check in spapr_irq_alloc*() Both spapr_irq_alloc() and spapr_irq_alloc_block() have an errp parameter, but they don't use it if XICS hasn't been initialized yet. This is doubly wrong: - all callers do pass a non-null Error **, ie, they expect an error to be propagated in case of failure - XICS obviously needs to be initialized before anything starts allocating IRQs So this patch turns the check into an assert. Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b92dad2273..5a1c1e25e1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3719,9 +3719,8 @@ int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, ICSState *ics = spapr->ics; int irq; - if (!ics) { - return -1; - } + assert(ics); + if (irq_hint) { if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint); @@ -3753,9 +3752,7 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, ICSState *ics = spapr->ics; int i, first = -1; - if (!ics) { - return -1; - } + assert(ics); /* * MSIMesage::data is used for storing VIRQ so -- cgit v1.2.3 From e47f1d2786c3d01a7894a493aafe0efa6b64453c Mon Sep 17 00:00:00 2001 From: Serhii Popovych Date: Wed, 11 Apr 2018 14:42:00 -0400 Subject: Revert "spapr: Don't allow memory hotplug to memory less nodes" This reverts commit b556854bd8524c26b8be98ab1bfdf0826831e793. Leave change @node type from uint32_t to to int from reverted commit because node < 0 is always false. Note that implementing capability or some trick to detect if guest kernel does not support hot-add to memory: this returns previous behavour where memory added to first non-empty node. Signed-off-by: Serhii Popovych Signed-off-by: David Gibson --- hw/ppc/spapr.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 5a1c1e25e1..fc86ba6934 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3478,28 +3478,6 @@ static void spapr_machine_device_plug(HotplugHandler *hotplug_dev, return; } - /* - * Currently PowerPC kernel doesn't allow hot-adding memory to - * memory-less node, but instead will silently add the memory - * to the first node that has some memory. This causes two - * unexpected behaviours for the user. - * - * - Memory gets hotplugged to a different node than what the user - * specified. - * - Since pc-dimm subsystem in QEMU still thinks that memory belongs - * to memory-less node, a reboot will set things accordingly - * and the previously hotplugged memory now ends in the right node. - * This appears as if some memory moved from one node to another. - * - * So until kernel starts supporting memory hotplug to memory-less - * nodes, just prevent such attempts upfront in QEMU. - */ - if (nb_numa_nodes && !numa_info[node].node_mem) { - error_setg(errp, "Can't hotplug memory to memory-less node %d", - node); - return; - } - spapr_memory_plug(hotplug_dev, dev, node, errp); } else if (object_dynamic_cast(OBJECT(dev), TYPE_SPAPR_CPU_CORE)) { spapr_core_plug(hotplug_dev, dev, errp); -- cgit v1.2.3 From b2692d5fed8b0549d70426d75c9ad4734dc557c8 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Wed, 11 Apr 2018 17:01:20 +0200 Subject: spapr: drop useless dynamic sysbus device sanity check Since commit 7da79a167aa11, the machine class init function registers dynamic sysbus device types it supports. Passing an unsupported device type on the command line causes QEMU to exit with an error message just after machine init. It is hence not needed to do the same sanity check at machine reset. Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fc86ba6934..d35a88ca80 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1440,21 +1440,6 @@ void spapr_setup_hpt_and_vrma(sPAPRMachineState *spapr) } } -static void find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) -{ - bool matched = false; - - if (object_dynamic_cast(OBJECT(sbdev), TYPE_SPAPR_PCI_HOST_BRIDGE)) { - matched = true; - } - - if (!matched) { - error_report("Device %s is not supported by this machine yet.", - qdev_fw_name(DEVICE(sbdev))); - exit(1); - } -} - static int spapr_reset_drcs(Object *child, void *opaque) { sPAPRDRConnector *drc = @@ -1478,9 +1463,6 @@ static void spapr_machine_reset(void) void *fdt; int rc; - /* Check for unknown sysbus devices */ - foreach_dynamic_sysbus_device(find_unknown_sysbus_device, NULL); - spapr_caps_reset(spapr); first_ppc_cpu = POWERPC_CPU(first_cpu); -- cgit v1.2.3 From 644a2c99a90b95957fd56fc3b9f8908ac9e90702 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 22 Mar 2018 16:18:40 +1100 Subject: target/ppc: Pass cpu instead of env to ppc_create_page_sizes_prop() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As a rule we prefer to pass PowerPCCPU instead of CPUPPCState, and this change will make some things simpler later on. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/fdt.c | 5 +++-- hw/ppc/pnv.c | 4 ++-- hw/ppc/spapr.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/ppc/fdt.c b/hw/ppc/fdt.c index 2ffc5866e4..2721603ffa 100644 --- a/hw/ppc/fdt.c +++ b/hw/ppc/fdt.c @@ -13,9 +13,10 @@ #include "hw/ppc/fdt.h" #if defined(TARGET_PPC64) -size_t ppc_create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, - size_t maxsize) +size_t ppc_create_page_sizes_prop(PowerPCCPU *cpu, uint32_t *prop, + size_t maxsize) { + CPUPPCState *env = &cpu->env; size_t maxcells = maxsize / sizeof(uint32_t); int i, j, count; uint32_t *p = prop; diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 549cfccdcb..3220ef8f79 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -209,8 +209,8 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt) _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1))); } - page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop, - sizeof(page_sizes_prop)); + page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop, + sizeof(page_sizes_prop)); if (page_sizes_prop_size) { _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes", page_sizes_prop, page_sizes_prop_size))); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index d35a88ca80..a4b3722656 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -581,8 +581,8 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1))); } - page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop, - sizeof(page_sizes_prop)); + page_sizes_prop_size = ppc_create_page_sizes_prop(cpu, page_sizes_prop, + sizeof(page_sizes_prop)); if (page_sizes_prop_size) { _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes", page_sizes_prop, page_sizes_prop_size))); -- cgit v1.2.3 From b07c59f7c8df6efc24576f07622b61ad115468e6 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 23 Mar 2018 13:31:52 +1100 Subject: target/ppc: Split page size information into a separate allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit env->sps contains page size encoding information as an embedded structure. Since this information is specific to 64-bit hash MMUs, split it out into a separately allocated structure, to reduce the basic env size for other cpus. Along the way we make a few other cleanups: * Rename to PPCHash64Options which is more in line with qemu name conventions, and reflects that we're going to merge some more hash64 mmu specific details in there in future. Also rename its substructures to match qemu conventions. * Move structure definitions to the mmu-hash64.[ch] files. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/fdt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/fdt.c b/hw/ppc/fdt.c index 2721603ffa..0828ad7254 100644 --- a/hw/ppc/fdt.c +++ b/hw/ppc/fdt.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "target/ppc/cpu.h" +#include "target/ppc/mmu-hash64.h" #include "hw/ppc/fdt.h" @@ -16,13 +17,12 @@ size_t ppc_create_page_sizes_prop(PowerPCCPU *cpu, uint32_t *prop, size_t maxsize) { - CPUPPCState *env = &cpu->env; size_t maxcells = maxsize / sizeof(uint32_t); int i, j, count; uint32_t *p = prop; for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) { - struct ppc_one_seg_page_size *sps = &env->sps.sps[i]; + PPCHash64SegmentPageSizes *sps = &cpu->hash64_opts->sps[i]; if (!sps->page_shift) { break; -- cgit v1.2.3 From 58969eeece99abd6d31d530ad371e789419ec9bf Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 23 Mar 2018 14:11:07 +1100 Subject: target/ppc: Move 1T segment and AMR options to PPCHash64Options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently env->mmu_model is a bit of an unholy mess of an enum of distinct MMU types, with various flag bits as well. This makes which bits of the field should be compared pretty confusing. Make a start on cleaning that up by moving two of the flags bits - POWERPC_MMU_1TSEG and POWERPC_MMU_AMR - which are specific to the 64-bit hash MMU into a new flags field in PPCHash64Options structure. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/pnv.c | 3 ++- hw/ppc/spapr.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 3220ef8f79..0e49c5e9b8 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -36,6 +36,7 @@ #include "monitor/monitor.h" #include "hw/intc/intc.h" #include "hw/ipmi/ipmi.h" +#include "target/ppc/mmu-hash64.h" #include "hw/ppc/xics.h" #include "hw/ppc/pnv_xscom.h" @@ -187,7 +188,7 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt) _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); } - if (env->mmu_model & POWERPC_MMU_1TSEG) { + if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) { _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", segs, sizeof(segs)))); } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index a4b3722656..9c26dc37e1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -557,7 +557,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); } - if (env->mmu_model & POWERPC_MMU_1TSEG) { + if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG)) { _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", segs, sizeof(segs)))); } -- cgit v1.2.3 From 26cd35b8613881c410d5226e6dc56e7bfb4b83d1 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 23 Mar 2018 14:32:48 +1100 Subject: target/ppc: Fold ci_large_pages flag into PPCHash64Options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ci_large_pages boolean in CPUPPCState is only relevant to 64-bit hash MMU machines, indicating whether it's possible to map large (> 4kiB) pages as cache-inhibitied (i.e. for IO, rather than memory). Fold it as another flag into the PPCHash64Options structure. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 9c26dc37e1..abf38c62e8 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -263,7 +263,6 @@ static void spapr_populate_pa_features(sPAPRMachineState *spapr, void *fdt, int offset, bool legacy_guest) { - CPUPPCState *env = &cpu->env; uint8_t pa_features_206[] = { 6, 0, 0xf6, 0x1f, 0xc7, 0x00, 0x80, 0xc0 }; uint8_t pa_features_207[] = { 24, 0, @@ -315,7 +314,7 @@ static void spapr_populate_pa_features(sPAPRMachineState *spapr, return; } - if (env->ci_large_pages) { + if (ppc_hash64_has(cpu, PPC_HASH64_CI_LARGEPAGE)) { /* * Note: we keep CI large pages off by default because a 64K capable * guest provisioned with large pages might otherwise try to map a qemu -- cgit v1.2.3 From 67d7d66f27c49a87c6f28ccff814f5d7eaaccec6 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 29 Mar 2018 18:29:38 +1100 Subject: target/ppc: Fold slb_nr into PPCHash64Options The env->slb_nr field gives the size of the SLB (Segment Lookaside Buffer). This is another static-after-initialization parameter of the specific version of the 64-bit hash MMU in the CPU. So, this patch folds the field into PPCHash64Options with the other hash MMU options. This is a bit more complicated that the things previously put in there, because slb_nr was foolishly included in the migration stream. So we need some of the usual dance to handle backwards compatible migration. Signed-off-by: David Gibson Reviewed-by: Greg Kurz --- hw/ppc/pnv.c | 2 +- hw/ppc/spapr.c | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'hw') diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 0e49c5e9b8..0314881316 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -180,7 +180,7 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt) _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq))); _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq))); - _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr))); + _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", cpu->hash64_opts->slb_size))); _FDT((fdt_setprop_string(fdt, offset, "status", "okay"))); _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index abf38c62e8..8c2e3ccb89 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -547,8 +547,8 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq))); _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq))); - _FDT((fdt_setprop_cell(fdt, offset, "slb-size", env->slb_nr))); - _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr))); + _FDT((fdt_setprop_cell(fdt, offset, "slb-size", cpu->hash64_opts->slb_size))); + _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", cpu->hash64_opts->slb_size))); _FDT((fdt_setprop_string(fdt, offset, "status", "okay"))); _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); @@ -3958,7 +3958,12 @@ DEFINE_SPAPR_MACHINE(2_13, "2.13", true); * pseries-2.12 */ #define SPAPR_COMPAT_2_12 \ - HW_COMPAT_2_12 + HW_COMPAT_2_12 \ + { \ + .driver = TYPE_POWERPC_CPU, \ + .property = "pre-2.13-migration", \ + .value = "on", \ + }, static void spapr_machine_2_12_instance_options(MachineState *machine) { -- cgit v1.2.3 From da9f80fbad21319194e73355dea8a1cff6a574e4 Mon Sep 17 00:00:00 2001 From: Serhii Popovych Date: Wed, 11 Apr 2018 14:41:59 -0400 Subject: spapr: Add ibm,max-associativity-domains property Now recent kernels (i.e. since linux-stable commit a346137e9142 ("powerpc/numa: Use ibm,max-associativity-domains to discover possible nodes") support this property to mark initially memory-less NUMA nodes as "possible" to allow further memory hot-add to them. Advertise this property for pSeries machines to let guest kernels detect maximum supported node configuration and benefit from kernel side change when hot-add memory to specific, possibly empty before, NUMA node. Signed-off-by: Serhii Popovych Signed-off-by: David Gibson --- hw/ppc/spapr.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 8c2e3ccb89..2203b6f46d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -909,6 +909,13 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) 0, cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE), cpu_to_be32(max_cpus / smp_threads), }; + uint32_t maxdomains[] = { + cpu_to_be32(4), + cpu_to_be32(0), + cpu_to_be32(0), + cpu_to_be32(0), + cpu_to_be32(nb_numa_nodes ? nb_numa_nodes - 1 : 0), + }; _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas")); @@ -945,6 +952,9 @@ static void spapr_dt_rtas(sPAPRMachineState *spapr, void *fdt) _FDT(fdt_setprop(fdt, rtas, "ibm,associativity-reference-points", refpoints, sizeof(refpoints))); + _FDT(fdt_setprop(fdt, rtas, "ibm,max-associativity-domains", + maxdomains, sizeof(maxdomains))); + _FDT(fdt_setprop_cell(fdt, rtas, "rtas-error-log-max", RTAS_ERROR_LOG_MAX)); _FDT(fdt_setprop_cell(fdt, rtas, "rtas-event-scan-rate", -- cgit v1.2.3 From 03f048090ee73bfb18b16a5dc462b5411120fb4d Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Wed, 18 Apr 2018 16:28:02 +0200 Subject: ppc: e500: switch E500 based machines to full machine definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert PPCE500Params to PCCE500MachineClass which it essentially is, and introduce PCCE500MachineState to keep track of E500 specific state instead of adding global variables or extra parameters to functions when we need to keep data beyond machine init (i.e. make it look like typical fully defined machine). It's pretty shallow conversion instead of currently used trivial DEFINE_MACHINE() macro. It adds extra 60LOC of boilerplate code of full machine definition. The patch on top[1] will use PCCE500MachineState to keep track of platform_bus device and add E500Plate specific machine class to use HOTPLUG_HANDLER for explicitly initializing dynamic sysbus devices at the time they are added instead of delaying it to machine done time by platform_bus_init_notify() which is being removed. 1) <1523551221-11612-3-git-send-email-imammedo@redhat.com> Signed-off-by: Igor Mammedov Suggested-by: David Gibson Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/ppc/e500.c | 119 ++++++++++++++++++++++++++++------------------------- hw/ppc/e500.h | 29 ++++++++++--- hw/ppc/e500plat.c | 64 +++++++++++++++++----------- hw/ppc/mpc8544ds.c | 47 +++++++++++++-------- 4 files changed, 156 insertions(+), 103 deletions(-) (limited to 'hw') diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 2ddab7ed24..3e0923cfba 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -221,14 +221,14 @@ static void sysbus_device_create_devtree(SysBusDevice *sbdev, void *opaque) } } -static void platform_bus_create_devtree(PPCE500Params *params, void *fdt, - const char *mpic) +static void platform_bus_create_devtree(const PPCE500MachineClass *pmc, + void *fdt, const char *mpic) { - gchar *node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base); + gchar *node = g_strdup_printf("/platform@%"PRIx64, pmc->platform_bus_base); const char platcomp[] = "qemu,platform\0simple-bus"; - uint64_t addr = params->platform_bus_base; - uint64_t size = params->platform_bus_size; - int irq_start = params->platform_bus_first_irq; + uint64_t addr = pmc->platform_bus_base; + uint64_t size = pmc->platform_bus_size; + int irq_start = pmc->platform_bus_first_irq; PlatformBusDevice *pbus; DeviceState *dev; @@ -265,8 +265,7 @@ static void platform_bus_create_devtree(PPCE500Params *params, void *fdt, g_free(node); } -static int ppce500_load_device_tree(MachineState *machine, - PPCE500Params *params, +static int ppce500_load_device_tree(PPCE500MachineState *pms, hwaddr addr, hwaddr initrd_base, hwaddr initrd_size, @@ -274,6 +273,8 @@ static int ppce500_load_device_tree(MachineState *machine, hwaddr kernel_size, bool dry_run) { + MachineState *machine = MACHINE(pms); + const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms); CPUPPCState *env = first_cpu->env_ptr; int ret = -1; uint64_t mem_reg_property[] = { 0, cpu_to_be64(machine->ram_size) }; @@ -295,12 +296,12 @@ static int ppce500_load_device_tree(MachineState *machine, int len; uint32_t pci_ranges[14] = { - 0x2000000, 0x0, params->pci_mmio_bus_base, - params->pci_mmio_base >> 32, params->pci_mmio_base, + 0x2000000, 0x0, pmc->pci_mmio_bus_base, + pmc->pci_mmio_base >> 32, pmc->pci_mmio_base, 0x0, 0x20000000, 0x1000000, 0x0, 0x0, - params->pci_pio_base >> 32, params->pci_pio_base, + pmc->pci_pio_base >> 32, pmc->pci_pio_base, 0x0, 0x10000, }; QemuOpts *machine_opts = qemu_get_machine_opts(); @@ -391,7 +392,7 @@ static int ppce500_load_device_tree(MachineState *machine, for (i = smp_cpus - 1; i >= 0; i--) { CPUState *cpu; char cpu_name[128]; - uint64_t cpu_release_addr = params->spin_base + (i * 0x20); + uint64_t cpu_release_addr = pmc->spin_base + (i * 0x20); cpu = qemu_get_cpu(i); if (cpu == NULL) { @@ -425,7 +426,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_add_subnode(fdt, "/aliases"); /* XXX These should go into their respective devices' code */ - snprintf(soc, sizeof(soc), "/soc@%"PRIx64, params->ccsrbar_base); + snprintf(soc, sizeof(soc), "/soc@%"PRIx64, pmc->ccsrbar_base); qemu_fdt_add_subnode(fdt, soc); qemu_fdt_setprop_string(fdt, soc, "device_type", "soc"); qemu_fdt_setprop(fdt, soc, "compatible", compatible_sb, @@ -433,7 +434,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, soc, "#address-cells", 1); qemu_fdt_setprop_cell(fdt, soc, "#size-cells", 1); qemu_fdt_setprop_cells(fdt, soc, "ranges", 0x0, - params->ccsrbar_base >> 32, params->ccsrbar_base, + pmc->ccsrbar_base >> 32, pmc->ccsrbar_base, MPC8544_CCSRBAR_SIZE); /* XXX should contain a reasonable value */ qemu_fdt_setprop_cell(fdt, soc, "bus-frequency", 0); @@ -493,7 +494,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, msi, "linux,phandle", msi_ph); snprintf(pci, sizeof(pci), "/pci@%llx", - params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET); + pmc->ccsrbar_base + MPC8544_PCI_REGS_OFFSET); qemu_fdt_add_subnode(fdt, pci); qemu_fdt_setprop_cell(fdt, pci, "cell-index", 0); qemu_fdt_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci"); @@ -501,7 +502,7 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0, 0x0, 0x7); pci_map = pci_map_create(fdt, qemu_fdt_get_phandle(fdt, mpic), - params->pci_first_slot, params->pci_nr_slots, + pmc->pci_first_slot, pmc->pci_nr_slots, &len); qemu_fdt_setprop(fdt, pci, "interrupt-map", pci_map, len); qemu_fdt_setprop_phandle(fdt, pci, "interrupt-parent", mpic); @@ -513,8 +514,8 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, pci, "fsl,msi", msi_ph); qemu_fdt_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges)); qemu_fdt_setprop_cells(fdt, pci, "reg", - (params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET) >> 32, - (params->ccsrbar_base + MPC8544_PCI_REGS_OFFSET), + (pmc->ccsrbar_base + MPC8544_PCI_REGS_OFFSET) >> 32, + (pmc->ccsrbar_base + MPC8544_PCI_REGS_OFFSET), 0, 0x1000); qemu_fdt_setprop_cell(fdt, pci, "clock-frequency", 66666666); qemu_fdt_setprop_cell(fdt, pci, "#interrupt-cells", 1); @@ -522,15 +523,15 @@ static int ppce500_load_device_tree(MachineState *machine, qemu_fdt_setprop_cell(fdt, pci, "#address-cells", 3); qemu_fdt_setprop_string(fdt, "/aliases", "pci0", pci); - if (params->has_mpc8xxx_gpio) { + if (pmc->has_mpc8xxx_gpio) { create_dt_mpc8xxx_gpio(fdt, soc, mpic); } - if (params->has_platform_bus) { - platform_bus_create_devtree(params, fdt, mpic); + if (pmc->has_platform_bus) { + platform_bus_create_devtree(pmc, fdt, mpic); } - params->fixup_devtree(params, fdt); + pmc->fixup_devtree(fdt); if (toplevel_compat) { qemu_fdt_setprop(fdt, "/", "compatible", toplevel_compat, @@ -551,8 +552,7 @@ out: } typedef struct DeviceTreeParams { - MachineState *machine; - PPCE500Params params; + PPCE500MachineState *machine; hwaddr addr; hwaddr initrd_base; hwaddr initrd_size; @@ -564,7 +564,7 @@ typedef struct DeviceTreeParams { static void ppce500_reset_device_tree(void *opaque) { DeviceTreeParams *p = opaque; - ppce500_load_device_tree(p->machine, &p->params, p->addr, p->initrd_base, + ppce500_load_device_tree(p->machine, p->addr, p->initrd_base, p->initrd_size, p->kernel_base, p->kernel_size, false); } @@ -575,8 +575,7 @@ static void ppce500_init_notify(Notifier *notifier, void *data) ppce500_reset_device_tree(p); } -static int ppce500_prep_device_tree(MachineState *machine, - PPCE500Params *params, +static int ppce500_prep_device_tree(PPCE500MachineState *machine, hwaddr addr, hwaddr initrd_base, hwaddr initrd_size, @@ -585,7 +584,6 @@ static int ppce500_prep_device_tree(MachineState *machine, { DeviceTreeParams *p = g_new(DeviceTreeParams, 1); p->machine = machine; - p->params = *params; p->addr = addr; p->initrd_base = initrd_base; p->initrd_size = initrd_size; @@ -597,9 +595,8 @@ static int ppce500_prep_device_tree(MachineState *machine, qemu_add_machine_init_done_notifier(&p->notifier); /* Issue the device tree loader once, so that we get the size of the blob */ - return ppce500_load_device_tree(machine, params, addr, initrd_base, - initrd_size, kernel_base, kernel_size, - true); + return ppce500_load_device_tree(machine, addr, initrd_base, initrd_size, + kernel_base, kernel_size, true); } /* Create -kernel TLB entries for BookE. */ @@ -685,17 +682,19 @@ static void ppce500_cpu_reset(void *opaque) mmubooke_create_initial_mapping(env); } -static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params, +static DeviceState *ppce500_init_mpic_qemu(PPCE500MachineState *pms, qemu_irq **irqs) { DeviceState *dev; SysBusDevice *s; int i, j, k; + MachineState *machine = MACHINE(pms); + const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms); dev = qdev_create(NULL, TYPE_OPENPIC); - object_property_add_child(qdev_get_machine(), "pic", OBJECT(dev), + object_property_add_child(OBJECT(machine), "pic", OBJECT(dev), &error_fatal); - qdev_prop_set_uint32(dev, "model", params->mpic_version); + qdev_prop_set_uint32(dev, "model", pmc->mpic_version); qdev_prop_set_uint32(dev, "nb_cpus", smp_cpus); qdev_init_nofail(dev); @@ -711,7 +710,7 @@ static DeviceState *ppce500_init_mpic_qemu(PPCE500Params *params, return dev; } -static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params, +static DeviceState *ppce500_init_mpic_kvm(const PPCE500MachineClass *pmc, qemu_irq **irqs, Error **errp) { Error *err = NULL; @@ -719,7 +718,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params, CPUState *cs; dev = qdev_create(NULL, TYPE_KVM_OPENPIC); - qdev_prop_set_uint32(dev, "model", params->mpic_version); + qdev_prop_set_uint32(dev, "model", pmc->mpic_version); object_property_set_bool(OBJECT(dev), true, "realized", &err); if (err) { @@ -739,11 +738,12 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params, return dev; } -static DeviceState *ppce500_init_mpic(MachineState *machine, - PPCE500Params *params, +static DeviceState *ppce500_init_mpic(PPCE500MachineState *pms, MemoryRegion *ccsr, qemu_irq **irqs) { + MachineState *machine = MACHINE(pms); + const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(pms); DeviceState *dev = NULL; SysBusDevice *s; @@ -751,7 +751,7 @@ static DeviceState *ppce500_init_mpic(MachineState *machine, Error *err = NULL; if (machine_kernel_irqchip_allowed(machine)) { - dev = ppce500_init_mpic_kvm(params, irqs, &err); + dev = ppce500_init_mpic_kvm(pmc, irqs, &err); } if (machine_kernel_irqchip_required(machine) && !dev) { error_reportf_err(err, @@ -761,7 +761,7 @@ static DeviceState *ppce500_init_mpic(MachineState *machine, } if (!dev) { - dev = ppce500_init_mpic_qemu(params, irqs); + dev = ppce500_init_mpic_qemu(pms, irqs); } s = SYS_BUS_DEVICE(dev); @@ -778,10 +778,12 @@ static void ppce500_power_off(void *opaque, int line, int on) } } -void ppce500_init(MachineState *machine, PPCE500Params *params) +void ppce500_init(MachineState *machine) { MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); + PPCE500MachineState *pms = PPCE500_MACHINE(machine); + const PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine); PCIBus *pci_bus; CPUPPCState *env = NULL; uint64_t loadaddr; @@ -835,8 +837,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i; - env->mpic_iack = params->ccsrbar_base + - MPC8544_MPIC_REGS_OFFSET + 0xa0; + env->mpic_iack = pmc->ccsrbar_base + MPC8544_MPIC_REGS_OFFSET + 0xa0; ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500); @@ -869,10 +870,10 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) qdev_init_nofail(dev); ccsr = CCSR(dev); ccsr_addr_space = &ccsr->ccsr_space; - memory_region_add_subregion(address_space_mem, params->ccsrbar_base, + memory_region_add_subregion(address_space_mem, pmc->ccsrbar_base, ccsr_addr_space); - mpicdev = ppce500_init_mpic(machine, params, ccsr_addr_space, irqs); + mpicdev = ppce500_init_mpic(pms, ccsr_addr_space, irqs); /* Serial */ if (serial_hd(0)) { @@ -898,7 +899,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) dev = qdev_create(NULL, "e500-pcihost"); object_property_add_child(qdev_get_machine(), "pci-host", OBJECT(dev), &error_abort); - qdev_prop_set_uint32(dev, "first_slot", params->pci_first_slot); + qdev_prop_set_uint32(dev, "first_slot", pmc->pci_first_slot); qdev_prop_set_uint32(dev, "first_pin_irq", pci_irq_nrs[0]); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); @@ -921,9 +922,9 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) } /* Register spinning region */ - sysbus_create_simple("e500-spin", params->spin_base, NULL); + sysbus_create_simple("e500-spin", pmc->spin_base, NULL); - if (params->has_mpc8xxx_gpio) { + if (pmc->has_mpc8xxx_gpio) { qemu_irq poweroff_irq; dev = qdev_create(NULL, "mpc8xxx_gpio"); @@ -939,21 +940,21 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) } /* Platform Bus Device */ - if (params->has_platform_bus) { + if (pmc->has_platform_bus) { dev = qdev_create(NULL, TYPE_PLATFORM_BUS_DEVICE); dev->id = TYPE_PLATFORM_BUS_DEVICE; - qdev_prop_set_uint32(dev, "num_irqs", params->platform_bus_num_irqs); - qdev_prop_set_uint32(dev, "mmio_size", params->platform_bus_size); + qdev_prop_set_uint32(dev, "num_irqs", pmc->platform_bus_num_irqs); + qdev_prop_set_uint32(dev, "mmio_size", pmc->platform_bus_size); qdev_init_nofail(dev); s = SYS_BUS_DEVICE(dev); - for (i = 0; i < params->platform_bus_num_irqs; i++) { - int irqn = params->platform_bus_first_irq + i; + for (i = 0; i < pmc->platform_bus_num_irqs; i++) { + int irqn = pmc->platform_bus_first_irq + i; sysbus_connect_irq(s, i, qdev_get_gpio_in(mpicdev, irqn)); } memory_region_add_subregion(address_space_mem, - params->platform_bus_base, + pmc->platform_bus_base, sysbus_mmio_get_region(s, 0)); } @@ -1056,7 +1057,7 @@ void ppce500_init(MachineState *machine, PPCE500Params *params) exit(1); } - dt_size = ppce500_prep_device_tree(machine, params, dt_base, + dt_size = ppce500_prep_device_tree(pms, dt_base, initrd_base, initrd_size, kernel_base, kernel_size); if (dt_size < 0) { @@ -1085,9 +1086,17 @@ static const TypeInfo e500_ccsr_info = { .instance_init = e500_ccsr_initfn, }; +static const TypeInfo ppce500_info = { + .name = TYPE_PPCE500_MACHINE, + .parent = TYPE_MACHINE, + .abstract = true, + .class_size = sizeof(PPCE500MachineClass), +}; + static void e500_register_types(void) { type_register_static(&e500_ccsr_info); + type_register_static(&ppce500_info); } type_init(e500_register_types) diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h index 70ba1d8f4f..621403bd24 100644 --- a/hw/ppc/e500.h +++ b/hw/ppc/e500.h @@ -3,12 +3,21 @@ #include "hw/boards.h" -typedef struct PPCE500Params { - int pci_first_slot; - int pci_nr_slots; +typedef struct PPCE500MachineState { + /*< private >*/ + MachineState parent_obj; + +} PPCE500MachineState; + +typedef struct PPCE500MachineClass { + /*< private >*/ + MachineClass parent_class; /* required -- must at least add toplevel board compatible */ - void (*fixup_devtree)(struct PPCE500Params *params, void *fdt); + void (*fixup_devtree)(void *fdt); + + int pci_first_slot; + int pci_nr_slots; int mpic_version; bool has_mpc8xxx_gpio; @@ -22,10 +31,18 @@ typedef struct PPCE500Params { hwaddr pci_mmio_base; hwaddr pci_mmio_bus_base; hwaddr spin_base; -} PPCE500Params; +} PPCE500MachineClass; -void ppce500_init(MachineState *machine, PPCE500Params *params); +void ppce500_init(MachineState *machine); hwaddr booke206_page_size_to_tlb(uint64_t size); +#define TYPE_PPCE500_MACHINE "ppce500-base-machine" +#define PPCE500_MACHINE(obj) \ + OBJECT_CHECK(PPCE500MachineState, (obj), TYPE_PPCE500_MACHINE) +#define PPCE500_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PPCE500MachineClass, obj, TYPE_PPCE500_MACHINE) +#define PPCE500_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(PPCE500MachineClass, klass, TYPE_PPCE500_MACHINE) + #endif diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index 81d03e1038..f69aadb666 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -21,7 +21,7 @@ #include "hw/ppc/openpic.h" #include "kvm_ppc.h" -static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt) +static void e500plat_fixup_devtree(void *fdt) { const char model[] = "QEMU ppce500"; const char compatible[] = "fsl,qemu-e500"; @@ -33,40 +33,54 @@ static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt) static void e500plat_init(MachineState *machine) { - PPCE500Params params = { - .pci_first_slot = 0x1, - .pci_nr_slots = PCI_SLOT_MAX - 1, - .fixup_devtree = e500plat_fixup_devtree, - .mpic_version = OPENPIC_MODEL_FSL_MPIC_42, - .has_mpc8xxx_gpio = true, - .has_platform_bus = true, - .platform_bus_base = 0xf00000000ULL, - .platform_bus_size = (128ULL * 1024 * 1024), - .platform_bus_first_irq = 5, - .platform_bus_num_irqs = 10, - .ccsrbar_base = 0xFE0000000ULL, - .pci_pio_base = 0xFE1000000ULL, - .pci_mmio_base = 0xC00000000ULL, - .pci_mmio_bus_base = 0xE0000000ULL, - .spin_base = 0xFEF000000ULL, - }; - + PPCE500MachineClass *pmc = PPCE500_MACHINE_GET_CLASS(machine); /* Older KVM versions don't support EPR which breaks guests when we announce MPIC variants that support EPR. Revert to an older one for those */ if (kvm_enabled() && !kvmppc_has_cap_epr()) { - params.mpic_version = OPENPIC_MODEL_FSL_MPIC_20; + pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_20; } - ppce500_init(machine, ¶ms); + ppce500_init(machine); } -static void e500plat_machine_init(MachineClass *mc) +#define TYPE_E500PLAT_MACHINE MACHINE_TYPE_NAME("ppce500") + +static void e500plat_machine_class_init(ObjectClass *oc, void *data) { + PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc); + MachineClass *mc = MACHINE_CLASS(oc); + + pmc->pci_first_slot = 0x1; + pmc->pci_nr_slots = PCI_SLOT_MAX - 1; + pmc->fixup_devtree = e500plat_fixup_devtree; + pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_42; + pmc->has_mpc8xxx_gpio = true; + pmc->has_platform_bus = true; + pmc->platform_bus_base = 0xf00000000ULL; + pmc->platform_bus_size = (128ULL * 1024 * 1024); + pmc->platform_bus_first_irq = 5; + pmc->platform_bus_num_irqs = 10; + pmc->ccsrbar_base = 0xFE0000000ULL; + pmc->pci_pio_base = 0xFE1000000ULL; + pmc->pci_mmio_base = 0xC00000000ULL; + pmc->pci_mmio_bus_base = 0xE0000000ULL; + pmc->spin_base = 0xFEF000000ULL; + mc->desc = "generic paravirt e500 platform"; mc->init = e500plat_init; mc->max_cpus = 32; - machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ETSEC_COMMON); mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30"); -} + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ETSEC_COMMON); + } + +static const TypeInfo e500plat_info = { + .name = TYPE_E500PLAT_MACHINE, + .parent = TYPE_PPCE500_MACHINE, + .class_init = e500plat_machine_class_init, +}; -DEFINE_MACHINE("ppce500", e500plat_machine_init) +static void e500plat_register_types(void) +{ + type_register_static(&e500plat_info); +} +type_init(e500plat_register_types) diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c index 1717953ec7..ab30a2a99e 100644 --- a/hw/ppc/mpc8544ds.c +++ b/hw/ppc/mpc8544ds.c @@ -18,7 +18,7 @@ #include "qemu/error-report.h" #include "cpu.h" -static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt) +static void mpc8544ds_fixup_devtree(void *fdt) { const char model[] = "MPC8544DS"; const char compatible[] = "MPC8544DS\0MPC85xxDS"; @@ -30,33 +30,46 @@ static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt) static void mpc8544ds_init(MachineState *machine) { - PPCE500Params params = { - .pci_first_slot = 0x11, - .pci_nr_slots = 2, - .fixup_devtree = mpc8544ds_fixup_devtree, - .mpic_version = OPENPIC_MODEL_FSL_MPIC_20, - .ccsrbar_base = 0xE0000000ULL, - .pci_mmio_base = 0xC0000000ULL, - .pci_mmio_bus_base = 0xC0000000ULL, - .pci_pio_base = 0xE1000000ULL, - .spin_base = 0xEF000000ULL, - }; - if (machine->ram_size > 0xc0000000) { error_report("The MPC8544DS board only supports up to 3GB of RAM"); exit(1); } - ppce500_init(machine, ¶ms); + ppce500_init(machine); } - -static void ppce500_machine_init(MachineClass *mc) +static void e500plat_machine_class_init(ObjectClass *oc, void *data) { + MachineClass *mc = MACHINE_CLASS(oc); + PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc); + + pmc->pci_first_slot = 0x11; + pmc->pci_nr_slots = 2; + pmc->fixup_devtree = mpc8544ds_fixup_devtree; + pmc->mpic_version = OPENPIC_MODEL_FSL_MPIC_20; + pmc->ccsrbar_base = 0xE0000000ULL; + pmc->pci_mmio_base = 0xC0000000ULL; + pmc->pci_mmio_bus_base = 0xC0000000ULL; + pmc->pci_pio_base = 0xE1000000ULL; + pmc->spin_base = 0xEF000000ULL; + mc->desc = "mpc8544ds"; mc->init = mpc8544ds_init; mc->max_cpus = 15; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30"); } -DEFINE_MACHINE("mpc8544ds", ppce500_machine_init) +#define TYPE_MPC8544DS_MACHINE MACHINE_TYPE_NAME("mpc8544ds") + +static const TypeInfo mpc8544ds_info = { + .name = TYPE_MPC8544DS_MACHINE, + .parent = TYPE_PPCE500_MACHINE, + .class_init = e500plat_machine_class_init, +}; + +static void mpc8544ds_register_types(void) +{ + type_register_static(&mpc8544ds_info); +} + +type_init(mpc8544ds_register_types) -- cgit v1.2.3 From a324d6f166970f8f6a82c61ffd2356fbda81c8f4 Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Thu, 19 Apr 2018 12:17:35 +0530 Subject: spapr: Support ibm,dynamic-memory-v2 property The new property ibm,dynamic-memory-v2 allows memory to be represented in a more compact manner in device tree. Signed-off-by: Bharata B Rao Signed-off-by: David Gibson --- hw/ppc/spapr.c | 230 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 182 insertions(+), 48 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 2203b6f46d..b35aff5d81 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -668,63 +668,137 @@ static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr) return -1; } -/* - * Adds ibm,dynamic-reconfiguration-memory node. - * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation - * of this device tree node. - */ -static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) +struct sPAPRDrconfCellV2 { + uint32_t seq_lmbs; + uint64_t base_addr; + uint32_t drc_index; + uint32_t aa_index; + uint32_t flags; +} QEMU_PACKED; + +typedef struct DrconfCellQueue { + struct sPAPRDrconfCellV2 cell; + QSIMPLEQ_ENTRY(DrconfCellQueue) entry; +} DrconfCellQueue; + +static DrconfCellQueue * +spapr_get_drconf_cell(uint32_t seq_lmbs, uint64_t base_addr, + uint32_t drc_index, uint32_t aa_index, + uint32_t flags) { - MachineState *machine = MACHINE(spapr); - int ret, i, offset; - uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; - uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; - uint32_t hotplug_lmb_start = spapr->hotplug_memory.base / lmb_size; - uint32_t nr_lmbs = (spapr->hotplug_memory.base + - memory_region_size(&spapr->hotplug_memory.mr)) / - lmb_size; - uint32_t *int_buf, *cur_index, buf_len; - int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; - MemoryDeviceInfoList *dimms = NULL; + DrconfCellQueue *elem; - /* - * Don't create the node if there is no hotpluggable memory - */ - if (machine->ram_size == machine->maxram_size) { - return 0; - } + elem = g_malloc0(sizeof(*elem)); + elem->cell.seq_lmbs = cpu_to_be32(seq_lmbs); + elem->cell.base_addr = cpu_to_be64(base_addr); + elem->cell.drc_index = cpu_to_be32(drc_index); + elem->cell.aa_index = cpu_to_be32(aa_index); + elem->cell.flags = cpu_to_be32(flags); - /* - * Allocate enough buffer size to fit in ibm,dynamic-memory - * or ibm,associativity-lookup-arrays - */ - buf_len = MAX(nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE + 1, nr_nodes * 4 + 2) - * sizeof(uint32_t); - cur_index = int_buf = g_malloc0(buf_len); + return elem; +} - offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory"); +/* ibm,dynamic-memory-v2 */ +static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt, + int offset, MemoryDeviceInfoList *dimms) +{ + uint8_t *int_buf, *cur_index, buf_len; + int ret; + uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; + uint64_t addr, cur_addr, size; + uint32_t nr_boot_lmbs = (spapr->hotplug_memory.base / lmb_size); + uint64_t mem_end = spapr->hotplug_memory.base + + memory_region_size(&spapr->hotplug_memory.mr); + uint32_t node, nr_entries = 0; + sPAPRDRConnector *drc; + DrconfCellQueue *elem, *next; + MemoryDeviceInfoList *info; + QSIMPLEQ_HEAD(, DrconfCellQueue) drconf_queue + = QSIMPLEQ_HEAD_INITIALIZER(drconf_queue); + + /* Entry to cover RAM and the gap area */ + elem = spapr_get_drconf_cell(nr_boot_lmbs, 0, 0, -1, + SPAPR_LMB_FLAGS_RESERVED | + SPAPR_LMB_FLAGS_DRC_INVALID); + QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry); + nr_entries++; + + cur_addr = spapr->hotplug_memory.base; + for (info = dimms; info; info = info->next) { + PCDIMMDeviceInfo *di = info->value->u.dimm.data; + + addr = di->addr; + size = di->size; + node = di->node; + + /* Entry for hot-pluggable area */ + if (cur_addr < addr) { + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, cur_addr / lmb_size); + g_assert(drc); + elem = spapr_get_drconf_cell((addr - cur_addr) / lmb_size, + cur_addr, spapr_drc_index(drc), -1, 0); + QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry); + nr_entries++; + } - ret = fdt_setprop(fdt, offset, "ibm,lmb-size", prop_lmb_size, - sizeof(prop_lmb_size)); - if (ret < 0) { - goto out; + /* Entry for DIMM */ + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, addr / lmb_size); + g_assert(drc); + elem = spapr_get_drconf_cell(size / lmb_size, addr, + spapr_drc_index(drc), node, + SPAPR_LMB_FLAGS_ASSIGNED); + QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry); + nr_entries++; + cur_addr = addr + size; } - ret = fdt_setprop_cell(fdt, offset, "ibm,memory-flags-mask", 0xff); - if (ret < 0) { - goto out; + /* Entry for remaining hotpluggable area */ + if (cur_addr < mem_end) { + drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, cur_addr / lmb_size); + g_assert(drc); + elem = spapr_get_drconf_cell((mem_end - cur_addr) / lmb_size, + cur_addr, spapr_drc_index(drc), -1, 0); + QSIMPLEQ_INSERT_TAIL(&drconf_queue, elem, entry); + nr_entries++; } - ret = fdt_setprop_cell(fdt, offset, "ibm,memory-preservation-time", 0x0); - if (ret < 0) { - goto out; + buf_len = nr_entries * sizeof(struct sPAPRDrconfCellV2) + sizeof(uint32_t); + int_buf = cur_index = g_malloc0(buf_len); + *(uint32_t *)int_buf = cpu_to_be32(nr_entries); + cur_index += sizeof(nr_entries); + + QSIMPLEQ_FOREACH_SAFE(elem, &drconf_queue, entry, next) { + memcpy(cur_index, &elem->cell, sizeof(elem->cell)); + cur_index += sizeof(elem->cell); + QSIMPLEQ_REMOVE(&drconf_queue, elem, DrconfCellQueue, entry); + g_free(elem); } - if (hotplug_lmb_start) { - dimms = qmp_pc_dimm_device_list(); + ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory-v2", int_buf, buf_len); + g_free(int_buf); + if (ret < 0) { + return -1; } + return 0; +} + +/* ibm,dynamic-memory */ +static int spapr_populate_drmem_v1(sPAPRMachineState *spapr, void *fdt, + int offset, MemoryDeviceInfoList *dimms) +{ + int i, ret; + uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; + uint32_t hotplug_lmb_start = spapr->hotplug_memory.base / lmb_size; + uint32_t nr_lmbs = (spapr->hotplug_memory.base + + memory_region_size(&spapr->hotplug_memory.mr)) / + lmb_size; + uint32_t *int_buf, *cur_index, buf_len; - /* ibm,dynamic-memory */ + /* + * Allocate enough buffer size to fit in ibm,dynamic-memory + */ + buf_len = (nr_lmbs * SPAPR_DR_LMB_LIST_ENTRY_SIZE + 1) * sizeof(uint32_t); + cur_index = int_buf = g_malloc0(buf_len); int_buf[0] = cpu_to_be32(nr_lmbs); cur_index++; for (i = 0; i < nr_lmbs; i++) { @@ -764,13 +838,71 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) cur_index += SPAPR_DR_LMB_LIST_ENTRY_SIZE; } - qapi_free_MemoryDeviceInfoList(dimms); ret = fdt_setprop(fdt, offset, "ibm,dynamic-memory", int_buf, buf_len); + g_free(int_buf); if (ret < 0) { - goto out; + return -1; + } + return 0; +} + +/* + * Adds ibm,dynamic-reconfiguration-memory node. + * Refer to docs/specs/ppc-spapr-hotplug.txt for the documentation + * of this device tree node. + */ +static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) +{ + MachineState *machine = MACHINE(spapr); + int ret, i, offset; + uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; + uint32_t prop_lmb_size[] = {0, cpu_to_be32(lmb_size)}; + uint32_t *int_buf, *cur_index, buf_len; + int nr_nodes = nb_numa_nodes ? nb_numa_nodes : 1; + MemoryDeviceInfoList *dimms = NULL; + + /* + * Don't create the node if there is no hotpluggable memory + */ + if (machine->ram_size == machine->maxram_size) { + return 0; + } + + offset = fdt_add_subnode(fdt, 0, "ibm,dynamic-reconfiguration-memory"); + + ret = fdt_setprop(fdt, offset, "ibm,lmb-size", prop_lmb_size, + sizeof(prop_lmb_size)); + if (ret < 0) { + return ret; + } + + ret = fdt_setprop_cell(fdt, offset, "ibm,memory-flags-mask", 0xff); + if (ret < 0) { + return ret; + } + + ret = fdt_setprop_cell(fdt, offset, "ibm,memory-preservation-time", 0x0); + if (ret < 0) { + return ret; + } + + /* ibm,dynamic-memory or ibm,dynamic-memory-v2 */ + dimms = qmp_pc_dimm_device_list(); + if (spapr_ovec_test(spapr->ov5_cas, OV5_DRMEM_V2)) { + ret = spapr_populate_drmem_v2(spapr, fdt, offset, dimms); + } else { + ret = spapr_populate_drmem_v1(spapr, fdt, offset, dimms); + } + qapi_free_MemoryDeviceInfoList(dimms); + + if (ret < 0) { + return ret; } /* ibm,associativity-lookup-arrays */ + buf_len = (nr_nodes * 4 + 2) * sizeof(uint32_t); + cur_index = int_buf = g_malloc0(buf_len); + cur_index = int_buf; int_buf[0] = cpu_to_be32(nr_nodes); int_buf[1] = cpu_to_be32(4); /* Number of entries per associativity list */ @@ -787,8 +919,8 @@ static int spapr_populate_drconf_memory(sPAPRMachineState *spapr, void *fdt) } ret = fdt_setprop(fdt, offset, "ibm,associativity-lookup-arrays", int_buf, (cur_index - int_buf) * sizeof(uint32_t)); -out: g_free(int_buf); + return ret; } @@ -2491,6 +2623,9 @@ static void spapr_machine_init(MachineState *machine) spapr_ovec_set(spapr->ov5, OV5_HPT_RESIZE); } + /* advertise support for ibm,dyamic-memory-v2 */ + spapr_ovec_set(spapr->ov5, OV5_DRMEM_V2); + /* init CPUs */ spapr_init_cpus(spapr); @@ -2918,7 +3053,6 @@ static void spapr_instance_init(Object *obj) " place of standard EPOW events when possible" " (required for memory hot-unplug support)", NULL); - ppc_compat_add_property(obj, "max-cpu-compat", &spapr->max_compat_pvr, "Maximum permitted CPU compatibility mode", &error_fatal); -- cgit v1.2.3 From 88f42c6773c0c09f5c38d5eb0cd6e8b7aed4dfeb Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 5 Apr 2018 15:49:23 +1000 Subject: spapr: Set compatibility mode before the rest of spapr_cpu_reset() Although the order doesn't really matter at the moment, it's possible other initializastions could depend on the compatiblity mode, so make sure we set it first in spapr_cpu_reset(). While we're at it drop the test against first_cpu. Setting the compat mode to the value it already has is redundant, but harmless, so we might as well make a small simplification to the code. Signed-off-by: David Gibson Reviewed-by: Greg Kurz --- hw/ppc/spapr_cpu_core.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 94afeb399e..01dbc69424 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -31,6 +31,11 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(cs); + /* Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. This should never fail. + */ + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); + /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ @@ -45,12 +50,6 @@ static void spapr_cpu_reset(void *opaque) env->spr[SPR_LPCR] &= ~pcc->lpcr_pm; } - /* Set compatibility mode to match the boot CPU, which was either set - * by the machine reset code or by CAS. This should never fail. - */ - if (cs != first_cpu) { - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); - } } static void spapr_cpu_destroy(PowerPCCPU *cpu) -- cgit v1.2.3