mips: Correct MIPS interrupt glue logic for icount

When hw interrupt pending bits in CP0_Cause are set, the CPU should
see the hw interrupt line as active. The CPU may or may not take the
interrupt based on internal state (global irq mask etc) but the glue
logic shouldn't care.

This fixes MIPS external hw interrupts in combination with -icount.

Signed-off-by: Edgar E. Iglesias <edgar@axis.com>
This commit is contained in:
Edgar E. Iglesias 2010-07-24 13:40:05 +02:00 committed by Edgar E. Iglesias
parent b2178704e4
commit 36388314fe
3 changed files with 6 additions and 31 deletions

View file

@ -24,22 +24,6 @@
#include "mips_cpudevs.h"
#include "cpu.h"
/* Raise IRQ to CPU if necessary. It must be called every time the active
IRQ may change */
void cpu_mips_update_irq(CPUState *env)
{
if ((env->CP0_Status & (1 << CP0St_IE)) &&
!(env->CP0_Status & (1 << CP0St_EXL)) &&
!(env->CP0_Status & (1 << CP0St_ERL)) &&
!(env->hflags & MIPS_HFLAG_DM)) {
if ((env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
!(env->interrupt_request & CPU_INTERRUPT_HARD)) {
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
} else
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
static void cpu_mips_irq_request(void *opaque, int irq, int level)
{
CPUState *env = (CPUState *)opaque;
@ -52,7 +36,12 @@ static void cpu_mips_irq_request(void *opaque, int irq, int level)
} else {
env->CP0_Cause &= ~(1 << (irq + CP0Ca_IP));
}
cpu_mips_update_irq(env);
if (env->CP0_Cause & CP0Ca_IP_mask) {
cpu_interrupt(env, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
}
void cpu_mips_irq_init_cpu(CPUState *env)