From cfc1611d6fb42e0cb4931b74e9a14224cbd418a6 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 2 Mar 2018 14:54:13 -0500 Subject: [PATCH] arm: Track M profile handler mode state in TB flags For M profile exception-return handling we'd like to generate different code for some instructions depending on whether we are in Handler mode or Thread mode. This isn't the same as "are we privileged or user", so we need an extra bit in the TB flags to distinguish. Backports commit 064c379c99b835bdcc478d21a3849507ea07d53a from qemu --- qemu/target/arm/cpu.h | 9 +++++++++ qemu/target/arm/translate.c | 1 + qemu/target/arm/translate.h | 1 + 3 files changed, 11 insertions(+) diff --git a/qemu/target/arm/cpu.h b/qemu/target/arm/cpu.h index 5aba3f2c..8059dadf 100644 --- a/qemu/target/arm/cpu.h +++ b/qemu/target/arm/cpu.h @@ -2224,6 +2224,9 @@ static inline bool arm_singlestep_active(CPUARMState *env) #define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT) #define ARM_TBFLAG_BE_DATA_SHIFT 20 #define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT) +/* For M profile only, Handler (ie not Thread) mode */ +#define ARM_TBFLAG_HANDLER_SHIFT 21 +#define ARM_TBFLAG_HANDLER_MASK (1 << ARM_TBFLAG_HANDLER_SHIFT) /* Bit usage when in AArch64 state */ #define ARM_TBFLAG_TBI0_SHIFT 0 /* TBI0 for EL0/1 or TBI for EL2/3 */ @@ -2260,6 +2263,8 @@ static inline bool arm_singlestep_active(CPUARMState *env) (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT) #define ARM_TBFLAG_BE_DATA(F) \ (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT) +#define ARM_TBFLAG_HANDLER(F) \ + (((F) & ARM_TBFLAG_HANDLER_MASK) >> ARM_TBFLAG_HANDLER_SHIFT) #define ARM_TBFLAG_TBI0(F) \ (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT) #define ARM_TBFLAG_TBI1(F) \ @@ -2487,6 +2492,10 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, } *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT; + if (env->v7m.exception != 0) { + *flags |= ARM_TBFLAG_HANDLER_MASK; + } + *cs_base = 0; } diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 9d27224d..f98bb335 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -11973,6 +11973,7 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags); dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags); dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags); + dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags); dc->cp_regs = cpu->cp_regs; dc->features = env->features; diff --git a/qemu/target/arm/translate.h b/qemu/target/arm/translate.h index 466a17d1..c4c51198 100644 --- a/qemu/target/arm/translate.h +++ b/qemu/target/arm/translate.h @@ -31,6 +31,7 @@ typedef struct DisasContext { bool vfp_enabled; /* FP enabled via FPSCR.EN */ int vec_len; int vec_stride; + bool v7m_handler_mode; /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI * so that top level loop can generate correct syndrome information. */