mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 15:05:37 +00:00
target/arm: Move arm_excp_unmasked to cpu.c
This inline function has one user in cpu.c, and need not be exposed otherwise. Code movement only, with fixups for checkpatch. Backports commit 310cedf39dea240a89f90729fd99481ff6158e90 from qemu
This commit is contained in:
parent
ad5a3b2532
commit
6023db20bc
|
@ -401,6 +401,125 @@ static void arm_cpu_reset(CPUState *s)
|
|||
hw_watchpoint_update_all(cpu);
|
||||
}
|
||||
|
||||
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
unsigned int target_el)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
unsigned int cur_el = arm_current_el(env);
|
||||
bool secure = arm_is_secure(env);
|
||||
bool pstate_unmasked;
|
||||
int8_t unmasked = 0;
|
||||
uint64_t hcr_el2;
|
||||
|
||||
/*
|
||||
* Don't take exceptions if they target a lower EL.
|
||||
* This check should catch any exceptions that would not be taken
|
||||
* but left pending.
|
||||
*/
|
||||
if (cur_el > target_el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hcr_el2 = arm_hcr_el2_eff(env);
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_FIQ:
|
||||
pstate_unmasked = !(env->daif & PSTATE_F);
|
||||
break;
|
||||
|
||||
case EXCP_IRQ:
|
||||
pstate_unmasked = !(env->daif & PSTATE_I);
|
||||
break;
|
||||
|
||||
case EXCP_VFIQ:
|
||||
if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VFIQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_F);
|
||||
case EXCP_VIRQ:
|
||||
if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VIRQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_I);
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the target EL, current execution state and SCR/HCR settings to
|
||||
* determine whether the corresponding CPSR bit is used to mask the
|
||||
* interrupt.
|
||||
*/
|
||||
if ((target_el > cur_el) && (target_el != 1)) {
|
||||
/* Exceptions targeting a higher EL may not be maskable */
|
||||
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
|
||||
/*
|
||||
* 64-bit masking rules are simple: exceptions to EL3
|
||||
* can't be masked, and exceptions to EL2 can only be
|
||||
* masked from Secure state. The HCR and SCR settings
|
||||
* don't affect the masking logic, only the interrupt routing.
|
||||
*/
|
||||
if (target_el == 3 || !secure) {
|
||||
unmasked = 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* The old 32-bit-only environment has a more complicated
|
||||
* masking setup. HCR and SCR bits not only affect interrupt
|
||||
* routing but also change the behaviour of masking.
|
||||
*/
|
||||
bool hcr, scr;
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_FIQ:
|
||||
/*
|
||||
* If FIQs are routed to EL3 or EL2 then there are cases where
|
||||
* we override the CPSR.F in determining if the exception is
|
||||
* masked or not. If neither of these are set then we fall back
|
||||
* to the CPSR.F setting otherwise we further assess the state
|
||||
* below.
|
||||
*/
|
||||
hcr = hcr_el2 & HCR_FMO;
|
||||
scr = (env->cp15.scr_el3 & SCR_FIQ);
|
||||
|
||||
/*
|
||||
* When EL3 is 32-bit, the SCR.FW bit controls whether the
|
||||
* CPSR.F bit masks FIQ interrupts when taken in non-secure
|
||||
* state. If SCR.FW is set then FIQs can be masked by CPSR.F
|
||||
* when non-secure but only when FIQs are only routed to EL3.
|
||||
*/
|
||||
scr = scr && !((env->cp15.scr_el3 & SCR_FW) && !hcr);
|
||||
break;
|
||||
case EXCP_IRQ:
|
||||
/*
|
||||
* When EL3 execution state is 32-bit, if HCR.IMO is set then
|
||||
* we may override the CPSR.I masking when in non-secure state.
|
||||
* The SCR.IRQ setting has already been taken into consideration
|
||||
* when setting the target EL, so it does not have a further
|
||||
* affect here.
|
||||
*/
|
||||
hcr = hcr_el2 & HCR_IMO;
|
||||
scr = false;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if ((scr || hcr) && !secure) {
|
||||
unmasked = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The PSTATE bits only mask the interrupt if we have not overriden the
|
||||
* ability above.
|
||||
*/
|
||||
return unmasked || pstate_unmasked;
|
||||
}
|
||||
|
||||
bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
|
|
|
@ -2601,118 +2601,6 @@ bool write_cpustate_to_list(ARMCPU *cpu);
|
|||
#define ARM_CPUID_TI915T 0x54029152
|
||||
#define ARM_CPUID_TI925T 0x54029252
|
||||
|
||||
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
unsigned int target_el)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
unsigned int cur_el = arm_current_el(env);
|
||||
bool secure = arm_is_secure(env);
|
||||
bool pstate_unmasked;
|
||||
int8_t unmasked = 0;
|
||||
uint64_t hcr_el2;
|
||||
|
||||
/* Don't take exceptions if they target a lower EL.
|
||||
* This check should catch any exceptions that would not be taken but left
|
||||
* pending.
|
||||
*/
|
||||
if (cur_el > target_el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hcr_el2 = arm_hcr_el2_eff(env);
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_FIQ:
|
||||
pstate_unmasked = !(env->daif & PSTATE_F);
|
||||
break;
|
||||
|
||||
case EXCP_IRQ:
|
||||
pstate_unmasked = !(env->daif & PSTATE_I);
|
||||
break;
|
||||
|
||||
case EXCP_VFIQ:
|
||||
if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VFIQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_F);
|
||||
case EXCP_VIRQ:
|
||||
if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
|
||||
/* VIRQs are only taken when hypervized and non-secure. */
|
||||
return false;
|
||||
}
|
||||
return !(env->daif & PSTATE_I);
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Use the target EL, current execution state and SCR/HCR settings to
|
||||
* determine whether the corresponding CPSR bit is used to mask the
|
||||
* interrupt.
|
||||
*/
|
||||
if ((target_el > cur_el) && (target_el != 1)) {
|
||||
/* Exceptions targeting a higher EL may not be maskable */
|
||||
if (arm_feature(env, ARM_FEATURE_AARCH64)) {
|
||||
/* 64-bit masking rules are simple: exceptions to EL3
|
||||
* can't be masked, and exceptions to EL2 can only be
|
||||
* masked from Secure state. The HCR and SCR settings
|
||||
* don't affect the masking logic, only the interrupt routing.
|
||||
*/
|
||||
if (target_el == 3 || !secure) {
|
||||
unmasked = 1;
|
||||
}
|
||||
} else {
|
||||
/* The old 32-bit-only environment has a more complicated
|
||||
* masking setup. HCR and SCR bits not only affect interrupt
|
||||
* routing but also change the behaviour of masking.
|
||||
*/
|
||||
bool hcr, scr;
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_FIQ:
|
||||
/* If FIQs are routed to EL3 or EL2 then there are cases where
|
||||
* we override the CPSR.F in determining if the exception is
|
||||
* masked or not. If neither of these are set then we fall back
|
||||
* to the CPSR.F setting otherwise we further assess the state
|
||||
* below.
|
||||
*/
|
||||
hcr = hcr_el2 & HCR_FMO;
|
||||
scr = (env->cp15.scr_el3 & SCR_FIQ);
|
||||
|
||||
/* When EL3 is 32-bit, the SCR.FW bit controls whether the
|
||||
* CPSR.F bit masks FIQ interrupts when taken in non-secure
|
||||
* state. If SCR.FW is set then FIQs can be masked by CPSR.F
|
||||
* when non-secure but only when FIQs are only routed to EL3.
|
||||
*/
|
||||
scr = scr && !((env->cp15.scr_el3 & SCR_FW) && !hcr);
|
||||
break;
|
||||
case EXCP_IRQ:
|
||||
/* When EL3 execution state is 32-bit, if HCR.IMO is set then
|
||||
* we may override the CPSR.I masking when in non-secure state.
|
||||
* The SCR.IRQ setting has already been taken into consideration
|
||||
* when setting the target EL, so it does not have a further
|
||||
* affect here.
|
||||
*/
|
||||
hcr = hcr_el2 & HCR_IMO;
|
||||
scr = false;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
if ((scr || hcr) && !secure) {
|
||||
unmasked = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The PSTATE bits only mask the interrupt if we have not overriden the
|
||||
* ability above.
|
||||
*/
|
||||
return unmasked || pstate_unmasked;
|
||||
}
|
||||
|
||||
#ifdef TARGET_ARM
|
||||
#define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
|
||||
#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
|
||||
|
|
Loading…
Reference in a new issue