target-arm: Update arm_generate_debug_exceptions() to handle EL2/EL3

The arm_generate_debug_exceptions() function as originally implemented
assumes no EL2 or EL3. Since we now have much more of an implementation
of those now, fix this assumption.

Backports commit 533e93f1cf12c570aab45f14663dab6fb8ea3ffc from qemu
This commit is contained in:
Peter Maydell 2018-02-20 11:12:34 -05:00 committed by Lioncash
parent 4552444928
commit 4838c1dfe9
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -1764,9 +1764,7 @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
return el;
}
/* Return the Exception Level targeted by debug exceptions;
* currently always EL1 since we don't implement EL2 or EL3.
*/
/* Return the Exception Level targeted by debug exceptions. */
static inline int arm_debug_target_el(CPUARMState *env)
{
bool secure = arm_is_secure(env);
@ -1789,6 +1787,14 @@ static inline int arm_debug_target_el(CPUARMState *env)
static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
{
if (arm_is_secure(env)) {
/* MDCR_EL3.SDD disables debug events from Secure state */
if (extract32(env->cp15.mdcr_el3, 16, 1) != 0
|| arm_current_el(env) == 3) {
return false;
}
}
if (arm_current_el(env) == arm_debug_target_el(env)) {
if ((extract32(env->cp15.mdscr_el1, 13, 1) == 0)
|| (env->daif & PSTATE_D)) {
@ -1800,10 +1806,42 @@ static inline bool aa64_generate_debug_exceptions(CPUARMState *env)
static inline bool aa32_generate_debug_exceptions(CPUARMState *env)
{
if (arm_current_el(env) == 0 && arm_el_is_aa64(env, 1)) {
int el = arm_current_el(env);
if (el == 0 && arm_el_is_aa64(env, 1)) {
return aa64_generate_debug_exceptions(env);
}
return arm_current_el(env) != 2;
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.