target-mips: move the test for enabled interrupts to a separate function

Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
This commit is contained in:
Leon Alrae 2015-09-14 13:58:23 +01:00
parent 7bc8e0c967
commit 71ca034a0d
3 changed files with 20 additions and 16 deletions

View File

@ -58,7 +58,9 @@ static bool mips_cpu_has_work(CPUState *cs)
check for interrupts that can be taken. */ check for interrupts that can be taken. */
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) && if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
cpu_mips_hw_interrupts_pending(env)) { cpu_mips_hw_interrupts_pending(env)) {
has_work = true; if (cpu_mips_hw_interrupts_enabled(env)) {
has_work = true;
}
} }
/* MIPS-MT has the ability to halt the CPU. */ /* MIPS-MT has the ability to halt the CPU. */

View File

@ -637,23 +637,24 @@ static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
return env->hflags & MIPS_HFLAG_KSU; return env->hflags & MIPS_HFLAG_KSU;
} }
static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env) static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env)
{ {
int32_t pending; return (env->CP0_Status & (1 << CP0St_IE)) &&
int32_t status; !(env->CP0_Status & (1 << CP0St_EXL)) &&
int r; !(env->CP0_Status & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM) &&
if (!(env->CP0_Status & (1 << CP0St_IE)) ||
(env->CP0_Status & (1 << CP0St_EXL)) ||
(env->CP0_Status & (1 << CP0St_ERL)) ||
/* Note that the TCStatus IXMT field is initialized to zero, /* Note that the TCStatus IXMT field is initialized to zero,
and only MT capable cores can set it to one. So we don't and only MT capable cores can set it to one. So we don't
need to check for MT capabilities here. */ need to check for MT capabilities here. */
(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) || !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT));
(env->hflags & MIPS_HFLAG_DM)) { }
/* Interrupts are disabled */
return 0; /* Check if there is pending and not masked out interrupt */
} static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
{
int32_t pending;
int32_t status;
bool r;
pending = env->CP0_Cause & CP0Ca_IP_mask; pending = env->CP0_Cause & CP0Ca_IP_mask;
status = env->CP0_Status & CP0Ca_IP_mask; status = env->CP0_Status & CP0Ca_IP_mask;
@ -667,7 +668,7 @@ static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
/* A MIPS configured with compatibility or VInt (Vectored Interrupts) /* A MIPS configured with compatibility or VInt (Vectored Interrupts)
treats the pending lines as individual interrupt lines, the status treats the pending lines as individual interrupt lines, the status
lines are individual masks. */ lines are individual masks. */
r = pending & status; r = (pending & status) != 0;
} }
return r; return r;
} }

View File

@ -759,7 +759,8 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
MIPSCPU *cpu = MIPS_CPU(cs); MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env; CPUMIPSState *env = &cpu->env;
if (cpu_mips_hw_interrupts_pending(env)) { if (cpu_mips_hw_interrupts_enabled(env) &&
cpu_mips_hw_interrupts_pending(env)) {
/* Raise it */ /* Raise it */
cs->exception_index = EXCP_EXT_INTERRUPT; cs->exception_index = EXCP_EXT_INTERRUPT;
env->error_code = 0; env->error_code = 0;