From b39701db1312dcdadf6b9f3c1e38513a42654e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Mon, 4 Feb 2019 22:04:33 +0100 Subject: hw/ppc/prep: Drop useless inclusion of "hw/i386/pc.h" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 47973a2dbf we split the last generic chipset out of the PC board, but forgot to remove the include of "hw/i386/pc.h". Since it is now unused, remove it. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Hervé Poussineau Signed-off-by: David Gibson --- hw/ppc/prep.c | 1 - 1 file changed, 1 deletion(-) diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 7bda86a7d0..847d320465 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -26,7 +26,6 @@ #include "cpu.h" #include "hw/hw.h" #include "hw/timer/m48t59.h" -#include "hw/i386/pc.h" #include "hw/char/serial.h" #include "hw/block/fdc.h" #include "net/net.h" -- cgit v1.2.3 From 5c7adcf422d4bd7235e0d2f2f85efcc393795fb2 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Thu, 17 Jan 2019 18:14:39 +0100 Subject: spapr: Rename xics to intc in interrupt controller agnostic code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All this code is used with both the XICS and XIVE interrupt controllers. Signed-off-by: Greg Kurz Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr.c | 6 +++--- hw/ppc/spapr_events.c | 2 +- hw/ppc/spapr_pci.c | 6 +++--- hw/ppc/spapr_vio.c | 2 +- include/hw/pci-host/spapr.h | 2 +- include/hw/ppc/spapr.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 332cba89d4..850cfe28c4 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -96,7 +96,7 @@ #define MIN_RMA_SLOF 128UL -#define PHANDLE_XICP 0x00001111 +#define PHANDLE_INTC 0x00001111 /* These two functions implement the VCPU id numbering: one to compute them * all and one to identify thread 0 of a VCORE. Any change to the first one @@ -1274,7 +1274,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr) /* /interrupt controller */ spapr->irq->dt_populate(spapr, spapr_max_server_number(spapr), fdt, - PHANDLE_XICP); + PHANDLE_INTC); ret = spapr_populate_memory(spapr, fdt); if (ret < 0) { @@ -1294,7 +1294,7 @@ static void *spapr_build_fdt(sPAPRMachineState *spapr) } QLIST_FOREACH(phb, &spapr->phbs, list) { - ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt, + ret = spapr_populate_pci_dt(phb, PHANDLE_INTC, fdt, spapr->irq->nr_msis); if (ret < 0) { error_report("couldn't setup PCI devices in fdt"); diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 32719a1b72..b9c7ecb9e9 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -282,7 +282,7 @@ void spapr_dt_events(sPAPRMachineState *spapr, void *fdt) continue; } - spapr_dt_xics_irq(interrupts, source->irq, false); + spapr_dt_irq(interrupts, source->irq, false); _FDT(node_offset = fdt_add_subnode(fdt, event_sources, source_name)); _FDT(fdt_setprop(fdt, node_offset, "interrupts", interrupts, diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index c99721cde8..41d81f4a85 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2063,7 +2063,7 @@ static void spapr_phb_pci_enumerate(sPAPRPHBState *phb) } -int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt, +int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt, uint32_t nr_msis) { int bus_off, i, j, ret; @@ -2161,8 +2161,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt, irqmap[1] = 0; irqmap[2] = 0; irqmap[3] = cpu_to_be32(j+1); - irqmap[4] = cpu_to_be32(xics_phandle); - spapr_dt_xics_irq(&irqmap[5], phb->lsi_table[lsi_num].irq, true); + irqmap[4] = cpu_to_be32(intc_phandle); + spapr_dt_irq(&irqmap[5], phb->lsi_table[lsi_num].irq, true); } } /* Write interrupt map */ diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 414673d313..2b7e7ecac5 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -126,7 +126,7 @@ static int vio_make_devnode(VIOsPAPRDevice *dev, if (dev->irq) { uint32_t ints_prop[2]; - spapr_dt_xics_irq(ints_prop, dev->irq, false); + spapr_dt_irq(ints_prop, dev->irq, false); ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop, sizeof(ints_prop)); if (ret < 0) { diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index a5a7bf4837..51d81c4b7c 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -112,7 +112,7 @@ static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin) return spapr_qirq(spapr, phb->lsi_table[pin].irq); } -int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t xics_phandle, void *fdt, +int spapr_populate_pci_dt(sPAPRPHBState *phb, uint32_t intc_phandle, void *fdt, uint32_t nr_msis); void spapr_pci_rtas_init(void); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index a947a0a0dc..cbd276ed2b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -683,7 +683,7 @@ void spapr_load_rtas(sPAPRMachineState *spapr, void *fdt, hwaddr addr); * "interrupt-controller" node has its "#interrupt-cells" property set to 2 (ie, * VIO devices, RTAS event sources and PHBs). */ -static inline void spapr_dt_xics_irq(uint32_t *intspec, int irq, bool is_lsi) +static inline void spapr_dt_irq(uint32_t *intspec, int irq, bool is_lsi) { intspec[0] = cpu_to_be32(irq); intspec[1] = is_lsi ? cpu_to_be32(1) : 0; -- cgit v1.2.3 From 707c7c2ee1f6fb425a3c78f587feda7cd8501905 Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Wed, 6 Feb 2019 14:51:33 -0200 Subject: target/ppc: Enable reporting of SPRs to GDB This allows reading and writing of SPRs via GDB: (gdb) p/x $srr1 $1 = 0x8000000002803033 (gdb) p/x $pvr $2 = 0x4b0201 (gdb) set $pvr=0x4b0000 (gdb) p/x $pvr $3 = 0x4b0000 The `info` command can also be used: (gdb) info registers spr For this purpose, GDB needs to be provided with an XML description of the registers (see the gdb-xml directory for examples) and a set of callbacks for reading and writing the registers must be defined. The XML file in this case is created dynamically, based on the SPRs already defined in the machine. This way we avoid the need for several XML files to suit each possible ppc machine. The gdb_{get,set}_spr_reg callbacks take an index based on the order the registers appear in the XML file. This index does not match the actual location of the registers in the env->spr array so the gdb_find_spr_idx function does that conversion. Note: GDB currently needs to know the guest endianness in order to properly print the registers values. This is done automatically by GDB when provided with the ELF file or explicitly with the `set endian ` command. Signed-off-by: Fabiano Rosas Signed-off-by: David Gibson --- target/ppc/cpu-qom.h | 4 +++ target/ppc/cpu.h | 5 ++++ target/ppc/gdbstub.c | 61 ++++++++++++++++++++++++++++++++++++++++ target/ppc/translate_init.inc.c | 62 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 2 deletions(-) diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h index 4ea67692e2..3130802304 100644 --- a/target/ppc/cpu-qom.h +++ b/target/ppc/cpu-qom.h @@ -179,6 +179,10 @@ typedef struct PowerPCCPUClass { uint32_t flags; int bfd_mach; uint32_t l1_dcache_size, l1_icache_size; +#ifndef CONFIG_USER_ONLY + unsigned int gdb_num_sprs; + const char *gdb_spr_xml; +#endif const PPCHash64Options *hash64_opts; struct ppc_radix_page_info *radix_page_info; void (*init_proc)(CPUPPCState *env); diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 2c22292e7f..78af7e4608 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -230,6 +230,7 @@ struct ppc_spr_t { void (*oea_write)(DisasContext *ctx, int spr_num, int gpr_num); void (*hea_read)(DisasContext *ctx, int gpr_num, int spr_num); void (*hea_write)(DisasContext *ctx, int spr_num, int gpr_num); + unsigned int gdb_id; #endif const char *name; target_ulong default_value; @@ -1263,6 +1264,10 @@ int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg); int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg); int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg); +#ifndef CONFIG_USER_ONLY +void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu); +const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name); +#endif int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs, int cpuid, void *opaque); int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 19565b584d..fbf3821f4b 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c @@ -319,3 +319,64 @@ int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) } return r; } + +#ifndef CONFIG_USER_ONLY +void ppc_gdb_gen_spr_xml(PowerPCCPU *cpu) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + CPUPPCState *env = &cpu->env; + GString *xml; + char *spr_name; + unsigned int num_regs = 0; + int i; + + if (pcc->gdb_spr_xml) { + return; + } + + xml = g_string_new(""); + g_string_append(xml, ""); + g_string_append(xml, ""); + + for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { + ppc_spr_t *spr = &env->spr_cb[i]; + + if (!spr->name) { + continue; + } + + spr_name = g_ascii_strdown(spr->name, -1); + g_string_append_printf(xml, ""); + + /* + * GDB identifies registers based on the order they are + * presented in the XML. These ids will not match QEMU's + * representation (which follows the PowerISA). + * + * Store the position of the current register description so + * we can make the correspondence later. + */ + spr->gdb_id = num_regs; + num_regs++; + } + + g_string_append(xml, ""); + + pcc->gdb_num_sprs = num_regs; + pcc->gdb_spr_xml = g_string_free(xml, false); +} + +const char *ppc_gdb_get_dynamic_xml(CPUState *cs, const char *xml_name) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); + + if (strcmp(xml_name, "power-spr.xml") == 0) { + return pcc->gdb_spr_xml; + } + return NULL; +} +#endif diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 59e0b86762..9295f78d5f 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8979,6 +8979,10 @@ static void init_ppc_proc(PowerPCCPU *cpu) /* PowerPC implementation specific initialisations (SPRs, timers, ...) */ (*pcc->init_proc)(env); +#if !defined(CONFIG_USER_ONLY) + ppc_gdb_gen_spr_xml(cpu); +#endif + /* MSR bits & flags consistency checks */ if (env->msr_mask & (1 << 25)) { switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) { @@ -9475,6 +9479,55 @@ static bool avr_need_swap(CPUPPCState *env) #endif } +#if !defined(CONFIG_USER_ONLY) +static int gdb_find_spr_idx(CPUPPCState *env, int n) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) { + ppc_spr_t *spr = &env->spr_cb[i]; + + if (spr->name && spr->gdb_id == n) { + return i; + } + } + return -1; +} + +static int gdb_get_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + int reg; + int len; + + reg = gdb_find_spr_idx(env, n); + if (reg < 0) { + return 0; + } + + len = TARGET_LONG_SIZE; + stn_p(mem_buf, len, env->spr[reg]); + ppc_maybe_bswap_register(env, mem_buf, len); + return len; +} + +static int gdb_set_spr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) +{ + int reg; + int len; + + reg = gdb_find_spr_idx(env, n); + if (reg < 0) { + return 0; + } + + len = TARGET_LONG_SIZE; + ppc_maybe_bswap_register(env, mem_buf, len); + env->spr[reg] = ldn_p(mem_buf, len); + + return len; +} +#endif + static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { @@ -9704,7 +9757,10 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp) gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg, 32, "power-vsx.xml", 0); } - +#ifndef CONFIG_USER_ONLY + gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg, + pcc->gdb_num_sprs, "power-spr.xml", 0); +#endif qemu_init_vcpu(cs); pcc->parent_realize(dev, errp); @@ -10467,7 +10523,9 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data) #endif cc->gdb_num_core_regs = 71; - +#ifndef CONFIG_USER_ONLY + cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml; +#endif #ifdef USE_APPLE_GDB cc->gdb_read_register = ppc_cpu_gdb_read_register_apple; cc->gdb_write_register = ppc_cpu_gdb_write_register_apple; -- cgit v1.2.3 From 27a3ea7eff2af5d8049d911802be4b13145491fc Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Sat, 26 Jan 2019 15:50:28 +0100 Subject: target/ppc: Fix msync to do what hardware does According to BookE docs, invalid bits (while undefined behaviour) should not raise exception but be ignored. This seems to be implementation dependent though and QEMU currently does what e500 CPUs do and raise exception for invalid bits. Unfortunately some versions of libstdc++ (and so all programs compiled with it) have lwsync on PPC440 which is invalid but on real hardware it's just executed as msync ignoring the invalid bits (maybe that's why it got undetected) but they fail on QEMU. This patch changes invalid mask of msync to allow these programs to run but keep generating exception on e500 cores to follow what hardware does. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- target/ppc/translate.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index e169c43643..5429ceb1ab 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6476,7 +6476,12 @@ static void gen_mbar(DisasContext *ctx) /* msync replaces sync on 440 */ static void gen_msync_4xx(DisasContext *ctx) { - /* interpreted as no-op */ + /* Only e500 seems to treat reserved bits as invalid */ + if ((ctx->insns_flags2 & PPC2_BOOKE206) && + (ctx->opcode & 0x03FFF801)) { + gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); + } + /* otherwise interpreted as no-op */ } /* icbt */ @@ -7054,11 +7059,11 @@ GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE), GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC), GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE, PPC2_BOOKE206), -GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE), +GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x039FF801, PPC_BOOKE), GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE, PPC2_BOOKE206), GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, - PPC_440_SPEC), + PPC_440_SPEC), GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), -- cgit v1.2.3 From 925969c3e28692b04ad4075022f985702bf62419 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Thu, 7 Feb 2019 18:28:37 +0100 Subject: spapr_pci: Fix interrupt leak in rtas_ibm_change_msi() error path Now that IRQ allocation has been split in two (first allocate IRQ numbers, then claim them), if the claiming fails, we must release the IRQs. Fixes: 4fe75a8ccd80 "spapr: split the IRQ allocation sequence" Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 41d81f4a85..c3fb0ac884 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -393,6 +393,12 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, for (i = 0; i < req_num; i++) { spapr_irq_claim(spapr, irq + i, false, &err); if (err) { + if (i) { + spapr_irq_free(spapr, irq, i); + } + if (!smc->legacy_irq_allocation) { + spapr_irq_msi_free(spapr, irq, req_num); + } error_reportf_err(err, "Can't allocate MSIs for device %x: ", config_addr); rtas_st(rets, 0, RTAS_OUT_HW_ERROR); -- cgit v1.2.3 From d6c666ad81f6f771ff40bb9c72dde327e6c87846 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 10 Feb 2019 17:44:21 +0000 Subject: cuda: decrease time delay before raising VIA SR interrupt and remove fast path In order to handle a race condition in the MacOS 9 CUDA driver, a delay was introduced when raising the VIA SR interrupt inspired by similar code in MacOnLinux. During original testing of the MacOS 9 patches it was found that the 30us delay used in MacOnLinux did not work reliably within QEMU, and a value of 300us was required to function correctly. Recent experiments have shown two things: firstly when booting Linux, MacOS 9 and MacOS X the fast path which bypasses the delay is never triggered once the OS kernel is loaded making it effectively useless. Rather than leave this code in place where a guest could potentially enable it by accident and break itself, we might as well just remove it. Secondly the previous reliability issues are no longer present, and this value can be reduced down to 20us with no apparent ill effects. This has the benefit of considerably improving the responsiveness of the ADB keyboard and mouse within the guest. Signed-off-by: Mark Cave-Ayland Signed-off-by: David Gibson --- hw/misc/macio/cuda.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index c4f7a2f39b..3febacdd1e 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -97,17 +97,8 @@ static void cuda_set_sr_int(void *opaque) static void cuda_delay_set_sr_int(CUDAState *s) { - MOS6522CUDAState *mcs = &s->mos6522_cuda; - MOS6522State *ms = MOS6522(mcs); - MOS6522DeviceClass *mdc = MOS6522_DEVICE_GET_CLASS(ms); int64_t expire; - if (ms->dirb == 0xff || s->sr_delay_ns == 0) { - /* Disabled or not in Mac OS, fire the IRQ directly */ - mdc->set_sr_int(ms); - return; - } - trace_cuda_delay_set_sr_int(); expire = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->sr_delay_ns; @@ -542,7 +533,7 @@ static void cuda_realize(DeviceState *dev, Error **errp) s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET; s->sr_delay_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_set_sr_int, s); - s->sr_delay_ns = 300 * SCALE_US; + s->sr_delay_ns = 20 * SCALE_US; s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s); s->adb_poll_mask = 0xffff; -- cgit v1.2.3 From 1a511340874e5a9d3b235261447d920fd8be493e Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 8 Feb 2019 19:17:47 +0100 Subject: spapr: Disallow unsupported kernel-irqchip settings Split mode doesn't make sense on pseries, neither with XICS nor XIVE. But passing kernel-irqchip=split silently behaves like kernel-irqchip=on. Other architectures that support kernel-irqchip do terminate QEMU when split mode is requested but not available though. Do the same with pseries for consistency. Similarly, passing kernel-irqchip=on,accel=tcg starts the machine with the emulated interrupt controller, ie, behaves like kernel-irqchip=off. However, when passing kernel-irqchip=on,accel=kvm, if we can't initialize the KVM XICS for some reason, ie, xics_kvm_init() fails, then QEMU is terminated. This is inconsistent. Terminate QEMU all the same when requesting the in-kernel interrupt controller without KVM. Signed-off-by: Greg Kurz Message-Id: <154964986747.291716.2679312373018476920.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 2d7a7c1638..80b0083b8e 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -600,6 +600,19 @@ sPAPRIrq spapr_irq_dual = { */ void spapr_irq_init(sPAPRMachineState *spapr, Error **errp) { + MachineState *machine = MACHINE(spapr); + + if (machine_kernel_irqchip_split(machine)) { + error_setg(errp, "kernel_irqchip split mode not supported on pseries"); + return; + } + + if (!kvm_enabled() && machine_kernel_irqchip_required(machine)) { + error_setg(errp, + "kernel_irqchip requested but only available with KVM"); + return; + } + /* Initialize the MSI IRQ allocator. */ if (!SPAPR_MACHINE_GET_CLASS(spapr)->legacy_irq_allocation) { spapr_irq_msi_init(spapr, spapr->irq->nr_msis); -- cgit v1.2.3 From 4479b51e62d025c954a1f01b5c67a51d3a39cab2 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 8 Feb 2019 17:22:01 +0000 Subject: mac_newworld: change default NIC to sungem for mac99 machine This model brings out-of-the-box networking for all of Linux, MacOS 9 and OS X without requiring the installation of additional drivers. Signed-off-by: Mark Cave-Ayland Message-Id: <20190208172201.29001-1-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- hw/ppc/mac_newworld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 10be728c37..98461052ac 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -432,7 +432,7 @@ static void ppc_core99_init(MachineState *machine) } for (i = 0; i < nb_nics; i++) { - pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); + pci_nic_init_nofail(&nd_table[i], pci_bus, "sungem", NULL); } /* The NewWorld NVRAM is not located in the MacIO device */ -- cgit v1.2.3 From 4c668f4a3d684ec133a52d936314379f6edd672e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 28 Jan 2019 10:46:12 +0100 Subject: target/ppc: Remove some #if 0'ed code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some debug stuff we don't need to keep there Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Cédric Le Goater Message-Id: <20190128094625.4428-7-clg@kaod.org> Signed-off-by: David Gibson --- target/ppc/excp_helper.c | 12 ------------ target/ppc/mmu_helper.c | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 0ec7ae1ad4..751d759fcc 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -748,13 +748,7 @@ void ppc_cpu_do_interrupt(CPUState *cs) static void ppc_hw_interrupt(CPUPPCState *env) { PowerPCCPU *cpu = ppc_env_get_cpu(env); -#if 0 - CPUState *cs = CPU(cpu); - qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n", - __func__, env, env->pending_interrupts, - cs->interrupt_request, (int)msr_me, (int)msr_ee); -#endif /* External reset */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); @@ -797,12 +791,6 @@ static void ppc_hw_interrupt(CPUPPCState *env) if (msr_ce != 0) { /* External critical interrupt */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) { - /* Taking a critical external interrupt does not clear the external - * critical interrupt status - */ -#if 0 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT); -#endif powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL); return; } diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c index cefed34da4..bcf19da61d 100644 --- a/target/ppc/mmu_helper.c +++ b/target/ppc/mmu_helper.c @@ -1415,10 +1415,6 @@ static int get_physical_address_wtlb( bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0) || (access_type != ACCESS_CODE && msr_dr == 0); -#if 0 - qemu_log("%s\n", __func__); -#endif - switch (env->mmu_model) { case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: @@ -1468,10 +1464,6 @@ static int get_physical_address_wtlb( cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n"); return -1; } -#if 0 - qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n", - __func__, eaddr, ret, ctx->raddr); -#endif return ret; } @@ -1805,10 +1797,6 @@ static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, break; } } -#if 0 - printf("%s: set exception to %d %02x\n", __func__, - cs->exception, env->error_code); -#endif ret = 1; } -- cgit v1.2.3 From e150ac89fbcf4ea15535f6718d0194310c39280d Mon Sep 17 00:00:00 2001 From: Roman Kapl Date: Tue, 12 Feb 2019 13:12:55 +0100 Subject: ppc: fix crash during branch stepping The PPC BRANCH exception could bubble up, but this is an QEMU internal exception and QEMU then crased. Instead it should trigger TRACE exception, according to PPC 2.07 book. It could happen only when using branch stepping, which is not commonly used. Change gen_prep_dbgex do do trigger TRACE. The excp, argument is now removed, since the type of exception can be inferred from the singlestep_enabled flags. removed the guards around gen_exception, since they are unnecessary. Fixes: 0e3bf48909 ("ppc: add DBCR based debugging"). Signed-off-by: Roman Kapl Message-Id: <20190212121255.2279-1-rka@sysgo.com> Signed-off-by: David Gibson --- target/ppc/translate.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 5429ceb1ab..d5f29d3536 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -287,26 +287,22 @@ static void gen_exception_nip(DisasContext *ctx, uint32_t excp, ctx->exception = (excp); } -/* Translates the EXCP_TRACE/BRANCH exceptions used on most PowerPCs to - * EXCP_DEBUG, if we are running on cores using the debug enable bit (e.g. - * BookE). +/* + * Tells the caller what is the appropriate exception to generate and prepares + * SPR registers for this exception. + * + * The exception can be either POWERPC_EXCP_TRACE (on most PowerPCs) or + * POWERPC_EXCP_DEBUG (on BookE). */ -static uint32_t gen_prep_dbgex(DisasContext *ctx, uint32_t excp) +static uint32_t gen_prep_dbgex(DisasContext *ctx) { - if ((ctx->singlestep_enabled & CPU_SINGLE_STEP) - && (excp == POWERPC_EXCP_BRANCH)) { - /* Trace excpt. has priority */ - excp = POWERPC_EXCP_TRACE; - } if (ctx->flags & POWERPC_FLAG_DE) { target_ulong dbsr = 0; - switch (excp) { - case POWERPC_EXCP_TRACE: + if (ctx->singlestep_enabled & CPU_SINGLE_STEP) { dbsr = DBCR0_ICMP; - break; - case POWERPC_EXCP_BRANCH: + } else { + /* Must have been branch */ dbsr = DBCR0_BRT; - break; } TCGv t0 = tcg_temp_new(); gen_load_spr(t0, SPR_BOOKE_DBSR); @@ -315,7 +311,7 @@ static uint32_t gen_prep_dbgex(DisasContext *ctx, uint32_t excp) tcg_temp_free(t0); return POWERPC_EXCP_DEBUG; } else { - return excp; + return POWERPC_EXCP_TRACE; } } @@ -3652,10 +3648,8 @@ static void gen_lookup_and_goto_ptr(DisasContext *ctx) if (sse & GDBSTUB_SINGLE_STEP) { gen_debug_exception(ctx); } else if (sse & (CPU_SINGLE_STEP | CPU_BRANCH_STEP)) { - uint32_t excp = gen_prep_dbgex(ctx, POWERPC_EXCP_BRANCH); - if (excp != POWERPC_EXCP_NONE) { - gen_exception(ctx, excp); - } + uint32_t excp = gen_prep_dbgex(ctx); + gen_exception(ctx, excp); } tcg_gen_exit_tb(NULL, 0); } else { @@ -7790,9 +7784,8 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) ctx->exception != POWERPC_SYSCALL && ctx->exception != POWERPC_EXCP_TRAP && ctx->exception != POWERPC_EXCP_BRANCH)) { - uint32_t excp = gen_prep_dbgex(ctx, POWERPC_EXCP_TRACE); - if (excp != POWERPC_EXCP_NONE) - gen_exception_nip(ctx, excp, ctx->base.pc_next); + uint32_t excp = gen_prep_dbgex(ctx); + gen_exception_nip(ctx, excp, ctx->base.pc_next); } if (tcg_check_temp_count()) { -- cgit v1.2.3 From 0afed8c8195886111dd8ab0d078b189c55949521 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Tue, 12 Feb 2019 19:24:06 +0100 Subject: xive: Only set source type for LSIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MSI is the default and LSI specific code is guarded by the xive_source_irq_is_lsi() helper. The xive_source_irq_set() helper is a nop for MSIs. Simplify the code by turning xive_source_irq_set() into xive_source_irq_set_lsi() and only call it for LSIs. The call to xive_source_irq_set(false) in spapr_xive_irq_free() is also a nop. Just drop it. Signed-off-by: Greg Kurz Reviewed-by: Cédric Le Goater Message-Id: <154999584656.690774.18352404495120358613.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/intc/spapr_xive.c | 7 +++---- include/hw/ppc/xive.h | 7 ++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index a0f5ff9294..290a290e43 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -489,20 +489,19 @@ bool spapr_xive_irq_claim(sPAPRXive *xive, uint32_t lisn, bool lsi) } xive->eat[lisn].w |= cpu_to_be64(EAS_VALID); - xive_source_irq_set(xsrc, lisn, lsi); + if (lsi) { + xive_source_irq_set_lsi(xsrc, lisn); + } return true; } bool spapr_xive_irq_free(sPAPRXive *xive, uint32_t lisn) { - XiveSource *xsrc = &xive->source; - if (lisn >= xive->nr_irqs) { return false; } xive->eat[lisn].w &= cpu_to_be64(~EAS_VALID); - xive_source_irq_set(xsrc, lisn, false); return true; } diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index ec3bb2aae4..13a487527b 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -283,13 +283,10 @@ static inline bool xive_source_irq_is_lsi(XiveSource *xsrc, uint32_t srcno) return test_bit(srcno, xsrc->lsi_map); } -static inline void xive_source_irq_set(XiveSource *xsrc, uint32_t srcno, - bool lsi) +static inline void xive_source_irq_set_lsi(XiveSource *xsrc, uint32_t srcno) { assert(srcno < xsrc->nr_irqs); - if (lsi) { - bitmap_set(xsrc->lsi_map, srcno, 1); - } + bitmap_set(xsrc->lsi_map, srcno, 1); } void xive_source_set_irq(void *opaque, int srcno, int val); -- cgit v1.2.3 From 94d1cc5f03a8f7e45925928d0c9a5ee9782e6c85 Mon Sep 17 00:00:00 2001 From: Michael Roth Date: Tue, 12 Feb 2019 19:24:59 +0100 Subject: qdev: pass an Object * to qbus_set_hotplug_handler() Certain devices types, like memory/CPU, are now being handled using a hotplug interface provided by a top-level MachineClass. Hotpluggable host bridges are another such device where it makes sense to use a machine-level hotplug handler. However, unlike those devices, host-bridges have a parent bus (the main system bus), and devices with a parent bus use a different mechanism for registering their hotplug handlers: qbus_set_hotplug_handler(). This interface currently expects a handler to be a subclass of DeviceClass, but this is not the case for MachineClass, which derives directly from ObjectClass. Internally, the interface only requires an ObjectClass, so expose that in qbus_set_hotplug_handler(). Cc: Michael S. Tsirkin Cc: Eduardo Habkost Signed-off-by: Michael Roth Signed-off-by: Greg Kurz Reviewed-by: David Gibson Reviewed-by: Cornelia Huck Acked-by: Halil Pasic Reviewed-by: Michael S. Tsirkin Message-Id: <154999589921.690774.3640149277362188566.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/acpi/pcihp.c | 2 +- hw/acpi/piix4.c | 2 +- hw/char/virtio-serial-bus.c | 2 +- hw/core/bus.c | 11 ++--------- hw/pci/pcie.c | 2 +- hw/pci/shpc.c | 2 +- hw/ppc/spapr_pci.c | 2 +- hw/s390x/css-bridge.c | 2 +- hw/s390x/s390-pci-bus.c | 6 +++--- hw/scsi/virtio-scsi.c | 2 +- hw/scsi/vmw_pvscsi.c | 2 +- hw/usb/dev-smartcard-reader.c | 2 +- include/hw/qdev-core.h | 3 +-- 13 files changed, 16 insertions(+), 24 deletions(-) diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 7bc7a72340..9429181323 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -251,7 +251,7 @@ void acpi_pcihp_device_plug_cb(HotplugHandler *hotplug_dev, AcpiPciHpState *s, object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) { PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev)); - qbus_set_hotplug_handler(BUS(sec), DEVICE(hotplug_dev), + qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev), &error_abort); /* We don't have to overwrite any other hotplug handler yet */ assert(QLIST_EMPTY(&sec->child)); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 88f9a9ec09..df8c0db909 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -536,7 +536,7 @@ static void piix4_pm_realize(PCIDevice *dev, Error **errp) piix4_acpi_system_hot_add_init(pci_address_space_io(dev), pci_get_bus(dev), s); - qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), DEVICE(s), &error_abort); + qbus_set_hotplug_handler(BUS(pci_get_bus(dev)), OBJECT(s), &error_abort); piix4_pm_add_propeties(s); } diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index d76351d748..bdd917bbb8 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -1052,7 +1052,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) /* Spawn a new virtio-serial bus on which the ports will ride as devices */ qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS, dev, vdev->bus_name); - qbus_set_hotplug_handler(BUS(&vser->bus), DEVICE(vser), errp); + qbus_set_hotplug_handler(BUS(&vser->bus), OBJECT(vser), errp); vser->bus.vser = vser; QTAILQ_INIT(&vser->ports); diff --git a/hw/core/bus.c b/hw/core/bus.c index 4651f24486..e09843f6ab 100644 --- a/hw/core/bus.c +++ b/hw/core/bus.c @@ -22,22 +22,15 @@ #include "hw/qdev.h" #include "qapi/error.h" -static void qbus_set_hotplug_handler_internal(BusState *bus, Object *handler, - Error **errp) +void qbus_set_hotplug_handler(BusState *bus, Object *handler, Error **errp) { - object_property_set_link(OBJECT(bus), OBJECT(handler), QDEV_HOTPLUG_HANDLER_PROPERTY, errp); } -void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, Error **errp) -{ - qbus_set_hotplug_handler_internal(bus, OBJECT(handler), errp); -} - void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp) { - qbus_set_hotplug_handler_internal(bus, OBJECT(bus), errp); + qbus_set_hotplug_handler(bus, OBJECT(bus), errp); } int qbus_walk_children(BusState *bus, diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 230478faab..3f7c366093 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -543,7 +543,7 @@ void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot) dev->exp.hpev_notified = false; qbus_set_hotplug_handler(BUS(pci_bridge_get_sec_bus(PCI_BRIDGE(dev))), - DEVICE(dev), NULL); + OBJECT(dev), NULL); } void pcie_cap_slot_reset(PCIDevice *dev) diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 45053b39b9..52ccdc5ae3 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -648,7 +648,7 @@ int shpc_init(PCIDevice *d, PCIBus *sec_bus, MemoryRegion *bar, shpc_cap_update_dword(d); memory_region_add_subregion(bar, offset, &shpc->mmio); - qbus_set_hotplug_handler(BUS(sec_bus), DEVICE(d), NULL); + qbus_set_hotplug_handler(BUS(sec_bus), OBJECT(d), NULL); d->cap_present |= QEMU_PCI_CAP_SHPC; return 0; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index c3fb0ac884..60777b2355 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1686,7 +1686,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) &sphb->memspace, &sphb->iospace, PCI_DEVFN(0, 0), PCI_NUM_PINS, TYPE_PCI_BUS); phb->bus = bus; - qbus_set_hotplug_handler(BUS(phb->bus), DEVICE(sphb), NULL); + qbus_set_hotplug_handler(BUS(phb->bus), OBJECT(sphb), NULL); /* * Initialize PHB address space. diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c index 1bd6c8b458..7573c40bad 100644 --- a/hw/s390x/css-bridge.c +++ b/hw/s390x/css-bridge.c @@ -108,7 +108,7 @@ VirtualCssBus *virtual_css_bus_init(void) cbus = VIRTUAL_CSS_BUS(bus); /* Enable hotplugging */ - qbus_set_hotplug_handler(bus, dev, &error_abort); + qbus_set_hotplug_handler(bus, OBJECT(dev), &error_abort); css_register_io_adapters(CSS_IO_ADAPTER_VIRTIO, true, false, 0, &error_abort); diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 80ff1ce33f..5998942b4c 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -742,7 +742,7 @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp) pci_setup_iommu(b, s390_pci_dma_iommu, s); bus = BUS(b); - qbus_set_hotplug_handler(bus, dev, &local_err); + qbus_set_hotplug_handler(bus, OBJECT(dev), &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -750,7 +750,7 @@ static void s390_pcihost_realize(DeviceState *dev, Error **errp) phb->bus = b; s->bus = S390_PCI_BUS(qbus_create(TYPE_S390_PCI_BUS, dev, NULL)); - qbus_set_hotplug_handler(BUS(s->bus), dev, &local_err); + qbus_set_hotplug_handler(BUS(s->bus), OBJECT(dev), &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -912,7 +912,7 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev, pci_bridge_map_irq(pb, dev->id, s390_pci_map_irq); pci_setup_iommu(&pb->sec_bus, s390_pci_dma_iommu, s); - qbus_set_hotplug_handler(BUS(&pb->sec_bus), DEVICE(s), errp); + qbus_set_hotplug_handler(BUS(&pb->sec_bus), OBJECT(s), errp); if (dev->hotplugged) { pci_default_write_config(pdev, PCI_PRIMARY_BUS, diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index eb90288f47..ce99d288b0 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -906,7 +906,7 @@ static void virtio_scsi_device_realize(DeviceState *dev, Error **errp) scsi_bus_new(&s->bus, sizeof(s->bus), dev, &virtio_scsi_scsi_info, vdev->bus_name); /* override default SCSI bus hotplug-handler, with virtio-scsi's one */ - qbus_set_hotplug_handler(BUS(&s->bus), dev, &error_abort); + qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev), &error_abort); virtio_scsi_dataplane_setup(s, errp); } diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index a3a019e30a..584b4be07e 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -1142,7 +1142,7 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp) scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev), &pvscsi_scsi_info, NULL); /* override default SCSI bus hotplug-handler, with pvscsi's one */ - qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(s), &error_abort); + qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(s), &error_abort); pvscsi_reset_state(s); } diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 8f716fc165..6b0137bb76 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -1322,7 +1322,7 @@ static void ccid_realize(USBDevice *dev, Error **errp) usb_desc_init(dev); qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev), NULL); - qbus_set_hotplug_handler(BUS(&s->bus), DEVICE(dev), &error_abort); + qbus_set_hotplug_handler(BUS(&s->bus), OBJECT(dev), &error_abort); s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP); s->bulk = usb_ep_get(dev, USB_TOKEN_IN, CCID_BULK_IN_EP); s->card = NULL; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 0a84c42756..e70a4bfa49 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -430,8 +430,7 @@ char *qdev_get_dev_path(DeviceState *dev); GSList *qdev_build_hotpluggable_device_list(Object *peripheral); -void qbus_set_hotplug_handler(BusState *bus, DeviceState *handler, - Error **errp); +void qbus_set_hotplug_handler(BusState *bus, Object *handler, Error **errp); void qbus_set_bus_hotplug_handler(BusState *bus, Error **errp); -- cgit v1.2.3 From 316aed64827ee51267adcf187e867747f29b9a6e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 28 Jan 2019 10:46:18 +0100 Subject: target/ppc: Disable ISA 2.06 PM instructions on POWER9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ISA 2.06/2.07 Power Management instructions (doze, nap & rvwinkle) don't exist on POWER9, don't enable them. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Cédric Le Goater Message-Id: <20190128094625.4428-13-clg@kaod.org> Signed-off-by: David Gibson --- target/ppc/translate_init.inc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index 9295f78d5f..c9985c0d22 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -8873,7 +8873,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300 | PPC2_PRCNTL; + PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_TM) | (1ull << MSR_VR) | -- cgit v1.2.3 From cc941111a5bc5f498185fa3824c3b6579c7d45ad Mon Sep 17 00:00:00 2001 From: Fabiano Rosas Date: Wed, 13 Feb 2019 15:29:26 -0200 Subject: spapr: fix out of bounds write in spapr_populate_drmem_v2 buf_len is uint8_t which is not large enough to hold the result of: nr_entries * sizeof(struct sPAPRDrconfCellV2) + sizeof(uint32_t); for a nr_entries greater than 10. This causes the allocated buffer 'int_buf' to be smaller than expected and we eventually overwrite some of glibc's control structures (see "chunk" in https://sourceware.org/glibc/wiki/MallocInternals) The following error is seen while trying to free int_buf: "free(): invalid next size (fast)" Fixes: a324d6f166 "spapr: Support ibm,dynamic-memory-v2 property" Signed-off-by: Fabiano Rosas Message-Id: <20190213172926.21740-1-farosas@linux.ibm.com> Reviewed-by: Greg Kurz Signed-off-by: David Gibson --- 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 850cfe28c4..abf9ebce59 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -687,14 +687,14 @@ static int spapr_populate_drmem_v2(sPAPRMachineState *spapr, void *fdt, int offset, MemoryDeviceInfoList *dimms) { MachineState *machine = MACHINE(spapr); - uint8_t *int_buf, *cur_index, buf_len; + uint8_t *int_buf, *cur_index; int ret; uint64_t lmb_size = SPAPR_MEMORY_BLOCK_SIZE; uint64_t addr, cur_addr, size; uint32_t nr_boot_lmbs = (machine->device_memory->base / lmb_size); uint64_t mem_end = machine->device_memory->base + memory_region_size(&machine->device_memory->mr); - uint32_t node, nr_entries = 0; + uint32_t node, buf_len, nr_entries = 0; sPAPRDRConnector *drc; DrconfCellQueue *elem, *next; MemoryDeviceInfoList *info; -- cgit v1.2.3 From 2e66cdb715b2df674a9dd1b2899b958a46a98bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 13 Feb 2019 22:07:55 +0100 Subject: spapr/irq: add an 'nr_irq' parameter to initialize the backend. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When using the 'dual' interrupt mode, the source numbers of both sPAPR IRQ backends are aligned to share a common IRQ number space and to use a similar mapping of the machine qemu_irq array which is indexed by the source number. The XICS IRQ number range initially being [ 0x1000 - 0x2000 ], this requires to change the XICS ICSState offset to 0 and to provision for an extra 4K of source numbers and qemu_irqs which will never be used by the machine when running under the XICS interrupt mode. This is not an optimal solution. Change the init() method to allocate an IRQ number space of the expected size for the XICS sPAPR IRQ backend. It breaks the interrupt signaling when under the 'dual' mode because source numbers have unexpected values but next patch will fix that. Signed-off-by: Cédric Le Goater Message-Id: <20190213210756.27032-2-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 18 ++++++++++-------- include/hw/ppc/spapr_irq.h | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 80b0083b8e..da52a46e80 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -93,10 +93,10 @@ error: return NULL; } -static void spapr_irq_init_xics(sPAPRMachineState *spapr, Error **errp) +static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs, + Error **errp) { MachineState *machine = MACHINE(spapr); - int nr_irqs = spapr->irq->nr_irqs; Error *local_err = NULL; if (kvm_enabled()) { @@ -262,7 +262,8 @@ sPAPRIrq spapr_irq_xics = { /* * XIVE IRQ backend. */ -static void spapr_irq_init_xive(sPAPRMachineState *spapr, Error **errp) +static void spapr_irq_init_xive(sPAPRMachineState *spapr, int nr_irqs, + Error **errp) { MachineState *machine = MACHINE(spapr); uint32_t nr_servers = spapr_max_server_number(spapr); @@ -278,7 +279,7 @@ static void spapr_irq_init_xive(sPAPRMachineState *spapr, Error **errp) } dev = qdev_create(NULL, TYPE_SPAPR_XIVE); - qdev_prop_set_uint32(dev, "nr-irqs", spapr->irq->nr_irqs); + qdev_prop_set_uint32(dev, "nr-irqs", nr_irqs); /* * 8 XIVE END structures per CPU. One for each available priority */ @@ -435,7 +436,8 @@ static sPAPRIrq *spapr_irq_current(sPAPRMachineState *spapr) &spapr_irq_xive : &spapr_irq_xics; } -static void spapr_irq_init_dual(sPAPRMachineState *spapr, Error **errp) +static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs, + Error **errp) { MachineState *machine = MACHINE(spapr); Error *local_err = NULL; @@ -445,7 +447,7 @@ static void spapr_irq_init_dual(sPAPRMachineState *spapr, Error **errp) return; } - spapr_irq_xics.init(spapr, &local_err); + spapr_irq_xics.init(spapr, spapr_irq_xics.nr_irqs, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -462,7 +464,7 @@ static void spapr_irq_init_dual(sPAPRMachineState *spapr, Error **errp) */ spapr->ics->offset = 0; - spapr_irq_xive.init(spapr, &local_err); + spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -618,7 +620,7 @@ void spapr_irq_init(sPAPRMachineState *spapr, Error **errp) spapr_irq_msi_init(spapr, spapr->irq->nr_msis); } - spapr->irq->init(spapr, errp); + spapr->irq->init(spapr, spapr->irq->nr_irqs, errp); spapr->qirqs = qemu_allocate_irqs(spapr->irq->set_irq, spapr, spapr->irq->nr_irqs); diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 14b02c3aca..488511c3d8 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -35,7 +35,7 @@ typedef struct sPAPRIrq { uint32_t nr_msis; uint8_t ov5; - void (*init)(sPAPRMachineState *spapr, Error **errp); + void (*init)(sPAPRMachineState *spapr, int nr_irqs, Error **errp); int (*claim)(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp); void (*free)(sPAPRMachineState *spapr, int irq, int num); qemu_irq (*qirq)(sPAPRMachineState *spapr, int irq); -- cgit v1.2.3 From 3a0d802c170c74807c1957f076b555daad867a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Date: Wed, 13 Feb 2019 22:07:56 +0100 Subject: spapr/irq: remove the XICS offset adjustment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we have changed the XICS and the XIVE interrupt backend to have different size for their IRQ number space, we do not need to align their source numbers anymore. Remove the offset adjustment and wire the dual 'qirq' handler to the 'qirq' handler of the current interrupt mode in use. Signed-off-by: Cédric Le Goater Message-Id: <20190213210756.27032-3-clg@kaod.org> Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index da52a46e80..48d6b2daed 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -453,17 +453,6 @@ static void spapr_irq_init_dual(sPAPRMachineState *spapr, int nr_irqs, return; } - /* - * Align the XICS and the XIVE IRQ number space under QEMU. - * - * However, the XICS KVM device still considers that the IRQ - * numbers should start at XICS_IRQ_BASE (0x1000). Either we - * should introduce a KVM device ioctl to set the offset or ignore - * the lower 4K numbers when using the get/set ioctl of the XICS - * KVM device. The second option seems the least intrusive. - */ - spapr->ics->offset = 0; - spapr_irq_xive.init(spapr, spapr_irq_xive.nr_irqs, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -500,21 +489,7 @@ static void spapr_irq_free_dual(sPAPRMachineState *spapr, int irq, int num) static qemu_irq spapr_qirq_dual(sPAPRMachineState *spapr, int irq) { - sPAPRXive *xive = spapr->xive; - ICSState *ics = spapr->ics; - - if (irq >= spapr->irq->nr_irqs) { - return NULL; - } - - /* - * The IRQ number should have been claimed under both interrupt - * controllers. - */ - assert(!ICS_IRQ_FREE(ics, irq - ics->offset)); - assert(xive_eas_is_valid(&xive->eat[irq])); - - return spapr->qirqs[irq]; + return spapr_irq_current(spapr)->qirq(spapr, irq); } static void spapr_irq_print_info_dual(sPAPRMachineState *spapr, Monitor *mon) -- cgit v1.2.3 From 0e5c7fad9cdc5d431796f899b6a0e860ec93b611 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:39:48 +0100 Subject: xics: Explicitely call KVM ICP methods from the common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pre_save(), post_load() and synchronize_state() methods of the ICPStateClass type are really KVM only things. Make that obvious by dropping the indirections and directly calling the KVM functions instead. Signed-off-by: Greg Kurz Message-Id: <155023078871.1011724.3083923389814185598.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 24 +++++++++++------------- hw/intc/xics_kvm.c | 12 ++++-------- include/hw/ppc/xics.h | 9 +++++---- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 16e8ffa2aa..988b53abd1 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -37,18 +37,18 @@ #include "qapi/visitor.h" #include "monitor/monitor.h" #include "hw/intc/intc.h" +#include "sysemu/kvm.h" void icp_pic_print_info(ICPState *icp, Monitor *mon) { - ICPStateClass *icpc = ICP_GET_CLASS(icp); int cpu_index = icp->cs ? icp->cs->cpu_index : -1; if (!icp->output) { return; } - if (icpc->synchronize_state) { - icpc->synchronize_state(icp); + if (kvm_irqchip_in_kernel()) { + icp_synchronize_state(icp); } monitor_printf(mon, "CPU %d XIRR=%08x (%p) PP=%02x MFRR=%02x\n", @@ -252,25 +252,23 @@ static void icp_irq(ICSState *ics, int server, int nr, uint8_t priority) } } -static int icp_dispatch_pre_save(void *opaque) +static int icp_pre_save(void *opaque) { ICPState *icp = opaque; - ICPStateClass *info = ICP_GET_CLASS(icp); - if (info->pre_save) { - info->pre_save(icp); + if (kvm_irqchip_in_kernel()) { + icp_get_kvm_state(icp); } return 0; } -static int icp_dispatch_post_load(void *opaque, int version_id) +static int icp_post_load(void *opaque, int version_id) { ICPState *icp = opaque; - ICPStateClass *info = ICP_GET_CLASS(icp); - if (info->post_load) { - return info->post_load(icp, version_id); + if (kvm_irqchip_in_kernel()) { + return icp_set_kvm_state(icp); } return 0; @@ -280,8 +278,8 @@ static const VMStateDescription vmstate_icp_server = { .name = "icp/server", .version_id = 1, .minimum_version_id = 1, - .pre_save = icp_dispatch_pre_save, - .post_load = icp_dispatch_post_load, + .pre_save = icp_pre_save, + .post_load = icp_post_load, .fields = (VMStateField[]) { /* Sanity check */ VMSTATE_UINT32(xirr, ICPState), diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index dff1330050..7efa99b8b4 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -54,7 +54,7 @@ static QLIST_HEAD(, KVMEnabledICP) /* * ICP-KVM */ -static void icp_get_kvm_state(ICPState *icp) +void icp_get_kvm_state(ICPState *icp) { uint64_t state; int ret; @@ -83,14 +83,14 @@ static void do_icp_synchronize_state(CPUState *cpu, run_on_cpu_data arg) icp_get_kvm_state(arg.host_ptr); } -static void icp_synchronize_state(ICPState *icp) +void icp_synchronize_state(ICPState *icp) { if (icp->cs) { run_on_cpu(icp->cs, do_icp_synchronize_state, RUN_ON_CPU_HOST_PTR(icp)); } } -static int icp_set_kvm_state(ICPState *icp, int version_id) +int icp_set_kvm_state(ICPState *icp) { uint64_t state; int ret; @@ -121,7 +121,7 @@ static void icp_kvm_reset(DeviceState *dev) icpc->parent_reset(dev); - icp_set_kvm_state(ICP(dev), 1); + icp_set_kvm_state(ICP(dev)); } static void icp_kvm_realize(DeviceState *dev, Error **errp) @@ -178,10 +178,6 @@ static void icp_kvm_class_init(ObjectClass *klass, void *data) &icpc->parent_realize); device_class_set_parent_reset(dc, icp_kvm_reset, &icpc->parent_reset); - - icpc->pre_save = icp_get_kvm_state; - icpc->post_load = icp_set_kvm_state; - icpc->synchronize_state = icp_synchronize_state; } static const TypeInfo icp_kvm_info = { diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index fad786e8b2..3236ccec92 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -66,10 +66,6 @@ struct ICPStateClass { DeviceRealize parent_realize; DeviceReset parent_reset; - - void (*pre_save)(ICPState *icp); - int (*post_load)(ICPState *icp, int version_id); - void (*synchronize_state)(ICPState *icp); }; struct ICPState { @@ -203,4 +199,9 @@ void icp_resend(ICPState *ss); Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp); +/* KVM */ +void icp_get_kvm_state(ICPState *icp); +int icp_set_kvm_state(ICPState *icp); +void icp_synchronize_state(ICPState *icp); + #endif /* XICS_H */ -- cgit v1.2.3 From d82f397183b41f25e5a2e41c4af887f102de60ef Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:39:54 +0100 Subject: xics: Handle KVM ICP reset from the common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The KVM ICP reset handler simply writes the ICP state to KVM. This doesn't need the overkill parent_reset logic we have today. Call icp_set_kvm_state() from the base ICP reset function instead. Since there are no other users for ICPStateClass::parent_reset, and it isn't currently expected to change, drop it as well. Signed-off-by: Greg Kurz Message-Id: <155023079461.1011724.12644984391500635645.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 12 ++++-------- hw/intc/xics_kvm.c | 11 ----------- include/hw/ppc/xics.h | 1 - 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 988b53abd1..822d367e63 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -289,7 +289,7 @@ static const VMStateDescription vmstate_icp_server = { }, }; -static void icp_reset(DeviceState *dev) +static void icp_reset_handler(void *dev) { ICPState *icp = ICP(dev); @@ -299,13 +299,10 @@ static void icp_reset(DeviceState *dev) /* Make all outputs are deasserted */ qemu_set_irq(icp->output, 0); -} -static void icp_reset_handler(void *dev) -{ - DeviceClass *dc = DEVICE_GET_CLASS(dev); - - dc->reset(dev); + if (kvm_irqchip_in_kernel()) { + icp_set_kvm_state(ICP(dev)); + } } static void icp_realize(DeviceState *dev, Error **errp) @@ -370,7 +367,6 @@ static void icp_class_init(ObjectClass *klass, void *data) dc->realize = icp_realize; dc->unrealize = icp_unrealize; - dc->reset = icp_reset; } static const TypeInfo icp_info = { diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 7efa99b8b4..80321e9b75 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -115,15 +115,6 @@ int icp_set_kvm_state(ICPState *icp) return 0; } -static void icp_kvm_reset(DeviceState *dev) -{ - ICPStateClass *icpc = ICP_GET_CLASS(dev); - - icpc->parent_reset(dev); - - icp_set_kvm_state(ICP(dev)); -} - static void icp_kvm_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); @@ -176,8 +167,6 @@ static void icp_kvm_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, icp_kvm_realize, &icpc->parent_realize); - device_class_set_parent_reset(dc, icp_kvm_reset, - &icpc->parent_reset); } static const TypeInfo icp_kvm_info = { diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 3236ccec92..e33282a576 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -65,7 +65,6 @@ struct ICPStateClass { DeviceClass parent_class; DeviceRealize parent_realize; - DeviceReset parent_reset; }; struct ICPState { -- cgit v1.2.3 From 8e6e6efef7af41c4d809b6991927949f354836f7 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:00 +0100 Subject: xics: Handle KVM ICP realize from the common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The realization of KVM ICP currently follows the parent_realize logic, which is a bit overkill here. Also we want to get rid of the KVM ICP class. Explicitely call icp_kvm_realize() from the base ICP realize function. Note that ICPStateClass::parent_realize is retained because powernv needs it. Signed-off-by: Greg Kurz Message-Id: <155023080049.1011724.15423463482790260696.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 8 ++++++++ hw/intc/xics_kvm.c | 10 +--------- include/hw/ppc/xics.h | 1 + 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 822d367e63..acd63ab5e0 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -349,6 +349,14 @@ static void icp_realize(DeviceState *dev, Error **errp) return; } + if (kvm_irqchip_in_kernel()) { + icp_kvm_realize(dev, &err); + if (err) { + error_propagate(errp, err); + return; + } + } + qemu_register_reset(icp_reset_handler, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 80321e9b75..4eebced516 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -115,11 +115,9 @@ int icp_set_kvm_state(ICPState *icp) return 0; } -static void icp_kvm_realize(DeviceState *dev, Error **errp) +void icp_kvm_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); - ICPStateClass *icpc = ICP_GET_CLASS(icp); - Error *local_err = NULL; CPUState *cs; KVMEnabledICP *enabled_icp; unsigned long vcpu_id; @@ -129,12 +127,6 @@ static void icp_kvm_realize(DeviceState *dev, Error **errp) abort(); } - icpc->parent_realize(dev, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } - cs = icp->cs; vcpu_id = kvm_arch_vcpu_id(cs); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index e33282a576..ab61dc2401 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -202,5 +202,6 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, void icp_get_kvm_state(ICPState *icp); int icp_set_kvm_state(ICPState *icp); void icp_synchronize_state(ICPState *icp); +void icp_kvm_realize(DeviceState *dev, Error **errp); #endif /* XICS_H */ -- cgit v1.2.3 From 56af66566dc728d951cba9b9d6b9772259d43d8d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:06 +0100 Subject: spapr/irq: Use the base ICP class for KVM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The base ICP class knows how to interact with KVM. Adapt sPAPR to use it instead of the ICP KVM class. Signed-off-by: Greg Kurz Message-Id: <155023080638.1011724.792095453419098948.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 4 +--- include/hw/ppc/spapr.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 48d6b2daed..e6893df61e 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -102,7 +102,6 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs, if (kvm_enabled()) { if (machine_kernel_irqchip_allowed(machine) && !xics_kvm_init(spapr, &local_err)) { - spapr->icp_type = TYPE_KVM_ICP; spapr->ics = spapr_ics_create(spapr, TYPE_ICS_KVM, nr_irqs, &local_err); } @@ -117,7 +116,6 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs, if (!spapr->ics) { xics_spapr_init(spapr); - spapr->icp_type = TYPE_ICP; spapr->ics = spapr_ics_create(spapr, TYPE_ICS_SIMPLE, nr_irqs, &local_err); } @@ -199,7 +197,7 @@ static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr, Object *obj; sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu); - obj = icp_create(OBJECT(cpu), spapr->icp_type, XICS_FABRIC(spapr), + obj = icp_create(OBJECT(cpu), TYPE_ICP, XICS_FABRIC(spapr), &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index cbd276ed2b..631fc5103b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -178,7 +178,6 @@ struct sPAPRMachineState { /*< public >*/ char *kvm_type; - const char *icp_type; int32_t irq_map_nr; unsigned long *irq_map; sPAPRXive *xive; -- cgit v1.2.3 From 8c1ced677dd0d7ebe96abb634d7398cd64236b11 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:12 +0100 Subject: xics: Drop the KVM ICP class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The KVM ICP class isn't used anymore. Drop it. Signed-off-by: Greg Kurz Message-Id: <155023081228.1011724.12474992370439652538.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics_kvm.c | 18 ------------------ include/hw/ppc/xics.h | 3 --- 2 files changed, 21 deletions(-) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 4eebced516..fae4ac431f 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -152,23 +152,6 @@ void icp_kvm_realize(DeviceState *dev, Error **errp) QLIST_INSERT_HEAD(&kvm_enabled_icps, enabled_icp, node); } -static void icp_kvm_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - ICPStateClass *icpc = ICP_CLASS(klass); - - device_class_set_parent_realize(dc, icp_kvm_realize, - &icpc->parent_realize); -} - -static const TypeInfo icp_kvm_info = { - .name = TYPE_KVM_ICP, - .parent = TYPE_ICP, - .instance_size = sizeof(ICPState), - .class_init = icp_kvm_class_init, - .class_size = sizeof(ICPStateClass), -}; - /* * ICS-KVM */ @@ -425,7 +408,6 @@ fail: static void xics_kvm_register_types(void) { type_register_static(&ics_kvm_info); - type_register_static(&icp_kvm_info); } type_init(xics_kvm_register_types) diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index ab61dc2401..fae54e6f28 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -50,9 +50,6 @@ typedef struct XICSFabric XICSFabric; #define TYPE_ICP "icp" #define ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_ICP) -#define TYPE_KVM_ICP "icp-kvm" -#define KVM_ICP(obj) OBJECT_CHECK(ICPState, (obj), TYPE_KVM_ICP) - #define TYPE_PNV_ICP "pnv-icp" #define PNV_ICP(obj) OBJECT_CHECK(PnvICPState, (obj), TYPE_PNV_ICP) -- cgit v1.2.3 From d80b2ccfa741dd689634ce6c2b2a703d7d449319 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:18 +0100 Subject: xics: Explicitely call KVM ICS methods from the common code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pre_save(), post_load() and synchronize_state() methods of the ICSStateClass type are really KVM only things. Make that obvious by dropping the indirections and directly calling the KVM functions instead. Signed-off-by: Greg Kurz Message-Id: <155023081817.1011724.14078777320394028836.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 23 ++++++++++------------- hw/intc/xics_kvm.c | 12 ++++-------- include/hw/ppc/xics.h | 7 ++++--- 3 files changed, 18 insertions(+), 24 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index acd63ab5e0..ae5d5ea135 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -58,7 +58,6 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon) void ics_pic_print_info(ICSState *ics, Monitor *mon) { - ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics); uint32_t i; monitor_printf(mon, "ICS %4x..%4x %p\n", @@ -68,8 +67,8 @@ void ics_pic_print_info(ICSState *ics, Monitor *mon) return; } - if (icsc->synchronize_state) { - icsc->synchronize_state(ics); + if (kvm_irqchip_in_kernel()) { + ics_synchronize_state(ics); } for (i = 0; i < ics->nr_irqs; i++) { @@ -647,25 +646,23 @@ static void ics_base_instance_init(Object *obj) ics->offset = XICS_IRQ_BASE; } -static int ics_base_dispatch_pre_save(void *opaque) +static int ics_base_pre_save(void *opaque) { ICSState *ics = opaque; - ICSStateClass *info = ICS_BASE_GET_CLASS(ics); - if (info->pre_save) { - info->pre_save(ics); + if (kvm_irqchip_in_kernel()) { + ics_get_kvm_state(ics); } return 0; } -static int ics_base_dispatch_post_load(void *opaque, int version_id) +static int ics_base_post_load(void *opaque, int version_id) { ICSState *ics = opaque; - ICSStateClass *info = ICS_BASE_GET_CLASS(ics); - if (info->post_load) { - return info->post_load(ics, version_id); + if (kvm_irqchip_in_kernel()) { + return ics_set_kvm_state(ics); } return 0; @@ -689,8 +686,8 @@ static const VMStateDescription vmstate_ics_base = { .name = "ics", .version_id = 1, .minimum_version_id = 1, - .pre_save = ics_base_dispatch_pre_save, - .post_load = ics_base_dispatch_post_load, + .pre_save = ics_base_pre_save, + .post_load = ics_base_post_load, .fields = (VMStateField[]) { /* Sanity check */ VMSTATE_UINT32_EQUAL(nr_irqs, ICSState, NULL), diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index fae4ac431f..642351e579 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -155,7 +155,7 @@ void icp_kvm_realize(DeviceState *dev, Error **errp) /* * ICS-KVM */ -static void ics_get_kvm_state(ICSState *ics) +void ics_get_kvm_state(ICSState *ics) { uint64_t state; int i; @@ -208,12 +208,12 @@ static void ics_get_kvm_state(ICSState *ics) } } -static void ics_synchronize_state(ICSState *ics) +void ics_synchronize_state(ICSState *ics) { ics_get_kvm_state(ics); } -static int ics_set_kvm_state(ICSState *ics, int version_id) +int ics_set_kvm_state(ICSState *ics) { uint64_t state; int i; @@ -286,7 +286,7 @@ static void ics_kvm_reset(DeviceState *dev) icsc->parent_reset(dev); - ics_set_kvm_state(ICS_KVM(dev), 1); + ics_set_kvm_state(ICS_KVM(dev)); } static void ics_kvm_reset_handler(void *dev) @@ -318,10 +318,6 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data) &icsc->parent_realize); device_class_set_parent_reset(dc, ics_kvm_reset, &icsc->parent_reset); - - icsc->pre_save = ics_get_kvm_state; - icsc->post_load = ics_set_kvm_state; - icsc->synchronize_state = ics_synchronize_state; } static const TypeInfo ics_kvm_info = { diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index fae54e6f28..06e87128f8 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -109,12 +109,9 @@ struct ICSStateClass { DeviceRealize parent_realize; DeviceReset parent_reset; - void (*pre_save)(ICSState *s); - int (*post_load)(ICSState *s, int version_id); void (*reject)(ICSState *s, uint32_t irq); void (*resend)(ICSState *s); void (*eoi)(ICSState *s, uint32_t irq); - void (*synchronize_state)(ICSState *s); }; struct ICSState { @@ -201,4 +198,8 @@ int icp_set_kvm_state(ICPState *icp); void icp_synchronize_state(ICPState *icp); void icp_kvm_realize(DeviceState *dev, Error **errp); +void ics_get_kvm_state(ICSState *ics); +int ics_set_kvm_state(ICSState *ics); +void ics_synchronize_state(ICSState *ics); + #endif /* XICS_H */ -- cgit v1.2.3 From f1f5b701b8978f7d783c3582252a3475c762800d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:24 +0100 Subject: xics: Handle KVM ICS reset from the "simple" ICS code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The KVM ICS reset handler simply writes the ICS state to KVM. This doesn't need the overkill parent_reset logic we have today. Also we want to use the same ICS type for the KVM and non-KVM case with pseries. Call icp_set_kvm_state() from the "simple" ICS reset function. Signed-off-by: Greg Kurz Message-Id: <155023082407.1011724.1983100830860273401.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics.c | 4 ++++ hw/intc/xics_kvm.c | 18 ------------------ 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index ae5d5ea135..49401745c4 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -553,6 +553,10 @@ static void ics_simple_reset(DeviceState *dev) ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); icsc->parent_reset(dev); + + if (kvm_irqchip_in_kernel()) { + ics_set_kvm_state(ICS_BASE(dev)); + } } static void ics_simple_reset_handler(void *dev) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index 642351e579..e7b8d4c29c 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -280,20 +280,6 @@ void ics_kvm_set_irq(void *opaque, int srcno, int val) } } -static void ics_kvm_reset(DeviceState *dev) -{ - ICSStateClass *icsc = ICS_BASE_GET_CLASS(dev); - - icsc->parent_reset(dev); - - ics_set_kvm_state(ICS_KVM(dev)); -} - -static void ics_kvm_reset_handler(void *dev) -{ - ics_kvm_reset(dev); -} - static void ics_kvm_realize(DeviceState *dev, Error **errp) { ICSState *ics = ICS_KVM(dev); @@ -305,8 +291,6 @@ static void ics_kvm_realize(DeviceState *dev, Error **errp) error_propagate(errp, local_err); return; } - - qemu_register_reset(ics_kvm_reset_handler, ics); } static void ics_kvm_class_init(ObjectClass *klass, void *data) @@ -316,8 +300,6 @@ static void ics_kvm_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, ics_kvm_realize, &icsc->parent_realize); - device_class_set_parent_reset(dc, ics_kvm_reset, - &icsc->parent_reset); } static const TypeInfo ics_kvm_info = { -- cgit v1.2.3 From 557b4567298a6952de347a4fb7676ff44775f495 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:30 +0100 Subject: xics: Handle KVM interrupt presentation from "simple" ICS code We want to use the "simple" ICS type in both KVM and non-KVM setups. Teach the "simple" ICS how to present interrupts to KVM and adapt sPAPR accordingly. Signed-off-by: Greg Kurz Message-Id: <155023082996.1011724.16237920586343905010.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/intc/xics.c | 5 +++++ hw/intc/xics_kvm.c | 3 +-- hw/ppc/spapr_irq.c | 7 +------ include/hw/ppc/xics.h | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 49401745c4..3009fa7472 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -466,6 +466,11 @@ void ics_simple_set_irq(void *opaque, int srcno, int val) { ICSState *ics = (ICSState *)opaque; + if (kvm_irqchip_in_kernel()) { + ics_kvm_set_irq(ics, srcno, val); + return; + } + if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) { ics_simple_set_irq_lsi(ics, srcno, val); } else { diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index e7b8d4c29c..f34eacda03 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -259,9 +259,8 @@ int ics_set_kvm_state(ICSState *ics) return 0; } -void ics_kvm_set_irq(void *opaque, int srcno, int val) +void ics_kvm_set_irq(ICSState *ics, int srcno, int val) { - ICSState *ics = opaque; struct kvm_irq_level args; int rc; diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index e6893df61e..9f43b7b3bf 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -222,13 +222,8 @@ static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id) static void spapr_irq_set_irq_xics(void *opaque, int srcno, int val) { sPAPRMachineState *spapr = opaque; - MachineState *machine = MACHINE(opaque); - if (kvm_enabled() && machine_kernel_irqchip_allowed(machine)) { - ics_kvm_set_irq(spapr->ics, srcno, val); - } else { - ics_simple_set_irq(spapr->ics, srcno, val); - } + ics_simple_set_irq(spapr->ics, srcno, val); } static void spapr_irq_reset_xics(sPAPRMachineState *spapr, Error **errp) diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 06e87128f8..61bd0fb978 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -180,7 +180,6 @@ void icp_eoi(ICPState *icp, uint32_t xirr); void ics_simple_write_xive(ICSState *ics, int nr, int server, uint8_t priority, uint8_t saved_priority); void ics_simple_set_irq(void *opaque, int srcno, int val); -void ics_kvm_set_irq(void *opaque, int srcno, int val); void ics_set_irq_type(ICSState *ics, int srcno, bool lsi); void icp_pic_print_info(ICPState *icp, Monitor *mon); @@ -201,5 +200,6 @@ void icp_kvm_realize(DeviceState *dev, Error **errp); void ics_get_kvm_state(ICSState *ics); int ics_set_kvm_state(ICSState *ics); void ics_synchronize_state(ICSState *ics); +void ics_kvm_set_irq(ICSState *ics, int srcno, int val); #endif /* XICS_H */ -- cgit v1.2.3 From 444d6ca301d97de141a502851940943b09a9ebee Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:35 +0100 Subject: spapr/irq: Use the "simple" ICS class for KVM The "simple" ICS class knows how to interract with KVM. Adapt sPAPR to use it instead of the ICS KVM class. Signed-off-by: Greg Kurz Message-Id: <155023083585.1011724.2868047424353921455.stgit@bahia.lan> Signed-off-by: David Gibson --- hw/ppc/spapr_irq.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 9f43b7b3bf..4aa8165307 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -67,13 +67,12 @@ void spapr_irq_msi_reset(sPAPRMachineState *spapr) */ static ICSState *spapr_ics_create(sPAPRMachineState *spapr, - const char *type_ics, int nr_irqs, Error **errp) { Error *local_err = NULL; Object *obj; - obj = object_new(type_ics); + obj = object_new(TYPE_ICS_SIMPLE); object_property_add_child(OBJECT(spapr), "ics", obj, &error_abort); object_property_add_const_link(obj, ICS_PROP_XICS, OBJECT(spapr), &error_abort); @@ -98,14 +97,14 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs, { MachineState *machine = MACHINE(spapr); Error *local_err = NULL; + bool xics_kvm = false; if (kvm_enabled()) { if (machine_kernel_irqchip_allowed(machine) && !xics_kvm_init(spapr, &local_err)) { - spapr->ics = spapr_ics_create(spapr, TYPE_ICS_KVM, nr_irqs, - &local_err); + xics_kvm = true; } - if (machine_kernel_irqchip_required(machine) && !spapr->ics) { + if (machine_kernel_irqchip_required(machine) && !xics_kvm) { error_prepend(&local_err, "kernel_irqchip requested but unavailable: "); goto error; @@ -114,12 +113,12 @@ static void spapr_irq_init_xics(sPAPRMachineState *spapr, int nr_irqs, local_err = NULL; } - if (!spapr->ics) { + if (!xics_kvm) { xics_spapr_init(spapr); - spapr->ics = spapr_ics_create(spapr, TYPE_ICS_SIMPLE, nr_irqs, - &local_err); } + spapr->ics = spapr_ics_create(spapr, nr_irqs, &local_err); + error: error_propagate(errp, local_err); } -- cgit v1.2.3 From 3272752a8b51cd91d8633048bf6f844117a4879c Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 15 Feb 2019 12:40:41 +0100 Subject: xics: Drop the KVM ICS class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The KVM ICS class isn't used anymore. Drop it. Signed-off-by: Greg Kurz Message-Id: <155023084177.1011724.14693955932559990358.stgit@bahia.lan> Reviewed-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/intc/xics_kvm.c | 40 ---------------------------------------- hw/ppc/spapr_irq.c | 2 +- include/hw/ppc/xics.h | 3 --- 3 files changed, 1 insertion(+), 44 deletions(-) diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c index f34eacda03..a00d0a7962 100644 --- a/hw/intc/xics_kvm.c +++ b/hw/intc/xics_kvm.c @@ -279,39 +279,6 @@ void ics_kvm_set_irq(ICSState *ics, int srcno, int val) } } -static void ics_kvm_realize(DeviceState *dev, Error **errp) -{ - ICSState *ics = ICS_KVM(dev); - ICSStateClass *icsc = ICS_BASE_GET_CLASS(ics); - Error *local_err = NULL; - - icsc->parent_realize(dev, &local_err); - if (local_err) { - error_propagate(errp, local_err); - return; - } -} - -static void ics_kvm_class_init(ObjectClass *klass, void *data) -{ - ICSStateClass *icsc = ICS_BASE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - - device_class_set_parent_realize(dc, ics_kvm_realize, - &icsc->parent_realize); -} - -static const TypeInfo ics_kvm_info = { - .name = TYPE_ICS_KVM, - .parent = TYPE_ICS_BASE, - .instance_size = sizeof(ICSState), - .class_init = ics_kvm_class_init, -}; - -/* - * XICS-KVM - */ - static void rtas_dummy(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, @@ -381,10 +348,3 @@ fail: kvmppc_define_rtas_kernel_token(0, "ibm,int-off"); return -1; } - -static void xics_kvm_register_types(void) -{ - type_register_static(&ics_kvm_info); -} - -type_init(xics_kvm_register_types) diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 4aa8165307..4297eed600 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -208,7 +208,7 @@ static void spapr_irq_cpu_intc_create_xics(sPAPRMachineState *spapr, static int spapr_irq_post_load_xics(sPAPRMachineState *spapr, int version_id) { - if (!object_dynamic_cast(OBJECT(spapr->ics), TYPE_ICS_KVM)) { + if (!kvm_irqchip_in_kernel()) { CPUState *cs; CPU_FOREACH(cs) { PowerPCCPU *cpu = POWERPC_CPU(cs); diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h index 61bd0fb978..d36bbe11ee 100644 --- a/include/hw/ppc/xics.h +++ b/include/hw/ppc/xics.h @@ -95,9 +95,6 @@ struct PnvICPState { #define TYPE_ICS_SIMPLE "ics" #define ICS_SIMPLE(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_SIMPLE) -#define TYPE_ICS_KVM "icskvm" -#define ICS_KVM(obj) OBJECT_CHECK(ICSState, (obj), TYPE_ICS_KVM) - #define ICS_BASE_CLASS(klass) \ OBJECT_CLASS_CHECK(ICSStateClass, (klass), TYPE_ICS_BASE) #define ICS_BASE_GET_CLASS(obj) \ -- cgit v1.2.3 From 50d24aedb3ecd872a0bcb8ac3a644721b593f6df Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 15 Feb 2019 10:00:42 +0000 Subject: target/ppc: convert VMX logical instructions to use vector operations Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate.c | 1 + target/ppc/translate/vmx-impl.inc.c | 47 +++++++++++++------------------------ 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index d5f29d3536..f4d70e725a 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -24,6 +24,7 @@ #include "disas/disas.h" #include "exec/exec-all.h" #include "tcg-op.h" +#include "tcg-op-gvec.h" #include "qemu/host-utils.h" #include "exec/cpu_ldst.h" diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index f99d0284c2..c74932e5ee 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -266,45 +266,30 @@ GEN_VX_VMUL10(vmul10euq, 1, 0); GEN_VX_VMUL10(vmul10cuq, 0, 1); GEN_VX_VMUL10(vmul10ecuq, 1, 1); -/* Logical operations */ -#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ +#define GEN_VXFORM_V(name, vece, tcg_op, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) \ { \ - TCGv_i64 t0; \ - TCGv_i64 t1; \ - TCGv_i64 avr; \ - \ if (unlikely(!ctx->altivec_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ - t0 = tcg_temp_new_i64(); \ - t1 = tcg_temp_new_i64(); \ - avr = tcg_temp_new_i64(); \ - \ - get_avr64(t0, rA(ctx->opcode), true); \ - get_avr64(t1, rB(ctx->opcode), true); \ - tcg_op(avr, t0, t1); \ - set_avr64(rD(ctx->opcode), avr, true); \ - \ - get_avr64(t0, rA(ctx->opcode), false); \ - get_avr64(t1, rB(ctx->opcode), false); \ - tcg_op(avr, t0, t1); \ - set_avr64(rD(ctx->opcode), avr, false); \ \ - tcg_temp_free_i64(t0); \ - tcg_temp_free_i64(t1); \ - tcg_temp_free_i64(avr); \ + tcg_op(vece, \ + avr64_offset(rD(ctx->opcode), true), \ + avr64_offset(rA(ctx->opcode), true), \ + avr64_offset(rB(ctx->opcode), true), \ + 16, 16); \ } -GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16); -GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17); -GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18); -GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19); -GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20); -GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26); -GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22); -GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21); +/* Logical operations */ +GEN_VXFORM_V(vand, MO_64, tcg_gen_gvec_and, 2, 16); +GEN_VXFORM_V(vandc, MO_64, tcg_gen_gvec_andc, 2, 17); +GEN_VXFORM_V(vor, MO_64, tcg_gen_gvec_or, 2, 18); +GEN_VXFORM_V(vxor, MO_64, tcg_gen_gvec_xor, 2, 19); +GEN_VXFORM_V(vnor, MO_64, tcg_gen_gvec_nor, 2, 20); +GEN_VXFORM_V(veqv, MO_64, tcg_gen_gvec_eqv, 2, 26); +GEN_VXFORM_V(vnand, MO_64, tcg_gen_gvec_nand, 2, 22); +GEN_VXFORM_V(vorc, MO_64, tcg_gen_gvec_orc, 2, 21); #define GEN_VXFORM(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ -- cgit v1.2.3 From 3e942a1a8025f694ff0e78b947c3bd57ec06d655 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 15 Feb 2019 10:00:43 +0000 Subject: target/ppc: convert vaddu[b,h,w,d] and vsubu[b,h,w,d] over to use vector operations Signed-off-by: Mark Cave-Ayland Reviewed-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 8 -------- target/ppc/int_helper.c | 7 ------- target/ppc/translate/vmx-impl.inc.c | 16 ++++++++-------- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index c7de04e068..553ff500c8 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -108,14 +108,6 @@ DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64) #define dh_ctype_avr ppc_avr_t * #define dh_is_signed_avr dh_is_signed_ptr -DEF_HELPER_3(vaddubm, void, avr, avr, avr) -DEF_HELPER_3(vadduhm, void, avr, avr, avr) -DEF_HELPER_3(vadduwm, void, avr, avr, avr) -DEF_HELPER_3(vaddudm, void, avr, avr, avr) -DEF_HELPER_3(vsububm, void, avr, avr, avr) -DEF_HELPER_3(vsubuhm, void, avr, avr, avr) -DEF_HELPER_3(vsubuwm, void, avr, avr, avr) -DEF_HELPER_3(vsubudm, void, avr, avr, avr) DEF_HELPER_3(vavgub, void, avr, avr, avr) DEF_HELPER_3(vavguh, void, avr, avr, avr) DEF_HELPER_3(vavguw, void, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 8efc283388..ffccda8b9b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -515,13 +515,6 @@ void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b) r->element[i] = a->element[i] op b->element[i]; \ } \ } -#define VARITH(suffix, element) \ - VARITH_DO(add##suffix, +, element) \ - VARITH_DO(sub##suffix, -, element) -VARITH(ubm, u8) -VARITH(uhm, u16) -VARITH(uwm, u32) -VARITH(udm, u64) VARITH_DO(muluwm, *, u32) #undef VARITH_DO #undef VARITH diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index c74932e5ee..b104c6e38e 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -395,18 +395,18 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_ptr(rb); \ } -GEN_VXFORM(vaddubm, 0, 0); +GEN_VXFORM_V(vaddubm, MO_8, tcg_gen_gvec_add, 0, 0); GEN_VXFORM_DUAL_EXT(vaddubm, PPC_ALTIVEC, PPC_NONE, 0, \ vmul10cuq, PPC_NONE, PPC2_ISA300, 0x0000F800) -GEN_VXFORM(vadduhm, 0, 1); +GEN_VXFORM_V(vadduhm, MO_16, tcg_gen_gvec_add, 0, 1); GEN_VXFORM_DUAL(vadduhm, PPC_ALTIVEC, PPC_NONE, \ vmul10ecuq, PPC_NONE, PPC2_ISA300) -GEN_VXFORM(vadduwm, 0, 2); -GEN_VXFORM(vaddudm, 0, 3); -GEN_VXFORM(vsububm, 0, 16); -GEN_VXFORM(vsubuhm, 0, 17); -GEN_VXFORM(vsubuwm, 0, 18); -GEN_VXFORM(vsubudm, 0, 19); +GEN_VXFORM_V(vadduwm, MO_32, tcg_gen_gvec_add, 0, 2); +GEN_VXFORM_V(vaddudm, MO_64, tcg_gen_gvec_add, 0, 3); +GEN_VXFORM_V(vsububm, MO_8, tcg_gen_gvec_sub, 0, 16); +GEN_VXFORM_V(vsubuhm, MO_16, tcg_gen_gvec_sub, 0, 17); +GEN_VXFORM_V(vsubuwm, MO_32, tcg_gen_gvec_sub, 0, 18); +GEN_VXFORM_V(vsubudm, MO_64, tcg_gen_gvec_sub, 0, 19); GEN_VXFORM(vmaxub, 1, 0); GEN_VXFORM(vmaxuh, 1, 1); GEN_VXFORM(vmaxuw, 1, 2); -- cgit v1.2.3 From 471ff3d0257135b938d0a5f2181f22cd753d50de Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:44 +0000 Subject: target/ppc: convert vspltis[bhw] to use vector operations Signed-off-by: Richard Henderson Message-Id: <20190215100058.20015-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 3 --- target/ppc/int_helper.c | 15 --------------- target/ppc/translate/vmx-impl.inc.c | 36 ++++++++---------------------------- 3 files changed, 8 insertions(+), 46 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 553ff500c8..2aa60e5d36 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -246,9 +246,6 @@ DEF_HELPER_3(vrld, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) -DEF_HELPER_2(vspltisb, void, avr, i32) -DEF_HELPER_2(vspltish, void, avr, i32) -DEF_HELPER_2(vspltisw, void, avr, i32) DEF_HELPER_3(vspltb, void, avr, avr, i32) DEF_HELPER_3(vsplth, void, avr, avr, i32) DEF_HELPER_3(vspltw, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index ffccda8b9b..2f793a3543 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1998,21 +1998,6 @@ VNEG(vnegw, s32) VNEG(vnegd, s64) #undef VNEG -#define VSPLTI(suffix, element, splat_type) \ - void helper_vspltis##suffix(ppc_avr_t *r, uint32_t splat) \ - { \ - splat_type x = (int8_t)(splat << 3) >> 3; \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - r->element[i] = x; \ - } \ - } -VSPLTI(b, s8, int8_t) -VSPLTI(h, s16, int16_t) -VSPLTI(w, s32, int32_t) -#undef VSPLTI - #define VSR(suffix, element, mask) \ void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index b104c6e38e..c26c342e16 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -704,25 +704,21 @@ GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \ GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \ vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207) -#define GEN_VXFORM_SIMM(name, opc2, opc3) \ +#define GEN_VXFORM_DUPI(name, tcg_op, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ - TCGv_ptr rd; \ - TCGv_i32 simm; \ + int simm; \ if (unlikely(!ctx->altivec_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VPU); \ return; \ } \ - simm = tcg_const_i32(SIMM5(ctx->opcode)); \ - rd = gen_avr_ptr(rD(ctx->opcode)); \ - gen_helper_##name (rd, simm); \ - tcg_temp_free_i32(simm); \ - tcg_temp_free_ptr(rd); \ + simm = SIMM5(ctx->opcode); \ + tcg_op(avr64_offset(rD(ctx->opcode), true), 16, 16, simm); \ } -GEN_VXFORM_SIMM(vspltisb, 6, 12); -GEN_VXFORM_SIMM(vspltish, 6, 13); -GEN_VXFORM_SIMM(vspltisw, 6, 14); +GEN_VXFORM_DUPI(vspltisb, tcg_gen_gvec_dup8i, 6, 12); +GEN_VXFORM_DUPI(vspltish, tcg_gen_gvec_dup16i, 6, 13); +GEN_VXFORM_DUPI(vspltisw, tcg_gen_gvec_dup32i, 6, 14); #define GEN_VXFORM_NOA(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ @@ -802,22 +798,6 @@ GEN_VXFORM_NOA(vprtybw, 1, 24); GEN_VXFORM_NOA(vprtybd, 1, 24); GEN_VXFORM_NOA(vprtybq, 1, 24); -#define GEN_VXFORM_SIMM(name, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ - { \ - TCGv_ptr rd; \ - TCGv_i32 simm; \ - if (unlikely(!ctx->altivec_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_VPU); \ - return; \ - } \ - simm = tcg_const_i32(SIMM5(ctx->opcode)); \ - rd = gen_avr_ptr(rD(ctx->opcode)); \ - gen_helper_##name (rd, simm); \ - tcg_temp_free_i32(simm); \ - tcg_temp_free_ptr(rd); \ - } - #define GEN_VXFORM_UIMM(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ @@ -1240,7 +1220,7 @@ GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE, #undef GEN_VXRFORM_DUAL #undef GEN_VXRFORM1 #undef GEN_VXRFORM -#undef GEN_VXFORM_SIMM +#undef GEN_VXFORM_DUPI #undef GEN_VXFORM_NOA #undef GEN_VXFORM_UIMM #undef GEN_VAFORM_PAIRED -- cgit v1.2.3 From 0f6a6d5db853c0cbe438c1831c70710bfb6530ee Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:45 +0000 Subject: target/ppc: convert vsplt[bhw] to use vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-5-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 3 --- target/ppc/int_helper.c | 19 --------------- target/ppc/translate/vmx-impl.inc.c | 46 ++++++++++++++++++++++--------------- 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 2aa60e5d36..069daa9883 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -246,9 +246,6 @@ DEF_HELPER_3(vrld, void, avr, avr, avr) DEF_HELPER_3(vsl, void, avr, avr, avr) DEF_HELPER_3(vsr, void, avr, avr, avr) DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32) -DEF_HELPER_3(vspltb, void, avr, avr, i32) -DEF_HELPER_3(vsplth, void, avr, avr, i32) -DEF_HELPER_3(vspltw, void, avr, avr, i32) DEF_HELPER_3(vextractub, void, avr, avr, i32) DEF_HELPER_3(vextractuh, void, avr, avr, i32) DEF_HELPER_3(vextractuw, void, avr, avr, i32) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 2f793a3543..5c9623e952 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1869,25 +1869,6 @@ void helper_vslo(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -/* Experimental testing shows that hardware masks the immediate. */ -#define _SPLAT_MASKED(element) (splat & (ARRAY_SIZE(r->element) - 1)) -#define SPLAT_ELEMENT(element) _SPLAT_MASKED(element) -#define VSPLT(suffix, element, access) \ - void helper_vsplt##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \ - { \ - uint32_t s = b->access(SPLAT_ELEMENT(element)); \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - r->access(i) = s; \ - } \ - } -VSPLT(b, u8, VsrB) -VSPLT(h, u16, VsrH) -VSPLT(w, u32, VsrW) -#undef VSPLT -#undef SPLAT_ELEMENT -#undef _SPLAT_MASKED #if defined(HOST_WORDS_BIGENDIAN) #define VINSERT(suffix, element) \ void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index c26c342e16..41ddbd879f 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -798,24 +798,32 @@ GEN_VXFORM_NOA(vprtybw, 1, 24); GEN_VXFORM_NOA(vprtybd, 1, 24); GEN_VXFORM_NOA(vprtybq, 1, 24); -#define GEN_VXFORM_UIMM(name, opc2, opc3) \ -static void glue(gen_, name)(DisasContext *ctx) \ - { \ - TCGv_ptr rb, rd; \ - TCGv_i32 uimm; \ - if (unlikely(!ctx->altivec_enabled)) { \ - gen_exception(ctx, POWERPC_EXCP_VPU); \ - return; \ - } \ - uimm = tcg_const_i32(UIMM5(ctx->opcode)); \ - rb = gen_avr_ptr(rB(ctx->opcode)); \ - rd = gen_avr_ptr(rD(ctx->opcode)); \ - gen_helper_##name (rd, rb, uimm); \ - tcg_temp_free_i32(uimm); \ - tcg_temp_free_ptr(rb); \ - tcg_temp_free_ptr(rd); \ +static void gen_vsplt(DisasContext *ctx, int vece) +{ + int uimm, dofs, bofs; + + if (unlikely(!ctx->altivec_enabled)) { + gen_exception(ctx, POWERPC_EXCP_VPU); + return; } + uimm = UIMM5(ctx->opcode); + bofs = avr64_offset(rB(ctx->opcode), true); + dofs = avr64_offset(rD(ctx->opcode), true); + + /* Experimental testing shows that hardware masks the immediate. */ + bofs += (uimm << vece) & 15; +#ifndef HOST_WORDS_BIGENDIAN + bofs ^= 15; + bofs &= ~((1 << vece) - 1); +#endif + + tcg_gen_gvec_dup_mem(vece, dofs, bofs, 16, 16); +} + +#define GEN_VXFORM_VSPLT(name, vece, opc2, opc3) \ +static void glue(gen_, name)(DisasContext *ctx) { gen_vsplt(ctx, vece); } + #define GEN_VXFORM_UIMM_ENV(name, opc2, opc3) \ static void glue(gen_, name)(DisasContext *ctx) \ { \ @@ -858,9 +866,9 @@ static void glue(gen_, name)(DisasContext *ctx) \ tcg_temp_free_ptr(rd); \ } -GEN_VXFORM_UIMM(vspltb, 6, 8); -GEN_VXFORM_UIMM(vsplth, 6, 9); -GEN_VXFORM_UIMM(vspltw, 6, 10); +GEN_VXFORM_VSPLT(vspltb, MO_8, 6, 8); +GEN_VXFORM_VSPLT(vsplth, MO_16, 6, 9); +GEN_VXFORM_VSPLT(vspltw, MO_32, 6, 10); GEN_VXFORM_UIMM_SPLAT(vextractub, 6, 8, 15); GEN_VXFORM_UIMM_SPLAT(vextractuh, 6, 9, 14); GEN_VXFORM_UIMM_SPLAT(vextractuw, 6, 10, 12); -- cgit v1.2.3 From 7b8fe477e12b164dda97f79e27b55b805d90384f Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:46 +0000 Subject: target/ppc: convert VSX logical operations to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-6-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate/vsx-impl.inc.c | 43 +++++++++++++++---------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index ed4fdceacf..2576d81ac5 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -10,6 +10,11 @@ static inline void set_vsr(int n, TCGv_i64 src) tcg_gen_st_i64(src, cpu_env, offsetof(CPUPPCState, vsr[n].u64[1])); } +static inline int vsr_full_offset(int n) +{ + return offsetof(CPUPPCState, vsr[n].u64[0]); +} + static inline void get_cpu_vsrh(TCGv_i64 dst, int n) { if (n < 32) { @@ -1255,40 +1260,26 @@ static void gen_xxbrw(DisasContext *ctx) tcg_temp_free_i64(xbl); } -#define VSX_LOGICAL(name, tcg_op) \ +#define VSX_LOGICAL(name, vece, tcg_op) \ static void glue(gen_, name)(DisasContext * ctx) \ { \ - TCGv_i64 t0; \ - TCGv_i64 t1; \ - TCGv_i64 t2; \ if (unlikely(!ctx->vsx_enabled)) { \ gen_exception(ctx, POWERPC_EXCP_VSXU); \ return; \ } \ - t0 = tcg_temp_new_i64(); \ - t1 = tcg_temp_new_i64(); \ - t2 = tcg_temp_new_i64(); \ - get_cpu_vsrh(t0, xA(ctx->opcode)); \ - get_cpu_vsrh(t1, xB(ctx->opcode)); \ - tcg_op(t2, t0, t1); \ - set_cpu_vsrh(xT(ctx->opcode), t2); \ - get_cpu_vsrl(t0, xA(ctx->opcode)); \ - get_cpu_vsrl(t1, xB(ctx->opcode)); \ - tcg_op(t2, t0, t1); \ - set_cpu_vsrl(xT(ctx->opcode), t2); \ - tcg_temp_free_i64(t0); \ - tcg_temp_free_i64(t1); \ - tcg_temp_free_i64(t2); \ + tcg_op(vece, vsr_full_offset(xT(ctx->opcode)), \ + vsr_full_offset(xA(ctx->opcode)), \ + vsr_full_offset(xB(ctx->opcode)), 16, 16); \ } -VSX_LOGICAL(xxland, tcg_gen_and_i64) -VSX_LOGICAL(xxlandc, tcg_gen_andc_i64) -VSX_LOGICAL(xxlor, tcg_gen_or_i64) -VSX_LOGICAL(xxlxor, tcg_gen_xor_i64) -VSX_LOGICAL(xxlnor, tcg_gen_nor_i64) -VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64) -VSX_LOGICAL(xxlnand, tcg_gen_nand_i64) -VSX_LOGICAL(xxlorc, tcg_gen_orc_i64) +VSX_LOGICAL(xxland, MO_64, tcg_gen_gvec_and) +VSX_LOGICAL(xxlandc, MO_64, tcg_gen_gvec_andc) +VSX_LOGICAL(xxlor, MO_64, tcg_gen_gvec_or) +VSX_LOGICAL(xxlxor, MO_64, tcg_gen_gvec_xor) +VSX_LOGICAL(xxlnor, MO_64, tcg_gen_gvec_nor) +VSX_LOGICAL(xxleqv, MO_64, tcg_gen_gvec_eqv) +VSX_LOGICAL(xxlnand, MO_64, tcg_gen_gvec_nand) +VSX_LOGICAL(xxlorc, MO_64, tcg_gen_gvec_orc) #define VSX_XXMRG(name, high) \ static void glue(gen_, name)(DisasContext * ctx) \ -- cgit v1.2.3 From cf95e701fe14478ad25fe7a71da0199a602c6af1 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:47 +0000 Subject: target/ppc: convert xxspltib to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-7-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate/vsx-impl.inc.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 2576d81ac5..944fc0608a 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1397,9 +1397,10 @@ static void gen_xxspltw(DisasContext *ctx) static void gen_xxspltib(DisasContext *ctx) { - unsigned char uim8 = IMM8(ctx->opcode); - TCGv_i64 vsr; - if (xS(ctx->opcode) < 32) { + uint8_t uim8 = IMM8(ctx->opcode); + int rt = xT(ctx->opcode); + + if (rt < 32) { if (unlikely(!ctx->altivec_enabled)) { gen_exception(ctx, POWERPC_EXCP_VPU); return; @@ -1410,11 +1411,7 @@ static void gen_xxspltib(DisasContext *ctx) return; } } - vsr = tcg_temp_new_i64(); - tcg_gen_movi_i64(vsr, pattern(uim8)); - set_cpu_vsrh(xT(ctx->opcode), vsr); - set_cpu_vsrl(xT(ctx->opcode), vsr); - tcg_temp_free_i64(vsr); + tcg_gen_gvec_dup8i(vsr_full_offset(rt), 16, 16, uim8); } static void gen_xxsldwi(DisasContext *ctx) -- cgit v1.2.3 From 9bb0048ec6f8f3bcc144b2c5769d9301e824f946 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:48 +0000 Subject: target/ppc: convert xxspltw to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-8-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate/vsx-impl.inc.c | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 944fc0608a..0e8cecb00a 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1359,38 +1359,24 @@ static void gen_xxsel(DisasContext * ctx) static void gen_xxspltw(DisasContext *ctx) { - TCGv_i64 b, b2; - TCGv_i64 vsr; + int rt = xT(ctx->opcode); + int rb = xB(ctx->opcode); + int uim = UIM(ctx->opcode); + int tofs, bofs; if (unlikely(!ctx->vsx_enabled)) { gen_exception(ctx, POWERPC_EXCP_VSXU); return; } - vsr = tcg_temp_new_i64(); - if (UIM(ctx->opcode) & 2) { - get_cpu_vsrl(vsr, xB(ctx->opcode)); - } else { - get_cpu_vsrh(vsr, xB(ctx->opcode)); - } - - b = tcg_temp_new_i64(); - b2 = tcg_temp_new_i64(); - - if (UIM(ctx->opcode) & 1) { - tcg_gen_ext32u_i64(b, vsr); - } else { - tcg_gen_shri_i64(b, vsr, 32); - } - - tcg_gen_shli_i64(b2, b, 32); - tcg_gen_or_i64(vsr, b, b2); - set_cpu_vsrh(xT(ctx->opcode), vsr); - set_cpu_vsrl(xT(ctx->opcode), vsr); + tofs = vsr_full_offset(rt); + bofs = vsr_full_offset(rb); + bofs += uim << MO_32; +#ifndef HOST_WORDS_BIG_ENDIAN + bofs ^= 8 | 4; +#endif - tcg_temp_free_i64(vsr); - tcg_temp_free_i64(b); - tcg_temp_free_i64(b2); + tcg_gen_gvec_dup_mem(MO_32, tofs, bofs, 16, 16); } #define pattern(x) (((x) & 0xff) * (~(uint64_t)0 / 0xff)) -- cgit v1.2.3 From 03dce230db4b66a4c4fa4173a46d40f182d59b18 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:49 +0000 Subject: target/ppc: convert xxsel to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-9-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate/vsx-impl.inc.c | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 0e8cecb00a..e73197e717 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -1321,40 +1321,39 @@ static void glue(gen_, name)(DisasContext * ctx) \ VSX_XXMRG(xxmrghw, 1) VSX_XXMRG(xxmrglw, 0) -static void gen_xxsel(DisasContext * ctx) +static void xxsel_i64(TCGv_i64 t, TCGv_i64 a, TCGv_i64 b, TCGv_i64 c) { - TCGv_i64 a, b, c, tmp; - if (unlikely(!ctx->vsx_enabled)) { - gen_exception(ctx, POWERPC_EXCP_VSXU); - return; - } - a = tcg_temp_new_i64(); - b = tcg_temp_new_i64(); - c = tcg_temp_new_i64(); - tmp = tcg_temp_new_i64(); - - get_cpu_vsrh(a, xA(ctx->opcode)); - get_cpu_vsrh(b, xB(ctx->opcode)); - get_cpu_vsrh(c, xC(ctx->opcode)); - tcg_gen_and_i64(b, b, c); tcg_gen_andc_i64(a, a, c); - tcg_gen_or_i64(tmp, a, b); - set_cpu_vsrh(xT(ctx->opcode), tmp); + tcg_gen_or_i64(t, a, b); +} - get_cpu_vsrl(a, xA(ctx->opcode)); - get_cpu_vsrl(b, xB(ctx->opcode)); - get_cpu_vsrl(c, xC(ctx->opcode)); +static void xxsel_vec(unsigned vece, TCGv_vec t, TCGv_vec a, + TCGv_vec b, TCGv_vec c) +{ + tcg_gen_and_vec(vece, b, b, c); + tcg_gen_andc_vec(vece, a, a, c); + tcg_gen_or_vec(vece, t, a, b); +} - tcg_gen_and_i64(b, b, c); - tcg_gen_andc_i64(a, a, c); - tcg_gen_or_i64(tmp, a, b); - set_cpu_vsrl(xT(ctx->opcode), tmp); +static void gen_xxsel(DisasContext *ctx) +{ + static const GVecGen4 g = { + .fni8 = xxsel_i64, + .fniv = xxsel_vec, + .vece = MO_64, + }; + int rt = xT(ctx->opcode); + int ra = xA(ctx->opcode); + int rb = xB(ctx->opcode); + int rc = xC(ctx->opcode); - tcg_temp_free_i64(a); - tcg_temp_free_i64(b); - tcg_temp_free_i64(c); - tcg_temp_free_i64(tmp); + if (unlikely(!ctx->vsx_enabled)) { + gen_exception(ctx, POWERPC_EXCP_VSXU); + return; + } + tcg_gen_gvec_4(vsr_full_offset(rt), vsr_full_offset(ra), + vsr_full_offset(rb), vsr_full_offset(rc), 16, 16, &g); } static void gen_xxspltw(DisasContext *ctx) -- cgit v1.2.3 From dedfaac74e239c66646bd9851e05fc07380b20b7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:50 +0000 Subject: target/ppc: Pass integer to helper_mtvscr We can re-use this helper elsewhere if we're not passing in an entire vector register. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-10-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 2 +- target/ppc/int_helper.c | 6 +++--- target/ppc/translate/vmx-impl.inc.c | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 069daa9883..b3ffe28103 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -294,7 +294,7 @@ DEF_HELPER_5(vmsumuhs, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr) DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) -DEF_HELPER_2(mtvscr, void, env, avr) +DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) DEF_HELPER_3(lvebx, void, env, avr, tl) DEF_HELPER_3(lvehx, void, env, avr, tl) DEF_HELPER_3(lvewx, void, env, avr, tl) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 5c9623e952..aa6ad2ce7e 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -457,10 +457,10 @@ void helper_lvsr(ppc_avr_t *r, target_ulong sh) } } -void helper_mtvscr(CPUPPCState *env, ppc_avr_t *r) +void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { - env->vscr = r->VsrW(3); - set_flush_to_zero(vscr_nj, &env->vec_status); + env->vscr = vscr; + set_flush_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status); } void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 41ddbd879f..182d3fc563 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -196,14 +196,23 @@ static void gen_mfvscr(DisasContext *ctx) static void gen_mtvscr(DisasContext *ctx) { - TCGv_ptr p; + TCGv_i32 val; + int bofs; + if (unlikely(!ctx->altivec_enabled)) { gen_exception(ctx, POWERPC_EXCP_VPU); return; } - p = gen_avr_ptr(rB(ctx->opcode)); - gen_helper_mtvscr(cpu_env, p); - tcg_temp_free_ptr(p); + + val = tcg_temp_new_i32(); + bofs = avr64_offset(rB(ctx->opcode), true); +#ifdef HOST_WORDS_BIGENDIAN + bofs += 3 * 4; +#endif + + tcg_gen_ld_i32(val, cpu_env, bofs); + gen_helper_mtvscr(cpu_env, val); + tcg_temp_free_i32(val); } #define GEN_VX_VMUL10(name, add_cin, ret_carry) \ -- cgit v1.2.3 From c5ba06a391127647d4b5d40f8261bad070a80821 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:51 +0000 Subject: target/ppc: Use helper_mtvscr for reset and gdb Not setting flush_to_zero from gdb_set_avr_reg was a bug. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-11-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/translate_init.inc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index c9985c0d22..ee574b342e 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -601,10 +601,9 @@ static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) static inline void vscr_init(CPUPPCState *env, uint32_t val) { - env->vscr = val; /* Altivec always uses round-to-nearest */ set_float_rounding_mode(float_round_nearest_even, &env->vec_status); - set_flush_to_zero(vscr_nj, &env->vec_status); + helper_mtvscr(env, val); } #ifdef CONFIG_USER_ONLY @@ -9603,7 +9602,7 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) } if (n == 32) { ppc_maybe_bswap_register(env, mem_buf, 4); - env->vscr = ldl_p(mem_buf); + helper_mtvscr(env, ldl_p(mem_buf)); return 4; } if (n == 33) { -- cgit v1.2.3 From be13d3026abe5a0dcd12c9639658a87a3b417769 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:52 +0000 Subject: target/ppc: Remove vscr_nj and vscr_sat These macros are no longer used. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-12-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/cpu.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 78af7e4608..1c883fa836 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -689,8 +689,6 @@ enum { /* Vector status and control register */ #define VSCR_NJ 16 /* Vector non-java */ #define VSCR_SAT 0 /* Vector saturation */ -#define vscr_nj (((env->vscr) >> VSCR_NJ) & 0x1) -#define vscr_sat (((env->vscr) >> VSCR_SAT) & 0x1) /*****************************************************************************/ /* BookE e500 MMU registers */ -- cgit v1.2.3 From cc2b90d7251c1aa4ace5a3058a7529c9887ab1e5 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:53 +0000 Subject: target/ppc: Add helper_mfvscr This is required before changing the representation of the register. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-13-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/arch_dump.c | 3 ++- target/ppc/helper.h | 1 + target/ppc/int_helper.c | 5 +++++ target/ppc/translate/vmx-impl.inc.c | 2 +- target/ppc/translate_init.inc.c | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/target/ppc/arch_dump.c b/target/ppc/arch_dump.c index 3a00606d01..9ab04b2c38 100644 --- a/target/ppc/arch_dump.c +++ b/target/ppc/arch_dump.c @@ -17,6 +17,7 @@ #include "elf.h" #include "sysemu/dump.h" #include "sysemu/kvm.h" +#include "exec/helper-proto.h" #ifdef TARGET_PPC64 #define ELFCLASS ELFCLASS64 @@ -175,7 +176,7 @@ static void ppc_write_elf_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu) vmxregset->avr[i].u64[1] = avr->u64[1]; } } - vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr); + vmxregset->vscr.u32[3] = cpu_to_dump32(s, helper_mfvscr(&cpu->env)); } static void ppc_write_elf_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index b3ffe28103..7dbb08b9dd 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -295,6 +295,7 @@ DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr) DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr) DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_2(mtvscr, TCG_CALL_NO_RWG, void, env, i32) +DEF_HELPER_FLAGS_1(mfvscr, TCG_CALL_NO_RWG, i32, env) DEF_HELPER_3(lvebx, void, env, avr, tl) DEF_HELPER_3(lvehx, void, env, avr, tl) DEF_HELPER_3(lvewx, void, env, avr, tl) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index aa6ad2ce7e..ec3ef9ff3f 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -463,6 +463,11 @@ void helper_mtvscr(CPUPPCState *env, uint32_t vscr) set_flush_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status); } +uint32_t helper_mfvscr(CPUPPCState *env) +{ + return env->vscr; +} + void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 182d3fc563..5e13edbf53 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -187,7 +187,7 @@ static void gen_mfvscr(DisasContext *ctx) tcg_gen_movi_i64(avr, 0); set_avr64(rD(ctx->opcode), avr, true); t = tcg_temp_new_i32(); - tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr)); + gen_helper_mfvscr(t, cpu_env); tcg_gen_extu_i32_i64(avr, t); set_avr64(rD(ctx->opcode), avr, false); tcg_temp_free_i32(t); diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c index ee574b342e..1657d88341 100644 --- a/target/ppc/translate_init.inc.c +++ b/target/ppc/translate_init.inc.c @@ -9573,7 +9573,7 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 16; } if (n == 32) { - stl_p(mem_buf, env->vscr); + stl_p(mem_buf, helper_mfvscr(env)); ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } -- cgit v1.2.3 From 596fff20d02b349820b30024fd15dd3efd61d164 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:54 +0000 Subject: target/ppc: Use mtvscr/mfvscr for vmstate This is required before changing the representation of the register. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-14-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/machine.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/target/ppc/machine.c b/target/ppc/machine.c index eff30053b0..756b6d2971 100644 --- a/target/ppc/machine.c +++ b/target/ppc/machine.c @@ -10,6 +10,7 @@ #include "migration/cpu.h" #include "qapi/error.h" #include "kvm_ppc.h" +#include "exec/helper-proto.h" static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { @@ -17,7 +18,7 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) CPUPPCState *env = &cpu->env; unsigned int i, j; target_ulong sdr1; - uint32_t fpscr; + uint32_t fpscr, vscr; #if defined(TARGET_PPC64) int32_t slb_nr; #endif @@ -84,7 +85,8 @@ static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) if (!cpu->vhyp) { ppc_store_sdr1(env, sdr1); } - qemu_get_be32s(f, &env->vscr); + qemu_get_be32s(f, &vscr); + helper_mtvscr(env, vscr); qemu_get_be64s(f, &env->spe_acc); qemu_get_be32s(f, &env->spe_fscr); qemu_get_betls(f, &env->msr_mask); @@ -429,6 +431,28 @@ static bool altivec_needed(void *opaque) return (cpu->env.insns_flags & PPC_ALTIVEC); } +static int get_vscr(QEMUFile *f, void *opaque, size_t size, + const VMStateField *field) +{ + PowerPCCPU *cpu = opaque; + helper_mtvscr(&cpu->env, qemu_get_be32(f)); + return 0; +} + +static int put_vscr(QEMUFile *f, void *opaque, size_t size, + const VMStateField *field, QJSON *vmdesc) +{ + PowerPCCPU *cpu = opaque; + qemu_put_be32(f, helper_mfvscr(&cpu->env)); + return 0; +} + +static const VMStateInfo vmstate_vscr = { + .name = "cpu/altivec/vscr", + .get = get_vscr, + .put = put_vscr, +}; + static const VMStateDescription vmstate_altivec = { .name = "cpu/altivec", .version_id = 1, @@ -436,7 +460,21 @@ static const VMStateDescription vmstate_altivec = { .needed = altivec_needed, .fields = (VMStateField[]) { VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32), - VMSTATE_UINT32(env.vscr, PowerPCCPU), + /* + * Save the architecture value of the vscr, not the internally + * expanded version. Since this architecture value does not + * exist in memory to be stored, this requires a but of hoop + * jumping. We want OFFSET=0 so that we effectively pass CPU + * to the helper functions. + */ + { + .name = "vscr", + .version_id = 0, + .size = sizeof(uint32_t), + .info = &vmstate_vscr, + .flags = VMS_SINGLE, + .offset = 0 + }, VMSTATE_END_OF_LIST() }, }; -- cgit v1.2.3 From 6175f5a058eb077fb4dd94c79e8ef961bb4dba69 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:55 +0000 Subject: target/ppc: Add set_vscr_sat This is required before changing the representation of the register. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-15-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/int_helper.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index ec3ef9ff3f..1d8a4b530b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -468,6 +468,11 @@ uint32_t helper_mfvscr(CPUPPCState *env) return env->vscr; } +static inline void set_vscr_sat(CPUPPCState *env) +{ + env->vscr |= 1 << VSCR_SAT; +} + void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; @@ -581,7 +586,7 @@ VARITHFPFMA(nmsubfp, float_muladd_negate_result | float_muladd_negate_c); } \ } \ if (sat) { \ - env->vscr |= (1 << VSCR_SAT); \ + set_vscr_sat(env); \ } \ } #define VARITHSAT_SIGNED(suffix, element, optype, cvt) \ @@ -853,7 +858,7 @@ void helper_vcmpbfp_dot(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } \ } \ if (sat) { \ - env->vscr |= (1 << VSCR_SAT); \ + set_vscr_sat(env); \ } \ } VCT(uxs, cvtsduw, u32) @@ -900,7 +905,7 @@ void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -917,7 +922,7 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -1029,7 +1034,7 @@ void helper_vmsumshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -1082,7 +1087,7 @@ void helper_vmsumuhs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -1599,7 +1604,7 @@ void helper_vpkpx(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } \ *r = result; \ if (dosat && sat) { \ - env->vscr |= (1 << VSCR_SAT); \ + set_vscr_sat(env); \ } \ } #define I(x, y) (x) @@ -2043,7 +2048,7 @@ void helper_vsumsws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) *r = result; if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -2066,7 +2071,7 @@ void helper_vsum2sws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) *r = result; if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -2085,7 +2090,7 @@ void helper_vsum4sbs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -2102,7 +2107,7 @@ void helper_vsum4shs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } @@ -2121,7 +2126,7 @@ void helper_vsum4ubs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } if (sat) { - env->vscr |= (1 << VSCR_SAT); + set_vscr_sat(env); } } -- cgit v1.2.3 From 9b5b74da0a07a89ef71c7f7da0b36560a3bac521 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:56 +0000 Subject: target/ppc: Split out VSCR_SAT to a vector field Change the representation of VSCR_SAT such that it is easy to set from vector code. Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-16-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/cpu.h | 4 +++- target/ppc/int_helper.c | 11 ++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 1c883fa836..325ebbeb98 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1052,10 +1052,12 @@ struct CPUPPCState { /* Special purpose registers */ target_ulong spr[1024]; ppc_spr_t spr_cb[1024]; - /* Vector status and control register */ + /* Vector status and control register, minus VSCR_SAT. */ uint32_t vscr; /* VSX registers (including FP and AVR) */ ppc_vsr_t vsr[64] QEMU_ALIGNED(16); + /* Non-zero if and only if VSCR_SAT should be set. */ + ppc_vsr_t vscr_sat QEMU_ALIGNED(16); /* SPE registers */ uint64_t spe_acc; uint32_t spe_fscr; diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 1d8a4b530b..6ad596a08b 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -459,18 +459,23 @@ void helper_lvsr(ppc_avr_t *r, target_ulong sh) void helper_mtvscr(CPUPPCState *env, uint32_t vscr) { - env->vscr = vscr; + env->vscr = vscr & ~(1u << VSCR_SAT); + /* Which bit we set is completely arbitrary, but clear the rest. */ + env->vscr_sat.u64[0] = vscr & (1u << VSCR_SAT); + env->vscr_sat.u64[1] = 0; set_flush_to_zero((vscr >> VSCR_NJ) & 1, &env->vec_status); } uint32_t helper_mfvscr(CPUPPCState *env) { - return env->vscr; + uint32_t sat = (env->vscr_sat.u64[0] | env->vscr_sat.u64[1]) != 0; + return env->vscr | (sat << VSCR_SAT); } static inline void set_vscr_sat(CPUPPCState *env) { - env->vscr |= 1 << VSCR_SAT; + /* The choice of non-zero value is arbitrary. */ + env->vscr_sat.u32[0] = 1; } void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) -- cgit v1.2.3 From fb11ae7daae19e022f37f0508cae0e106304d167 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:57 +0000 Subject: target/ppc: convert vadd*s and vsub*s to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-17-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 24 ++++++++-------- target/ppc/int_helper.c | 18 +++--------- target/ppc/translate/vmx-impl.inc.c | 57 +++++++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 7dbb08b9dd..3daf6bf863 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -219,18 +219,18 @@ DEF_HELPER_2(vprtybq, void, avr, avr) DEF_HELPER_3(vsubcuw, void, avr, avr, avr) DEF_HELPER_2(lvsl, void, avr, tl) DEF_HELPER_2(lvsr, void, avr, tl) -DEF_HELPER_4(vaddsbs, void, env, avr, avr, avr) -DEF_HELPER_4(vaddshs, void, env, avr, avr, avr) -DEF_HELPER_4(vaddsws, void, env, avr, avr, avr) -DEF_HELPER_4(vsubsbs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubshs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubsws, void, env, avr, avr, avr) -DEF_HELPER_4(vaddubs, void, env, avr, avr, avr) -DEF_HELPER_4(vadduhs, void, env, avr, avr, avr) -DEF_HELPER_4(vadduws, void, env, avr, avr, avr) -DEF_HELPER_4(vsububs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubuhs, void, env, avr, avr, avr) -DEF_HELPER_4(vsubuws, void, env, avr, avr, avr) +DEF_HELPER_FLAGS_5(vaddsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubsbs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubshs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubsws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vaddubs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vadduhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vadduws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsububs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubuhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) +DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_3(vadduqm, void, avr, avr, avr) DEF_HELPER_4(vaddecuq, void, avr, avr, avr, avr) DEF_HELPER_4(vaddeuqm, void, avr, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 6ad596a08b..4aeb375edd 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -571,27 +571,17 @@ VARITHFPFMA(nmsubfp, float_muladd_negate_result | float_muladd_negate_c); } #define VARITHSAT_DO(name, op, optype, cvt, element) \ - void helper_v##name(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, \ - ppc_avr_t *b) \ + void helper_v##name(ppc_avr_t *r, ppc_avr_t *vscr_sat, \ + ppc_avr_t *a, ppc_avr_t *b, uint32_t desc) \ { \ int sat = 0; \ int i; \ \ for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - switch (sizeof(r->element[0])) { \ - case 1: \ - VARITHSAT_CASE(optype, op, cvt, element); \ - break; \ - case 2: \ - VARITHSAT_CASE(optype, op, cvt, element); \ - break; \ - case 4: \ - VARITHSAT_CASE(optype, op, cvt, element); \ - break; \ - } \ + VARITHSAT_CASE(optype, op, cvt, element); \ } \ if (sat) { \ - set_vscr_sat(env); \ + vscr_sat->u32[0] = 1; \ } \ } #define VARITHSAT_SIGNED(suffix, element, optype, cvt) \ diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 5e13edbf53..62c5578070 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -552,22 +552,55 @@ GEN_VXFORM(vslo, 6, 16); GEN_VXFORM(vsro, 6, 17); GEN_VXFORM(vaddcuw, 0, 6); GEN_VXFORM(vsubcuw, 0, 22); -GEN_VXFORM_ENV(vaddubs, 0, 8); + +#define GEN_VXFORM_SAT(NAME, VECE, NORM, SAT, OPC2, OPC3) \ +static void glue(glue(gen_, NAME), _vec)(unsigned vece, TCGv_vec t, \ + TCGv_vec sat, TCGv_vec a, \ + TCGv_vec b) \ +{ \ + TCGv_vec x = tcg_temp_new_vec_matching(t); \ + glue(glue(tcg_gen_, NORM), _vec)(VECE, x, a, b); \ + glue(glue(tcg_gen_, SAT), _vec)(VECE, t, a, b); \ + tcg_gen_cmp_vec(TCG_COND_NE, VECE, x, x, t); \ + tcg_gen_or_vec(VECE, sat, sat, x); \ + tcg_temp_free_vec(x); \ +} \ +static void glue(gen_, NAME)(DisasContext *ctx) \ +{ \ + static const GVecGen4 g = { \ + .fniv = glue(glue(gen_, NAME), _vec), \ + .fno = glue(gen_helper_, NAME), \ + .opc = glue(glue(INDEX_op_, SAT), _vec), \ + .write_aofs = true, \ + .vece = VECE, \ + }; \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + tcg_gen_gvec_4(avr64_offset(rD(ctx->opcode), true), \ + offsetof(CPUPPCState, vscr_sat), \ + avr64_offset(rA(ctx->opcode), true), \ + avr64_offset(rB(ctx->opcode), true), \ + 16, 16, &g); \ +} + +GEN_VXFORM_SAT(vaddubs, MO_8, add, usadd, 0, 8); GEN_VXFORM_DUAL_EXT(vaddubs, PPC_ALTIVEC, PPC_NONE, 0, \ vmul10uq, PPC_NONE, PPC2_ISA300, 0x0000F800) -GEN_VXFORM_ENV(vadduhs, 0, 9); +GEN_VXFORM_SAT(vadduhs, MO_16, add, usadd, 0, 9); GEN_VXFORM_DUAL(vadduhs, PPC_ALTIVEC, PPC_NONE, \ vmul10euq, PPC_NONE, PPC2_ISA300) -GEN_VXFORM_ENV(vadduws, 0, 10); -GEN_VXFORM_ENV(vaddsbs, 0, 12); -GEN_VXFORM_ENV(vaddshs, 0, 13); -GEN_VXFORM_ENV(vaddsws, 0, 14); -GEN_VXFORM_ENV(vsububs, 0, 24); -GEN_VXFORM_ENV(vsubuhs, 0, 25); -GEN_VXFORM_ENV(vsubuws, 0, 26); -GEN_VXFORM_ENV(vsubsbs, 0, 28); -GEN_VXFORM_ENV(vsubshs, 0, 29); -GEN_VXFORM_ENV(vsubsws, 0, 30); +GEN_VXFORM_SAT(vadduws, MO_32, add, usadd, 0, 10); +GEN_VXFORM_SAT(vaddsbs, MO_8, add, ssadd, 0, 12); +GEN_VXFORM_SAT(vaddshs, MO_16, add, ssadd, 0, 13); +GEN_VXFORM_SAT(vaddsws, MO_32, add, ssadd, 0, 14); +GEN_VXFORM_SAT(vsububs, MO_8, sub, ussub, 0, 24); +GEN_VXFORM_SAT(vsubuhs, MO_16, sub, ussub, 0, 25); +GEN_VXFORM_SAT(vsubuws, MO_32, sub, ussub, 0, 26); +GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); +GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); +GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); GEN_VXFORM(vadduqm, 0, 4); GEN_VXFORM(vaddcuq, 0, 5); GEN_VXFORM3(vaddeuqm, 30, 0); -- cgit v1.2.3 From 73e14c6a9cdefb94c01ea488f04e7fba7ac0dc5b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 15 Feb 2019 10:00:58 +0000 Subject: target/ppc: convert vmin* and vmax* to vector operations Signed-off-by: Richard Henderson Acked-by: David Gibson Message-Id: <20190215100058.20015-18-mark.cave-ayland@ilande.co.uk> Signed-off-by: David Gibson --- target/ppc/helper.h | 16 ---------------- target/ppc/int_helper.c | 27 --------------------------- target/ppc/translate/vmx-impl.inc.c | 32 ++++++++++++++++---------------- 3 files changed, 16 insertions(+), 59 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 3daf6bf863..18910d18a4 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -117,22 +117,6 @@ DEF_HELPER_3(vabsduw, void, avr, avr, avr) DEF_HELPER_3(vavgsb, void, avr, avr, avr) DEF_HELPER_3(vavgsh, void, avr, avr, avr) DEF_HELPER_3(vavgsw, void, avr, avr, avr) -DEF_HELPER_3(vminsb, void, avr, avr, avr) -DEF_HELPER_3(vminsh, void, avr, avr, avr) -DEF_HELPER_3(vminsw, void, avr, avr, avr) -DEF_HELPER_3(vminsd, void, avr, avr, avr) -DEF_HELPER_3(vmaxsb, void, avr, avr, avr) -DEF_HELPER_3(vmaxsh, void, avr, avr, avr) -DEF_HELPER_3(vmaxsw, void, avr, avr, avr) -DEF_HELPER_3(vmaxsd, void, avr, avr, avr) -DEF_HELPER_3(vminub, void, avr, avr, avr) -DEF_HELPER_3(vminuh, void, avr, avr, avr) -DEF_HELPER_3(vminuw, void, avr, avr, avr) -DEF_HELPER_3(vminud, void, avr, avr, avr) -DEF_HELPER_3(vmaxub, void, avr, avr, avr) -DEF_HELPER_3(vmaxuh, void, avr, avr, avr) -DEF_HELPER_3(vmaxuw, void, avr, avr, avr) -DEF_HELPER_3(vmaxud, void, avr, avr, avr) DEF_HELPER_4(vcmpequb, void, env, avr, avr, avr) DEF_HELPER_4(vcmpequh, void, env, avr, avr, avr) DEF_HELPER_4(vcmpequw, void, env, avr, avr, avr) diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 4aeb375edd..162add561e 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -921,33 +921,6 @@ void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, } } -#define VMINMAX_DO(name, compare, element) \ - void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ - { \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ - if (a->element[i] compare b->element[i]) { \ - r->element[i] = b->element[i]; \ - } else { \ - r->element[i] = a->element[i]; \ - } \ - } \ - } -#define VMINMAX(suffix, element) \ - VMINMAX_DO(min##suffix, >, element) \ - VMINMAX_DO(max##suffix, <, element) -VMINMAX(sb, s8) -VMINMAX(sh, s16) -VMINMAX(sw, s32) -VMINMAX(sd, s64) -VMINMAX(ub, u8) -VMINMAX(uh, u16) -VMINMAX(uw, u32) -VMINMAX(ud, u64) -#undef VMINMAX_DO -#undef VMINMAX - void helper_vmladduhm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int i; diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c index 62c5578070..f1b15ae2cb 100644 --- a/target/ppc/translate/vmx-impl.inc.c +++ b/target/ppc/translate/vmx-impl.inc.c @@ -416,22 +416,22 @@ GEN_VXFORM_V(vsububm, MO_8, tcg_gen_gvec_sub, 0, 16); GEN_VXFORM_V(vsubuhm, MO_16, tcg_gen_gvec_sub, 0, 17); GEN_VXFORM_V(vsubuwm, MO_32, tcg_gen_gvec_sub, 0, 18); GEN_VXFORM_V(vsubudm, MO_64, tcg_gen_gvec_sub, 0, 19); -GEN_VXFORM(vmaxub, 1, 0); -GEN_VXFORM(vmaxuh, 1, 1); -GEN_VXFORM(vmaxuw, 1, 2); -GEN_VXFORM(vmaxud, 1, 3); -GEN_VXFORM(vmaxsb, 1, 4); -GEN_VXFORM(vmaxsh, 1, 5); -GEN_VXFORM(vmaxsw, 1, 6); -GEN_VXFORM(vmaxsd, 1, 7); -GEN_VXFORM(vminub, 1, 8); -GEN_VXFORM(vminuh, 1, 9); -GEN_VXFORM(vminuw, 1, 10); -GEN_VXFORM(vminud, 1, 11); -GEN_VXFORM(vminsb, 1, 12); -GEN_VXFORM(vminsh, 1, 13); -GEN_VXFORM(vminsw, 1, 14); -GEN_VXFORM(vminsd, 1, 15); +GEN_VXFORM_V(vmaxub, MO_8, tcg_gen_gvec_umax, 1, 0); +GEN_VXFORM_V(vmaxuh, MO_16, tcg_gen_gvec_umax, 1, 1); +GEN_VXFORM_V(vmaxuw, MO_32, tcg_gen_gvec_umax, 1, 2); +GEN_VXFORM_V(vmaxud, MO_64, tcg_gen_gvec_umax, 1, 3); +GEN_VXFORM_V(vmaxsb, MO_8, tcg_gen_gvec_smax, 1, 4); +GEN_VXFORM_V(vmaxsh, MO_16, tcg_gen_gvec_smax, 1, 5); +GEN_VXFORM_V(vmaxsw, MO_32, tcg_gen_gvec_smax, 1, 6); +GEN_VXFORM_V(vmaxsd, MO_64, tcg_gen_gvec_smax, 1, 7); +GEN_VXFORM_V(vminub, MO_8, tcg_gen_gvec_umin, 1, 8); +GEN_VXFORM_V(vminuh, MO_16, tcg_gen_gvec_umin, 1, 9); +GEN_VXFORM_V(vminuw, MO_32, tcg_gen_gvec_umin, 1, 10); +GEN_VXFORM_V(vminud, MO_64, tcg_gen_gvec_umin, 1, 11); +GEN_VXFORM_V(vminsb, MO_8, tcg_gen_gvec_smin, 1, 12); +GEN_VXFORM_V(vminsh, MO_16, tcg_gen_gvec_smin, 1, 13); +GEN_VXFORM_V(vminsw, MO_32, tcg_gen_gvec_smin, 1, 14); +GEN_VXFORM_V(vminsd, MO_64, tcg_gen_gvec_smin, 1, 15); GEN_VXFORM(vavgub, 1, 16); GEN_VXFORM(vabsdub, 1, 16); GEN_VXFORM_DUAL(vavgub, PPC_ALTIVEC, PPC_NONE, \ -- cgit v1.2.3