From 58803318e5a546b2eb0efd7a053ed36b6c29ae6f Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Tue, 31 Oct 2017 11:50:50 +0000 Subject: fix WFI/WFE length in syndrome register WFI/E are often, but not always, 4 bytes long. When they are, we need to set ARM_EL_IL_SHIFT in the syndrome register. Pass the instruction length to HELPER(wfi), use it to decrement pc appropriately and to pass an is_16bit flag to syn_wfx, which sets ARM_EL_IL_SHIFT if needed. Set dc->insn in both arm_tr_translate_insn and thumb_tr_translate_insn. Signed-off-by: Stefano Stabellini Message-id: alpine.DEB.2.10.1710241055160.574@sstabellini-ThinkPad-X260 [PMM: move setting of dc->insn for Thumb so it is correct for 32 bit insns] Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- target/arm/helper.h | 2 +- target/arm/internals.h | 3 ++- target/arm/op_helper.c | 7 ++++--- target/arm/psci.c | 2 +- target/arm/translate-a64.c | 7 ++++++- target/arm/translate.c | 10 +++++++++- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/target/arm/helper.h b/target/arm/helper.h index 2cf6f74152..439d228420 100644 --- a/target/arm/helper.h +++ b/target/arm/helper.h @@ -48,7 +48,7 @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE, DEF_HELPER_2(exception_internal, void, env, i32) DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32) DEF_HELPER_1(setend, void, env) -DEF_HELPER_1(wfi, void, env) +DEF_HELPER_2(wfi, void, env, i32) DEF_HELPER_1(wfe, void, env) DEF_HELPER_1(yield, void, env) DEF_HELPER_1(pre_hvc, void, env) diff --git a/target/arm/internals.h b/target/arm/internals.h index 43106a2d6c..d9cc75e4c5 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -428,9 +428,10 @@ static inline uint32_t syn_breakpoint(int same_el) | ARM_EL_IL | 0x22; } -static inline uint32_t syn_wfx(int cv, int cond, int ti) +static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit) { return (EC_WFX_TRAP << ARM_EL_EC_SHIFT) | + (is_16bit ? 0 : (1 << ARM_EL_IL_SHIFT)) | (cv << 24) | (cond << 20) | ti; } diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 138d0df82f..a40a84ac24 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -463,7 +463,7 @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) return 0; } -void HELPER(wfi)(CPUARMState *env) +void HELPER(wfi)(CPUARMState *env, uint32_t insn_len) { CPUState *cs = CPU(arm_env_get_cpu(env)); int target_el = check_wfx_trap(env, false); @@ -476,8 +476,9 @@ void HELPER(wfi)(CPUARMState *env) } if (target_el) { - env->pc -= 4; - raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0), target_el); + env->pc -= insn_len; + raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2), + target_el); } cs->exception_index = EXCP_HLT; diff --git a/target/arm/psci.c b/target/arm/psci.c index fc34b263d3..eb7b88e926 100644 --- a/target/arm/psci.c +++ b/target/arm/psci.c @@ -189,7 +189,7 @@ void arm_handle_psci_call(ARMCPU *cpu) } else { env->regs[0] = 0; } - helper_wfi(env); + helper_wfi(env, 4); break; case QEMU_PSCI_0_1_FN_MIGRATE: case QEMU_PSCI_0_2_FN_MIGRATE: diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index e98fbcf261..caca05aa41 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -11400,17 +11400,22 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) gen_helper_yield(cpu_env); break; case DISAS_WFI: + { /* This is a special case because we don't want to just halt the CPU * if trying to debug across a WFI. */ + TCGv_i32 tmp = tcg_const_i32(4); + gen_a64_set_pc_im(dc->pc); - gen_helper_wfi(cpu_env); + gen_helper_wfi(cpu_env, tmp); + tcg_temp_free_i32(tmp); /* The helper doesn't necessarily throw an exception, but we * must go back to the main loop to check for interrupts anyway. */ tcg_gen_exit_tb(0); break; } + } } /* Functions above can change dc->pc, so re-align db->pc_next */ diff --git a/target/arm/translate.c b/target/arm/translate.c index 6ba4ae92dc..df57dbb11f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -12125,6 +12125,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) } insn = arm_ldl_code(env, dc->pc, dc->sctlr_b); + dc->insn = insn; dc->pc += 4; disas_arm_insn(dc, insn); @@ -12200,6 +12201,7 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) insn = insn << 16 | insn2; dc->pc += 2; } + dc->insn = insn; if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) { uint32_t cond = dc->condexec_cond; @@ -12326,12 +12328,18 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) /* nothing more to generate */ break; case DISAS_WFI: - gen_helper_wfi(cpu_env); + { + TCGv_i32 tmp = tcg_const_i32((dc->thumb && + !(dc->insn & (1U << 31))) ? 2 : 4); + + gen_helper_wfi(cpu_env, tmp); + tcg_temp_free_i32(tmp); /* The helper doesn't necessarily throw an exception, but we * must go back to the main loop to check for interrupts anyway. */ tcg_gen_exit_tb(0); break; + } case DISAS_WFE: gen_helper_wfe(cpu_env); break; -- cgit v1.2.3 From 0f2bf05ce7b2b64f2a3ecb98de10a8100228c9a6 Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Tue, 31 Oct 2017 11:50:51 +0000 Subject: xlnx-zcu102: Specify the max number of CPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Specify the number of CPUs that can run on ZynqMP. Signed-off-by: Alistair Francis Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/xlnx-zcu102.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index 519a16ed98..e2d15a1c9d 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -240,6 +240,7 @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data) mc->block_default_type = IF_IDE; mc->units_per_default_bus = 1; mc->ignore_memory_transaction_failures = true; + mc->max_cpus = XLNX_ZYNQMP_NUM_APU_CPUS + XLNX_ZYNQMP_NUM_RPU_CPUS; } static const TypeInfo xlnx_zcu102_machine_init_typeinfo = { -- cgit v1.2.3 From cda607d5e0178d0268066d94dd06b89614304a7d Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Date: Tue, 31 Oct 2017 11:50:51 +0000 Subject: msf2: Remove dead code reported by Coverity Fixed incorrect frame size mask, validated maximum frame size in spi_write and removed dead code. Signed-off-by: Subbaraya Sundeep Reviewed-by: Darren Kenny Reviewed-by: Alistair Francis Message-id: 1508898544-10307-1-git-send-email-sundeep.lkml@gmail.com Signed-off-by: Peter Maydell --- hw/ssi/mss-spi.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c index 5a8e308e69..d60daba882 100644 --- a/hw/ssi/mss-spi.c +++ b/hw/ssi/mss-spi.c @@ -76,9 +76,10 @@ #define C_BIGFIFO (1 << 29) #define C_RESET (1 << 31) -#define FRAMESZ_MASK 0x1F +#define FRAMESZ_MASK 0x3F #define FMCOUNT_MASK 0x00FFFF00 #define FMCOUNT_SHIFT 8 +#define FRAMESZ_MAX 32 static void txfifo_reset(MSSSpiState *s) { @@ -104,10 +105,8 @@ static void set_fifodepth(MSSSpiState *s) s->fifo_depth = 32; } else if (size <= 16) { s->fifo_depth = 16; - } else if (size <= 32) { - s->fifo_depth = 8; } else { - s->fifo_depth = 4; + s->fifo_depth = 8; } } @@ -301,6 +300,17 @@ static void spi_write(void *opaque, hwaddr addr, if (s->enabled) { break; } + /* + * [31:6] bits are reserved bits and for future use. + * [5:0] are for frame size. Only [5:0] bits are validated + * during write, [31:6] bits are untouched. + */ + if ((value & FRAMESZ_MASK) > FRAMESZ_MAX) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: Incorrect size %u provided." + "Maximum frame size is %u\n", + __func__, value & FRAMESZ_MASK, FRAMESZ_MAX); + break; + } s->regs[R_SPI_DFSIZE] = value; break; -- cgit v1.2.3 From db7b98c6bb57312a49d9c47ee890e5e50a1db86d Mon Sep 17 00:00:00 2001 From: Subbaraya Sundeep Date: Tue, 31 Oct 2017 11:50:52 +0000 Subject: msf2: Wire up SYSRESETREQ in SoC for system reset Implemented system reset by creating SYSRESETREQ gpio out from nvic. Signed-off-by: Subbaraya Sundeep Message-id: 1509253165-7434-1-git-send-email-sundeep.lkml@gmail.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/msf2-soc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index 6f97fa9fe3..a8ec2cdf36 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -57,6 +57,13 @@ static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 }; static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 }; static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 }; +static void do_sys_reset(void *opaque, int n, int level) +{ + if (level) { + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + } +} + static void m2sxxx_soc_initfn(Object *obj) { MSF2State *s = MSF2_SOC(obj); @@ -125,6 +132,10 @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp) error_append_hint(errp, "m3clk can not be zero\n"); return; } + + qdev_connect_gpio_out_named(DEVICE(&s->armv7m.nvic), "SYSRESETREQ", 0, + qemu_allocate_irq(&do_sys_reset, NULL, 0)); + system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk; for (i = 0; i < MSF2_NUM_UARTS; i++) { -- cgit v1.2.3 From 168df2dea701bbf3118bdfea7794369dfa694d3d Mon Sep 17 00:00:00 2001 From: Eric Auger Date: Tue, 31 Oct 2017 11:50:52 +0000 Subject: hw/pci-host/gpex: Improve INTX to gsi routing error checking We exposed gpex_set_irq_num() for machines to set the INTx to GSI routing. However if the machine forgets to call that function we currently do not check the association was properly done. Let's initialize gsi values to -1 and if this value is found in gpex_route_intx_pin_to_irq, set the routing mode as disabled. Signed-off-by: Eric Auger Message-id: 1508776211-22175-1-git-send-email-eric.auger@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/pci-host/gpex.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c index 4090793cf0..edf305b1fd 100644 --- a/hw/pci-host/gpex.c +++ b/hw/pci-host/gpex.c @@ -57,9 +57,14 @@ static PCIINTxRoute gpex_route_intx_pin_to_irq(void *opaque, int pin) { PCIINTxRoute route; GPEXHost *s = opaque; + int gsi = s->irq_num[pin]; - route.mode = PCI_INTX_ENABLED; - route.irq = s->irq_num[pin]; + route.irq = gsi; + if (gsi < 0) { + route.mode = PCI_INTX_DISABLED; + } else { + route.mode = PCI_INTX_ENABLED; + } return route; } @@ -81,6 +86,7 @@ static void gpex_host_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->io_ioport); for (i = 0; i < GPEX_NUM_IRQS; i++) { sysbus_init_irq(sbd, &s->irq[i]); + s->irq_num[i] = -1; } pci->bus = pci_register_bus(dev, "pcie.0", gpex_set_irq, -- cgit v1.2.3