From 416756cc049006ab8a05fe39e5f2e6af25cad9d2 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 21 Aug 2018 13:27:48 +0200 Subject: [PATCH 01/14] Record history of ppcemb target in common.json We recently removed the long deprecated "ppcemb" target. This adds a comment in common.json about the SysEmuTarget type, recording when it was removed. Suggested-by: Eric Blake Signed-off-by: David Gibson --- qapi/common.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qapi/common.json b/qapi/common.json index 50ac121d25..021174f04e 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -140,6 +140,8 @@ # prefix to produce the corresponding QEMU executable name. This # is true even for "qemu-system-x86_64". # +# ppcemb: dropped in 3.1 +# # Since: 3.0 ## { 'enum' : 'SysEmuTarget', From 9545f2e10997155aa28b1fc229302cf4e8608c9b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 7 Sep 2018 15:19:54 +0200 Subject: [PATCH 02/14] target/ppc/cpu-models: Re-group the 970 CPUs together again The addition of the POWER9 CPUs divided the entries for the 970 CPUs, which is a little bit confusing when you look at the code. So let's re-group the 970 CPUs together again, and since these chips have been based on the POWER4 processor, move them also in front of the POWER5 chips now. Signed-off-by: Thomas Huth Signed-off-by: David Gibson --- target/ppc/cpu-models.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c index 6c9bfde2d2..7c75963e3c 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c @@ -741,26 +741,8 @@ "PowerPC 7457A v1.2 (G4)") /* 64 bits PowerPC */ #if defined (TARGET_PPC64) - POWERPC_DEF("power5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, - "POWER5+ v2.1") - POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, - "POWER7 v2.3") - POWERPC_DEF("power7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, - "POWER7+ v2.1") - POWERPC_DEF("power8e_v2.1", CPU_POWERPC_POWER8E_v21, POWER8, - "POWER8E v2.1") - POWERPC_DEF("power8_v2.0", CPU_POWERPC_POWER8_v20, POWER8, - "POWER8 v2.0") - POWERPC_DEF("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10, POWER8, - "POWER8NVL v1.0") POWERPC_DEF("970_v2.2", CPU_POWERPC_970_v22, 970, "PowerPC 970 v2.2") - - POWERPC_DEF("power9_v1.0", CPU_POWERPC_POWER9_DD1, POWER9, - "POWER9 v1.0") - POWERPC_DEF("power9_v2.0", CPU_POWERPC_POWER9_DD20, POWER9, - "POWER9 v2.0") - POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970, "PowerPC 970FX v1.0 (G5)") POWERPC_DEF("970fx_v2.0", CPU_POWERPC_970FX_v20, 970, @@ -775,6 +757,22 @@ "PowerPC 970MP v1.0") POWERPC_DEF("970mp_v1.1", CPU_POWERPC_970MP_v11, 970, "PowerPC 970MP v1.1") + POWERPC_DEF("power5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P, + "POWER5+ v2.1") + POWERPC_DEF("power7_v2.3", CPU_POWERPC_POWER7_v23, POWER7, + "POWER7 v2.3") + POWERPC_DEF("power7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7, + "POWER7+ v2.1") + POWERPC_DEF("power8e_v2.1", CPU_POWERPC_POWER8E_v21, POWER8, + "POWER8E v2.1") + POWERPC_DEF("power8_v2.0", CPU_POWERPC_POWER8_v20, POWER8, + "POWER8 v2.0") + POWERPC_DEF("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10, POWER8, + "POWER8NVL v1.0") + POWERPC_DEF("power9_v1.0", CPU_POWERPC_POWER9_DD1, POWER9, + "POWER9 v1.0") + POWERPC_DEF("power9_v2.0", CPU_POWERPC_POWER9_DD20, POWER9, + "POWER9 v2.0") #endif /* defined (TARGET_PPC64) */ /***************************************************************************/ @@ -940,6 +938,9 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "7457a", "7457a_v1.2" }, { "apollo7pm", "7457a_v1.0" }, #if defined(TARGET_PPC64) + { "970", "970_v2.2" }, + { "970fx", "970fx_v3.1" }, + { "970mp", "970mp_v1.1" }, { "power5+", "power5+_v2.1" }, { "power5gs", "power5+_v2.1" }, { "power7", "power7_v2.3" }, @@ -948,9 +949,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "power8", "power8_v2.0" }, { "power8nvl", "power8nvl_v1.0" }, { "power9", "power9_v2.0" }, - { "970", "970_v2.2" }, - { "970fx", "970fx_v3.1" }, - { "970mp", "970mp_v1.1" }, #endif /* Generic PowerPCs */ From 8e93b2c3930b635032739ed3d944f72ac2ae6355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sat, 8 Sep 2018 18:14:21 +0200 Subject: [PATCH 03/14] hw/ppc: on 40p machine, change default firmware to OpenBIOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit OpenBIOS gained 40p support in 5b20e4cacecb62fb2bdc6867c11d44cddd77c4ff Use it, instead of relying on an unmaintained and very limited firmware. Signed-off-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/ppc/prep.c | 2 +- tests/boot-serial-test.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 162b27a3b8..baca1d7c04 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -651,7 +651,7 @@ static void ibm_40p_init(MachineState *machine) /* PCI host */ dev = qdev_create(NULL, "raven-pcihost"); if (!bios_name) { - bios_name = BIOS_FILENAME; + bios_name = "openbios-ppc"; } qdev_prop_set_string(dev, "bios-name", bios_name); qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE); diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c index f123b15e3e..f865822e32 100644 --- a/tests/boot-serial-test.c +++ b/tests/boot-serial-test.c @@ -75,12 +75,12 @@ typedef struct testdef { static testdef_t tests[] = { { "alpha", "clipper", "", "PCI:" }, { "ppc", "ppce500", "", "U-Boot" }, - { "ppc", "40p", "-boot d", "Booting from device d" }, + { "ppc", "40p", "-vga none -boot d", "Trying cd:," }, { "ppc", "g3beige", "", "PowerPC,750" }, { "ppc", "mac99", "", "PowerPC,G4" }, { "ppc", "sam460ex", "-m 256", "DRAM: 256 MiB" }, { "ppc64", "ppce500", "", "U-Boot" }, - { "ppc64", "40p", "-m 192", "Memory size: 192 MB" }, + { "ppc64", "40p", "-m 192", "Memory: 192M" }, { "ppc64", "mac99", "", "PowerPC,970FX" }, { "ppc64", "pseries", "", "Open Firmware" }, { "ppc64", "powernv", "-cpu POWER8", "OPAL" }, From 55a2290254192d828b9464acb175fb0dc24c7035 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sat, 8 Sep 2018 10:08:18 +0100 Subject: [PATCH 04/14] raven: some minor IRQ-related tidy-ups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This really lays the groundwork for the upcoming patches: it renames the irqs PREPPCIState struct member to pci_irqs (as soon there will be a distinction) and then changes the raven IRQ opaque to use PREPPCIState instead of just irqs array. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Tested-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/pci-host/prep.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 88f035c20b..9b36f19c97 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -55,7 +55,7 @@ typedef struct RavenPCIState { typedef struct PRePPCIState { PCIHostState parent_obj; - qemu_irq irq[PCI_NUM_PINS]; + qemu_irq pci_irqs[PCI_NUM_PINS]; PCIBus pci_bus; AddressSpace pci_io_as; MemoryRegion pci_io; @@ -194,9 +194,9 @@ static int raven_map_irq(PCIDevice *pci_dev, int irq_num) static void raven_set_irq(void *opaque, int irq_num, int level) { - qemu_irq *pic = opaque; + PREPPCIState *s = opaque; - qemu_set_irq(pic[irq_num] , level); + qemu_set_irq(s->pci_irqs[irq_num], level); } static AddressSpace *raven_pcihost_set_iommu(PCIBus *bus, void *opaque, @@ -223,13 +223,12 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp) int i; for (i = 0; i < PCI_NUM_PINS; i++) { - sysbus_init_irq(dev, &s->irq[i]); + sysbus_init_irq(dev, &s->pci_irqs[i]); } qdev_init_gpio_in(d, raven_change_gpio, 1); - pci_bus_irqs(&s->pci_bus, raven_set_irq, raven_map_irq, s->irq, - PCI_NUM_PINS); + pci_bus_irqs(&s->pci_bus, raven_set_irq, raven_map_irq, s, PCI_NUM_PINS); memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, s, "pci-conf-idx", 4); From f40b83a4e31ae1b56ae5494cf7dc8b015975ac4a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sat, 8 Sep 2018 10:08:19 +0100 Subject: [PATCH 05/14] 40p: use OR gate to wire up raven PCI interrupts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the PReP specification section 6.1.6 "System Interrupt Assignments", all PCI interrupts are routed via IRQ 15. Instead of mapping each PCI IRQ separately, we introduce an OR gate within the raven PCI host bridge and then wire the single output of the OR gate to the interrupt controller. Note that whilst the (now deprecated) PReP machine still exists we still need to preserve the old IRQ routing. This is done by adding a new "is-legacy-prep" property to the raven PCI host bridge which is set to true for the PReP machine. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Tested-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/pci-host/prep.c | 25 +++++++++++++++++++++++-- hw/ppc/prep.c | 4 +--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 9b36f19c97..b1b6b16bad 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -32,6 +32,7 @@ #include "hw/pci/pci_host.h" #include "hw/i386/pc.h" #include "hw/loader.h" +#include "hw/or-irq.h" #include "exec/address-spaces.h" #include "elf.h" @@ -55,6 +56,7 @@ typedef struct RavenPCIState { typedef struct PRePPCIState { PCIHostState parent_obj; + qemu_or_irq *or_irq; qemu_irq pci_irqs[PCI_NUM_PINS]; PCIBus pci_bus; AddressSpace pci_io_as; @@ -69,6 +71,7 @@ typedef struct PRePPCIState { RavenPCIState pci_dev; int contiguous_map; + bool is_legacy_prep; } PREPPCIState; #define BIOS_SIZE (1 * MiB) @@ -222,8 +225,23 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp) MemoryRegion *address_space_mem = get_system_memory(); int i; - for (i = 0; i < PCI_NUM_PINS; i++) { - sysbus_init_irq(dev, &s->pci_irqs[i]); + if (s->is_legacy_prep) { + for (i = 0; i < PCI_NUM_PINS; i++) { + sysbus_init_irq(dev, &s->pci_irqs[i]); + } + } else { + /* According to PReP specification section 6.1.6 "System Interrupt + * Assignments", all PCI interrupts are routed via IRQ 15 */ + s->or_irq = OR_IRQ(object_new(TYPE_OR_IRQ)); + object_property_set_int(OBJECT(s->or_irq), PCI_NUM_PINS, "num-lines", + &error_fatal); + object_property_set_bool(OBJECT(s->or_irq), true, "realized", + &error_fatal); + sysbus_init_irq(dev, &s->or_irq->out_irq); + + for (i = 0; i < PCI_NUM_PINS; i++) { + s->pci_irqs[i] = qdev_get_gpio_in(DEVICE(s->or_irq), i); + } } qdev_init_gpio_in(d, raven_change_gpio, 1); @@ -382,6 +400,9 @@ static Property raven_pcihost_properties[] = { DEFINE_PROP_UINT32("elf-machine", PREPPCIState, pci_dev.elf_machine, EM_NONE), DEFINE_PROP_STRING("bios-name", PREPPCIState, pci_dev.bios_name), + /* Temporary workaround until legacy prep machine is removed */ + DEFINE_PROP_BOOL("is-legacy-prep", PREPPCIState, is_legacy_prep, + false), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index baca1d7c04..4bb831c3e6 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -502,6 +502,7 @@ static void ppc_prep_init(MachineState *machine) } qdev_prop_set_string(dev, "bios-name", bios_name); qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE); + qdev_prop_set_bit(dev, "is-legacy-prep", true); pcihost = PCI_HOST_BRIDGE(dev); object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL); qdev_init_nofail(dev); @@ -669,9 +670,6 @@ static void ibm_40p_init(MachineState *machine) qdev_connect_gpio_out(dev, 0, cpu->env.irq_inputs[PPC6xx_INPUT_INT]); sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 15)); - sysbus_connect_irq(pcihost, 1, qdev_get_gpio_in(dev, 13)); - sysbus_connect_irq(pcihost, 2, qdev_get_gpio_in(dev, 15)); - sysbus_connect_irq(pcihost, 3, qdev_get_gpio_in(dev, 13)); isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); /* Memory controller */ From e39de895f6adc3a274f3116d4f38845d8fcbf135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 11 Sep 2018 07:55:02 +0200 Subject: [PATCH 06/14] spapr: introduce a spapr_irq class 'nr_msis' attribute MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The number of MSI interrupts a sPAPR machine can allocate is in direct relation with the number of interrupts of the sPAPRIrq backend. Define statically this value at the sPAPRIrq class level and use it for the "ibm,pe-total-#msi" property of the sPAPR PHB. According to the PAPR specs, "ibm,pe-total-#msi" defines the maximum number of MSIs that are available to the PE. We choose to advertise the maximum number of MSIs that are available to the machine for simplicity of the model and to avoid segmenting the MSI interrupt pool which can be easily shared. If the pool limit is reached, it can be extended dynamically. Finally, remove XICS_IRQS_SPAPR which is now unused. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 9 +++++++-- hw/ppc/spapr_pci.c | 5 +++-- include/hw/ppc/spapr_irq.h | 1 + include/hw/ppc/xics.h | 2 -- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 0cbb5dd393..fe8be5f521 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -99,7 +99,7 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, Error **errp) /* Initialize the MSI IRQ allocator. */ if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { - spapr_irq_msi_init(spapr, XICS_IRQ_BASE + nr_irqs - SPAPR_IRQ_MSI); + spapr_irq_msi_init(spapr, smc->irq->nr_msis); } if (kvm_enabled()) { @@ -195,8 +195,13 @@ static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon) ics_pic_print_info(spapr->ics, mon); } +#define SPAPR_IRQ_XICS_NR_IRQS 0x400 +#define SPAPR_IRQ_XICS_NR_MSIS \ + (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI) + sPAPRIrq spapr_irq_xics = { - .nr_irqs = XICS_IRQS_SPAPR, + .nr_irqs = SPAPR_IRQ_XICS_NR_IRQS, + .nr_msis = SPAPR_IRQ_XICS_NR_MSIS, .init = spapr_irq_init_xics, .claim = spapr_irq_claim_xics, diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 6bcb4f419b..bb736177e7 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2121,6 +2121,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, sPAPRTCETable *tcet; PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus; sPAPRFDT s_fdt; + sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); /* Start populating the FDT */ nodename = g_strdup_printf("pci@%" PRIx64, phb->buid); @@ -2138,8 +2139,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges)); _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1)); - /* TODO: fine tune the total count of allocatable MSIs per PHB */ - _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", XICS_IRQS_SPAPR)); + _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", + smc->irq->nr_msis)); /* Dynamic DMA window */ if (phb->ddw_enabled) { diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 0e98c4474b..650f810ad2 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -31,6 +31,7 @@ void spapr_irq_msi_reset(sPAPRMachineState *spapr); typedef struct sPAPRIrq { uint32_t nr_irqs; + uint32_t nr_msis; void (*init)(sPAPRMachineState *spapr, Error **errp); int (*claim)(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 9c2916c9b2..9958443d19 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -181,8 +181,6 @@ typedef struct XICSFabricClass { ICPState *(*icp_get)(XICSFabric *xi, int server); } XICSFabricClass; -#define XICS_IRQS_SPAPR 1024 - void spapr_dt_xics(int nr_servers, void *fdt, uint32_t phandle); ICPState *xics_icp_get(XICSFabric *xi, int server); From ae837402379b649e942b6a968de88b94585a5c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Tue, 11 Sep 2018 07:55:03 +0200 Subject: [PATCH 07/14] spapr: increase the size of the IRQ number space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new layout using static IRQ number does not leave much space to the dynamic MSI range, only 0x100 IRQ numbers. Increase the total number of IRQS for newer machines and introduce a legacy XICS backend for pre-3.1 machines to maintain compatibility. For the old backend, provide a 'nr_msis' value covering the full IRQ number space as it does not use the bitmap allocator to allocate MSI interrupt numbers. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 1 + hw/ppc/spapr_irq.c | 15 ++++++++++++++- include/hw/ppc/spapr_irq.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4a9dd4d9bc..eba7d60a30 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3971,6 +3971,7 @@ static void spapr_machine_3_0_class_options(MachineClass *mc) SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_3_0); smc->legacy_irq_allocation = true; + smc->irq = &spapr_irq_xics_legacy; } DEFINE_SPAPR_MACHINE(3_0, "3.0", false); diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index fe8be5f521..e77b94cc68 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -195,7 +195,7 @@ static void spapr_irq_print_info_xics(sPAPRMachineState *spapr, Monitor *mon) ics_pic_print_info(spapr->ics, mon); } -#define SPAPR_IRQ_XICS_NR_IRQS 0x400 +#define SPAPR_IRQ_XICS_NR_IRQS 0x1000 #define SPAPR_IRQ_XICS_NR_MSIS \ (XICS_IRQ_BASE + SPAPR_IRQ_XICS_NR_IRQS - SPAPR_IRQ_MSI) @@ -289,3 +289,16 @@ int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp) return first + ics->offset; } + +#define SPAPR_IRQ_XICS_LEGACY_NR_IRQS 0x400 + +sPAPRIrq spapr_irq_xics_legacy = { + .nr_irqs = SPAPR_IRQ_XICS_LEGACY_NR_IRQS, + .nr_msis = SPAPR_IRQ_XICS_LEGACY_NR_IRQS, + + .init = spapr_irq_init_xics, + .claim = spapr_irq_claim_xics, + .free = spapr_irq_free_xics, + .qirq = spapr_qirq_xics, + .print_info = spapr_irq_print_info_xics, +}; diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 650f810ad2..a467ce696e 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -41,6 +41,7 @@ typedef struct sPAPRIrq { } sPAPRIrq; extern sPAPRIrq spapr_irq_xics; +extern sPAPRIrq spapr_irq_xics_legacy; int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp); void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); From 0976efd51bbfb28292704a248cb9454fc12f911d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Thu, 13 Sep 2018 07:16:05 +0200 Subject: [PATCH 08/14] spapr_pci: add an extra 'nr_msis' argument to spapr_populate_pci_dt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that we don't have to call qdev_get_machine() to get the machine class and the sPAPRIrq backend holding the number of MSIs. Signed-off-by: Cédric Le Goater Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr.c | 2 +- hw/ppc/spapr_pci.c | 9 +++------ include/hw/pci-host/spapr.h | 5 ++--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index eba7d60a30..98868d893a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1267,7 +1267,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr, } QLIST_FOREACH(phb, &spapr->phbs, list) { - ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt); + ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt, smc->irq->nr_msis); if (ret < 0) { error_report("couldn't setup PCI devices in fdt"); exit(1); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index bb736177e7..c2271e6ed4 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2069,9 +2069,8 @@ static void spapr_phb_pci_enumerate(sPAPRPHBState *phb) } -int spapr_populate_pci_dt(sPAPRPHBState *phb, - uint32_t xics_phandle, - void *fdt) +int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt, + uint32_t nr_msis) { int bus_off, i, j, ret; gchar *nodename; @@ -2121,7 +2120,6 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, sPAPRTCETable *tcet; PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus; sPAPRFDT s_fdt; - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(qdev_get_machine()); /* Start populating the FDT */ nodename = g_strdup_printf("pci@%" PRIx64, phb->buid); @@ -2139,8 +2137,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof_ranges)); _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg))); _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pci-config-space-type", 0x1)); - _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", - smc->irq->nr_msis)); + _FDT(fdt_setprop_cell(fdt, bus_off, "ibm,pe-total-#msi", nr_msis)); /* Dynamic DMA window */ if (phb->ddw_enabled) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 0fae4fc6a4..7c66c3872f 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -113,9 +113,8 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index); -int spapr_populate_pci_dt(sPAPRPHBState *phb, - uint32_t xics_phandle, - void *fdt); +int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt, + uint32_t nr_msis); void spapr_pci_rtas_init(void); From f3a60058c97f2f923e3883a8b129c7c8dfe46a3a Mon Sep 17 00:00:00 2001 From: Marcus Comstedt Date: Wed, 19 Sep 2018 14:31:14 +0200 Subject: [PATCH 09/14] sm501: Adjust endianness of pixel value in rectangle fill The value from twoD_foreground (which is in host endian format) must be converted to the endianness of the framebuffer (currently always little endian) before it can be used to perform the fill operation. Signed-off-by: Marcus Comstedt Reviewed-by: BALATON Zoltan Reviewed-by: Peter Maydell Signed-off-by: David Gibson --- hw/display/sm501.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 874260a143..4a8686f0f5 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -39,6 +39,7 @@ #include "hw/i2c/i2c-ddc.h" #include "qemu/range.h" #include "ui/pixel_ops.h" +#include "qemu/bswap.h" /* * Status: 2010/05/07 @@ -812,9 +813,11 @@ static void sm501_2d_operation(SM501State *s) FILL_RECT(1, uint8_t); break; case 1: + color = cpu_to_le16(color); FILL_RECT(2, uint16_t); break; case 2: + color = cpu_to_le32(color); FILL_RECT(4, uint32_t); break; } From f74a4f3a59b6168b8f3e84e4276c47eda610891d Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 19 Sep 2018 18:20:57 +0100 Subject: [PATCH 10/14] scsi: add lsi53c8xx_handle_legacy_cmdline() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the function that will soon be used to replace lsi53c895a_create() and lsi53c810_create(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/scsi/lsi53c895a.c | 7 +++++++ include/hw/pci/pci.h | 1 + 2 files changed, 8 insertions(+) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 955ba94800..8f5ab82d57 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -2290,3 +2290,10 @@ void lsi53c810_create(PCIBus *bus, int devfn) scsi_bus_legacy_handle_cmdline(&s->bus); } + +void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev) +{ + LSIState *s = LSI53C895A(lsi_dev); + + scsi_bus_legacy_handle_cmdline(&s->bus); +} diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 990d6fcbde..0d907dc084 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -709,6 +709,7 @@ PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); void lsi53c895a_create(PCIBus *bus); void lsi53c810_create(PCIBus *bus, int devfn); +void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); qemu_irq pci_allocate_irq(PCIDevice *pci_dev); void pci_set_irq(PCIDevice *pci_dev, int level); From 877eb21d5607e5097b8331e7a5b3d9714c0c5b91 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 19 Sep 2018 18:20:58 +0100 Subject: [PATCH 11/14] scsi: move lsi53c8xx_create() callers to lsi53c8xx_handle_legacy_cmdline() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As part of commits a64aa5785d "hw: Deprecate -drive if=scsi with non-onboard HBAs" and b891538e81 "hw/ppc/prep: Fix implicit creation of "-drive if=scsi" devices" the lsi53c895a_create() and lsi53c810_create() functions were added to wrap pci_create_simple() and scsi_bus_legacy_handle_cmdline(). Unfortunately this prevents us from changing qdev properties on the device and/or changing the PCI configuration. By switching over to using the new lsi53c8xx_handle_legacy_cmdline() function then the caller can now configure and realize the LSI SCSI device exactly as required. Signed-off-by: Mark Cave-Ayland Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Acked-by: Peter Maydell [arm parts] Signed-off-by: David Gibson --- hw/arm/realview.c | 3 ++- hw/arm/versatilepb.c | 3 ++- hw/hppa/machine.c | 4 +++- hw/ppc/prep.c | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/hw/arm/realview.c b/hw/arm/realview.c index ab8c14fde3..242f5a87b6 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -257,7 +257,8 @@ static void realview_init(MachineState *machine, } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { - lsi53c895a_create(pci_bus); + dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); + lsi53c8xx_handle_legacy_cmdline(dev); n--; } } diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 8b74857059..22b09a1e61 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -278,7 +278,8 @@ static void versatile_init(MachineState *machine, int board_id) } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { - lsi53c895a_create(pci_bus); + dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); + lsi53c8xx_handle_legacy_cmdline(dev); n--; } diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index cf7c61c6cc..0fb8fb877e 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -59,6 +59,7 @@ static void machine_hppa_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; + DeviceState *dev; PCIBus *pci_bus; ISABus *isa_bus; qemu_irq rtc_irq, serial_irq; @@ -115,7 +116,8 @@ static void machine_hppa_init(MachineState *machine) } /* SCSI disk setup. */ - lsi53c895a_create(pci_bus); + dev = DEVICE(pci_create_simple(pci_bus, -1, "lsi53c895a")); + lsi53c8xx_handle_legacy_cmdline(dev); /* Network setup. e1000 is good enough, failing Tulip support. */ for (i = 0; i < nb_nics; i++) { diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 4bb831c3e6..7e2c70b92a 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -700,7 +700,9 @@ static void ibm_40p_init(MachineState *machine) qdev_prop_set_uint32(dev, "equipment", 0xc0); qdev_init_nofail(dev); - lsi53c810_create(pci_bus, PCI_DEVFN(1, 0)); + dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(1, 0), + "lsi53c810")); + lsi53c8xx_handle_legacy_cmdline(dev); /* XXX: s3-trio at PCI_DEVFN(2, 0) */ pci_vga_init(pci_bus); From e090a054a7c1d8cada034a362d05b2a8fee3a420 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 19 Sep 2018 18:20:59 +0100 Subject: [PATCH 12/14] scsi: remove unused lsi53c895a_create() and lsi53c810_create() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that these functions are no longer required they can be removed. Signed-off-by: Mark Cave-Ayland Reviewed-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: David Gibson --- hw/scsi/lsi53c895a.c | 14 -------------- include/hw/pci/pci.h | 2 -- 2 files changed, 16 deletions(-) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 8f5ab82d57..f5cbbf653c 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -2277,20 +2277,6 @@ static void lsi53c895a_register_types(void) type_init(lsi53c895a_register_types) -void lsi53c895a_create(PCIBus *bus) -{ - LSIState *s = LSI53C895A(pci_create_simple(bus, -1, "lsi53c895a")); - - scsi_bus_legacy_handle_cmdline(&s->bus); -} - -void lsi53c810_create(PCIBus *bus, int devfn) -{ - LSIState *s = LSI53C895A(pci_create_simple(bus, devfn, "lsi53c810")); - - scsi_bus_legacy_handle_cmdline(&s->bus); -} - void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev) { LSIState *s = LSI53C895A(lsi_dev); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 0d907dc084..e6514bba23 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -707,8 +707,6 @@ PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn, PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name); PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name); -void lsi53c895a_create(PCIBus *bus); -void lsi53c810_create(PCIBus *bus, int devfn); void lsi53c8xx_handle_legacy_cmdline(DeviceState *lsi_dev); qemu_irq pci_allocate_irq(PCIDevice *pci_dev); From 3cc1b9cba915c4adfa73d68e344677574a5a5267 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 19 Sep 2018 18:21:00 +0100 Subject: [PATCH 13/14] lsi53c895a: add optional external IRQ via qdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On some early machines the on-board PCI devices IRQs are wired directly to the interrupt controller instead of via the PCI host bridge. Add an optional external IRQ that if wired up via qdev will replace the in-built PCI IRQ. Signed-off-by: Mark Cave-Ayland Reviewed-by: David Gibson Reviewed-by: Fam Zheng Reviewed-by: Hervé Poussineau Tested-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/scsi/lsi53c895a.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index f5cbbf653c..996b40650d 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -207,6 +207,7 @@ typedef struct { PCIDevice parent_obj; /*< public >*/ + qemu_irq ext_irq; MemoryRegion mmio_io; MemoryRegion ram_io; MemoryRegion io_io; @@ -443,9 +444,19 @@ static void lsi_stop_script(LSIState *s) s->istat1 &= ~LSI_ISTAT1_SRUN; } -static void lsi_update_irq(LSIState *s) +static void lsi_set_irq(LSIState *s, int level) { PCIDevice *d = PCI_DEVICE(s); + + if (s->ext_irq) { + qemu_set_irq(s->ext_irq, level); + } else { + pci_set_irq(d, level); + } +} + +static void lsi_update_irq(LSIState *s) +{ int level; static int last_level; lsi_request *p; @@ -477,7 +488,7 @@ static void lsi_update_irq(LSIState *s) level, s->dstat, s->sist1, s->sist0); last_level = level; } - pci_set_irq(d, level); + lsi_set_irq(s, level); if (!level && lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON)) { DPRINTF("Handled IRQs & disconnected, looking for pending " @@ -2213,6 +2224,7 @@ static void lsi_scsi_realize(PCIDevice *dev, Error **errp) "lsi-io", 256); address_space_init(&s->pci_io_as, pci_address_space_io(dev), "lsi-pci-io"); + qdev_init_gpio_out(d, &s->ext_irq, 1); pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io); pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_io); From 0358687b16407670f09649dfdc079c04a3522493 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 19 Sep 2018 18:21:01 +0100 Subject: [PATCH 14/14] 40p: add fixed IRQ routing for LSI SCSI device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whilst the PReP specification describes how all PCI IRQs are routed via IRQ 15 on the interrupt controller, the real 40p machine has a routing quirk in that the LSI SCSI device is routed directly to IRQ 13. Enable the external IRQ for the LSI SCSI device by wiring up the IRQ with qdev to the relevant interrupt controller gpio. Signed-off-by: Mark Cave-Ayland Acked-by: David Gibson Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Tested-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/ppc/prep.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 7e2c70b92a..2afb7f437e 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -621,7 +621,7 @@ static void ibm_40p_init(MachineState *machine) CPUPPCState *env = NULL; uint16_t cmos_checksum; PowerPCCPU *cpu; - DeviceState *dev; + DeviceState *dev, *i82378_dev; SysBusDevice *pcihost, *s; Nvram *m48t59 = NULL; PCIBus *pci_bus; @@ -666,11 +666,11 @@ static void ibm_40p_init(MachineState *machine) } /* PCI -> ISA bridge */ - dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378")); - qdev_connect_gpio_out(dev, 0, + i82378_dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(11, 0), "i82378")); + qdev_connect_gpio_out(i82378_dev, 0, cpu->env.irq_inputs[PPC6xx_INPUT_INT]); - sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(dev, 15)); - isa_bus = ISA_BUS(qdev_get_child_bus(dev, "isa.0")); + sysbus_connect_irq(pcihost, 0, qdev_get_gpio_in(i82378_dev, 15)); + isa_bus = ISA_BUS(qdev_get_child_bus(i82378_dev, "isa.0")); /* Memory controller */ dev = DEVICE(isa_create(isa_bus, "rs6000-mc")); @@ -703,6 +703,7 @@ static void ibm_40p_init(MachineState *machine) dev = DEVICE(pci_create_simple(pci_bus, PCI_DEVFN(1, 0), "lsi53c810")); lsi53c8xx_handle_legacy_cmdline(dev); + qdev_connect_gpio_out(dev, 0, qdev_get_gpio_in(i82378_dev, 13)); /* XXX: s3-trio at PCI_DEVFN(2, 0) */ pci_vga_init(pci_bus);