aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Bellows <greg.bellows@linaro.org>2014-10-14 13:25:35 -0500
committerGreg Bellows <greg.bellows@linaro.org>2014-10-15 11:35:49 -0500
commitd51a3436b9c42397b88e28e6a2745ace9c229121 (patch)
tree8e8399d5db86173d1b5b2ab6aaaa965e2a3411e7
parentb79e4a2c04109f55536255ead7c4036a746c5b25 (diff)
WORKAROUND - Reenable group 1 interruptspmm.v6.uart.tzgic_v2
This patch is a workaround to reenable group 1 interrupts in both the GICC_CTLR and GICD_CTLR is disabled on write. It is believed that Linux is inadvertantly disabling these causing group 1 interrupts to not be raised. Signed-off-by: Greg Bellows <greg.bellows@linaro.org>
-rw-r--r--hw/intc/arm_gic.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 85a4be253..5d96a14d0 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -452,6 +452,14 @@ void gic_set_cpu_control(GICState *s, int cpu, uint32_t value)
s->cpu_control[cpu][1] &= ~GICC_CTLR_NS_EN_GRP1;
s->cpu_control[cpu][1] |=
(value & GICC_CTLR_S_EN_GRP1) ? GICC_CTLR_NS_EN_GRP1 : 0;
+ if ((s->cpu_control[cpu][0] & GICC_CTLR_S_EN_GRP0) == 1 &&
+ (s->cpu_control[cpu][1] & GICC_CTLR_NS_EN_GRP1) == 0) {
+ DPRINTF("Group 1 interrupts disabled, reenabling\n");
+ s->cpu_control[cpu][0] |= GICC_CTLR_S_EN_GRP1;
+ s->cpu_control[cpu][0] |= GICC_CTLR_S_FIQ_EN;
+ s->cpu_control[cpu][1] |= GICC_CTLR_NS_EN_GRP1;
+ }
+
DPRINTF("CPU Interface %d: Group0 Interrupts %sabled, "
"Group1 Interrupts %sabled\n", cpu,
(s->cpu_control[cpu][0] & GICC_CTLR_S_EN_GRP0) ? "En" : "Dis",
@@ -800,6 +808,10 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
* enabled bit is bit[1] in the secure/GICv2 GICD_CTLR..
*/
s->enabled_grp[1] = (value >> 1) & 0x1; /* EnableGrp1 */
+ if ((s->enabled_grp[1] & 0x1) == 0) {
+ DPRINTF("Group 1 interrupts disabled, reenabling\n");
+ s->enabled_grp[1] = 0x1;
+ }
DPRINTF("Group0 distribution %sabled\n"
"Group1 distribution %sabled\n",
s->enabled_grp[0] ? "En" : "Dis",
@@ -892,6 +904,10 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
DPRINTF("Disabled IRQ %d\n", irq + i);
}
GIC_CLEAR_ENABLED(irq + i, cm);
+ if ((34 == irq+i)) {
+ GIC_SET_ENABLED(irq + i, cm);
+ DPRINTF("Reenabled IRQ 34\n");
+ }
}
}
} else if (offset < 0x280) {