diff options
-rw-r--r-- | target/arm/cpu.h | 5 | ||||
-rw-r--r-- | target/arm/helper.c | 6 | ||||
-rw-r--r-- | target/arm/translate-a64.c | 2 | ||||
-rw-r--r-- | target/arm/translate.c | 4 | ||||
-rw-r--r-- | target/arm/translate.h | 15 |
5 files changed, 26 insertions, 6 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 67f2af0e16..d12c746085 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3148,6 +3148,11 @@ FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1) /* Target EL if we take a floating-point-disabled exception */ FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2) FIELD(TBFLAG_ANY, BE_DATA, 23, 1) +/* + * For A-profile only, target EL for debug exceptions. + * Note that this overlaps with the M-profile-only HANDLER and STACKCHECK bits. + */ +FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 21, 2) /* Bit usage when in AArch32 state: */ FIELD(TBFLAG_A32, THUMB, 0, 1) diff --git a/target/arm/helper.c b/target/arm/helper.c index b74c23a9bc..24806c16ca 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -11170,6 +11170,12 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc, } } + if (!arm_feature(env, ARM_FEATURE_M)) { + int target_el = arm_debug_target_el(env); + + flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL, target_el); + } + *pflags = flags; *cs_base = 0; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index f6729b96fd..90850eadc1 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -14180,7 +14180,7 @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase, dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE); dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS); dc->is_ldex = false; - dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el); + dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL); /* Bound the number of insns to execute to those left on the page. */ bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4; diff --git a/target/arm/translate.c b/target/arm/translate.c index 19b9d8f272..b32508cd2f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -11882,7 +11882,9 @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE); dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS); dc->is_ldex = false; - dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */ + if (!arm_feature(env, ARM_FEATURE_M)) { + dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL); + } dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK; diff --git a/target/arm/translate.h b/target/arm/translate.h index 45053190ba..b65954c669 100644 --- a/target/arm/translate.h +++ b/target/arm/translate.h @@ -50,6 +50,8 @@ typedef struct DisasContext { uint32_t svc_imm; int aarch64; int current_el; + /* Debug target exception level for single-step exceptions */ + int debug_target_el; GHashTable *cp_regs; uint64_t features; /* CPU features bits */ /* Because unallocated encodings generate different exception syndrome @@ -70,8 +72,6 @@ typedef struct DisasContext { * ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*. */ bool is_ldex; - /* True if a single-step exception will be taken to the current EL */ - bool ss_same_el; /* True if v8.3-PAuth is active. */ bool pauth_active; /* True with v8.5-BTI and SCTLR_ELx.BT* set. */ @@ -251,8 +251,15 @@ static inline void gen_exception(int excp, uint32_t syndrome, /* Generate an architectural singlestep exception */ static inline void gen_swstep_exception(DisasContext *s, int isv, int ex) { - gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex), - default_exception_el(s)); + bool same_el = (s->debug_target_el == s->current_el); + + /* + * If singlestep is targeting a lower EL than the current one, + * then s->ss_active must be false and we can never get here. + */ + assert(s->debug_target_el >= s->current_el); + + gen_exception(EXCP_UDEF, syn_swstep(same_el, isv, ex), s->debug_target_el); } /* |