diff options
author | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-11-07 08:38:23 +0000 |
---|---|---|
committer | Jeenu Viswambharan <jeenu.viswambharan@arm.com> | 2017-11-13 07:49:30 +0000 |
commit | 385f1dbb294b36c5fbdbbf3d10b6cb105239a76e (patch) | |
tree | 8426ee28b85307e7c9131233d098dadb54c983b5 /drivers | |
parent | 058efeef98315d21f59092c80dd1d24d58008b4d (diff) |
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: Jeenu Viswambharan <jeenu.viswambharan@arm.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/arm/gic/v2/gicv2_main.c | 9 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_helpers.c | 12 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 14 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_private.h | 2 |
4 files changed, 31 insertions, 6 deletions
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 4b0984d8..72f15cd7 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -72,6 +72,8 @@ void gicv2_cpuif_disable(void) ******************************************************************************/ void gicv2_pcpu_distif_init(void) { + unsigned int ctlr; + assert(driver_data); assert(driver_data->gicd_base); @@ -89,6 +91,13 @@ void gicv2_pcpu_distif_init(void) driver_data->g0_interrupt_array); } #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); + } } /******************************************************************************* diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 25226956..dee63f18 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -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. ******************************************************************************/ -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, unsigned int interrupt_props_num) { unsigned int i; const interrupt_prop_t *current_prop; + unsigned int ctlr_enable = 0; /* Make sure there's a valid property array */ assert(interrupt_props != NULL); @@ -564,10 +565,13 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, /* Configure this interrupt as G0 or a G1S interrupt */ assert((current_prop->intr_grp == INTR_GROUP0) || (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); - else + ctlr_enable |= CTLR_ENABLE_G1S_BIT; + } else { gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num); + ctlr_enable |= CTLR_ENABLE_G0_BIT; + } /* Set the priority of this interrupt */ gicr_set_ipriorityr(gicr_base, current_prop->intr_num, @@ -586,4 +590,6 @@ void gicv3_secure_ppi_sgi_configure_props(uintptr_t gicr_base, /* Enable this interrupt */ gicr_set_isenabler0(gicr_base, current_prop->intr_num); } + + return ctlr_enable; } diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index 8c4f5084..8de5be3f 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -224,12 +224,16 @@ void gicv3_distif_init(void) void gicv3_rdistif_init(unsigned int proc_num) { uintptr_t gicr_base; + unsigned int bitmap = 0; + uint32_t ctlr; assert(gicv3_driver_data); assert(proc_num < gicv3_driver_data->rdistif_num); assert(gicv3_driver_data->rdistif_base_addrs); 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()); @@ -244,7 +248,7 @@ void gicv3_rdistif_init(unsigned int proc_num) #if !ERROR_DEPRECATED if (gicv3_driver_data->interrupt_props != NULL) { #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_num); #if !ERROR_DEPRECATED @@ -258,6 +262,7 @@ void gicv3_rdistif_init(unsigned int proc_num) gicv3_driver_data->g1s_interrupt_num, gicv3_driver_data->g1s_interrupt_array, INTR_GROUP1S); + bitmap |= CTLR_ENABLE_G1S_BIT; } /* Configure the G0 SGIs/PPIs */ @@ -266,9 +271,14 @@ void gicv3_rdistif_init(unsigned int proc_num) gicv3_driver_data->g0_interrupt_num, gicv3_driver_data->g0_interrupt_array, INTR_GROUP0); + bitmap |= CTLR_ENABLE_G0_BIT; } } #endif + + /* Enable interrupt groups as required, if not already */ + if ((ctlr & bitmap) != bitmap) + gicd_set_ctlr(gicv3_driver_data->gicd_base, bitmap, RWP_TRUE); } /******************************************************************************* diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index a5093d0c..52039074 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -95,7 +95,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, const unsigned int *sec_intr_list, unsigned int int_grp); #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, unsigned int interrupt_props_num); unsigned int gicv3_secure_spis_configure_props(uintptr_t gicd_base, |