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:
parent
55ba15b737
commit
31c8df53ee
@ -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
|
||||
|
@ -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.)
|
||||
|
@ -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 \
|
||||
|
Loading…
Reference in New Issue
Block a user