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:
parent
f05f6b4adb
commit
23cf96e197
29
hw/sun4u.c
29
hw/sun4u.c
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user