summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorachingupta <achin.gupta@arm.com>2015-03-26 15:42:28 +0000
committerachingupta <achin.gupta@arm.com>2015-03-26 15:42:28 +0000
commit93713e7fb7df11edc8ed2ed8f3010a39b74bbca0 (patch)
treeeca8435a0575e70af3b1e1acedcc83f5abee8b5f
parent27a51c72489ebb11bbda86069d6d3ae6df2275f7 (diff)
parent8cfc3fd2954380afdea0590b359a665102ea7ef3 (diff)
downloadarm-trusted-firmware-93713e7fb7df11edc8ed2ed8f3010a39b74bbca0.tar.gz
Merge pull request #273 from achingupta/ag/genfw-389
Set group status of PPIs and SGIs correctly on GICv3 systems
-rw-r--r--drivers/arm/gic/arm_gic.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/arm/gic/arm_gic.c b/drivers/arm/gic/arm_gic.c
index 58fbc89a7..2888e719f 100644
--- a/drivers/arm/gic/arm_gic.c
+++ b/drivers/arm/gic/arm_gic.c
@@ -219,13 +219,10 @@ void arm_gic_cpuif_deactivate(void)
******************************************************************************/
void arm_gic_pcpu_distif_setup(void)
{
- unsigned int index, irq_num;
+ unsigned int index, irq_num, sec_ppi_sgi_mask;
assert(g_gicd_base);
- /* Mark all 32 SGI+PPI interrupts as Group 1 (non-secure) */
- gicd_write_igroupr(g_gicd_base, 0, ~0);
-
/* Setup PPI priorities doing four at a time */
for (index = 0; index < 32; index += 4) {
gicd_write_ipriorityr(g_gicd_base, index,
@@ -233,16 +230,25 @@ void arm_gic_pcpu_distif_setup(void)
}
assert(g_irq_sec_ptr);
+ sec_ppi_sgi_mask = 0;
for (index = 0; index < g_num_irqs; index++) {
irq_num = g_irq_sec_ptr[index];
if (irq_num < MIN_SPI_ID) {
- /* We have an SGI or a PPI */
- gicd_clr_igroupr(g_gicd_base, irq_num);
+ /* We have an SGI or a PPI. They are Group0 at reset */
+ sec_ppi_sgi_mask |= 1U << irq_num;
gicd_set_ipriorityr(g_gicd_base, irq_num,
GIC_HIGHEST_SEC_PRIORITY);
gicd_set_isenabler(g_gicd_base, irq_num);
}
}
+
+ /*
+ * Invert the bitmask to create a mask for non-secure PPIs and
+ * SGIs. Program the GICD_IGROUPR0 with this bit mask. This write will
+ * update the GICR_IGROUPR0 as well in case we are running on a GICv3
+ * system. This is critical if GICD_CTLR.ARE_NS=1.
+ */
+ gicd_write_igroupr(g_gicd_base, 0, ~sec_ppi_sgi_mask);
}
/*******************************************************************************