intc/arm_gic: Implement GICD_ISACTIVERn and GICD_ICACTIVERn registers
Implement GICD_ISACTIVERn and GICD_ICACTIVERn registers in the GICv2. Those registers allow to set or clear the active state of an IRQ in the distributor. Signed-off-by: Luc Michel <luc.michel@greensocs.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20180727095421.386-3-luc.michel@greensocs.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
67ce697ac8
commit
3bb0b03897
|
@ -725,8 +725,16 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs)
|
|||
}
|
||||
}
|
||||
} else if (offset < 0x400) {
|
||||
/* Interrupt Active. */
|
||||
irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
|
||||
/* Interrupt Set/Clear Active. */
|
||||
if (offset < 0x380) {
|
||||
irq = (offset - 0x300) * 8;
|
||||
} else if (s->revision == 2) {
|
||||
irq = (offset - 0x380) * 8;
|
||||
} else {
|
||||
goto bad_reg;
|
||||
}
|
||||
|
||||
irq += GIC_BASE_IRQ;
|
||||
if (irq >= s->num_irq)
|
||||
goto bad_reg;
|
||||
res = 0;
|
||||
|
@ -1007,9 +1015,54 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
|
|||
GIC_DIST_CLEAR_PENDING(irq + i, ALL_CPU_MASK);
|
||||
}
|
||||
}
|
||||
} else if (offset < 0x380) {
|
||||
/* Interrupt Set Active. */
|
||||
if (s->revision != 2) {
|
||||
goto bad_reg;
|
||||
}
|
||||
|
||||
irq = (offset - 0x300) * 8 + GIC_BASE_IRQ;
|
||||
if (irq >= s->num_irq) {
|
||||
goto bad_reg;
|
||||
}
|
||||
|
||||
/* This register is banked per-cpu for PPIs */
|
||||
int cm = irq < GIC_INTERNAL ? (1 << cpu) : ALL_CPU_MASK;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s->security_extn && !attrs.secure &&
|
||||
!GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) {
|
||||
continue; /* Ignore Non-secure access of Group0 IRQ */
|
||||
}
|
||||
|
||||
if (value & (1 << i)) {
|
||||
GIC_DIST_SET_ACTIVE(irq + i, cm);
|
||||
}
|
||||
}
|
||||
} else if (offset < 0x400) {
|
||||
/* Interrupt Active. */
|
||||
goto bad_reg;
|
||||
/* Interrupt Clear Active. */
|
||||
if (s->revision != 2) {
|
||||
goto bad_reg;
|
||||
}
|
||||
|
||||
irq = (offset - 0x380) * 8 + GIC_BASE_IRQ;
|
||||
if (irq >= s->num_irq) {
|
||||
goto bad_reg;
|
||||
}
|
||||
|
||||
/* This register is banked per-cpu for PPIs */
|
||||
int cm = irq < GIC_INTERNAL ? (1 << cpu) : ALL_CPU_MASK;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (s->security_extn && !attrs.secure &&
|
||||
!GIC_DIST_TEST_GROUP(irq + i, 1 << cpu)) {
|
||||
continue; /* Ignore Non-secure access of Group0 IRQ */
|
||||
}
|
||||
|
||||
if (value & (1 << i)) {
|
||||
GIC_DIST_CLEAR_ACTIVE(irq + i, cm);
|
||||
}
|
||||
}
|
||||
} else if (offset < 0x800) {
|
||||
/* Interrupt Priority. */
|
||||
irq = (offset - 0x400) + GIC_BASE_IRQ;
|
||||
|
|
Loading…
Reference in a new issue