target/arm: Move arm_generate_debug_exceptions out of line

Move arm_generate_debug_exceptions and its two subroutines,
{aa32,aa64}_generate_debug_exceptions into debug_helper.c,
and the one interface declaration to internals.h.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220609202901.1177572-6-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2022-06-10 14:32:31 +01:00 committed by Peter Maydell
parent 55ba15b737
commit 31c8df53ee
3 changed files with 95 additions and 91 deletions

View file

@ -3015,97 +3015,6 @@ static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
return (cpu->clidr & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0;
}
/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
{
int cur_el = arm_current_el(env);
int debug_el;
if (cur_el == 3) {
return false;
}
/* MDCR_EL3.SDD disables debug events from Secure state */
if (arm_is_secure_below_el3(env)
&& extract32(env->cp15.mdcr_el3, 16, 1)) {
return false;
}
/*
* Same EL to same EL debug exceptions need MDSCR_KDE enabled
* while not masking the (D)ebug bit in DAIF.
*/
debug_el = arm_debug_target_el(env);
if (cur_el == debug_el) {
return extract32(env->cp15.mdscr_el1, 13, 1)
&& !(env->daif & PSTATE_D);
}
/* Otherwise the debug target needs to be a higher EL */
return debug_el > cur_el;
}
static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
{
int el = arm_current_el(env);
if (el == 0 && arm_el_is_aa64(env, 1)) {
return aa64_generate_debug_exceptions(env);
}
if (arm_is_secure(env)) {
int spd;
if (el == 0 && (env->cp15.sder & 1)) {
/* SDER.SUIDEN means debug exceptions from Secure EL0
* are always enabled. Otherwise they are controlled by
* SDCR.SPD like those from other Secure ELs.
*/
return true;
}
spd = extract32(env->cp15.mdcr_el3, 14, 2);
switch (spd) {
case 1:
/* SPD == 0b01 is reserved, but behaves as 0b00. */
case 0:
/* For 0b00 we return true if external secure invasive debug
* is enabled. On real hardware this is controlled by external
* signals to the core. QEMU always permits debug, and behaves
* as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.
*/
return true;
case 2:
return false;
case 3:
return true;
}
}
return el != 2;
}
/* Return true if debugging exceptions are currently enabled.
* This corresponds to what in ARM ARM pseudocode would be
* if UsingAArch32() then
* return AArch32.GenerateDebugExceptions()
* else
* return AArch64.GenerateDebugExceptions()
* We choose to push the if() down into this function for clarity,
* since the pseudocode has it at all callsites except for the one in
* CheckSoftwareStep(), where it is elided because both branches would
* always return the same value.
*/
static inline bool arm_generate_debug_exceptions(CPUARMState *env)
{
if (env->aarch64) {
return aa64_generate_debug_exceptions(env);
} else {
return aa32_generate_debug_exceptions(env);
}
}
static inline bool arm_sctlr_b(CPUARMState *env)
{
return

View file

@ -12,6 +12,100 @@
#include "exec/helper-proto.h"
/* See AArch64.GenerateDebugExceptionsFrom() in ARM ARM pseudocode */
static bool aa64_generate_debug_exceptions(CPUARMState *env)
{
int cur_el = arm_current_el(env);
int debug_el;
if (cur_el == 3) {
return false;
}
/* MDCR_EL3.SDD disables debug events from Secure state */
if (arm_is_secure_below_el3(env)
&& extract32(env->cp15.mdcr_el3, 16, 1)) {
return false;
}
/*
* Same EL to same EL debug exceptions need MDSCR_KDE enabled
* while not masking the (D)ebug bit in DAIF.
*/
debug_el = arm_debug_target_el(env);
if (cur_el == debug_el) {
return extract32(env->cp15.mdscr_el1, 13, 1)
&& !(env->daif & PSTATE_D);
}
/* Otherwise the debug target needs to be a higher EL */
return debug_el > cur_el;
}
static bool aa32_generate_debug_exceptions(CPUARMState *env)
{
int el = arm_current_el(env);
if (el == 0 && arm_el_is_aa64(env, 1)) {
return aa64_generate_debug_exceptions(env);
}
if (arm_is_secure(env)) {
int spd;
if (el == 0 && (env->cp15.sder & 1)) {
/*
* SDER.SUIDEN means debug exceptions from Secure EL0
* are always enabled. Otherwise they are controlled by
* SDCR.SPD like those from other Secure ELs.
*/
return true;
}
spd = extract32(env->cp15.mdcr_el3, 14, 2);
switch (spd) {
case 1:
/* SPD == 0b01 is reserved, but behaves as 0b00. */
case 0:
/*
* For 0b00 we return true if external secure invasive debug
* is enabled. On real hardware this is controlled by external
* signals to the core. QEMU always permits debug, and behaves
* as if DBGEN, SPIDEN, NIDEN and SPNIDEN are all tied high.
*/
return true;
case 2:
return false;
case 3:
return true;
}
}
return el != 2;
}
/*
* Return true if debugging exceptions are currently enabled.
* This corresponds to what in ARM ARM pseudocode would be
* if UsingAArch32() then
* return AArch32.GenerateDebugExceptions()
* else
* return AArch64.GenerateDebugExceptions()
* We choose to push the if() down into this function for clarity,
* since the pseudocode has it at all callsites except for the one in
* CheckSoftwareStep(), where it is elided because both branches would
* always return the same value.
*/
bool arm_generate_debug_exceptions(CPUARMState *env)
{
if (env->aarch64) {
return aa64_generate_debug_exceptions(env);
} else {
return aa32_generate_debug_exceptions(env);
}
}
/*
* Is single-stepping active? (Note that the "is EL_D AArch64?" check
* implicitly means this always returns false in pre-v8 CPUs.)

View file

@ -1326,6 +1326,7 @@ bool el_is_in_host(CPUARMState *env, int el);
void aa32_max_features(ARMCPU *cpu);
int exception_target_el(CPUARMState *env);
bool arm_singlestep_active(CPUARMState *env);
bool arm_generate_debug_exceptions(CPUARMState *env);
/* Powers of 2 for sve_vq_map et al. */
#define SVE_VQ_POW2_MAP \