Commit 385f1dbb authored by Jeenu Viswambharan's avatar Jeenu Viswambharan
Browse files

GIC: Fix Group 0 enabling



At present, the GIC drivers enable Group 0 interrupts only if there are
Secure SPIs listed in the interrupt properties/list. This means that,
even if there are Group 0 SGIs/PPIs configured, the group remained
disabled in the absence of a Group 0 SPI.

Modify both GICv2 and GICv3 SGI/PPI configuration to enable Group 0 when
corresponding SGIs/PPIs are present.

Change-Id: Id123e8aaee0c22b476eebe3800340906d83bbc6d
Signed-off-by: default avatarJeenu Viswambharan <jeenu.viswambharan@arm.com>
parent 058efeef
...@@ -72,6 +72,8 @@ void gicv2_cpuif_disable(void) ...@@ -72,6 +72,8 @@ void gicv2_cpuif_disable(void)
******************************************************************************/ ******************************************************************************/
void gicv2_pcpu_distif_init(void) void gicv2_pcpu_distif_init(void)
{ {
unsigned int ctlr;
assert(driver_data); assert(driver_data);
assert(driver_data->gicd_base); assert(driver_data->gicd_base);
...@@ -89,6 +91,13 @@ void gicv2_pcpu_distif_init(void) ...@@ -89,6 +91,13 @@ void gicv2_pcpu_distif_init(void)
driver_data->g0_interrupt_array); driver_data->g0_interrupt_array);
} }
#endif #endif
/* Enable G0 interrupts if not already */
ctlr = gicd_read_ctlr(driver_data->gicd_base);
if ((ctlr & CTLR_ENABLE_G0_BIT) == 0) {
gicd_write_ctlr(driver_data->gicd_base,
ctlr | CTLR_ENABLE_G0_BIT);
}
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -541,12 +541,13 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, ...@@ -541,12 +541,13 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
/******************************************************************************* /*******************************************************************************
* Helper function to configure properties of secure G0 and G1S PPIs and SGIs. * Helper function to configure properties of secure G0 and G1S PPIs and SGIs.
******************************************************************************/ ******************************************************************************/
void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, unsigned int gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
const interrupt_prop_t *interrupt_props, const interrupt_prop_t *interrupt_props,
unsigned int interrupt_props_num) unsigned int interrupt_props_num)
{ {
unsigned int i; unsigned int i;
const interrupt_prop_t *current_prop; const interrupt_prop_t *current_prop;
unsigned int ctlr_enable = 0;
/* Make sure there's a valid property array */ /* Make sure there's a valid property array */
assert(interrupt_props != NULL); assert(interrupt_props != NULL);
...@@ -564,10 +565,13 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, ...@@ -564,10 +565,13 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
/* Configure this interrupt as G0 or a G1S interrupt */ /* Configure this interrupt as G0 or a G1S interrupt */
assert((current_prop->intr_grp == INTR_GROUP0) || assert((current_prop->intr_grp == INTR_GROUP0) ||
(current_prop->intr_grp == INTR_GROUP1S)); (current_prop->intr_grp == INTR_GROUP1S));
if (current_prop->intr_grp == INTR_GROUP1S) if (current_prop->intr_grp == INTR_GROUP1S) {
gicr_set_igrpmodr0(gicr_base, current_prop->intr_num); gicr_set_igrpmodr0(gicr_base, current_prop->intr_num);
else ctlr_enable |= CTLR_ENABLE_G1S_BIT;
} else {
gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num); gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num);
ctlr_enable |= CTLR_ENABLE_G0_BIT;
}
/* Set the priority of this interrupt */ /* Set the priority of this interrupt */
gicr_set_ipriorityr(gicr_base, current_prop->intr_num, gicr_set_ipriorityr(gicr_base, current_prop->intr_num,
...@@ -586,4 +590,6 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, ...@@ -586,4 +590,6 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
/* Enable this interrupt */ /* Enable this interrupt */
gicr_set_isenabler0(gicr_base, current_prop->intr_num); gicr_set_isenabler0(gicr_base, current_prop->intr_num);
} }
return ctlr_enable;
} }
...@@ -224,12 +224,16 @@ void gicv3_distif_init(void) ...@@ -224,12 +224,16 @@ void gicv3_distif_init(void)
void gicv3_rdistif_init(unsigned int proc_num) void gicv3_rdistif_init(unsigned int proc_num)
{ {
uintptr_t gicr_base; uintptr_t gicr_base;
unsigned int bitmap = 0;
uint32_t ctlr;
assert(gicv3_driver_data); assert(gicv3_driver_data);
assert(proc_num < gicv3_driver_data->rdistif_num); assert(proc_num < gicv3_driver_data->rdistif_num);
assert(gicv3_driver_data->rdistif_base_addrs); assert(gicv3_driver_data->rdistif_base_addrs);
assert(gicv3_driver_data->gicd_base); assert(gicv3_driver_data->gicd_base);
assert(gicd_read_ctlr(gicv3_driver_data->gicd_base) & CTLR_ARE_S_BIT);
ctlr = gicd_read_ctlr(gicv3_driver_data->gicd_base);
assert(ctlr & CTLR_ARE_S_BIT);
assert(IS_IN_EL3()); assert(IS_IN_EL3());
...@@ -244,7 +248,7 @@ void gicv3_rdistif_init(unsigned int proc_num) ...@@ -244,7 +248,7 @@ void gicv3_rdistif_init(unsigned int proc_num)
#if !ERROR_DEPRECATED #if !ERROR_DEPRECATED
if (gicv3_driver_data->interrupt_props != NULL) { if (gicv3_driver_data->interrupt_props != NULL) {
#endif #endif
gicv3_secure_ppi_sgi_configure_props(gicr_base, bitmap = gicv3_secure_ppi_sgi_configure_props(gicr_base,
gicv3_driver_data->interrupt_props, gicv3_driver_data->interrupt_props,
gicv3_driver_data->interrupt_props_num); gicv3_driver_data->interrupt_props_num);
#if !ERROR_DEPRECATED #if !ERROR_DEPRECATED
...@@ -258,6 +262,7 @@ void gicv3_rdistif_init(unsigned int proc_num) ...@@ -258,6 +262,7 @@ void gicv3_rdistif_init(unsigned int proc_num)
gicv3_driver_data->g1s_interrupt_num, gicv3_driver_data->g1s_interrupt_num,
gicv3_driver_data->g1s_interrupt_array, gicv3_driver_data->g1s_interrupt_array,
INTR_GROUP1S); INTR_GROUP1S);
bitmap |= CTLR_ENABLE_G1S_BIT;
} }
/* Configure the G0 SGIs/PPIs */ /* Configure the G0 SGIs/PPIs */
...@@ -266,9 +271,14 @@ void gicv3_rdistif_init(unsigned int proc_num) ...@@ -266,9 +271,14 @@ void gicv3_rdistif_init(unsigned int proc_num)
gicv3_driver_data->g0_interrupt_num, gicv3_driver_data->g0_interrupt_num,
gicv3_driver_data->g0_interrupt_array, gicv3_driver_data->g0_interrupt_array,
INTR_GROUP0); INTR_GROUP0);
bitmap |= CTLR_ENABLE_G0_BIT;
} }
} }
#endif #endif
/* Enable interrupt groups as required, if not already */
if ((ctlr & bitmap) != bitmap)
gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE);
} }
/******************************************************************************* /*******************************************************************************
......
...@@ -95,7 +95,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, ...@@ -95,7 +95,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base,
const unsigned int *sec_intr_list, const unsigned int *sec_intr_list,
unsigned int int_grp); unsigned int int_grp);
#endif #endif
void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, unsigned int gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base,
const interrupt_prop_t *interrupt_props, const interrupt_prop_t *interrupt_props,
unsigned int interrupt_props_num); unsigned int interrupt_props_num);
unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base, unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment