* [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 @ 2015-06-24 6:30 David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 01/22] spapr: ensure we have at least one XICS server David Gibson ` (22 more replies) 0 siblings, 23 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, David Gibson Hi Alex, Here are my accumulated spapr related qemu updates for the last little while. Highlights are a SLOF update and changes to move PCI device node creation from SLOF into qemu (using the same code paths as for hotplug). This also has some preliminaries for CPU and memory hotplug on -machine pseries, but the actual code for those is still on the way. These are based against mainline master, not ppc-next, since mainline is a fast-forward of the latest ppc-next that I can see. I've done a compile and "make check" on x86, ppc64 and ppc64le hosts, plus a basic sanity check of booting an LE guest. NOTE: 2 patches here touch things outside the strictly spapr specific code: - 15/22 adds a new way of iterating through CPUs in the core code. It has a R-b from Andreas who's responsible for that code AFAICT, but I never got a reply when I asked if he'd prefer it sent through a different tree. - 18/22 makes some small cleanups acrossa all the ppc machine types. Let me know if you'd like me to stage this differently. Alexey Kardashevskiy (1): pseries: Update SLOF firmware image to qemu-slof-20150429 Bharata B Rao (7): spapr: Consider max_cpus during xics initialization spapr: Support ibm,lrdr-capacity device tree property cpus: Add a macro to walk CPUs in reverse spapr: Reorganize CPU dt generation code spapr: Consolidate cpu init code into a routine ppc: Update cpu_model in MachineState xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled David Gibson (4): spapr: Merge sPAPREnvironment into sPAPRMachineState spapr: Remove obsolete ram_limit field from sPAPRMachineState spapr: Remove obsolete entry_point field from sPAPRMachineState spapr: Add sPAPRMachineClass Greg Kurz (3): spapr: ensure we have at least one XICS server spapr_iommu: drop erroneous check in h_put_tce_indirect() spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags Markus Armbruster (1): Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" Nikunj A Dadhania (6): spapr_pci: encode missing 64-bit memory address space spapr_pci: encode class code including Prog IF register spapr_pci: set device node unit address as hex spapr_pci: enumerate and add PCI device tree spapr_pci: populate ibm,loc-code spapr_pci: drop redundant args in spapr_[populate,create]_pci_child_dt docs/specs/ppc-spapr-hotplug.txt | 18 ++ hw/char/spapr_vty.c | 6 +- hw/intc/xics.c | 20 +- hw/intc/xics_kvm.c | 12 +- hw/net/spapr_llan.c | 12 +- hw/nvram/spapr_nvram.c | 4 +- hw/ppc/mac_newworld.c | 10 +- hw/ppc/mac_oldworld.c | 7 +- hw/ppc/ppc440_bamboo.c | 7 +- hw/ppc/prep.c | 7 +- hw/ppc/spapr.c | 450 +++++++++++++++++++++------------------ hw/ppc/spapr_events.c | 13 +- hw/ppc/spapr_hcall.c | 39 ++-- hw/ppc/spapr_iommu.c | 30 ++- hw/ppc/spapr_pci.c | 318 +++++++++++++++++++++------ hw/ppc/spapr_rtas.c | 54 +++-- hw/ppc/spapr_rtc.c | 4 +- hw/ppc/spapr_vio.c | 15 +- hw/ppc/virtex_ml507.c | 7 +- include/hw/pci-host/spapr.h | 10 +- include/hw/ppc/spapr.h | 53 ++++- include/hw/ppc/spapr_vio.h | 4 +- include/hw/ppc/xics.h | 1 + include/qom/cpu.h | 2 + pc-bios/README | 2 +- pc-bios/slof.bin | Bin 912192 -> 912720 bytes roms/SLOF | 2 +- 27 files changed, 708 insertions(+), 399 deletions(-) -- 2.4.3 ^ permalink raw reply [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 01/22] spapr: ensure we have at least one XICS server 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 02/22] pseries: Update SLOF firmware image to qemu-slof-20150429 David Gibson ` (21 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Greg Kurz From: Greg Kurz <gkurz@linux.vnet.ibm.com> XICS needs to know the upper value for cpu_index as it is used to compute the number of servers: smp_cpus * kvmppc_smt_threads() / smp_threads When passing -smp cpus=1,threads=9 on a POWER8 host, we end up with: 1 * 8 / 9 = 0 ... which leads to an assertion in both emulated: Number of servers needs to be greater 0 Aborted (core dumped) ... and in-kernel XICS: xics_kvm_realize: Assertion `icp->nr_servers' failed. Aborted (core dumped) With this patch, we are sure that nr_servers > 0. Passing the same bogus -smp option then leads to: qemu-system-ppc64: Cannot support more than 8 threads on PPC with KVM ... which is a lot more explicit than the XICS errors. Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f174e5a..10ca866 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1467,7 +1467,8 @@ static void ppc_spapr_init(MachineState *machine) /* Set up Interrupt Controller before we create the VCPUs */ spapr->icp = xics_system_init(machine, - smp_cpus * kvmppc_smt_threads() / smp_threads, + DIV_ROUND_UP(smp_cpus * kvmppc_smt_threads(), + smp_threads), XICS_IRQS); /* init CPUs */ -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 02/22] pseries: Update SLOF firmware image to qemu-slof-20150429 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 01/22] spapr: ensure we have at least one XICS server David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 03/22] spapr: Merge sPAPREnvironment into sPAPRMachineState David Gibson ` (20 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel From: Alexey Kardashevskiy <aik@ozlabs.ru> The changelog is: > version: update to 20150429 > pci: Use QEMU created PCI device nodes > usb: support 64-bit pci bars > pci: Support 64-bit address translation > pci: program correct bridge limit registers during probe > scsi: handle report-luns failure > Fix "key?" Forth word when using USB keyboards > Remove bulk.fs package > Include make.rules in the library Makefiles Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 912192 -> 912720 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index 63e7254..05cf042 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20150313. + built from git tag qemu-slof-20150429. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index ab72cba80c528aea2545974e9c717cee583c254c..0398ac67bc8d07410fe2ccc9d62c376ef3cf87c3 100644 GIT binary patch delta 88316 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 T!XFI1a^w*!hWz_a+Yb1DL}#t0 delta 88582 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 Me)x!w=Y0PE0V;bn!2kdN diff --git a/roms/SLOF b/roms/SLOF index c89b0df..7d766a3 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit c89b0df661c0a6bfa9ff0ed4a371f631f5ee38b0 +Subproject commit 7d766a3ac9b2474f6c7da0084d43590cbbf047bf -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 03/22] spapr: Merge sPAPREnvironment into sPAPRMachineState 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 01/22] spapr: ensure we have at least one XICS server David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 02/22] pseries: Update SLOF firmware image to qemu-slof-20150429 David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 04/22] spapr: Remove obsolete ram_limit field from sPAPRMachineState David Gibson ` (19 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, David Gibson The code for -machine pseries maintains a global sPAPREnvironment structure which keeps track of general state information about the guest platform. This predates the existence of the MachineState structure, but performs basically the same function. Now that we have the generic MachineState, fold sPAPREnvironment into sPAPRMachineState, the pseries specific subclass of MachineState. This is mostly a matter of search and replace, although a few places which relied on the global spapr variable are changed to find the structure via qdev_get_machine(). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/char/spapr_vty.c | 6 ++-- hw/intc/xics.c | 20 ++++++------- hw/intc/xics_kvm.c | 2 +- hw/net/spapr_llan.c | 12 ++++---- hw/nvram/spapr_nvram.c | 4 +-- hw/ppc/spapr.c | 73 +++++++++++++++++++-------------------------- hw/ppc/spapr_events.c | 13 +++++--- hw/ppc/spapr_hcall.c | 36 +++++++++++----------- hw/ppc/spapr_iommu.c | 8 ++--- hw/ppc/spapr_pci.c | 37 ++++++++++++----------- hw/ppc/spapr_rtas.c | 38 +++++++++++------------ hw/ppc/spapr_rtc.c | 4 +-- hw/ppc/spapr_vio.c | 15 +++++----- include/hw/pci-host/spapr.h | 10 ++++--- include/hw/ppc/spapr.h | 33 ++++++++++++++------ include/hw/ppc/spapr_vio.h | 4 ++- 16 files changed, 167 insertions(+), 148 deletions(-) diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 4e464bd..1d53035 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -74,7 +74,7 @@ static void spapr_vty_realize(VIOsPAPRDevice *sdev, Error **errp) } /* Forward declaration */ -static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -101,7 +101,7 @@ static target_ulong h_put_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_get_term_char(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -214,7 +214,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus) return selected; } -VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg) +VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg) { VIOsPAPRDevice *sdev; diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 0fd2a84..924b1ae 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -806,7 +806,7 @@ void xics_free(XICSState *icp, int irq, int num) * Guest interfaces */ -static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_cppr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -816,7 +816,7 @@ static target_ulong h_cppr(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_ipi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong server = get_cpu_index_by_dt_id(args[0]); @@ -830,7 +830,7 @@ static target_ulong h_ipi(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_xirr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -840,7 +840,7 @@ static target_ulong h_xirr(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -852,7 +852,7 @@ static target_ulong h_xirr_x(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_eoi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -862,7 +862,7 @@ static target_ulong h_eoi(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -874,7 +874,7 @@ static target_ulong h_ipoll(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_set_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -902,7 +902,7 @@ static void rtas_set_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_get_xive(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -927,7 +927,7 @@ static void rtas_get_xive(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 2, ics->irqs[nr - ics->offset].priority); } -static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_int_off(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -953,7 +953,7 @@ static void rtas_int_off(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -static void rtas_int_on(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_int_on(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index c15453f..ea886da 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -368,7 +368,7 @@ static void xics_kvm_set_nr_servers(XICSState *icp, uint32_t nr_servers, } } -static void rtas_dummy(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 2dd5ec1..1ca5e9c 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -284,7 +284,7 @@ static int check_bd(VIOsPAPRVLANDevice *dev, vlan_bd_t bd, } static target_ulong h_register_logical_lan(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -349,7 +349,8 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu, } -static target_ulong h_free_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_free_logical_lan(PowerPCCPU *cpu, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -371,7 +372,7 @@ static target_ulong h_free_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, } static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -421,7 +422,8 @@ static target_ulong h_add_logical_lan_buffer(PowerPCCPU *cpu, return H_SUCCESS; } -static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_send_logical_lan(PowerPCCPU *cpu, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -490,7 +492,7 @@ static target_ulong h_send_logical_lan(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_multicast_ctrl(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c index 11332d1..fcaa77d 100644 --- a/hw/nvram/spapr_nvram.c +++ b/hw/nvram/spapr_nvram.c @@ -45,7 +45,7 @@ typedef struct sPAPRNVRAM { #define DEFAULT_NVRAM_SIZE 65536 #define MAX_NVRAM_SIZE 1048576 -static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -86,7 +86,7 @@ static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 1, len); } -static void rtas_nvram_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_nvram_store(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 10ca866..f820534 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -90,25 +90,6 @@ #define HTAB_SIZE(spapr) (1ULL << ((spapr)->htab_shift)) -typedef struct sPAPRMachineState sPAPRMachineState; - -#define TYPE_SPAPR_MACHINE "spapr-machine" -#define SPAPR_MACHINE(obj) \ - OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE) - -/** - * sPAPRMachineState: - */ -struct sPAPRMachineState { - /*< private >*/ - MachineState parent_obj; - - /*< public >*/ - char *kvm_type; -}; - -sPAPREnvironment *spapr; - static XICSState *try_create_xics(const char *type, int nr_servers, int nr_irqs, Error **errp) { @@ -184,7 +165,7 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu, return ret; } -static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr) +static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) { int ret = 0, offset, cpus_offset; CPUState *cs; @@ -604,7 +585,8 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, return fdt; } -int spapr_h_cas_compose_response(target_ulong addr, target_ulong size) +int spapr_h_cas_compose_response(sPAPRMachineState *spapr, + target_ulong addr, target_ulong size) { void *fdt, *fdt_skel; sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 }; @@ -665,7 +647,7 @@ static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, sizeof(associativity)))); } -static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt) +static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) { hwaddr mem_start, node_size; int i, nb_nodes = nb_numa_nodes; @@ -714,7 +696,7 @@ static int spapr_populate_memory(sPAPREnvironment *spapr, void *fdt) return 0; } -static void spapr_finalize_fdt(sPAPREnvironment *spapr, +static void spapr_finalize_fdt(sPAPRMachineState *spapr, hwaddr fdt_addr, hwaddr rtas_addr, hwaddr rtas_size) @@ -830,7 +812,7 @@ static void emulate_spapr_hypercall(PowerPCCPU *cpu) #define CLEAN_HPTE(_hpte) ((*(uint64_t *)(_hpte)) &= tswap64(~HPTE64_V_HPTE_DIRTY)) #define DIRTY_HPTE(_hpte) ((*(uint64_t *)(_hpte)) |= tswap64(HPTE64_V_HPTE_DIRTY)) -static void spapr_reset_htab(sPAPREnvironment *spapr) +static void spapr_reset_htab(sPAPRMachineState *spapr) { long shift; int index; @@ -892,7 +874,7 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) * A guest reset will cause spapr->htab_fd to become stale if being used. * Reopen the file descriptor to make sure the whole HTAB is properly read. */ -static int spapr_check_htab_fd(sPAPREnvironment *spapr) +static int spapr_check_htab_fd(sPAPRMachineState *spapr) { int rc = 0; @@ -912,6 +894,7 @@ static int spapr_check_htab_fd(sPAPREnvironment *spapr) static void ppc_spapr_reset(void) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); PowerPCCPU *first_ppc_cpu; uint32_t rtas_limit; @@ -951,6 +934,7 @@ static void ppc_spapr_reset(void) static void spapr_cpu_reset(void *opaque) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; @@ -979,12 +963,12 @@ static void spapr_cpu_reset(void *opaque) * We have 8 hpte per group, and each hpte is 16 bytes. * ie have 128 bytes per hpte entry. */ - env->htab_mask = (1ULL << ((spapr)->htab_shift - 7)) - 1; + env->htab_mask = (1ULL << (spapr->htab_shift - 7)) - 1; env->spr[SPR_SDR1] = (target_ulong)(uintptr_t)spapr->htab | (spapr->htab_shift - 18); } -static void spapr_create_nvram(sPAPREnvironment *spapr) +static void spapr_create_nvram(sPAPRMachineState *spapr) { DeviceState *dev = qdev_create(&spapr->vio_bus->bus, "spapr-nvram"); DriveInfo *dinfo = drive_get(IF_PFLASH, 0, 0); @@ -998,7 +982,7 @@ static void spapr_create_nvram(sPAPREnvironment *spapr) spapr->nvram = (struct sPAPRNVRAM *)dev; } -static void spapr_rtc_create(sPAPREnvironment *spapr) +static void spapr_rtc_create(sPAPRMachineState *spapr) { DeviceState *dev = qdev_create(NULL, TYPE_SPAPR_RTC); @@ -1028,7 +1012,7 @@ static int spapr_vga_init(PCIBus *pci_bus) static int spapr_post_load(void *opaque, int version_id) { - sPAPREnvironment *spapr = (sPAPREnvironment *)opaque; + sPAPRMachineState *spapr = (sPAPRMachineState *)opaque; int err = 0; /* In earlier versions, there was no separate qdev for the PAPR @@ -1057,16 +1041,16 @@ static const VMStateDescription vmstate_spapr = { VMSTATE_UNUSED_BUFFER(version_before_3, 0, 4), /* RTC offset */ - VMSTATE_UINT64_TEST(rtc_offset, sPAPREnvironment, version_before_3), + VMSTATE_UINT64_TEST(rtc_offset, sPAPRMachineState, version_before_3), - VMSTATE_PPC_TIMEBASE_V(tb, sPAPREnvironment, 2), + VMSTATE_PPC_TIMEBASE_V(tb, sPAPRMachineState, 2), VMSTATE_END_OF_LIST() }, }; static int htab_save_setup(QEMUFile *f, void *opaque) { - sPAPREnvironment *spapr = opaque; + sPAPRMachineState *spapr = opaque; /* "Iteration" header */ qemu_put_be32(f, spapr->htab_shift); @@ -1090,7 +1074,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque) return 0; } -static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, +static void htab_save_first_pass(QEMUFile *f, sPAPRMachineState *spapr, int64_t max_ns) { int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; @@ -1140,7 +1124,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr, spapr->htab_save_index = index; } -static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, +static int htab_save_later_pass(QEMUFile *f, sPAPRMachineState *spapr, int64_t max_ns) { bool final = max_ns < 0; @@ -1222,7 +1206,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, static int htab_save_iterate(QEMUFile *f, void *opaque) { - sPAPREnvironment *spapr = opaque; + sPAPRMachineState *spapr = opaque; int rc = 0; /* Iteration header */ @@ -1257,7 +1241,7 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) static int htab_save_complete(QEMUFile *f, void *opaque) { - sPAPREnvironment *spapr = opaque; + sPAPRMachineState *spapr = opaque; /* Iteration header */ qemu_put_be32(f, 0); @@ -1292,7 +1276,7 @@ static int htab_save_complete(QEMUFile *f, void *opaque) static int htab_load(QEMUFile *f, void *opaque, int version_id) { - sPAPREnvironment *spapr = opaque; + sPAPRMachineState *spapr = opaque; uint32_t section_hdr; int fd = -1; @@ -1389,6 +1373,7 @@ static void spapr_boot_set(void *opaque, const char *boot_device, /* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(MachineState *machine) { + sPAPRMachineState *spapr = SPAPR_MACHINE(machine); ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; @@ -1412,7 +1397,6 @@ static void ppc_spapr_init(MachineState *machine) msi_supported = true; - spapr = g_malloc0(sizeof(*spapr)); QLIST_INIT(&spapr->phbs); cpu_ppc_hypercall = emulate_spapr_hypercall; @@ -1661,6 +1645,9 @@ static void ppc_spapr_init(MachineState *machine) spapr->entry_point = 0x100; + /* FIXME: Should register things through the MachineState's qdev + * interface, this is a legacy from the sPAPREnvironment structure + * which predated MachineState but had a similar function */ vmstate_register(NULL, 0, &vmstate_spapr, spapr); register_savevm_live(NULL, "spapr/htab", -1, 1, &savevm_htab_handlers, spapr); @@ -1756,17 +1743,17 @@ static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus, static char *spapr_get_kvm_type(Object *obj, Error **errp) { - sPAPRMachineState *sm = SPAPR_MACHINE(obj); + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); - return g_strdup(sm->kvm_type); + return g_strdup(spapr->kvm_type); } static void spapr_set_kvm_type(Object *obj, const char *value, Error **errp) { - sPAPRMachineState *sm = SPAPR_MACHINE(obj); + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); - g_free(sm->kvm_type); - sm->kvm_type = g_strdup(value); + g_free(spapr->kvm_type); + spapr->kvm_type = g_strdup(value); } static void spapr_machine_initfn(Object *obj) diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index fda9e35..f626eb7 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -238,6 +238,7 @@ void spapr_events_fdt_skel(void *fdt, uint32_t check_exception_irq) static void rtas_event_log_queue(int log_type, void *data, bool exception) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPREventLogEntry *entry = g_new(sPAPREventLogEntry, 1); g_assert(data); @@ -250,6 +251,7 @@ static void rtas_event_log_queue(int log_type, void *data, bool exception) static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask, bool exception) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPREventLogEntry *entry = NULL; /* we only queue EPOW events atm. */ @@ -278,6 +280,7 @@ static sPAPREventLogEntry *rtas_event_log_dequeue(uint32_t event_mask, static bool rtas_event_log_contains(uint32_t event_mask, bool exception) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPREventLogEntry *entry = NULL; /* we only queue EPOW events atm. */ @@ -314,6 +317,7 @@ static void spapr_init_v6hdr(struct rtas_event_log_v6 *v6hdr) static void spapr_init_maina(struct rtas_event_log_v6_maina *maina, int section_count) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); struct tm tm; int year; @@ -336,7 +340,7 @@ static void spapr_init_maina(struct rtas_event_log_v6_maina *maina, static void spapr_powerdown_req(Notifier *n, void *opaque) { - sPAPREnvironment *spapr = container_of(n, sPAPREnvironment, epow_notifier); + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); struct rtas_error_log *hdr; struct rtas_event_log_v6 *v6hdr; struct rtas_event_log_v6_maina *maina; @@ -384,6 +388,7 @@ static void spapr_powerdown_req(Notifier *n, void *opaque) static void spapr_hotplug_req_event(sPAPRDRConnector *drc, uint8_t hp_action) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); struct hp_log_full *new_hp; struct rtas_error_log *hdr; struct rtas_event_log_v6 *v6hdr; @@ -453,7 +458,7 @@ void spapr_hotplug_req_remove_event(sPAPRDRConnector *drc) spapr_hotplug_req_event(drc, RTAS_LOG_V6_HP_ACTION_REMOVE); } -static void check_exception(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -508,7 +513,7 @@ out_no_events: rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND); } -static void event_scan(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -548,7 +553,7 @@ out_no_events: rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND); } -void spapr_events_init(sPAPREnvironment *spapr) +void spapr_events_init(sPAPRMachineState *spapr) { QTAILQ_INIT(&spapr->pending_events); spapr->check_exception_irq = xics_alloc(spapr->icp, 0, 0, false); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 4f76f1c..1a20884 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -84,7 +84,7 @@ static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index) return true; } -static target_ulong h_enter(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -205,7 +205,7 @@ static RemoveResult remove_hpte(CPUPPCState *env, target_ulong ptex, return REMOVE_SUCCESS; } -static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -252,7 +252,7 @@ static target_ulong h_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, #define H_BULK_REMOVE_MAX_BATCH 4 -static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -299,7 +299,7 @@ static target_ulong h_bulk_remove(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_protect(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -337,7 +337,7 @@ static target_ulong h_protect(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_read(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -367,7 +367,7 @@ static target_ulong h_read(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { /* FIXME: actually implement this */ @@ -506,7 +506,7 @@ static target_ulong deregister_dtl(CPUPPCState *env, target_ulong addr) return H_SUCCESS; } -static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong flags = args[0]; @@ -551,7 +551,7 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPREnvironment *spapr, return ret; } -static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_cede(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUPPCState *env = &cpu->env; @@ -567,7 +567,7 @@ static target_ulong h_cede(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_rtas(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong rtas_r3 = args[0]; @@ -579,7 +579,7 @@ static target_ulong h_rtas(PowerPCCPU *cpu, sPAPREnvironment *spapr, nret, rtas_r3 + 12 + 4*nargs); } -static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -603,7 +603,7 @@ static target_ulong h_logical_load(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_PARAMETER; } -static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -629,7 +629,7 @@ static target_ulong h_logical_store(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_PARAMETER; } -static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { CPUState *cs = CPU(cpu); @@ -698,14 +698,14 @@ static target_ulong h_logical_memop(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_SUCCESS; } -static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_logical_icbi(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { /* Nothing to do on emulation, KVM will trap this in the kernel */ return H_SUCCESS; } -static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { /* Nothing to do on emulation, KVM will trap this in the kernel */ @@ -788,7 +788,7 @@ static target_ulong h_set_mode_resource_addr_trans_mode(PowerPCCPU *cpu, return H_SUCCESS; } -static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong resource = args[1]; @@ -828,7 +828,7 @@ static void do_set_compat(void *arg) ((cpuver) == CPU_POWERPC_LOGICAL_2_07) ? 2070 : 0) static target_ulong h_client_architecture_support(PowerPCCPU *cpu_, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { @@ -921,7 +921,7 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu_, return H_SUCCESS; } - if (spapr_h_cas_compose_response(args[1], args[2])) { + if (spapr_h_cas_compose_response(spapr, args[1], args[2])) { qemu_system_reset_request(); } @@ -952,6 +952,8 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn) target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode, target_ulong *args) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + if ((opcode <= MAX_HCALL_OPCODE) && ((opcode & 0x3) == 0)) { spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 8cd9dba..d58d9ba 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -240,7 +240,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, } static target_ulong h_put_tce_indirect(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { int i; @@ -287,7 +287,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu, return ret; } -static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { int i; @@ -326,7 +326,7 @@ static target_ulong h_stuff_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr, return ret; } -static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong liobn = args[0]; @@ -367,7 +367,7 @@ static target_ulong get_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, return H_SUCCESS; } -static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_get_tce(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong liobn = args[0]; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index d4a6150..eab4cfb 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -58,7 +58,7 @@ } \ } while (0) -sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid) +sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid) { sPAPRPHBState *sphb; @@ -72,7 +72,7 @@ sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid) return NULL; } -PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid, +PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid, uint32_t config_addr) { sPAPRPHBState *sphb = spapr_pci_find_phb(spapr, buid); @@ -93,7 +93,7 @@ static uint32_t rtas_pci_cfgaddr(uint32_t arg) return ((arg >> 20) & 0xf00) | (arg & 0xff); } -static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid, +static void finish_read_pci_config(sPAPRMachineState *spapr, uint64_t buid, uint32_t addr, uint32_t size, target_ulong rets) { @@ -123,7 +123,7 @@ static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid, rtas_st(rets, 1, val); } -static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -143,7 +143,7 @@ static void rtas_ibm_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, finish_read_pci_config(spapr, buid, addr, size, rets); } -static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -161,7 +161,7 @@ static void rtas_read_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, finish_read_pci_config(spapr, 0, addr, size, rets); } -static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid, +static void finish_write_pci_config(sPAPRMachineState *spapr, uint64_t buid, uint32_t addr, uint32_t size, uint32_t val, target_ulong rets) { @@ -189,7 +189,7 @@ static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid, rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -210,7 +210,7 @@ static void rtas_ibm_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, finish_write_pci_config(spapr, buid, addr, size, val, rets); } -static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_write_pci_config(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -259,7 +259,7 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix, } } -static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -377,7 +377,7 @@ out: } static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, @@ -418,7 +418,7 @@ static void rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu, } static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -456,7 +456,7 @@ param_error_exit: } static void rtas_ibm_get_config_addr_info2(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -512,7 +512,7 @@ param_error_exit: } static void rtas_ibm_read_slot_reset_state2(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -556,7 +556,7 @@ param_error_exit: } static void rtas_ibm_set_slot_reset(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -592,7 +592,7 @@ param_error_exit: } static void rtas_ibm_configure_pe(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -627,7 +627,7 @@ param_error_exit: /* To support it later */ static void rtas_ibm_slot_error_detail(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -718,6 +718,7 @@ static PCIINTxRoute spapr_route_intx_pin_to_irq(void *opaque, int pin) static void spapr_msi_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); uint32_t irq = data; trace_spapr_pci_msi_write(addr, data, irq); @@ -1110,6 +1111,7 @@ static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler, static void spapr_phb_realize(DeviceState *dev, Error **errp) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); @@ -1464,7 +1466,7 @@ static const TypeInfo spapr_phb_info = { } }; -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index) +PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index) { DeviceState *dev; @@ -1631,6 +1633,7 @@ static int spapr_switch_one_vga(DeviceState *dev, void *opaque) void spapr_pci_switch_vga(bool big_endian) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); sPAPRPHBState *sphb; /* diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index fa28d43..3b95dfc 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -47,7 +47,7 @@ do { } while (0) #endif -static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPREnvironment *spapr, +static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPRMachineState *spapr, uint32_t drc_index) { sPAPRConfigureConnectorState *ccs = NULL; @@ -61,14 +61,14 @@ static sPAPRConfigureConnectorState *spapr_ccs_find(sPAPREnvironment *spapr, return ccs; } -static void spapr_ccs_add(sPAPREnvironment *spapr, +static void spapr_ccs_add(sPAPRMachineState *spapr, sPAPRConfigureConnectorState *ccs) { g_assert(!spapr_ccs_find(spapr, ccs->drc_index)); QTAILQ_INSERT_HEAD(&spapr->ccs_list, ccs, next); } -static void spapr_ccs_remove(sPAPREnvironment *spapr, +static void spapr_ccs_remove(sPAPRMachineState *spapr, sPAPRConfigureConnectorState *ccs) { QTAILQ_REMOVE(&spapr->ccs_list, ccs, next); @@ -77,7 +77,7 @@ static void spapr_ccs_remove(sPAPREnvironment *spapr, void spapr_ccs_reset_hook(void *opaque) { - sPAPREnvironment *spapr = opaque; + sPAPRMachineState *spapr = opaque; sPAPRConfigureConnectorState *ccs, *ccs_tmp; QTAILQ_FOREACH_SAFE(ccs, &spapr->ccs_list, next, ccs_tmp) { @@ -85,7 +85,7 @@ void spapr_ccs_reset_hook(void *opaque) } } -static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_display_character(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -101,7 +101,7 @@ static void rtas_display_character(PowerPCCPU *cpu, sPAPREnvironment *spapr, } } -static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_power_off(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { @@ -113,7 +113,7 @@ static void rtas_power_off(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_system_reboot(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -127,7 +127,7 @@ static void rtas_system_reboot(PowerPCCPU *cpu, sPAPREnvironment *spapr, } static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -157,7 +157,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_, rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); } -static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr, +static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -204,7 +204,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr, rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); } -static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -227,7 +227,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, } static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -262,7 +262,7 @@ static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, } static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -282,7 +282,7 @@ static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, } static void rtas_ibm_os_term(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -294,7 +294,7 @@ static void rtas_ibm_os_term(PowerPCCPU *cpu, rtas_st(rets, 0, ret); } -static void rtas_set_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_set_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -319,7 +319,7 @@ static void rtas_set_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 1, 100); } -static void rtas_get_power_level(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_get_power_level(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -356,7 +356,7 @@ static bool sensor_type_is_dr(uint32_t sensor_type) return false; } -static void rtas_set_indicator(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -427,7 +427,7 @@ out_unimplemented: rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); } -static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -481,7 +481,7 @@ static void rtas_get_sensor_state(PowerPCCPU *cpu, sPAPREnvironment *spapr, #define CC_WA_LEN 4096 static void rtas_ibm_configure_connector(PowerPCCPU *cpu, - sPAPREnvironment *spapr, + sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -601,7 +601,7 @@ static struct rtas_call { spapr_rtas_fn fn; } rtas_table[RTAS_TOKEN_MAX - RTAS_TOKEN_BASE]; -target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr, +target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index 83eb7c1..22a1ab5 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -77,7 +77,7 @@ int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset) return 0; } -static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -107,7 +107,7 @@ static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 7, ns); } -static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_set_time_of_day(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 8b59b64..c51eb8e 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -160,7 +160,7 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, /* * CRQ handling */ -static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_reg_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -218,7 +218,7 @@ static target_ulong free_crq(VIOsPAPRDevice *dev) return H_SUCCESS; } -static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -232,7 +232,7 @@ static target_ulong h_free_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, return free_crq(dev); } -static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -255,7 +255,7 @@ static target_ulong h_send_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, return H_HARDWARE; } -static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_enable_crq(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { target_ulong reg = args[0]; @@ -333,7 +333,7 @@ void spapr_vio_set_bypass(VIOsPAPRDevice *dev, bool bypass) dev->tcet->bypass = bypass; } -static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -364,7 +364,7 @@ static void rtas_set_tce_bypass(PowerPCCPU *cpu, sPAPREnvironment *spapr, rtas_st(rets, 0, RTAS_OUT_SUCCESS); } -static void rtas_quiesce(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static void rtas_quiesce(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) @@ -426,6 +426,7 @@ static void spapr_vio_busdev_reset(DeviceState *qdev) static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *id; @@ -491,7 +492,7 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) pc->realize(dev, errp); } -static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPREnvironment *spapr, +static target_ulong h_vio_signal(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index 9dca388..5322b56 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -119,21 +119,23 @@ struct sPAPRPHBVFIOState { static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq); } -PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index); +PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index); int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt); -void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr); +void spapr_pci_msi_init(sPAPRMachineState *spapr, hwaddr addr); void spapr_pci_rtas_init(void); -sPAPRPHBState *spapr_pci_find_phb(sPAPREnvironment *spapr, uint64_t buid); -PCIDevice *spapr_pci_find_dev(sPAPREnvironment *spapr, uint64_t buid, +sPAPRPHBState *spapr_pci_find_phb(sPAPRMachineState *spapr, uint64_t buid); +PCIDevice *spapr_pci_find_dev(sPAPRMachineState *spapr, uint64_t buid, uint32_t config_addr); #endif /* __HW_SPAPR_PCI_H__ */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 7b4b1bb..c3652aa 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -2,6 +2,7 @@ #define __HW_SPAPR_H__ #include "sysemu/dma.h" +#include "hw/boards.h" #include "hw/ppc/xics.h" #include "hw/ppc/spapr_drc.h" @@ -13,7 +14,19 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL -typedef struct sPAPREnvironment { +typedef struct sPAPRMachineState sPAPRMachineState; + +#define TYPE_SPAPR_MACHINE "spapr-machine" +#define SPAPR_MACHINE(obj) \ + OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE) + +/** + * sPAPRMachineState: + */ +struct sPAPRMachineState { + /*< private >*/ + MachineState parent_obj; + struct VIOsPAPRBus *vio_bus; QLIST_HEAD(, sPAPRPHBState) phbs; struct sPAPRNVRAM *nvram; @@ -46,7 +59,10 @@ typedef struct sPAPREnvironment { /* RTAS state */ QTAILQ_HEAD(, sPAPRConfigureConnectorState) ccs_list; -} sPAPREnvironment; + + /*< public >*/ + char *kvm_type; +}; #define H_SUCCESS 0 #define H_BUSY 1 /* Hardware busy -- retry later */ @@ -319,8 +335,6 @@ typedef struct sPAPREnvironment { #define KVMPPC_H_CAS (KVMPPC_HCALL_BASE + 0x2) #define KVMPPC_HCALL_MAX KVMPPC_H_CAS -extern sPAPREnvironment *spapr; - typedef struct sPAPRDeviceTreeUpdateHeader { uint32_t version_id; } sPAPRDeviceTreeUpdateHeader; @@ -335,7 +349,7 @@ typedef struct sPAPRDeviceTreeUpdateHeader { do { } while (0) #endif -typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr, +typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm, target_ulong opcode, target_ulong *args); @@ -490,12 +504,12 @@ static inline void rtas_st_buffer(target_ulong phys, target_ulong phys_len, rtas_st_buffer_direct(phys + 2, phys_len - 2, buffer, buffer_len); } -typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr, +typedef void (*spapr_rtas_fn)(PowerPCCPU *cpu, sPAPRMachineState *sm, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn); -target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr, +target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPRMachineState *sm, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets); int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, @@ -546,9 +560,10 @@ struct sPAPREventLogEntry { QTAILQ_ENTRY(sPAPREventLogEntry) next; }; -void spapr_events_init(sPAPREnvironment *spapr); +void spapr_events_init(sPAPRMachineState *sm); void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); -int spapr_h_cas_compose_response(target_ulong addr, target_ulong size); +int spapr_h_cas_compose_response(sPAPRMachineState *sm, + target_ulong addr, target_ulong size); sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, uint64_t bus_offset, uint32_t page_shift, diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index f95016a..2299a54 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -88,6 +88,8 @@ extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode); static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev) { + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + return xics_get_qirq(spapr->icp, dev->irq); } @@ -126,7 +128,7 @@ static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr, int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq); -VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg); +VIOsPAPRDevice *vty_lookup(sPAPRMachineState *spapr, target_ulong reg); void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len); void spapr_vty_create(VIOsPAPRBus *bus, CharDriverState *chardev); void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 04/22] spapr: Remove obsolete ram_limit field from sPAPRMachineState 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (2 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 03/22] spapr: Merge sPAPREnvironment into sPAPRMachineState David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 05/22] spapr: Remove obsolete entry_point " David Gibson ` (18 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, David Gibson The ram_limit field was imported from sPAPREnvironment where it predates the machine's ram size being available generically from machine->ram_size. Worse, the existing code was inconsistent about where it got the ram size from. Sometimes it used spapr->ram_limit, sometimes the global 'ram_size' and sometimes a local 'ram_size' masking the global. This cleans up the code to consistently use machine->ram_size, eliminating spapr->ram_limit in the process. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 22 ++++++++++++---------- hw/ppc/spapr_hcall.c | 3 ++- include/hw/ppc/spapr.h | 1 - 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index f820534..6adfb68 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -265,15 +265,18 @@ static size_t create_page_sizes_prop(CPUPPCState *env, uint32_t *prop, static hwaddr spapr_node0_size(void) { + MachineState *machine = MACHINE(qdev_get_machine()); + if (nb_numa_nodes) { int i; for (i = 0; i < nb_numa_nodes; ++i) { if (numa_info[i].node_mem) { - return MIN(pow2floor(numa_info[i].node_mem), ram_size); + return MIN(pow2floor(numa_info[i].node_mem), + machine->ram_size); } } } - return ram_size; + return machine->ram_size; } #define _FDT(exp) \ @@ -649,6 +652,7 @@ static void spapr_populate_memory_node(void *fdt, int nodeid, hwaddr start, static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) { + MachineState *machine = MACHINE(spapr); hwaddr mem_start, node_size; int i, nb_nodes = nb_numa_nodes; NodeInfo *nodes = numa_info; @@ -657,7 +661,7 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) /* No NUMA nodes, assume there is just one node with whole RAM */ if (!nb_numa_nodes) { nb_nodes = 1; - ramnode.node_mem = ram_size; + ramnode.node_mem = machine->ram_size; nodes = &ramnode; } @@ -665,12 +669,12 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) if (!nodes[i].node_mem) { continue; } - if (mem_start >= ram_size) { + if (mem_start >= machine->ram_size) { node_size = 0; } else { node_size = nodes[i].node_mem; - if (node_size > ram_size - mem_start) { - node_size = ram_size - mem_start; + if (node_size > machine->ram_size - mem_start) { + node_size = machine->ram_size - mem_start; } } if (!mem_start) { @@ -1374,7 +1378,6 @@ static void spapr_boot_set(void *opaque, const char *boot_device, static void ppc_spapr_init(MachineState *machine) { sPAPRMachineState *spapr = SPAPR_MACHINE(machine); - ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; @@ -1443,7 +1446,7 @@ static void ppc_spapr_init(MachineState *machine) * more than needed for the Linux guests we support. */ spapr->htab_shift = 18; /* Minimum architected size */ while (spapr->htab_shift <= 46) { - if ((1ULL << (spapr->htab_shift + 7)) >= ram_size) { + if ((1ULL << (spapr->htab_shift + 7)) >= machine->ram_size) { break; } spapr->htab_shift++; @@ -1497,9 +1500,8 @@ static void ppc_spapr_init(MachineState *machine) } /* allocate RAM */ - spapr->ram_limit = ram_size; memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram", - spapr->ram_limit); + machine->ram_size); memory_region_add_subregion(sysmem, 0, ram); if (rma_alloc_size && rma) { diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 1a20884..652ddf6 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -87,6 +87,7 @@ static inline bool valid_pte_index(CPUPPCState *env, target_ulong pte_index) static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr, target_ulong opcode, target_ulong *args) { + MachineState *machine = MACHINE(spapr); CPUPPCState *env = &cpu->env; target_ulong flags = args[0]; target_ulong pte_index = args[1]; @@ -118,7 +119,7 @@ static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr, raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << page_shift) - 1); - if (raddr < spapr->ram_limit) { + if (raddr < machine->ram_size) { /* Regular RAM - should have WIMG=0010 */ if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) { return H_PARAMETER; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index c3652aa..9e7cf0f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -33,7 +33,6 @@ struct sPAPRMachineState { XICSState *icp; DeviceState *rtc; - hwaddr ram_limit; void *htab; uint32_t htab_shift; hwaddr rma_size; -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 05/22] spapr: Remove obsolete entry_point field from sPAPRMachineState 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (3 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 04/22] spapr: Remove obsolete ram_limit field from sPAPRMachineState David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 06/22] spapr: Add sPAPRMachineClass David Gibson ` (17 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, David Gibson The sPAPRMachineState structure includes an entry_point field containing the initial PC value for starting the machine, even though this always has the value 0x100. I think this is a hangover from very early versions which bypassed the firmware when using -kernel. In any case it has no function now, so remove it. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 4 +--- include/hw/ppc/spapr.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6adfb68..3aeb2ea 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -932,7 +932,7 @@ static void ppc_spapr_reset(void) first_ppc_cpu->env.gpr[3] = spapr->fdt_addr; first_ppc_cpu->env.gpr[5] = 0; first_cpu->halted = 0; - first_ppc_cpu->env.nip = spapr->entry_point; + first_ppc_cpu->env.nip = SPAPR_ENTRY_POINT; } @@ -1645,8 +1645,6 @@ static void ppc_spapr_init(MachineState *machine) } g_free(filename); - spapr->entry_point = 0x100; - /* FIXME: Should register things through the MachineState's qdev * interface, this is a legacy from the sPAPREnvironment structure * which predated MachineState but had a similar function */ diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9e7cf0f..785b094 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -13,6 +13,7 @@ typedef struct sPAPRConfigureConnectorState sPAPRConfigureConnectorState; typedef struct sPAPREventLogEntry sPAPREventLogEntry; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL +#define SPAPR_ENTRY_POINT 0x100 typedef struct sPAPRMachineState sPAPRMachineState; @@ -41,7 +42,6 @@ struct sPAPRMachineState { ssize_t rtas_size; void *rtas_blob; void *fdt_skel; - target_ulong entry_point; uint64_t rtc_offset; /* Now used only during incoming migration */ struct PPCTimebase tb; bool has_graphics; -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 06/22] spapr: Add sPAPRMachineClass 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (4 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 05/22] spapr: Remove obsolete entry_point " David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 07/22] spapr_pci: encode missing 64-bit memory address space David Gibson ` (16 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber Cc: Michael Roth, Bharata B Rao, qemu-ppc, qemu-devel, David Gibson Currently although we have an sPAPRMachineState descended from MachineState we don't have an sPAPRMAchineClass descended from MachineClass. So far it hasn't been needed, but several upcoming features are going to want it, so this patch creates a stub implementation. Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 1 + include/hw/ppc/spapr.h | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3aeb2ea..0dba32f 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1808,6 +1808,7 @@ static const TypeInfo spapr_machine_info = { .abstract = true, .instance_size = sizeof(sPAPRMachineState), .instance_init = spapr_machine_initfn, + .class_size = sizeof(sPAPRMachineClass), .class_init = spapr_machine_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 785b094..0aeac50 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -15,11 +15,26 @@ typedef struct sPAPREventLogEntry sPAPREventLogEntry; #define HPTE64_V_HPTE_DIRTY 0x0000000000000040ULL #define SPAPR_ENTRY_POINT 0x100 +typedef struct sPAPRMachineClass sPAPRMachineClass; typedef struct sPAPRMachineState sPAPRMachineState; #define TYPE_SPAPR_MACHINE "spapr-machine" #define SPAPR_MACHINE(obj) \ OBJECT_CHECK(sPAPRMachineState, (obj), TYPE_SPAPR_MACHINE) +#define SPAPR_MACHINE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(sPAPRMachineClass, obj, TYPE_SPAPR_MACHINE) +#define SPAPR_MACHINE_CLASS(klass) \ + OBJECT_CLASS_CHECK(sPAPRMachineClass, klass, TYPE_SPAPR_MACHINE) + +/** + * sPAPRMachineClass: + */ +struct sPAPRMachineClass { + /*< private >*/ + MachineClass parent_class; + + /*< public >*/ +}; /** * sPAPRMachineState: -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 07/22] spapr_pci: encode missing 64-bit memory address space 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (5 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 06/22] spapr: Add sPAPRMachineClass David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 08/22] spapr_pci: encode class code including Prog IF register David Gibson ` (15 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, Nikunj A Dadhania, David Gibson From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> The properties reg/assigned-resources need to encode 64-bit memory address space as part of phys.hi dword. 00 if configuration space 01 if IO region, 10 if 32-bit MEM region 11 if 64-bit MEM region Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index eab4cfb..870fe81 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -787,7 +787,13 @@ typedef struct ResourceProps { * phys.hi = 0xYYXXXXZZ, where: * 0xYY = npt000ss * ||| | - * ||| +-- space code: 1 if IO region, 2 if MEM region + * ||| +-- space code + * ||| | + * ||| + 00 if configuration space + * ||| + 01 if IO region, + * ||| + 10 if 32-bit MEM region + * ||| + 11 if 64-bit MEM region + * ||| * ||+------ for non-relocatable IO: 1 if aliased * || for relocatable IO: 1 if below 64KB * || for MEM: 1 if below 1MB @@ -847,6 +853,8 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp) reg->phys_hi = cpu_to_be32(dev_id | b_rrrrrrrr(pci_bar(d, i))); if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) { reg->phys_hi |= cpu_to_be32(b_ss(1)); + } else if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_TYPE_64) { + reg->phys_hi |= cpu_to_be32(b_ss(3)); } else { reg->phys_hi |= cpu_to_be32(b_ss(2)); } -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 08/22] spapr_pci: encode class code including Prog IF register 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (6 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 07/22] spapr_pci: encode missing 64-bit memory address space David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 09/22] spapr_pci: set device node unit address as hex David Gibson ` (14 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, Nikunj A Dadhania, David Gibson From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Current code missed the Prog IF register. All Class Code, Subclass, and Prog IF registers are needed to identify the accurate device type. For example: USB controllers use the PROG IF for denoting: USB FullSpeed, HighSpeed or SuperSpeed. Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 870fe81..7660a20 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -900,8 +900,7 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, _FDT(fdt_setprop_cell(fdt, offset, "revision-id", pci_default_read_config(dev, PCI_REVISION_ID, 1))); _FDT(fdt_setprop_cell(fdt, offset, "class-code", - pci_default_read_config(dev, PCI_CLASS_DEVICE, 2) - << 8)); + pci_default_read_config(dev, PCI_CLASS_PROG, 3))); if (pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1)) { _FDT(fdt_setprop_cell(fdt, offset, "interrupts", pci_default_read_config(dev, PCI_INTERRUPT_PIN, 1))); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 09/22] spapr_pci: set device node unit address as hex 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (7 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 08/22] spapr_pci: encode class code including Prog IF register David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 10/22] spapr_iommu: drop erroneous check in h_put_tce_indirect() David Gibson ` (13 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, Nikunj A Dadhania, David Gibson From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Device node names should encode the unit address as hex, while the code was encodind it as integers. Also, use FDT_NAME_MAX macro for allocating and composing the name. Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Reviewed-by: Thomas Huth <thuth@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 7660a20..51196b5 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -50,6 +50,8 @@ #define RTAS_TYPE_MSI 1 #define RTAS_TYPE_MSIX 2 +#define FDT_NAME_MAX 128 + #define _FDT(exp) \ do { \ int ret = (exp); \ @@ -973,13 +975,13 @@ static void *spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, int offset, ret, fdt_size; int slot = PCI_SLOT(dev->devfn); int func = PCI_FUNC(dev->devfn); - char nodename[512]; + char nodename[FDT_NAME_MAX]; fdt = create_device_tree(&fdt_size); if (func != 0) { - sprintf(nodename, "pci@%d,%d", slot, func); + snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func); } else { - sprintf(nodename, "pci@%d", slot); + snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot); } offset = fdt_add_subnode(fdt, 0, nodename); ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index, @@ -1489,7 +1491,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, void *fdt) { int bus_off, i, j, ret; - char nodename[256]; + char nodename[FDT_NAME_MAX]; uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) }; const uint64_t mmiosize = memory_region_size(&phb->memwindow); const uint64_t w32max = (1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET; @@ -1525,7 +1527,7 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, sPAPRTCETable *tcet; /* Start populating the FDT */ - sprintf(nodename, "pci@%" PRIx64, phb->buid); + snprintf(nodename, FDT_NAME_MAX, "pci@%" PRIx64, phb->buid); bus_off = fdt_add_subnode(fdt, 0, nodename); if (bus_off < 0) { return bus_off; -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 10/22] spapr_iommu: drop erroneous check in h_put_tce_indirect() 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (8 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 09/22] spapr_pci: set device node unit address as hex David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 11/22] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags David Gibson ` (12 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Greg Kurz From: Greg Kurz <gkurz@linux.vnet.ibm.com> The tce_list variable is not a TCE but the address to a TCE: we shouldn't clear permission bits as we do now. And this is dead code anyway since we check tce_list is 4K aligned a few lines above. This patch doesn't fix any bug, it is only code cleanup. Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_iommu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index d58d9ba..3121998 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -267,9 +267,7 @@ static target_ulong h_put_tce_indirect(PowerPCCPU *cpu, ioba &= page_mask; for (i = 0; i < npages; ++i, ioba += page_size) { - target_ulong off = (tce_list & ~SPAPR_TCE_RW) + - i * sizeof(target_ulong); - tce = ldq_be_phys(cs->as, off); + tce = ldq_be_phys(cs->as, tce_list + i * sizeof(target_ulong)); ret = put_tce_emu(tcet, ioba, tce); if (ret) { -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 11/22] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (9 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 10/22] spapr_iommu: drop erroneous check in h_put_tce_indirect() David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 12/22] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" David Gibson ` (11 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Greg Kurz From: Greg Kurz <gkurz@linux.vnet.ibm.com> The fact that these enums have matching values is pure coincidence. We actually need to translate from the PAPR definition to the QEMU one. This patch doesn't fix any bug, it is only code cleanup. Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_iommu.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 3121998..f61504e 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -60,6 +60,20 @@ sPAPRTCETable *spapr_tce_find_by_liobn(target_ulong liobn) return NULL; } +static IOMMUAccessFlags spapr_tce_iommu_access_flags(uint64_t tce) +{ + switch (tce & SPAPR_TCE_RW) { + case SPAPR_TCE_FAULT: + return IOMMU_NONE; + case SPAPR_TCE_RO: + return IOMMU_RO; + case SPAPR_TCE_WO: + return IOMMU_WO; + default: /* SPAPR_TCE_RW */ + return IOMMU_RW; + } +} + /* Called from RCU critical section */ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, bool is_write) @@ -82,7 +96,7 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr, ret.iova = addr & page_mask; ret.translated_addr = tce & page_mask; ret.addr_mask = ~page_mask; - ret.perm = tce & IOMMU_RW; + ret.perm = spapr_tce_iommu_access_flags(tce); } trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm, ret.addr_mask); @@ -233,7 +247,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba, entry.iova = ioba & page_mask; entry.translated_addr = tce & page_mask; entry.addr_mask = ~page_mask; - entry.perm = tce & IOMMU_RW; + entry.perm = spapr_tce_iommu_access_flags(tce); memory_region_notify_iommu(&tcet->iommu, entry); return H_SUCCESS; -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 12/22] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (10 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 11/22] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 13/22] spapr: Consider max_cpus during xics initialization David Gibson ` (10 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Markus Armbruster From: Markus Armbruster <armbru@redhat.com> Since we now require GLib 2.22+ (commit f40685c), we don't have to work around lack of g_hash_table_iter_init() & friends anymore. This reverts commit f8833a37c0c6b22ddd57b45e48cfb0f97dbd5af4. Signed-off-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 51196b5..dc4a683 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1362,34 +1362,28 @@ static const VMStateDescription vmstate_spapr_pci_msi = { }, }; -static void spapr_pci_fill_msi_devs(gpointer key, gpointer value, - gpointer opaque) -{ - sPAPRPHBState *sphb = opaque; - - sphb->msi_devs[sphb->msi_devs_num].key = *(uint32_t *)key; - sphb->msi_devs[sphb->msi_devs_num].value = *(spapr_pci_msi *)value; - sphb->msi_devs_num++; -} - static void spapr_pci_pre_save(void *opaque) { sPAPRPHBState *sphb = opaque; - int msi_devs_num; + GHashTableIter iter; + gpointer key, value; + int i; if (sphb->msi_devs) { g_free(sphb->msi_devs); sphb->msi_devs = NULL; } - sphb->msi_devs_num = 0; - msi_devs_num = g_hash_table_size(sphb->msi); - if (!msi_devs_num) { + sphb->msi_devs_num = g_hash_table_size(sphb->msi); + if (!sphb->msi_devs_num) { return; } - sphb->msi_devs = g_malloc(msi_devs_num * sizeof(spapr_pci_msi_mig)); + sphb->msi_devs = g_malloc(sphb->msi_devs_num * sizeof(spapr_pci_msi_mig)); - g_hash_table_foreach(sphb->msi, spapr_pci_fill_msi_devs, sphb); - assert(sphb->msi_devs_num == msi_devs_num); + g_hash_table_iter_init(&iter, sphb->msi); + for (i = 0; g_hash_table_iter_next(&iter, &key, &value); ++i) { + sphb->msi_devs[i].key = *(uint32_t *) key; + sphb->msi_devs[i].value = *(spapr_pci_msi *) value; + } } static int spapr_pci_post_load(void *opaque, int version_id) -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 13/22] spapr: Consider max_cpus during xics initialization 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (11 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 12/22] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 14/22] spapr: Support ibm, lrdr-capacity device tree property David Gibson ` (9 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Use max_cpus instead of smp_cpus when intializating xics system. Also report max_cpus in ibm,interrupt-server-ranges device tree property of interrupt controller node. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0dba32f..61d04c6 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -308,7 +308,7 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, GString *hypertas = g_string_sized_new(256); GString *qemu_hypertas = g_string_sized_new(256); uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)}; - uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)}; + uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)}; int smt = kvmppc_smt_threads(); unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL); @@ -1454,7 +1454,7 @@ static void ppc_spapr_init(MachineState *machine) /* Set up Interrupt Controller before we create the VCPUs */ spapr->icp = xics_system_init(machine, - DIV_ROUND_UP(smp_cpus * kvmppc_smt_threads(), + DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(), smp_threads), XICS_IRQS); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 14/22] spapr: Support ibm, lrdr-capacity device tree property 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (12 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 13/22] spapr: Consider max_cpus during xics initialization David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 15/22] cpus: Add a macro to walk CPUs in reverse David Gibson ` (8 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Add support for ibm,lrdr-capacity since this is needed by the guest kernel to know about the possible hot-pluggable CPUs and Memory. With this, pseries kernels will start reporting correct maxcpus in /sys/devices/system/cpu/possible. Also define the minimum hotpluggable memory size as 256MB. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- docs/specs/ppc-spapr-hotplug.txt | 18 ++++++++++++++++++ hw/ppc/spapr_rtas.c | 16 ++++++++++++++++ include/hw/ppc/spapr.h | 2 ++ 3 files changed, 36 insertions(+) diff --git a/docs/specs/ppc-spapr-hotplug.txt b/docs/specs/ppc-spapr-hotplug.txt index d35771c..46e0719 100644 --- a/docs/specs/ppc-spapr-hotplug.txt +++ b/docs/specs/ppc-spapr-hotplug.txt @@ -284,4 +284,22 @@ struct rtas_event_log_v6_hp { } drc; } QEMU_PACKED; +== ibm,lrdr-capacity == + +ibm,lrdr-capacity is a property in the /rtas device tree node that identifies +the dynamic reconfiguration capabilities of the guest. It consists of a triple +consisting of <phys>, <size> and <maxcpus>. + + <phys>, encoded in BE format represents the maximum address in bytes and + hence the maximum memory that can be allocated to the guest. + + <size>, encoded in BE format represents the size increments in which + memory can be hot-plugged to the guest. + + <maxcpus>, a BE-encoded integer, represents the maximum number of + processors that the guest can have. + +pseries guests use this property to note the maximum allowed CPUs for the +guest. + [1] http://thread.gmane.org/gmane.linux.ports.ppc.embedded/75350/focus=106867 diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 3b95dfc..592e504 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -29,6 +29,7 @@ #include "sysemu/char.h" #include "hw/qdev.h" #include "sysemu/device_tree.h" +#include "sysemu/cpus.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" @@ -651,6 +652,8 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, { int ret; int i; + uint32_t lrdr_capacity[5]; + MachineState *machine = MACHINE(qdev_get_machine()); ret = fdt_add_mem_rsv(fdt, rtas_addr, rtas_size); if (ret < 0) { @@ -699,6 +702,19 @@ int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr, } } + + lrdr_capacity[0] = cpu_to_be32(machine->maxram_size >> 32); + lrdr_capacity[1] = cpu_to_be32(machine->maxram_size & 0xffffffff); + lrdr_capacity[2] = 0; + lrdr_capacity[3] = cpu_to_be32(SPAPR_MEMORY_BLOCK_SIZE); + lrdr_capacity[4] = cpu_to_be32(max_cpus/smp_threads); + ret = qemu_fdt_setprop(fdt, "/rtas", "ibm,lrdr-capacity", lrdr_capacity, + sizeof(lrdr_capacity)); + if (ret < 0) { + fprintf(stderr, "Couldn't add ibm,lrdr-capacity rtas property\n"); + return ret; + } + return 0; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 0aeac50..91a61ab 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -607,4 +607,6 @@ void spapr_ccs_reset_hook(void *opaque); void spapr_rtc_read(DeviceState *dev, struct tm *tm, uint32_t *ns); int spapr_rtc_import_offset(DeviceState *dev, int64_t legacy_offset); +#define SPAPR_MEMORY_BLOCK_SIZE (1 << 28) /* 256MB */ + #endif /* !defined (__HW_SPAPR_H__) */ -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 15/22] cpus: Add a macro to walk CPUs in reverse 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (13 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 14/22] spapr: Support ibm, lrdr-capacity device tree property David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 16/22] spapr: Reorganize CPU dt generation code David Gibson ` (7 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Add CPU_FOREACH_REVERSE that walks CPUs in reverse. Needed for PowerPC CPU device tree reorganization. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Reviewed-by: Andreas Färber <afaerber@suse.de> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- include/qom/cpu.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/qom/cpu.h b/include/qom/cpu.h index 39f0f19..42f42f5 100644 --- a/include/qom/cpu.h +++ b/include/qom/cpu.h @@ -323,6 +323,8 @@ extern struct CPUTailQ cpus; #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node) #define CPU_FOREACH_SAFE(cpu, next_cpu) \ QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu) +#define CPU_FOREACH_REVERSE(cpu) \ + QTAILQ_FOREACH_REVERSE(cpu, &cpus, CPUTailQ, node) #define first_cpu QTAILQ_FIRST(&cpus) DECLARE_TLS(CPUState *, current_cpu); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 16/22] spapr: Reorganize CPU dt generation code 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (14 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 15/22] cpus: Add a macro to walk CPUs in reverse David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 17/22] spapr: Consolidate cpu init code into a routine David Gibson ` (6 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Reorganize CPU device tree generation code so that it be reused from hotplug path. CPU dt entries are now generated from spapr_finalize_fdt() instead of spapr_create_fdt_skel(). Note: This is how the split-up looks like now: Boot path --------- spapr_finalize_fdt spapr_populate_cpus_dt_node spapr_populate_cpu_dt spapr_fixup_cpu_numa_dt spapr_fixup_cpu_smt_dt ibm,cas path ------------ spapr_h_cas_compose_response spapr_fixup_cpu_dt spapr_fixup_cpu_numa_dt spapr_fixup_cpu_smt_dt Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 284 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 159 insertions(+), 125 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 61d04c6..bcf7ffa 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -165,6 +165,27 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu, return ret; } +static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, CPUState *cs) +{ + int ret = 0; + PowerPCCPU *cpu = POWERPC_CPU(cs); + int index = ppc_get_vcpu_dt_id(cpu); + uint32_t associativity[] = {cpu_to_be32(0x5), + cpu_to_be32(0x0), + cpu_to_be32(0x0), + cpu_to_be32(0x0), + cpu_to_be32(cs->numa_node), + cpu_to_be32(index)}; + + /* Advertise NUMA via ibm,associativity */ + if (nb_numa_nodes > 1) { + ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity, + sizeof(associativity)); + } + + return ret; +} + static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) { int ret = 0, offset, cpus_offset; @@ -177,12 +198,6 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) PowerPCCPU *cpu = POWERPC_CPU(cs); DeviceClass *dc = DEVICE_GET_CLASS(cs); int index = ppc_get_vcpu_dt_id(cpu); - uint32_t associativity[] = {cpu_to_be32(0x5), - cpu_to_be32(0x0), - cpu_to_be32(0x0), - cpu_to_be32(0x0), - cpu_to_be32(cs->numa_node), - cpu_to_be32(index)}; if ((index % smt) != 0) { continue; @@ -206,20 +221,17 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr) } } - if (nb_numa_nodes > 1) { - ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity, - sizeof(associativity)); - if (ret < 0) { - return ret; - } - } - ret = fdt_setprop(fdt, offset, "ibm,pft-size", pft_size_prop, sizeof(pft_size_prop)); if (ret < 0) { return ret; } + ret = spapr_fixup_cpu_numa_dt(fdt, offset, cs); + if (ret < 0) { + return ret; + } + ret = spapr_fixup_cpu_smt_dt(fdt, offset, cpu, ppc_get_compat_smt_threads(cpu)); if (ret < 0) { @@ -302,18 +314,13 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, uint32_t epow_irq) { void *fdt; - CPUState *cs; uint32_t start_prop = cpu_to_be32(initrd_base); uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size); GString *hypertas = g_string_sized_new(256); GString *qemu_hypertas = g_string_sized_new(256); uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)}; uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(max_cpus)}; - int smt = kvmppc_smt_threads(); unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80}; - QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL); - unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0; - uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; char *buf; add_str(hypertas, "hcall-pft"); @@ -399,107 +406,6 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base, _FDT((fdt_end_node(fdt))); - /* cpus */ - _FDT((fdt_begin_node(fdt, "cpus"))); - - _FDT((fdt_property_cell(fdt, "#address-cells", 0x1))); - _FDT((fdt_property_cell(fdt, "#size-cells", 0x0))); - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - DeviceClass *dc = DEVICE_GET_CLASS(cs); - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); - int index = ppc_get_vcpu_dt_id(cpu); - char *nodename; - uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), - 0xffffffff, 0xffffffff}; - uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; - uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; - uint32_t page_sizes_prop[64]; - size_t page_sizes_prop_size; - - if ((index % smt) != 0) { - continue; - } - - nodename = g_strdup_printf("%s@%x", dc->fw_name, index); - - _FDT((fdt_begin_node(fdt, nodename))); - - g_free(nodename); - - _FDT((fdt_property_cell(fdt, "reg", index))); - _FDT((fdt_property_string(fdt, "device_type", "cpu"))); - - _FDT((fdt_property_cell(fdt, "cpu-version", env->spr[SPR_PVR]))); - _FDT((fdt_property_cell(fdt, "d-cache-block-size", - env->dcache_line_size))); - _FDT((fdt_property_cell(fdt, "d-cache-line-size", - env->dcache_line_size))); - _FDT((fdt_property_cell(fdt, "i-cache-block-size", - env->icache_line_size))); - _FDT((fdt_property_cell(fdt, "i-cache-line-size", - env->icache_line_size))); - - if (pcc->l1_dcache_size) { - _FDT((fdt_property_cell(fdt, "d-cache-size", pcc->l1_dcache_size))); - } else { - fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n"); - } - if (pcc->l1_icache_size) { - _FDT((fdt_property_cell(fdt, "i-cache-size", pcc->l1_icache_size))); - } else { - fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n"); - } - - _FDT((fdt_property_cell(fdt, "timebase-frequency", tbfreq))); - _FDT((fdt_property_cell(fdt, "clock-frequency", cpufreq))); - _FDT((fdt_property_cell(fdt, "ibm,slb-size", env->slb_nr))); - _FDT((fdt_property_string(fdt, "status", "okay"))); - _FDT((fdt_property(fdt, "64-bit", NULL, 0))); - - if (env->spr_cb[SPR_PURR].oea_read) { - _FDT((fdt_property(fdt, "ibm,purr", NULL, 0))); - } - - if (env->mmu_model & POWERPC_MMU_1TSEG) { - _FDT((fdt_property(fdt, "ibm,processor-segment-sizes", - segs, sizeof(segs)))); - } - - /* Advertise VMX/VSX (vector extensions) if available - * 0 / no property == no vector extensions - * 1 == VMX / Altivec available - * 2 == VSX available */ - if (env->insns_flags & PPC_ALTIVEC) { - uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1; - - _FDT((fdt_property_cell(fdt, "ibm,vmx", vmx))); - } - - /* Advertise DFP (Decimal Floating Point) if available - * 0 / no property == no DFP - * 1 == DFP available */ - if (env->insns_flags2 & PPC2_DFP) { - _FDT((fdt_property_cell(fdt, "ibm,dfp", 1))); - } - - page_sizes_prop_size = create_page_sizes_prop(env, page_sizes_prop, - sizeof(page_sizes_prop)); - if (page_sizes_prop_size) { - _FDT((fdt_property(fdt, "ibm,segment-page-sizes", - page_sizes_prop, page_sizes_prop_size))); - } - - _FDT((fdt_property_cell(fdt, "ibm,chip-id", - cs->cpu_index / cpus_per_socket))); - - _FDT((fdt_end_node(fdt))); - } - - _FDT((fdt_end_node(fdt))); - /* RTAS */ _FDT((fdt_begin_node(fdt, "rtas"))); @@ -700,6 +606,137 @@ static int spapr_populate_memory(sPAPRMachineState *spapr, void *fdt) return 0; } +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset, + sPAPRMachineState *spapr) +{ + PowerPCCPU *cpu = POWERPC_CPU(cs); + CPUPPCState *env = &cpu->env; + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); + int index = ppc_get_vcpu_dt_id(cpu); + uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), + 0xffffffff, 0xffffffff}; + uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ; + uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000; + uint32_t page_sizes_prop[64]; + size_t page_sizes_prop_size; + QemuOpts *opts = qemu_opts_find(qemu_find_opts("smp-opts"), NULL); + unsigned sockets = opts ? qemu_opt_get_number(opts, "sockets", 0) : 0; + uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1; + uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)}; + + _FDT((fdt_setprop_cell(fdt, offset, "reg", index))); + _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu"))); + + _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR]))); + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size", + env->dcache_line_size))); + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size", + env->dcache_line_size))); + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size", + env->icache_line_size))); + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size", + env->icache_line_size))); + + if (pcc->l1_dcache_size) { + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size", + pcc->l1_dcache_size))); + } else { + fprintf(stderr, "Warning: Unknown L1 dcache size for cpu\n"); + } + if (pcc->l1_icache_size) { + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size", + pcc->l1_icache_size))); + } else { + fprintf(stderr, "Warning: Unknown L1 icache size for cpu\n"); + } + + _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_string(fdt, offset, "status", "okay"))); + _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); + + if (env->spr_cb[SPR_PURR].oea_read) { + _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); + } + + if (env->mmu_model & POWERPC_MMU_1TSEG) { + _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", + segs, sizeof(segs)))); + } + + /* Advertise VMX/VSX (vector extensions) if available + * 0 / no property == no vector extensions + * 1 == VMX / Altivec available + * 2 == VSX available */ + if (env->insns_flags & PPC_ALTIVEC) { + uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1; + + _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx))); + } + + /* Advertise DFP (Decimal Floating Point) if available + * 0 / no property == no DFP + * 1 == DFP available */ + if (env->insns_flags2 & PPC2_DFP) { + _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1))); + } + + page_sizes_prop_size = create_page_sizes_prop(env, 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))); + } + + _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", + cs->cpu_index / cpus_per_socket))); + + _FDT((fdt_setprop(fdt, offset, "ibm,pft-size", + pft_size_prop, sizeof(pft_size_prop)))); + + _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cs)); + + _FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu, + ppc_get_compat_smt_threads(cpu))); +} + +static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) +{ + CPUState *cs; + int cpus_offset; + char *nodename; + int smt = kvmppc_smt_threads(); + + cpus_offset = fdt_add_subnode(fdt, 0, "cpus"); + _FDT(cpus_offset); + _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0x1))); + _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0))); + + /* + * We walk the CPUs in reverse order to ensure that CPU DT nodes + * created by fdt_add_subnode() end up in the right order in FDT + * for the guest kernel the enumerate the CPUs correctly. + */ + CPU_FOREACH_REVERSE(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + int index = ppc_get_vcpu_dt_id(cpu); + DeviceClass *dc = DEVICE_GET_CLASS(cs); + int offset; + + if ((index % smt) != 0) { + continue; + } + + nodename = g_strdup_printf("%s@%x", dc->fw_name, index); + offset = fdt_add_subnode(fdt, cpus_offset, nodename); + g_free(nodename); + _FDT(offset); + spapr_populate_cpu_dt(cs, fdt, offset, spapr); + } + +} + static void spapr_finalize_fdt(sPAPRMachineState *spapr, hwaddr fdt_addr, hwaddr rtas_addr, @@ -745,11 +782,8 @@ static void spapr_finalize_fdt(sPAPRMachineState *spapr, fprintf(stderr, "Couldn't set up RTAS device tree properties\n"); } - /* Advertise NUMA via ibm,associativity */ - ret = spapr_fixup_cpu_dt(fdt, spapr); - if (ret < 0) { - fprintf(stderr, "Couldn't finalize CPU device tree properties\n"); - } + /* cpus */ + spapr_populate_cpus_dt_node(fdt, spapr); bootlist = get_boot_devices_list(&cb, true); if (cb && bootlist) { -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 17/22] spapr: Consolidate cpu init code into a routine 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (15 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 16/22] spapr: Reorganize CPU dt generation code David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 18/22] ppc: Update cpu_model in MachineState David Gibson ` (5 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Factor out bits of sPAPR specific CPU initialization code into a separate routine so that it can be called from CPU hotplug path too. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr.c | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index bcf7ffa..fd371c1 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1408,6 +1408,34 @@ static void spapr_boot_set(void *opaque, const char *boot_device, machine->boot_order = g_strdup(boot_device); } +static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu) +{ + CPUPPCState *env = &cpu->env; + + /* Set time-base frequency to 512 MHz */ + cpu_ppc_tb_init(env, TIMEBASE_FREQ); + + /* PAPR always has exception vectors in RAM not ROM. To ensure this, + * MSR[IP] should never be set. + */ + env->msr_mask &= ~(1 << 6); + + /* Tell KVM that we're in PAPR mode */ + if (kvm_enabled()) { + kvmppc_set_papr(cpu); + } + + if (cpu->max_compat) { + if (ppc_set_compat(cpu, cpu->max_compat) < 0) { + exit(1); + } + } + + xics_cpu_setup(spapr->icp, cpu); + + qemu_register_reset(spapr_cpu_reset, cpu); +} + /* pSeries LPAR / sPAPR hardware init */ static void ppc_spapr_init(MachineState *machine) { @@ -1417,7 +1445,6 @@ static void ppc_spapr_init(MachineState *machine) const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; PowerPCCPU *cpu; - CPUPPCState *env; PCIHostState *phb; int i; MemoryRegion *sysmem = get_system_memory(); @@ -1502,30 +1529,7 @@ static void ppc_spapr_init(MachineState *machine) fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } - env = &cpu->env; - - /* Set time-base frequency to 512 MHz */ - cpu_ppc_tb_init(env, TIMEBASE_FREQ); - - /* PAPR always has exception vectors in RAM not ROM. To ensure this, - * MSR[IP] should never be set. - */ - env->msr_mask &= ~(1 << 6); - - /* Tell KVM that we're in PAPR mode */ - if (kvm_enabled()) { - kvmppc_set_papr(cpu); - } - - if (cpu->max_compat) { - if (ppc_set_compat(cpu, cpu->max_compat) < 0) { - exit(1); - } - } - - xics_cpu_setup(spapr->icp, cpu); - - qemu_register_reset(spapr_cpu_reset, cpu); + spapr_cpu_init(spapr, cpu); } if (kvm_enabled()) { -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 18/22] ppc: Update cpu_model in MachineState 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (16 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 17/22] spapr: Consolidate cpu init code into a routine David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 19/22] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled David Gibson ` (4 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> Keep cpu_model field in MachineState uptodate so that it can be used from the CPU hotplug path. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/mac_newworld.c | 10 +++++----- hw/ppc/mac_oldworld.c | 7 +++---- hw/ppc/ppc440_bamboo.c | 7 +++---- hw/ppc/prep.c | 7 +++---- hw/ppc/spapr.c | 7 +++---- hw/ppc/virtex_ml507.c | 7 +++---- 6 files changed, 20 insertions(+), 25 deletions(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 0f3e341..77d5c81 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -145,7 +145,6 @@ static void ppc_core99_reset(void *opaque) static void ppc_core99_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -182,14 +181,15 @@ static void ppc_core99_init(MachineState *machine) linux_boot = (kernel_filename != NULL); /* init CPUs */ - if (cpu_model == NULL) + if (machine->cpu_model == NULL) { #ifdef TARGET_PPC64 - cpu_model = "970fx"; + machine->cpu_model = "970fx"; #else - cpu_model = "G4"; + machine->cpu_model = "G4"; #endif + } for (i = 0; i < smp_cpus; i++) { - cpu = cpu_ppc_init(cpu_model); + cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 99879dd..06fdbaf 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -75,7 +75,6 @@ static void ppc_heathrow_reset(void *opaque) static void ppc_heathrow_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -107,10 +106,10 @@ static void ppc_heathrow_init(MachineState *machine) linux_boot = (kernel_filename != NULL); /* init CPUs */ - if (cpu_model == NULL) - cpu_model = "G3"; + if (machine->cpu_model == NULL) + machine->cpu_model = "G3"; for (i = 0; i < smp_cpus; i++) { - cpu = cpu_ppc_init(cpu_model); + cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 778970a..032fa80 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -159,7 +159,6 @@ static void main_cpu_reset(void *opaque) static void bamboo_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -184,10 +183,10 @@ static void bamboo_init(MachineState *machine) int i; /* Setup CPU. */ - if (cpu_model == NULL) { - cpu_model = "440EP"; + if (machine->cpu_model == NULL) { + machine->cpu_model = "440EP"; } - cpu = cpu_ppc_init(cpu_model); + cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to initialize CPU!\n"); exit(1); diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 998ee2d..45b5f62 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -506,7 +506,6 @@ static int PPC_NVRAM_set_params (Nvram *nvram, uint16_t NVRAM_size, static void ppc_prep_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -536,10 +535,10 @@ static void ppc_prep_init(MachineState *machine) linux_boot = (kernel_filename != NULL); /* init CPUs */ - if (cpu_model == NULL) - cpu_model = "602"; + if (machine->cpu_model == NULL) + machine->cpu_model = "602"; for (i = 0; i < smp_cpus; i++) { - cpu = cpu_ppc_init(cpu_model); + cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fd371c1..5ca817c 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1440,7 +1440,6 @@ static void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu) static void ppc_spapr_init(MachineState *machine) { sPAPRMachineState *spapr = SPAPR_MACHINE(machine); - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; @@ -1520,11 +1519,11 @@ static void ppc_spapr_init(MachineState *machine) XICS_IRQS); /* init CPUs */ - if (cpu_model == NULL) { - cpu_model = kvm_enabled() ? "host" : "POWER7"; + if (machine->cpu_model == NULL) { + machine->cpu_model = kvm_enabled() ? "host" : "POWER7"; } for (i = 0; i < smp_cpus; i++) { - cpu = cpu_ppc_init(cpu_model); + cpu = cpu_ppc_init(machine->cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 439732f..de86f7c 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -197,7 +197,6 @@ static int xilinx_load_device_tree(hwaddr addr, static void virtex_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; - const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; hwaddr initrd_base = 0; @@ -214,11 +213,11 @@ static void virtex_init(MachineState *machine) int i; /* init CPUs */ - if (cpu_model == NULL) { - cpu_model = "440-Xilinx"; + if (machine->cpu_model == NULL) { + machine->cpu_model = "440-Xilinx"; } - cpu = ppc440_init_xilinx(&ram_size, 1, cpu_model, 400000000); + cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_model, 400000000); env = &cpu->env; qemu_register_reset(main_cpu_reset, cpu); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 19/22] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (17 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 18/22] ppc: Update cpu_model in MachineState David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 20/22] spapr_pci: enumerate and add PCI device tree David Gibson ` (3 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: David Gibson, qemu-ppc, qemu-devel, Bharata B Rao From: Bharata B Rao <bharata@linux.vnet.ibm.com> When supporting CPU hot removal by parking the vCPU fd and reusing it during hotplug again, there can be cases where we try to reenable KVM_CAP_IRQ_XICS CAP for the vCPU for which it was already enabled. Introduce a boolean member in ICPState to track this and don't reenable the CAP if it was already enabled earlier. Re-enabling this CAP should ideally work, but currently it results in kernel trying to create and associate ICP with this vCPU and that fails since there is already an ICP associated with it. Hence this patch is needed to work around this problem in the kernel. This change allows CPU hot removal to work for sPAPR. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/intc/xics_kvm.c | 10 ++++++++++ include/hw/ppc/xics.h | 1 + 2 files changed, 11 insertions(+) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index ea886da..d58729c 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -331,6 +331,15 @@ static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu) abort(); } + /* + * If we are reusing a parked vCPU fd corresponding to the CPU + * which was hot-removed earlier we don't have to renable + * KVM_CAP_IRQ_XICS capability again. + */ + if (ss->cap_irq_xics_enabled) { + return; + } + if (icpkvm->kernel_xics_fd != -1) { int ret; @@ -343,6 +352,7 @@ static void xics_kvm_cpu_setup(XICSState *icp, PowerPCCPU *cpu) kvm_arch_vcpu_id(cs), strerror(errno)); exit(1); } + ss->cap_irq_xics_enabled = true; } } diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index a214dd7..355a966 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -109,6 +109,7 @@ struct ICPState { uint8_t pending_priority; uint8_t mfrr; qemu_irq output; + bool cap_irq_xics_enabled; }; #define TYPE_ICS "ics" -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 20/22] spapr_pci: enumerate and add PCI device tree 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (18 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 19/22] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 21/22] spapr_pci: populate ibm,loc-code David Gibson ` (2 subsequent siblings) 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber Cc: David Gibson, qemu-ppc, qemu-devel, Nikunj A Dadhania, Michael Roth From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> All the PCI enumeration and device node creation was off-loaded to SLOF. With PCI hotplug support, code needed to be added to add device node. This creates multiple copy of the code one in SLOF and other in hotplug code. To unify this, the patch adds the pci device node creation in Qemu. For backward compatibility, a flag "qemu,phb-enumerated" is added to the phb, suggesting to SLOF to not do device node creation. Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> [ Squashed Michael's drc_index changes ] Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 133 insertions(+), 17 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index dc4a683..7c3621c 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ #include "hw/hw.h" +#include "hw/sysbus.h" #include "hw/pci/pci.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" @@ -35,6 +36,7 @@ #include "qemu/error-report.h" #include "qapi/qmp/qerror.h" +#include "hw/pci/pci_bridge.h" #include "hw/pci/pci_bus.h" #include "hw/ppc/spapr_drc.h" #include "sysemu/device_tree.h" @@ -966,30 +968,32 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, return 0; } +static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb, + PCIDevice *pdev); + /* create OF node for pci device and required OF DT properties */ -static void *spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, - int drc_index, const char *drc_name, - int *dt_offset) +static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, + int drc_index, const char *drc_name, + void *fdt, int node_offset) { - void *fdt; - int offset, ret, fdt_size; + int offset, ret; int slot = PCI_SLOT(dev->devfn); int func = PCI_FUNC(dev->devfn); char nodename[FDT_NAME_MAX]; - fdt = create_device_tree(&fdt_size); if (func != 0) { snprintf(nodename, FDT_NAME_MAX, "pci@%x,%x", slot, func); } else { snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot); } - offset = fdt_add_subnode(fdt, 0, nodename); + offset = fdt_add_subnode(fdt, node_offset, nodename); ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index, drc_name); g_assert(!ret); - - *dt_offset = offset; - return fdt; + if (ret) { + return 0; + } + return offset; } static void spapr_phb_add_pci_device(sPAPRDRConnector *drc, @@ -1002,19 +1006,22 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc, int drc_index = drck->get_index(drc); const char *drc_name = drck->get_name(drc); void *fdt = NULL; - int fdt_start_offset = 0; + int fdt_start_offset = 0, fdt_size; - /* boot-time devices get their device tree node created by SLOF, but for - * hotplugged devices we need QEMU to generate it so the guest can fetch - * it via RTAS - */ if (dev->hotplugged) { - fdt = spapr_create_pci_child_dt(phb, pdev, drc_index, drc_name, - &fdt_start_offset); + fdt = create_device_tree(&fdt_size); + fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, + drc_index, drc_name, + fdt, 0); + if (!fdt_start_offset) { + error_setg(errp, "Failed to create pci child device tree node"); + goto out; + } } drck->attach(drc, DEVICE(pdev), fdt, fdt_start_offset, !dev->hotplugged, errp); +out: if (*errp) { g_free(fdt); } @@ -1056,6 +1063,20 @@ static sPAPRDRConnector *spapr_phb_get_pci_drc(sPAPRPHBState *phb, pdev->devfn); } +static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb, + PCIDevice *pdev) +{ + sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev); + sPAPRDRConnectorClass *drck; + + if (!drc) { + return 0; + } + + drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); + return drck->get_index(drc); +} + static void spapr_phb_hot_plug_child(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { @@ -1480,6 +1501,87 @@ PCIHostState *spapr_create_phb(sPAPRMachineState *spapr, int index) return PCI_HOST_BRIDGE(dev); } +typedef struct sPAPRFDT { + void *fdt; + int node_off; + sPAPRPHBState *sphb; +} sPAPRFDT; + +static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev, + void *opaque) +{ + PCIBus *sec_bus; + sPAPRFDT *p = opaque; + int offset; + sPAPRFDT s_fdt; + uint32_t drc_index = spapr_phb_get_pci_drc_index(p->sphb, pdev); + + offset = spapr_create_pci_child_dt(p->sphb, pdev, + drc_index, NULL, + p->fdt, p->node_off); + if (!offset) { + error_report("Failed to create pci child device tree node"); + return; + } + + if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) != + PCI_HEADER_TYPE_BRIDGE)) { + return; + } + + sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev)); + if (!sec_bus) { + return; + } + + s_fdt.fdt = p->fdt; + s_fdt.node_off = offset; + s_fdt.sphb = p->sphb; + pci_for_each_device(sec_bus, pci_bus_num(sec_bus), + spapr_populate_pci_devices_dt, + &s_fdt); +} + +static void spapr_phb_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev, + void *opaque) +{ + unsigned int *bus_no = opaque; + unsigned int primary = *bus_no; + unsigned int subordinate = 0xff; + PCIBus *sec_bus = NULL; + + if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) != + PCI_HEADER_TYPE_BRIDGE)) { + return; + } + + (*bus_no)++; + pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1); + pci_default_write_config(pdev, PCI_SECONDARY_BUS, *bus_no, 1); + pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1); + + sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev)); + if (!sec_bus) { + return; + } + + pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1); + pci_for_each_device(sec_bus, pci_bus_num(sec_bus), + spapr_phb_pci_enumerate_bridge, bus_no); + pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, *bus_no, 1); +} + +static void spapr_phb_pci_enumerate(sPAPRPHBState *phb) +{ + PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus; + unsigned int bus_no = 0; + + pci_for_each_device(bus, pci_bus_num(bus), + spapr_phb_pci_enumerate_bridge, + &bus_no); + +} + int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt) @@ -1519,6 +1621,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, cpu_to_be32(b_ddddd(-1)|b_fff(0)), 0x0, 0x0, cpu_to_be32(-1)}; uint32_t interrupt_map[PCI_SLOT_MAX * PCI_NUM_PINS][7]; sPAPRTCETable *tcet; + PCIBus *bus = PCI_HOST_BRIDGE(phb)->bus; + sPAPRFDT s_fdt; /* Start populating the FDT */ snprintf(nodename, FDT_NAME_MAX, "pci@%" PRIx64, phb->buid); @@ -1568,6 +1672,18 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, tcet->liobn, tcet->bus_offset, tcet->nb_table << tcet->page_shift); + /* Walk the bridges and program the bus numbers*/ + spapr_phb_pci_enumerate(phb); + _FDT(fdt_setprop_cell(fdt, bus_off, "qemu,phb-enumerated", 0x1)); + + /* Populate tree nodes with PCI devices attached */ + s_fdt.fdt = fdt; + s_fdt.node_off = bus_off; + s_fdt.sphb = phb; + pci_for_each_device(bus, pci_bus_num(bus), + spapr_populate_pci_devices_dt, + &s_fdt); + ret = spapr_drc_populate_dt(fdt, bus_off, OBJECT(phb), SPAPR_DR_CONNECTOR_TYPE_PCI); if (ret) { -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 21/22] spapr_pci: populate ibm,loc-code 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (19 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 20/22] spapr_pci: enumerate and add PCI device tree David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 22/22] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt David Gibson 2015-06-24 6:50 ` [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, Nikunj A Dadhania, David Gibson From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Each hardware instance has a platform unique location code. The OF device tree that describes a part of a hardware entity must include the “ibm,loc-code” property with a value that represents the location code for that hardware entity. Populate ibm,loc-code. 1) PCI passthru devices need to identify with its own ibm,loc-code available on the host. In failure cases use: vfio_<name>:<phb-index>:<bus>:<slot>.<fn> 2) Emulated devices encode as following: qemu_<name>:<phb-index>:<bus>:<slot>.<fn> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 7c3621c..7585983 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -747,6 +747,60 @@ static AddressSpace *spapr_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn) return &phb->iommu_as; } +static char *spapr_phb_vfio_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev) +{ + char *path = NULL, *buf = NULL, *host = NULL; + + /* Get the PCI VFIO host id */ + host = object_property_get_str(OBJECT(pdev), "host", NULL); + if (!host) { + goto err_out; + } + + /* Construct the path of the file that will give us the DT location */ + path = g_strdup_printf("/sys/bus/pci/devices/%s/devspec", host); + g_free(host); + if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) { + goto err_out; + } + g_free(path); + + /* Construct and read from host device tree the loc-code */ + path = g_strdup_printf("/proc/device-tree%s/ibm,loc-code", buf); + g_free(buf); + if (!path || !g_file_get_contents(path, &buf, NULL, NULL)) { + goto err_out; + } + return buf; + +err_out: + g_free(path); + return NULL; +} + +static char *spapr_phb_get_loc_code(sPAPRPHBState *sphb, PCIDevice *pdev) +{ + char *buf; + const char *devtype = "qemu"; + uint32_t busnr = pci_bus_num(PCI_BUS(qdev_get_parent_bus(DEVICE(pdev)))); + + if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) { + buf = spapr_phb_vfio_get_loc_code(sphb, pdev); + if (buf) { + return buf; + } + devtype = "vfio"; + } + /* + * For emulated devices and VFIO-failure case, make up + * the loc-code. + */ + buf = g_strdup_printf("%s_%s:%04x:%02x:%02x.%x", + devtype, pdev->name, sphb->index, busnr, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + return buf; +} + /* Macros to operate with address in OF binding to PCI */ #define b_x(x, p, l) (((x) & ((1<<(l))-1)) << (p)) #define b_n(x) b_x((x), 31, 1) /* 0 if relocatable */ @@ -885,11 +939,12 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp) static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, int phb_index, int drc_index, - const char *drc_name) + sPAPRPHBState *sphb) { ResourceProps rp; bool is_bridge = false; - int pci_status; + int pci_status, err; + char *buf = NULL; if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) == PCI_HEADER_TYPE_BRIDGE) { @@ -950,7 +1005,18 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, * processed by OF beforehand */ _FDT(fdt_setprop_string(fdt, offset, "name", "pci")); - _FDT(fdt_setprop(fdt, offset, "ibm,loc-code", drc_name, strlen(drc_name))); + buf = spapr_phb_get_loc_code(sphb, dev); + if (!buf) { + error_report("Failed setting the ibm,loc-code"); + return -1; + } + + err = fdt_setprop_string(fdt, offset, "ibm,loc-code", buf); + g_free(buf); + if (err < 0) { + return err; + } + _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)); _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", @@ -988,7 +1054,7 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, } offset = fdt_add_subnode(fdt, node_offset, nodename); ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index, - drc_name); + phb); g_assert(!ret); if (ret) { return 0; @@ -1004,14 +1070,13 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc, sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); DeviceState *dev = DEVICE(pdev); int drc_index = drck->get_index(drc); - const char *drc_name = drck->get_name(drc); void *fdt = NULL; int fdt_start_offset = 0, fdt_size; if (dev->hotplugged) { fdt = create_device_tree(&fdt_size); fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, - drc_index, drc_name, + drc_index, NULL, fdt, 0); if (!fdt_start_offset) { error_setg(errp, "Failed to create pci child device tree node"); -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* [Qemu-devel] [PATCH 22/22] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (20 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 21/22] spapr_pci: populate ibm,loc-code David Gibson @ 2015-06-24 6:30 ` David Gibson 2015-06-24 6:50 ` [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:30 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel, Nikunj A Dadhania, David Gibson From: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> * phb_index is not being used and if required can be obtained from sphb * use helper to get drc_index in spapr_populate_pci_child_dt() * Check if drc_index is zero Suggested-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> --- hw/ppc/spapr_pci.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 7585983..a139aea 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -937,14 +937,17 @@ static void populate_resource_props(PCIDevice *d, ResourceProps *rp) rp->assigned_len = assigned_idx * sizeof(ResourceFields); } +static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb, + PCIDevice *pdev); + static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, - int phb_index, int drc_index, sPAPRPHBState *sphb) { ResourceProps rp; bool is_bridge = false; int pci_status, err; char *buf = NULL; + uint32_t drc_index = spapr_phb_get_pci_drc_index(sphb, dev); if (pci_default_read_config(dev, PCI_HEADER_TYPE, 1) == PCI_HEADER_TYPE_BRIDGE) { @@ -1017,7 +1020,9 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, return err; } - _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)); + if (drc_index) { + _FDT(fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)); + } _FDT(fdt_setprop_cell(fdt, offset, "#address-cells", RESOURCE_CELLS_ADDRESS)); @@ -1034,12 +1039,8 @@ static int spapr_populate_pci_child_dt(PCIDevice *dev, void *fdt, int offset, return 0; } -static uint32_t spapr_phb_get_pci_drc_index(sPAPRPHBState *phb, - PCIDevice *pdev); - /* create OF node for pci device and required OF DT properties */ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, - int drc_index, const char *drc_name, void *fdt, int node_offset) { int offset, ret; @@ -1053,8 +1054,8 @@ static int spapr_create_pci_child_dt(sPAPRPHBState *phb, PCIDevice *dev, snprintf(nodename, FDT_NAME_MAX, "pci@%x", slot); } offset = fdt_add_subnode(fdt, node_offset, nodename); - ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb->index, drc_index, - phb); + ret = spapr_populate_pci_child_dt(dev, fdt, offset, phb); + g_assert(!ret); if (ret) { return 0; @@ -1069,15 +1070,12 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector *drc, { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); DeviceState *dev = DEVICE(pdev); - int drc_index = drck->get_index(drc); void *fdt = NULL; int fdt_start_offset = 0, fdt_size; if (dev->hotplugged) { fdt = create_device_tree(&fdt_size); - fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, - drc_index, NULL, - fdt, 0); + fdt_start_offset = spapr_create_pci_child_dt(phb, pdev, fdt, 0); if (!fdt_start_offset) { error_setg(errp, "Failed to create pci child device tree node"); goto out; @@ -1579,11 +1577,8 @@ static void spapr_populate_pci_devices_dt(PCIBus *bus, PCIDevice *pdev, sPAPRFDT *p = opaque; int offset; sPAPRFDT s_fdt; - uint32_t drc_index = spapr_phb_get_pci_drc_index(p->sphb, pdev); - offset = spapr_create_pci_child_dt(p->sphb, pdev, - drc_index, NULL, - p->fdt, p->node_off); + offset = spapr_create_pci_child_dt(p->sphb, pdev, p->fdt, p->node_off); if (!offset) { error_report("Failed to create pci child device tree node"); return; -- 2.4.3 ^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson ` (21 preceding siblings ...) 2015-06-24 6:30 ` [Qemu-devel] [PATCH 22/22] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt David Gibson @ 2015-06-24 6:50 ` David Gibson 22 siblings, 0 replies; 24+ messages in thread From: David Gibson @ 2015-06-24 6:50 UTC (permalink / raw) To: agraf, afaerber; +Cc: qemu-ppc, qemu-devel [-- Attachment #1: Type: text/plain, Size: 1106 bytes --] On Wed, Jun 24, 2015 at 04:30:14PM +1000, David Gibson wrote: > Hi Alex, > > Here are my accumulated spapr related qemu updates for the last little > while. Highlights are a SLOF update and changes to move PCI device > node creation from SLOF into qemu (using the same code paths as for > hotplug). This also has some preliminaries for CPU and memory hotplug > on -machine pseries, but the actual code for those is still on the > way. > > These are based against mainline master, not ppc-next, since mainline > is a fast-forward of the latest ppc-next that I can see. > > I've done a compile and "make check" on x86, ppc64 and ppc64le hosts, > plus a basic sanity check of booting an LE guest. I should clarify. On a ppc64 (but not ppc64le) host I get make check failures in check-qtest-i386 and check-qtest-x86_64, however, it looks like the same failures exist in current mainline. -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson [-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2015-06-24 6:50 UTC | newest] Thread overview: 24+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-06-24 6:30 [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 01/22] spapr: ensure we have at least one XICS server David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 02/22] pseries: Update SLOF firmware image to qemu-slof-20150429 David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 03/22] spapr: Merge sPAPREnvironment into sPAPRMachineState David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 04/22] spapr: Remove obsolete ram_limit field from sPAPRMachineState David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 05/22] spapr: Remove obsolete entry_point " David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 06/22] spapr: Add sPAPRMachineClass David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 07/22] spapr_pci: encode missing 64-bit memory address space David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 08/22] spapr_pci: encode class code including Prog IF register David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 09/22] spapr_pci: set device node unit address as hex David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 10/22] spapr_iommu: drop erroneous check in h_put_tce_indirect() David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 11/22] spapr_iommu: translate sPAPRTCEAccess to IOMMUAccessFlags David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 12/22] Revert "hw/ppc/spapr_pci.c: Avoid functions not in glib 2.12 (g_hash_table_iter_*)" David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 13/22] spapr: Consider max_cpus during xics initialization David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 14/22] spapr: Support ibm, lrdr-capacity device tree property David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 15/22] cpus: Add a macro to walk CPUs in reverse David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 16/22] spapr: Reorganize CPU dt generation code David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 17/22] spapr: Consolidate cpu init code into a routine David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 18/22] ppc: Update cpu_model in MachineState David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 19/22] xics_kvm: Don't enable KVM_CAP_IRQ_XICS if already enabled David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 20/22] spapr_pci: enumerate and add PCI device tree David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 21/22] spapr_pci: populate ibm,loc-code David Gibson 2015-06-24 6:30 ` [Qemu-devel] [PATCH 22/22] spapr_pci: drop redundant args in spapr_[populate, create]_pci_child_dt David Gibson 2015-06-24 6:50 ` [Qemu-devel] [PATCH 00/22] sPAPR updates 2015-06-24 David Gibson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).