Lines Matching +full:cpu +full:- +full:interrupt +full:- +full:controller

2  * ARM Generic Interrupt Controller v3 (emulation)
12 /* This file contains implementation code for an interrupt controller
28 * pending interrupt for this CPU. We also return true if in irqbetter()
29 * the current recorded highest priority pending interrupt in irqbetter()
33 if (prio != cs->hppi.prio) { in irqbetter()
34 return prio < cs->hppi.prio; in irqbetter()
38 * The same priority IRQ with non-maskable property should signal to in irqbetter()
39 * the CPU as it have the priority higher than the labelled 0x80 or 0x00. in irqbetter()
41 if (nmi != cs->hppi.nmi) { in irqbetter()
46 * IMPDEF choice which of them to signal to the CPU. We choose to in irqbetter()
47 * signal the one with the lowest interrupt number. in irqbetter()
49 if (irq <= cs->hppi.irq) { in irqbetter()
59 * of 32), and return a 32-bit integer which has a bit set for each in gicd_int_pending()
60 * interrupt that is eligible to be signaled to the CPU interface. in gicd_int_pending()
62 * An interrupt is pending if: in gicd_int_pending()
67 * Conveniently we can bulk-calculate this with bitwise operations. in gicd_int_pending()
70 uint32_t pending = *gic_bmp_ptr32(s->pending, irq); in gicd_int_pending()
71 uint32_t edge_trigger = *gic_bmp_ptr32(s->edge_trigger, irq); in gicd_int_pending()
72 uint32_t level = *gic_bmp_ptr32(s->level, irq); in gicd_int_pending()
73 uint32_t group = *gic_bmp_ptr32(s->group, irq); in gicd_int_pending()
74 uint32_t grpmod = *gic_bmp_ptr32(s->grpmod, irq); in gicd_int_pending()
75 uint32_t enable = *gic_bmp_ptr32(s->enabled, irq); in gicd_int_pending()
76 uint32_t active = *gic_bmp_ptr32(s->active, irq); in gicd_int_pending()
82 if (s->gicd_ctlr & GICD_CTLR_DS) { in gicd_int_pending()
87 if (s->gicd_ctlr & GICD_CTLR_EN_GRP1NS) { in gicd_int_pending()
90 if (s->gicd_ctlr & GICD_CTLR_EN_GRP1S) { in gicd_int_pending()
93 if (s->gicd_ctlr & GICD_CTLR_EN_GRP0) { in gicd_int_pending()
104 * and return a 32-bit integer which has a bit set for each interrupt in gicr_int_pending()
105 * that is eligible to be signaled to the CPU interface. in gicr_int_pending()
107 * An interrupt is pending if: in gicr_int_pending()
112 * Conveniently we can bulk-calculate this with bitwise operations. in gicr_int_pending()
116 pend = cs->gicr_ipendr0 | (~cs->edge_trigger & cs->level); in gicr_int_pending()
117 pend &= cs->gicr_ienabler0; in gicr_int_pending()
118 pend &= ~cs->gicr_iactiver0; in gicr_int_pending()
120 if (cs->gic->gicd_ctlr & GICD_CTLR_DS) { in gicr_int_pending()
123 grpmod = cs->gicr_igrpmodr0; in gicr_int_pending()
127 if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) { in gicr_int_pending()
128 grpmask |= cs->gicr_igroupr0; in gicr_int_pending()
130 if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1S) { in gicr_int_pending()
131 grpmask |= (~cs->gicr_igroupr0 & grpmod); in gicr_int_pending()
133 if (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP0) { in gicr_int_pending()
134 grpmask |= (~cs->gicr_igroupr0 & ~grpmod); in gicr_int_pending()
147 nmi = extract32(cs->gicr_inmir0, irq, 1); in gicv3_get_priority()
149 nmi = *gic_bmp_ptr32(cs->gic->nmi, irq); in gicv3_get_priority()
154 /* DS = 0 & Non-secure NMI */ in gicv3_get_priority()
155 if (!(cs->gic->gicd_ctlr & GICD_CTLR_DS) && in gicv3_get_priority()
156 ((is_redist && extract32(cs->gicr_igroupr0, irq, 1)) || in gicv3_get_priority()
157 (!is_redist && gicv3_gicd_group_test(cs->gic, irq)))) { in gicv3_get_priority()
167 *prio = cs->gicr_ipriorityr[irq]; in gicv3_get_priority()
169 *prio = cs->gic->gicd_ipriority[irq]; in gicv3_get_priority()
175 /* Update the interrupt status after state in a redistributor
176 * or CPU interface has changed, but don't tell the CPU i/f.
180 /* Find the highest priority pending interrupt among the in gicv3_redist_update_noirqset()
190 * signaled to the CPU interface. in gicv3_redist_update_noirqset()
201 cs->hppi.irq = i; in gicv3_redist_update_noirqset()
202 cs->hppi.prio = prio; in gicv3_redist_update_noirqset()
203 cs->hppi.nmi = nmi; in gicv3_redist_update_noirqset()
210 cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq); in gicv3_redist_update_noirqset()
213 if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable && in gicv3_redist_update_noirqset()
214 (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) && in gicv3_redist_update_noirqset()
215 (cs->hpplpi.prio != 0xff)) { in gicv3_redist_update_noirqset()
216 if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio, cs->hpplpi.nmi)) { in gicv3_redist_update_noirqset()
217 cs->hppi.irq = cs->hpplpi.irq; in gicv3_redist_update_noirqset()
218 cs->hppi.prio = cs->hpplpi.prio; in gicv3_redist_update_noirqset()
219 cs->hppi.nmi = cs->hpplpi.nmi; in gicv3_redist_update_noirqset()
220 cs->hppi.grp = cs->hpplpi.grp; in gicv3_redist_update_noirqset()
225 /* If the best interrupt we just found would preempt whatever in gicv3_redist_update_noirqset()
226 * was the previous best interrupt before this update, then in gicv3_redist_update_noirqset()
228 * If we didn't find an interrupt that would preempt the previous in gicv3_redist_update_noirqset()
230 * previous pending interrupt at all), then that is still valid, and in gicv3_redist_update_noirqset()
233 * interrupt has reduced in priority and any other interrupt could in gicv3_redist_update_noirqset()
236 if (!seenbetter && cs->hppi.prio != 0xff && in gicv3_redist_update_noirqset()
237 (cs->hppi.irq < GIC_INTERNAL || in gicv3_redist_update_noirqset()
238 cs->hppi.irq >= GICV3_LPI_INTID_START)) { in gicv3_redist_update_noirqset()
239 gicv3_full_update_noirqset(cs->gic); in gicv3_redist_update_noirqset()
244 * CPU interface has changed, and inform the CPU i/f of
245 * its new highest priority pending interrupt.
255 * but don't tell the CPU i/f.
267 for (i = 0; i < s->num_cpu; i++) { in gicv3_update_noirqset()
268 s->cpu[i].seenbetter = false; in gicv3_update_noirqset()
271 /* Find the highest priority pending interrupt in this range. */ in gicv3_update_noirqset()
283 cs = s->gicd_irouter_target[i]; in gicv3_update_noirqset()
285 /* Interrupts targeting no implemented CPU should remain pending in gicv3_update_noirqset()
286 * and not be forwarded to any CPU. in gicv3_update_noirqset()
292 cs->hppi.irq = i; in gicv3_update_noirqset()
293 cs->hppi.prio = prio; in gicv3_update_noirqset()
294 cs->hppi.nmi = nmi; in gicv3_update_noirqset()
295 cs->seenbetter = true; in gicv3_update_noirqset()
299 /* If the best interrupt we just found would preempt whatever in gicv3_update_noirqset()
300 * was the previous best interrupt before this update, then in gicv3_update_noirqset()
302 * If we didn't find an interrupt that would preempt the previous in gicv3_update_noirqset()
304 * no previous pending interrupt at all), then that in gicv3_update_noirqset()
307 * interrupt has reduced in priority and any other interrupt could in gicv3_update_noirqset()
310 for (i = 0; i < s->num_cpu; i++) { in gicv3_update_noirqset()
311 GICv3CPUState *cs = &s->cpu[i]; in gicv3_update_noirqset()
313 if (cs->seenbetter) { in gicv3_update_noirqset()
314 cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq); in gicv3_update_noirqset()
317 if (!cs->seenbetter && cs->hppi.prio != 0xff && in gicv3_update_noirqset()
318 cs->hppi.irq >= start && cs->hppi.irq < start + len) { in gicv3_update_noirqset()
330 for (i = 0; i < s->num_cpu; i++) { in gicv3_update()
331 gicv3_cpuif_update(&s->cpu[i]); in gicv3_update()
342 for (i = 0; i < s->num_cpu; i++) { in gicv3_full_update_noirqset()
343 s->cpu[i].hppi.prio = 0xff; in gicv3_full_update_noirqset()
344 s->cpu[i].hppi.nmi = false; in gicv3_full_update_noirqset()
352 gicv3_update_noirqset(s, GIC_INTERNAL, s->num_irq - GIC_INTERNAL); in gicv3_full_update_noirqset()
354 for (i = 0; i < s->num_cpu; i++) { in gicv3_full_update_noirqset()
355 gicv3_redist_update_noirqset(&s->cpu[i]); in gicv3_full_update_noirqset()
367 for (i = 0; i < s->num_cpu; i++) { in gicv3_full_update()
368 gicv3_cpuif_update(&s->cpu[i]); in gicv3_full_update()
376 * [0..N-1] : external interrupts in gicv3_set_irq()
377 * [N..N+31] : PPI (internal) interrupts for CPU 0 in gicv3_set_irq()
378 * [N+32..N+63] : PPI (internal interrupts for CPU 1 in gicv3_set_irq()
383 if (irq < (s->num_irq - GIC_INTERNAL)) { in gicv3_set_irq()
384 /* external interrupt (SPI) */ in gicv3_set_irq()
387 /* per-cpu interrupt (PPI) */ in gicv3_set_irq()
388 int cpu; in gicv3_set_irq() local
390 irq -= (s->num_irq - GIC_INTERNAL); in gicv3_set_irq()
391 cpu = irq / GIC_INTERNAL; in gicv3_set_irq()
393 assert(cpu < s->num_cpu); in gicv3_set_irq()
398 gicv3_redist_set_irq(&s->cpu[cpu], irq, level); in gicv3_set_irq()
406 * pending interrupt, but don't set IRQ or FIQ lines. in arm_gicv3_post_load()
408 for (i = 0; i < s->num_cpu; i++) { in arm_gicv3_post_load()
409 gicv3_redist_update_lpi_only(&s->cpu[i]); in arm_gicv3_post_load()
444 agc->parent_realize(dev, &local_err); in arm_gic_realize()
461 agcc->post_load = arm_gicv3_post_load; in arm_gicv3_class_init()
462 device_class_set_parent_realize(dc, arm_gic_realize, &agc->parent_realize); in arm_gicv3_class_init()