diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index 4b0984d..72f15cd 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -72,6 +72,8 @@ ******************************************************************************/ void gicv2_pcpu_distif_init(void) { + unsigned int ctlr; + assert(driver_data); assert(driver_data->gicd_base); @@ -89,6 +91,13 @@ 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 2522695..dee63f1 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -541,12 +541,13 @@ /******************************************************************************* * 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 @@ /* 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 @@ /* 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 8c4f508..8de5be3 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -224,12 +224,16 @@ 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 @@ #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 @@ 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 @@ 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 a5093d0..5203907 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -95,7 +95,7 @@ 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,