@@ -12,6 +12,26 @@
#include "exec/helper-proto.h"
+/*
+ * Raise an exception to the debug target el.
+ * Modify syndrome to indicate when origin and target EL are the same.
+ */
+G_NORETURN static void
+raise_exception_debug(CPUARMState *env, uint32_t excp, uint32_t syndrome)
+{
+ int debug_el = arm_debug_target_el(env);
+ int cur_el = arm_current_el(env);
+
+ /*
+ * If singlestep is targeting a lower EL than the current one, then
+ * DisasContext.ss_active must be false and we can never get here.
+ * Similarly for watchpoint and breakpoint matches.
+ */
+ assert(debug_el >= cur_el);
+ syndrome |= (debug_el == cur_el) << ARM_EL_EC_SHIFT;
+ raise_exception(env, excp, syndrome, debug_el);
+}
+
/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
static bool aa64_generate_debug_exceptions(CPUARMState *env)
{
@@ -418,19 +438,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.
@@ -450,9 +467,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));
}
}
@@ -489,18 +504,7 @@ void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
void HELPER(exception_swstep)(CPUARMState *env, uint32_t syndrome)
{
- int debug_el = arm_debug_target_el(env);
- int cur_el = arm_current_el(env);
-
- /*
- * If singlestep is targeting a lower EL than the current one, then
- * DisasContext.ss_active must be false and we can never get here.
- */
- assert(debug_el >= cur_el);
- if (debug_el == cur_el) {
- syndrome |= 1 << ARM_EL_EC_SHIFT;
- }
- raise_exception(env, EXCP_UDEF, syndrome, debug_el);
+ raise_exception_debug(env, EXCP_UDEF, syndrome);
}
#if !defined(CONFIG_USER_ONLY)
Handle the debug vs current el exception test in one place. Leave EXCP_BKPT alone, since that treats debug < current differently. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/debug_helper.c | 44 +++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 20 deletions(-)