static void arm_gic_common_reset(DeviceState *dev) { GICState *s = ARM_GIC_COMMON(dev); int i; memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state)); for (i = 0 ; i < s->num_cpu; i++) { if (s->revision == REV_11MPCORE) { s->priority_mask[i] = 0xf0; } else { s->priority_mask[i] = 0; } s->current_pending[i] = 1023; s->running_irq[i] = 1023; s->running_priority[i] = 0x100; s->cpu_enabled[i] = false; } for (i = 0; i < 16; i++) { GIC_SET_ENABLED(i, ALL_CPU_MASK); GIC_SET_EDGE_TRIGGER(i); } if (s->num_cpu == 1) { /* For uniprocessor GICs all interrupts always target the sole CPU */ for (i = 0; i < GIC_MAXIRQ; i++) { s->irq_target[i] = 1; } } s->enabled = false; }
static void arm_gic_common_realize(DeviceState *dev, Error **errp) { GICState *s = ARM_GIC_COMMON(dev); int num_irq = s->num_irq; if (s->num_cpu > GIC_NCPU) { error_setg(errp, "requested %u CPUs exceeds GIC maximum %d", s->num_cpu, GIC_NCPU); return; } s->num_irq += GIC_BASE_IRQ; if (s->num_irq > GIC_MAXIRQ) { error_setg(errp, "requested %u interrupt lines exceeds GIC maximum %d", num_irq, GIC_MAXIRQ); return; } /* ITLinesNumber is represented as (N / 32) - 1 (see * gic_dist_readb) so this is an implementation imposed * restriction, not an architectural one: */ if (s->num_irq < 32 || (s->num_irq % 32)) { error_setg(errp, "%d interrupt lines unsupported: not divisible by 32", num_irq); return; } if (s->security_extn && (s->revision == REV_11MPCORE || s->revision == REV_NVIC)) { error_setg(errp, "this GIC revision does not implement " "the security extensions"); return; } }
static void arm_gic_common_linux_init(ARMLinuxBootIf *obj, bool secure_boot) { GICState *s = ARM_GIC_COMMON(obj); if (s->security_extn && !secure_boot) { /* We're directly booting a kernel into NonSecure. If this GIC * implements the security extensions then we must configure it * to have all the interrupts be NonSecure (this is a job that * is done by the Secure boot firmware in real hardware, and in * this mode QEMU is acting as a minimalist firmware-and-bootloader * equivalent). */ s->irq_reset_nonsecure = true; } }
static void arm_gic_common_reset(DeviceState *dev) { GICState *s = ARM_GIC_COMMON(dev); int i, j; memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state)); for (i = 0 ; i < s->num_cpu; i++) { if (s->revision == REV_11MPCORE) { s->priority_mask[i] = 0xf0; } else { s->priority_mask[i] = 0; } s->current_pending[i] = 1023; s->running_irq[i] = 1023; s->running_priority[i] = 0x100; s->cpu_ctlr[i] = 0; s->bpr[i] = GIC_MIN_BPR; s->abpr[i] = GIC_MIN_ABPR; for (j = 0; j < GIC_INTERNAL; j++) { s->priority1[j][i] = 0; } for (j = 0; j < GIC_NR_SGIS; j++) { s->sgi_pending[j][i] = 0; } } for (i = 0; i < GIC_NR_SGIS; i++) { GIC_SET_ENABLED(i, ALL_CPU_MASK); GIC_SET_EDGE_TRIGGER(i); } for (i = 0; i < ARRAY_SIZE(s->priority2); i++) { s->priority2[i] = 0; } for (i = 0; i < GIC_MAXIRQ; i++) { /* For uniprocessor GICs all interrupts always target the sole CPU */ if (s->num_cpu == 1) { s->irq_target[i] = 1; } else { s->irq_target[i] = 0; } } s->ctlr = 0; }
static void arm_gic_common_reset(DeviceState *dev) { GICState *s = ARM_GIC_COMMON(dev); int i, j; int resetprio; /* If we're resetting a TZ-aware GIC as if secure firmware * had set it up ready to start a kernel in non-secure, * we need to set interrupt priorities to a "zero for the * NS view" value. This is particularly critical for the * priority_mask[] values, because if they are zero then NS * code cannot ever rewrite the priority to anything else. */ if (s->security_extn && s->irq_reset_nonsecure) { resetprio = 0x80; } else { resetprio = 0; } memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state)); for (i = 0 ; i < s->num_cpu; i++) { if (s->revision == REV_11MPCORE) { s->priority_mask[i] = 0xf0; } else { s->priority_mask[i] = resetprio; } s->current_pending[i] = 1023; s->running_priority[i] = 0x100; s->cpu_ctlr[i] = 0; s->bpr[i] = GIC_MIN_BPR; s->abpr[i] = GIC_MIN_ABPR; for (j = 0; j < GIC_INTERNAL; j++) { s->priority1[j][i] = resetprio; } for (j = 0; j < GIC_NR_SGIS; j++) { s->sgi_pending[j][i] = 0; } } for (i = 0; i < GIC_NR_SGIS; i++) { GIC_SET_ENABLED(i, ALL_CPU_MASK); GIC_SET_EDGE_TRIGGER(i); } for (i = 0; i < ARRAY_SIZE(s->priority2); i++) { s->priority2[i] = resetprio; } for (i = 0; i < GIC_MAXIRQ; i++) { /* For uniprocessor GICs all interrupts always target the sole CPU */ if (s->num_cpu == 1) { s->irq_target[i] = 1; } else { s->irq_target[i] = 0; } } if (s->security_extn && s->irq_reset_nonsecure) { for (i = 0; i < GIC_MAXIRQ; i++) { GIC_SET_GROUP(i, ALL_CPU_MASK); } } s->ctlr = 0; }