Lines Matching +full:cpu +full:- +full:interrupt +full:- +full:controller
2 * QEMU Sparc SLAVIO interrupt controller emulation
4 * Copyright (c) 2003-2005 Fabrice Bellard
37 * Registers of interrupt controller in sun4m.
39 * This is the interrupt controller part of chip STP2001 (Slave I/O), also
41 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
43 * There is a system master controller and one for each cpu.
56 uint32_t cpu; member
88 // per-cpu interrupt controller
98 ret = s->intreg_pending; in slavio_intctl_mem_readl()
104 trace_slavio_intctl_mem_readl(s->cpu, addr, ret); in slavio_intctl_mem_readl()
116 trace_slavio_intctl_mem_writel(s->cpu, addr, val); in slavio_intctl_mem_writel()
120 s->intreg_pending &= ~val; in slavio_intctl_mem_writel()
121 slavio_check_interrupts(s->master, 1); in slavio_intctl_mem_writel()
122 trace_slavio_intctl_mem_writel_clear(s->cpu, val, s->intreg_pending); in slavio_intctl_mem_writel()
126 s->intreg_pending |= val; in slavio_intctl_mem_writel()
127 slavio_check_interrupts(s->master, 1); in slavio_intctl_mem_writel()
128 trace_slavio_intctl_mem_writel_set(s->cpu, val, s->intreg_pending); in slavio_intctl_mem_writel()
145 // master system interrupt controller
155 ret = s->intregm_pending & ~MASTER_DISABLE; in slavio_intctlm_mem_readl()
158 ret = s->intregm_disabled & MASTER_IRQ_MASK; in slavio_intctlm_mem_readl()
161 ret = s->target_cpu; in slavio_intctlm_mem_readl()
184 s->intregm_disabled &= ~val; in slavio_intctlm_mem_writel()
185 trace_slavio_intctlm_mem_writel_enable(val, s->intregm_disabled); in slavio_intctlm_mem_writel()
191 s->intregm_disabled |= val; in slavio_intctlm_mem_writel()
193 trace_slavio_intctlm_mem_writel_disable(val, s->intregm_disabled); in slavio_intctlm_mem_writel()
196 s->target_cpu = val & (MAX_CPUS - 1); in slavio_intctlm_mem_writel()
198 trace_slavio_intctlm_mem_writel_target(s->target_cpu); in slavio_intctlm_mem_writel()
222 uint32_t pending = s->intregm_pending, pil_pending; in slavio_check_interrupts()
225 pending &= ~s->intregm_disabled; in slavio_check_interrupts()
227 trace_slavio_check_interrupts(pending, s->intregm_disabled); in slavio_check_interrupts()
231 /* If we are the current interrupt target, get hard interrupts */ in slavio_check_interrupts()
232 if (pending && !(s->intregm_disabled & MASTER_DISABLE) && in slavio_check_interrupts()
233 (i == s->target_cpu)) { in slavio_check_interrupts()
242 s->slaves[i].intreg_pending &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN | in slavio_check_interrupts()
244 if (i == s->target_cpu) { in slavio_check_interrupts()
246 if ((s->intregm_pending & (1U << j)) && intbit_to_level[j]) { in slavio_check_interrupts()
247 s->slaves[i].intreg_pending |= 1 << intbit_to_level[j]; in slavio_check_interrupts()
252 /* Level 15 and CPU timer interrupts are only masked when in slavio_check_interrupts()
254 if (!(s->intregm_disabled & MASTER_DISABLE)) { in slavio_check_interrupts()
255 pil_pending |= s->slaves[i].intreg_pending & in slavio_check_interrupts()
260 pil_pending |= (s->slaves[i].intreg_pending & CPU_SOFTIRQ_MASK) >> 16; in slavio_check_interrupts()
263 /* Since there is not really an interrupt 0 (and pil_pending in slavio_check_interrupts()
268 for (j = MAX_PILS-1; j > 0; j--) { in slavio_check_interrupts()
270 if (!(s->slaves[i].irl_out & (1 << j))) { in slavio_check_interrupts()
271 qemu_irq_raise(s->cpu_irqs[i][j]); in slavio_check_interrupts()
274 if (s->slaves[i].irl_out & (1 << j)) { in slavio_check_interrupts()
275 qemu_irq_lower(s->cpu_irqs[i][j]); in slavio_check_interrupts()
280 s->slaves[i].irl_out = pil_pending; in slavio_check_interrupts()
285 * "irq" here is the bit number in the system interrupt register to
295 trace_slavio_set_irq(s->target_cpu, irq, pil, level); in slavio_set_irq()
299 s->irq_count[pil]++; in slavio_set_irq()
301 s->intregm_pending |= mask; in slavio_set_irq()
304 s->slaves[i].intreg_pending |= 1 << pil; in slavio_set_irq()
308 s->intregm_pending &= ~mask; in slavio_set_irq()
311 s->slaves[i].intreg_pending &= ~(1 << pil); in slavio_set_irq()
319 static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level) in slavio_set_timer_irq_cpu() argument
323 trace_slavio_set_timer_irq_cpu(cpu, level); in slavio_set_timer_irq_cpu()
326 s->slaves[cpu].intreg_pending |= CPU_IRQ_TIMER_IN; in slavio_set_timer_irq_cpu()
328 s->slaves[cpu].intreg_pending &= ~CPU_IRQ_TIMER_IN; in slavio_set_timer_irq_cpu()
339 slavio_set_timer_irq_cpu(opaque, irq - 32, level); in slavio_set_irq_all()
382 s->slaves[i].intreg_pending = 0; in slavio_intctl_reset()
383 s->slaves[i].irl_out = 0; in slavio_intctl_reset()
385 s->intregm_disabled = ~MASTER_IRQ_MASK; in slavio_intctl_reset()
386 s->intregm_pending = 0; in slavio_intctl_reset()
387 s->target_cpu = 0; in slavio_intctl_reset()
397 *irq_counts = s->irq_count; in slavio_intctl_get_statistics()
398 *nb_irqs = ARRAY_SIZE(s->irq_count); in slavio_intctl_get_statistics()
409 g_string_append_printf(buf, "per-cpu %d: pending 0x%08x\n", i, in slavio_intctl_print_info()
410 s->slaves[i].intreg_pending); in slavio_intctl_print_info()
413 s->intregm_pending, s->intregm_disabled); in slavio_intctl_print_info()
425 memory_region_init_io(&s->iomem, obj, &slavio_intctlm_mem_ops, s, in slavio_intctl_init()
426 "master-interrupt-controller", INTCTLM_SIZE); in slavio_intctl_init()
427 sysbus_init_mmio(sbd, &s->iomem); in slavio_intctl_init()
431 "slave-interrupt-controller-%i", i); in slavio_intctl_init()
433 sysbus_init_irq(sbd, &s->cpu_irqs[i][j]); in slavio_intctl_init()
435 memory_region_init_io(&s->slaves[i].iomem, OBJECT(s), in slavio_intctl_init()
437 &s->slaves[i], slave_name, INTCTL_SIZE); in slavio_intctl_init()
438 sysbus_init_mmio(sbd, &s->slaves[i].iomem); in slavio_intctl_init()
439 s->slaves[i].cpu = i; in slavio_intctl_init()
440 s->slaves[i].master = s; in slavio_intctl_init()
450 dc->vmsd = &vmstate_intctl; in slavio_intctl_class_init()
452 ic->get_statistics = slavio_intctl_get_statistics; in slavio_intctl_class_init()
454 ic->print_info = slavio_intctl_print_info; in slavio_intctl_class_init()