[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 12/18] target/arm: Create raise_exception_debug
From: |
Richard Henderson |
Subject: |
[PATCH 12/18] target/arm: Create raise_exception_debug |
Date: |
Mon, 23 May 2022 13:47:36 -0700 |
Handle EL testing for debug exceptions in a single place.
Split out raise_exception_int as a common helper.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/arm/internals.h | 8 ++++++++
target/arm/debug_helper.c | 27 ++++--------------------
target/arm/op_helper.c | 43 ++++++++++++++++++++++++++++++++-------
3 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 685214503b..6df38db836 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -125,6 +125,14 @@ G_NORETURN void raise_exception_ra(CPUARMState *env,
uint32_t excp,
uint32_t syndrome,
uint32_t cur_or_target_el, uintptr_t ra);
+/**
+ * raise_exception_debug:
+ * Similarly. If @excp != EXCPBKPT, modify syndrome to indicate
+ * when origin and target EL are the same.
+ */
+G_NORETURN void raise_exception_debug(CPUARMState *env, uint32_t excp,
+ uint32_t syndrome);
+
/*
* For AArch64, map a given EL to an index in the banked_spsr array.
* Note that this mapping and the AArch32 mapping defined in bank_number()
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
index 08d461fd19..181ba7b042 100644
--- a/target/arm/debug_helper.c
+++ b/target/arm/debug_helper.c
@@ -417,19 +417,16 @@ void arm_debug_excp_handler(CPUState *cs)
if (wp_hit) {
if (wp_hit->flags & BP_CPU) {
bool wnr = (wp_hit->flags & BP_WATCHPOINT_HIT_WRITE) != 0;
- bool same_el = arm_debug_target_el(env) == arm_current_el(env);
cs->watchpoint_hit = NULL;
env->exception.fsr = arm_debug_exception_fsr(env);
env->exception.vaddress = wp_hit->hitaddr;
- raise_exception(env, EXCP_DATA_ABORT,
- syn_watchpoint(same_el, 0, wnr),
- arm_debug_target_el(env));
+ raise_exception_debug(env, EXCP_DATA_ABORT,
+ syn_watchpoint(0, 0, wnr));
}
} else {
uint64_t pc = is_a64(env) ? env->pc : env->regs[15];
- bool same_el = (arm_debug_target_el(env) == arm_current_el(env));
/*
* (1) GDB breakpoints should be handled first.
@@ -449,9 +446,7 @@ void arm_debug_excp_handler(CPUState *cs)
* exception/security level.
*/
env->exception.vaddress = 0;
- raise_exception(env, EXCP_PREFETCH_ABORT,
- syn_breakpoint(same_el),
- arm_debug_target_el(env));
+ raise_exception_debug(env, EXCP_PREFETCH_ABORT, syn_breakpoint(0));
}
}
@@ -461,9 +456,6 @@ void arm_debug_excp_handler(CPUState *cs)
*/
void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
{
- int debug_el = arm_debug_target_el(env);
- int cur_el = arm_current_el(env);
-
/* FSR will only be used if the debug target EL is AArch32. */
env->exception.fsr = arm_debug_exception_fsr(env);
/*
@@ -472,18 +464,7 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env,
uint32_t syndrome)
* exception/security level.
*/
env->exception.vaddress = 0;
- /*
- * Other kinds of architectural debug exception are ignored if
- * they target an exception level below the current one (in QEMU
- * this is checked by arm_generate_debug_exceptions()). Breakpoint
- * instructions are special because they always generate an exception
- * to somewhere: if they can't go to the configured debug exception
- * level they are taken to the current exception level.
- */
- if (debug_el < cur_el) {
- debug_el = cur_el;
- }
- raise_exception(env, EXCP_BKPT, syndrome, debug_el);
+ raise_exception_debug(env, EXCP_BKPT, syndrome);
}
#if !defined(CONFIG_USER_ONLY)
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 0a50dbf274..c4988b6c41 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -65,15 +65,11 @@ int exception_target_el(CPUARMState *env, int cur_el,
uint32_t *psyn)
return 1;
}
-void raise_exception(CPUARMState *env, uint32_t excp, uint32_t syndrome,
- uint32_t cur_or_target_el)
+G_NORETURN static
+void raise_exception_int(CPUARMState *env, uint32_t excp,
+ uint32_t syndrome, uint32_t target_el)
{
CPUState *cs = env_cpu(env);
- int target_el = cur_or_target_el;
-
- if (cur_or_target_el <= 1) {
- target_el = exception_target_el(env, cur_or_target_el, &syndrome);
- }
assert(!excp_is_internal(excp));
cs->exception_index = excp;
@@ -82,6 +78,39 @@ void raise_exception(CPUARMState *env, uint32_t excp,
uint32_t syndrome,
cpu_loop_exit(cs);
}
+void raise_exception(CPUARMState *env, uint32_t excp, uint32_t syndrome,
+ uint32_t cur_or_target_el)
+{
+ int target_el = cur_or_target_el;
+ if (cur_or_target_el <= 1) {
+ target_el = exception_target_el(env, cur_or_target_el, &syndrome);
+ }
+ raise_exception_int(env, excp, syndrome, target_el);
+}
+
+void raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
+{
+ int cur_el = arm_current_el(env);
+ int debug_el = arm_debug_target_el(env);
+
+ /*
+ * Most kinds of architectural debug exception are ignored if
+ * they target an exception level below the current (in QEMU
+ * this is checked by arm_generate_debug_exceptions()).
+ * Breakpoint instructions are special because they always generate
+ * an exception to somewhere: if they can't go to the configured
+ * debug exception level they are taken to the current exception level.
+ */
+ if (excp == EXCP_BKPT) {
+ debug_el = MAX(cur_el, debug_el);
+ } else {
+ assert(debug_el >= cur_el);
+ syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
+ }
+
+ raise_exception_int(env, excp, syndrome, debug_el);
+}
+
void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
uint32_t cur_or_target_el, uintptr_t ra)
{
--
2.34.1
- [PATCH 11/18] target/arm: Move arm_debug_target_el to internals.h, (continued)
- [PATCH 11/18] target/arm: Move arm_debug_target_el to internals.h, Richard Henderson, 2022/05/23
- [PATCH 10/18] target/arm: Move arm_debug_exception_fsr to debug_helper.c, Richard Henderson, 2022/05/23
- [PATCH 06/18] target/arm: Move arm_generate_debug_exceptions out of line, Richard Henderson, 2022/05/23
- [PATCH 14/18] target/arm: Mark exception helpers as noreturn, Richard Henderson, 2022/05/23
- [PATCH 08/18] target/arm: Use is_a64 in arm_generate_debug_exceptions, Richard Henderson, 2022/05/23
- [PATCH 13/18] target/arm: Move MDCR_TDE test into exception_target_el, Richard Henderson, 2022/05/23
- [PATCH 12/18] target/arm: Create raise_exception_debug,
Richard Henderson <=
- [PATCH 15/18] target/arm: Create helper_exception_swstep, Richard Henderson, 2022/05/23
- [PATCH 17/18] target/arm: Add cur_el parameter to arm_generate_debug_exceptions, Richard Henderson, 2022/05/23
- [PATCH 18/18] target/arm: Remove route_to_el2 case from sve_exception_el, Richard Henderson, 2022/05/23
- [PATCH 16/18] target/arm: Remove TBFLAG_ANY.DEBUG_TARGET_EL, Richard Henderson, 2022/05/23