From 385f1dbb294b36c5fbdbbf3d10b6cb105239a76e Mon Sep 17 00:00:00 2001 From: Jeenu Viswambharan Date: Tue, 7 Nov 2017 08:38:23 +0000 Subject: 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 --- drivers/arm/gic/v2/gicv2_main.c | 9 +++++++++ drivers/arm/gic/v3/gicv3_helpers.c | 12 +++++++++--- drivers/arm/gic/v3/gicv3_main.c | 14 ++++++++++++-- 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, -- cgit v1.2.3