Fix vector interrupt handling

Don't produce stray irq 5, don't overwrite ivec_data if still busy with
processing of the previous interrupt.

Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Artyom Tarasenko 2012-04-03 17:49:04 +02:00 committed by Blue Swirl
parent f05f6b4adb
commit 23cf96e197

View File

@ -309,19 +309,22 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level)
CPUSPARCState *env = opaque;
if (level) {
CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
env->interrupt_index = TT_IVEC;
env->pil_in |= 1 << 5;
env->ivec_status |= 0x20;
env->ivec_data[0] = (0x1f << 6) | irq;
env->ivec_data[1] = 0;
env->ivec_data[2] = 0;
cpu_interrupt(env, CPU_INTERRUPT_HARD);
} else {
CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
env->pil_in &= ~(1 << 5);
env->ivec_status &= ~0x20;
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
if (!(env->ivec_status & 0x20)) {
CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
env->halted = 0;
env->interrupt_index = TT_IVEC;
env->ivec_status |= 0x20;
env->ivec_data[0] = (0x1f << 6) | irq;
env->ivec_data[1] = 0;
env->ivec_data[2] = 0;
cpu_interrupt(env, CPU_INTERRUPT_HARD);
}
} else {
if (env->ivec_status & 0x20) {
CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
env->ivec_status &= ~0x20;
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
}
}