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. Tested-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200206105448.4726-39-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
cd3f80aba0
commit
310cedf39d
119
target/arm/cpu.c
119
target/arm/cpu.c
@ -410,6 +410,125 @@ static void arm_cpu_reset(CPUState *s)
|
|||||||
arm_rebuild_hflags(env);
|
arm_rebuild_hflags(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
||||||
{
|
{
|
||||||
CPUClass *cc = CPU_GET_CLASS(cs);
|
CPUClass *cc = CPU_GET_CLASS(cs);
|
||||||
|
111
target/arm/cpu.h
111
target/arm/cpu.h
@ -2709,117 +2709,6 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
|
|||||||
#define ARM_CPUID_TI915T 0x54029152
|
#define ARM_CPUID_TI915T 0x54029152
|
||||||
#define ARM_CPUID_TI925T 0x54029252
|
#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();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
|
#define ARM_CPU_TYPE_SUFFIX "-" TYPE_ARM_CPU
|
||||||
#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
|
#define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX)
|
||||||
#define CPU_RESOLVING_TYPE TYPE_ARM_CPU
|
#define CPU_RESOLVING_TYPE TYPE_ARM_CPU
|
||||||
|
Loading…
x
Reference in New Issue
Block a user