]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
GIC: Fix Group 0 enabling
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>
Tue, 7 Nov 2017 08:38:23 +0000 (08:38 +0000)
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>
Mon, 13 Nov 2017 07:49:30 +0000 (07:49 +0000)
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>
drivers/arm/gic/v2/gicv2_main.c
drivers/arm/gic/v3/gicv3_helpers.c
drivers/arm/gic/v3/gicv3_main.c
drivers/arm/gic/v3/gicv3_private.h

index 4b0984d8a9c020de52ab93fabf476b06f8b463bc..72f15cd7c3a2735d0b6aca093ccc76de52ab00a2 100644 (file)
@@ -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);
+       }
 }
 
 /*******************************************************************************
index 2522695682517452fee5ab94db761b78586f99a2..dee63f18a9beb5bc968faf4ba3050ce694a4d0fa 100644 (file)
@@ -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;
 }
index 8c4f508472ab6c63f1d92bdae3f06a7299af29ee..8de5be3f4d2dceeccb32ee82f39e97e3d002028c 100644 (file)
@@ -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);
 }
 
 /*******************************************************************************
index a5093d0c747e7c7bbc2c561564907abab485c801..52039074c2e39902ac3672dee7f89e472f4e08e0 100644 (file)
@@ -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,