mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-06-20 16:57:54 +00:00
target-mips: move the test for enabled interrupts to a separate function
Backports commit 71ca034a0dee69f77c8ac6ea7d21e5b6a0b0d836 from qemu
This commit is contained in:
parent
b9cf91307e
commit
5a60450b96
|
@ -57,8 +57,10 @@ 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)) {
|
||||||
|
if (cpu_mips_hw_interrupts_enabled(env)) {
|
||||||
has_work = true;
|
has_work = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* MIPS-MT has the ability to halt the CPU. */
|
/* MIPS-MT has the ability to halt the CPU. */
|
||||||
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
|
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
|
||||||
|
|
|
@ -643,24 +643,26 @@ 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;
|
||||||
|
|
||||||
|
@ -673,7 +675,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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -746,7 +746,8 @@ bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request) // qq
|
||||||
MIPSCPU *cpu = MIPS_CPU(cs->uc, cs);
|
MIPSCPU *cpu = MIPS_CPU(cs->uc, 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;
|
||||||
|
|
Loading…
Reference in a new issue