#define CPU_IRQ_INT15_IN 0x0004000
#define CPU_IRQ_INT15_MASK 0x80000000
-static void slavio_check_interrupts(SLAVIO_INTCTLState *s);
+static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs);
// per-cpu interrupt controller
static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
val |= CPU_IRQ_INT15_MASK;
val &= CPU_SOFTIRQ_MASK;
s->intreg_pending &= ~val;
- slavio_check_interrupts(s->master);
+ slavio_check_interrupts(s->master, 1);
DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val,
s->intreg_pending);
break;
case 2: // set softint
val &= CPU_SOFTIRQ_MASK;
s->intreg_pending |= val;
- slavio_check_interrupts(s->master);
+ slavio_check_interrupts(s->master, 1);
DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val,
s->intreg_pending);
break;
s->intregm_disabled &= ~val;
DPRINTF("Enabled master irq mask %x, curmask %x\n", val,
s->intregm_disabled);
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 1);
break;
case 3: // set (disable, clear pending)
// Force clear unused bits
val &= MASTER_IRQ_MASK;
s->intregm_disabled |= val;
s->intregm_pending &= ~val;
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 1);
DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
s->intregm_disabled);
break;
case 4:
s->target_cpu = val & (MAX_CPUS - 1);
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 1);
DPRINTF("Set master irq cpu %d\n", s->target_cpu);
break;
default:
#endif
}
-static void slavio_check_interrupts(SLAVIO_INTCTLState *s)
+static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs)
{
uint32_t pending = s->intregm_pending, pil_pending;
unsigned int i, j;
}
pil_pending |= (s->slaves[i]->intreg_pending & CPU_SOFTIRQ_MASK) >> 16;
- for (j = 0; j < MAX_PILS; j++) {
- if (pil_pending & (1 << j)) {
- if (!(s->pil_out[i] & (1 << j)))
- qemu_irq_raise(s->cpu_irqs[i][j]);
- } else {
- if (s->pil_out[i] & (1 << j))
- qemu_irq_lower(s->cpu_irqs[i][j]);
+ if (set_irqs) {
+ for (j = 0; j < MAX_PILS; j++) {
+ if (pil_pending & (1 << j)) {
+ if (!(s->pil_out[i] & (1 << j))) {
+ qemu_irq_raise(s->cpu_irqs[i][j]);
+ }
+ } else {
+ if (s->pil_out[i] & (1 << j)) {
+ qemu_irq_lower(s->cpu_irqs[i][j]);
+ }
+ }
}
}
s->pil_out[i] = pil_pending;
s->intregm_pending &= ~mask;
s->slaves[s->target_cpu]->intreg_pending &= ~(1 << pil);
}
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 1);
}
}
s->slaves[cpu]->intreg_pending &= ~s->cputimer_lbit;
}
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 1);
}
static void slavio_intctl_save(QEMUFile *f, void *opaque)
qemu_get_be32s(f, &s->intregm_pending);
qemu_get_be32s(f, &s->intregm_disabled);
qemu_get_be32s(f, &s->target_cpu);
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 0);
return 0;
}
s->intregm_disabled = ~MASTER_IRQ_MASK;
s->intregm_pending = 0;
s->target_cpu = 0;
- slavio_check_interrupts(s);
+ slavio_check_interrupts(s, 0);
}
void *slavio_intctl_init(target_phys_addr_t addr, target_phys_addr_t addrg,