static void translate_active(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) { int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; if (to_kernel) { *field = GIC_TEST_ACTIVE(irq, cm); } else { if (*field & 1) { GIC_SET_ACTIVE(irq, cm); } } }
static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) { gic_state *s = (gic_state *)opaque; uint32_t res; int irq; int i; offset -= s->base + 0x1000; if (offset < 0x100) { if (offset == 0) return s->enabled; if (offset == 4) return (GIC_NIRQ / 32) - 1; if (offset < 0x08) return 0; goto bad_reg; } else if (offset < 0x200) { /* Interrupt Set/Clear Enable. */ if (offset < 0x180) irq = (offset - 0x100) * 8; else irq = (offset - 0x180) * 8; if (irq >= GIC_NIRQ) goto bad_reg; res = 0; for (i = 0; i < 8; i++) { if (GIC_TEST_ENABLED(irq + i)) { res |= (1 << i); } } } else if (offset < 0x300) { /* Interrupt Set/Clear Pending. */ if (offset < 0x280) irq = (offset - 0x200) * 8; else irq = (offset - 0x280) * 8; if (irq >= GIC_NIRQ) goto bad_reg; res = 0; for (i = 0; i < 8; i++) { if (GIC_TEST_PENDING(irq + i)) { res |= (1 << i); } } } else if (offset < 0x400) { /* Interrupt Active. */ irq = (offset - 0x300) * 8; if (irq >= GIC_NIRQ) goto bad_reg; res = 0; for (i = 0; i < 8; i++) { if (GIC_TEST_ACTIVE(irq + i)) { res |= (1 << i); } } } else if (offset < 0x800) { /* Interrupt Priority. */ irq = offset - 0x400; if (irq >= GIC_NIRQ) goto bad_reg; res = s->priority[irq]; } else if (offset < 0xc00) { /* Interrupt CPU Target. */ irq = offset - 0x800; if (irq >= GIC_NIRQ) goto bad_reg; res = s->irq_target[irq]; } else if (offset < 0xf00) { /* Interrupt Configuration. */ irq = (offset - 0xc00) * 2; if (irq >= GIC_NIRQ) goto bad_reg; res = 0; for (i = 0; i < 4; i++) { if (GIC_TEST_MODEL(irq + i)) res |= (1 << (i * 2)); if (GIC_TEST_TRIGGER(irq + i)) res |= (2 << (i * 2)); } } else if (offset < 0xfe0) { goto bad_reg; } else /* offset >= 0xfe0 */ { if (offset & 3) { res = 0; } else { res = gic_id[(offset - 0xfe0) >> 2]; } } return res; bad_reg: cpu_abort (cpu_single_env, "gic_dist_readb: Bad offset %x\n", offset); return 0; }