diff options
Diffstat (limited to 'target/arm/op_helper.c')
-rw-r--r-- | target/arm/op_helper.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 7a88fd2c92..a266cc0116 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -483,6 +483,21 @@ void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp, raise_exception(env, excp, syndrome, target_el); } +/* Raise an EXCP_BKPT with the specified syndrome register value, + * targeting the correct exception level for debug exceptions. + */ +void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome) +{ + /* FSR will only be used if the debug target EL is AArch32. */ + env->exception.fsr = arm_debug_exception_fsr(env); + /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing + * values to the guest that it shouldn't be able to see at its + * exception/security level. + */ + env->exception.vaddress = 0; + raise_exception(env, EXCP_BKPT, syndrome, arm_debug_target_el(env)); +} + uint32_t HELPER(cpsr_read)(CPUARMState *env) { return cpsr_read(env) & ~(CPSR_EXEC | CPSR_RESERVED); @@ -1322,11 +1337,7 @@ void arm_debug_excp_handler(CPUState *cs) cs->watchpoint_hit = NULL; - if (extended_addresses_enabled(env)) { - env->exception.fsr = (1 << 9) | 0x22; - } else { - env->exception.fsr = 0x2; - } + 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), @@ -1346,12 +1357,12 @@ void arm_debug_excp_handler(CPUState *cs) return; } - if (extended_addresses_enabled(env)) { - env->exception.fsr = (1 << 9) | 0x22; - } else { - env->exception.fsr = 0x2; - } - /* FAR is UNKNOWN, so doesn't need setting */ + env->exception.fsr = arm_debug_exception_fsr(env); + /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing + * values to the guest that it shouldn't be able to see at its + * exception/security level. + */ + env->exception.vaddress = 0; raise_exception(env, EXCP_PREFETCH_ABORT, syn_breakpoint(same_el), arm_debug_target_el(env)); |