1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_helpers.h> 9 #include <assert.h> 10 #include <debug.h> 11 #include <gic_common.h> 12 #include <gicv2.h> 13 #include "../common/gic_common_private.h" 14 #include "gicv2_private.h" 15 16 static const gicv2_driver_data_t *driver_data; 17 18 /******************************************************************************* 19 * Enable secure interrupts and use FIQs to route them. Disable legacy bypass 20 * and set the priority mask register to allow all interrupts to trickle in. 21 ******************************************************************************/ 22 void gicv2_cpuif_enable(void) 23 { 24 unsigned int val; 25 26 assert(driver_data); 27 assert(driver_data->gicc_base); 28 29 /* 30 * Enable the Group 0 interrupts, FIQEn and disable Group 0/1 31 * bypass. 32 */ 33 val = CTLR_ENABLE_G0_BIT | FIQ_EN_BIT | FIQ_BYP_DIS_GRP0; 34 val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; 35 36 /* Program the idle priority in the PMR */ 37 gicc_write_pmr(driver_data->gicc_base, GIC_PRI_MASK); 38 gicc_write_ctlr(driver_data->gicc_base, val); 39 } 40 41 /******************************************************************************* 42 * Place the cpu interface in a state where it can never make a cpu exit wfi as 43 * as result of an asserted interrupt. This is critical for powering down a cpu 44 ******************************************************************************/ 45 void gicv2_cpuif_disable(void) 46 { 47 unsigned int val; 48 49 assert(driver_data); 50 assert(driver_data->gicc_base); 51 52 /* Disable secure, non-secure interrupts and disable their bypass */ 53 val = gicc_read_ctlr(driver_data->gicc_base); 54 val &= ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT); 55 val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; 56 val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; 57 gicc_write_ctlr(driver_data->gicc_base, val); 58 } 59 60 /******************************************************************************* 61 * Per cpu gic distributor setup which will be done by all cpus after a cold 62 * boot/hotplug. This marks out the secure SPIs and PPIs & enables them. 63 ******************************************************************************/ 64 void gicv2_pcpu_distif_init(void) 65 { 66 assert(driver_data); 67 assert(driver_data->gicd_base); 68 assert(driver_data->g0_interrupt_array); 69 70 gicv2_secure_ppi_sgi_setup(driver_data->gicd_base, 71 driver_data->g0_interrupt_num, 72 driver_data->g0_interrupt_array); 73 } 74 75 /******************************************************************************* 76 * Global gic distributor init which will be done by the primary cpu after a 77 * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It 78 * then enables the secure GIC distributor interface. 79 ******************************************************************************/ 80 void gicv2_distif_init(void) 81 { 82 unsigned int ctlr; 83 84 assert(driver_data); 85 assert(driver_data->gicd_base); 86 assert(driver_data->g0_interrupt_array); 87 88 /* Disable the distributor before going further */ 89 ctlr = gicd_read_ctlr(driver_data->gicd_base); 90 gicd_write_ctlr(driver_data->gicd_base, 91 ctlr & ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT)); 92 93 /* Set the default attribute of all SPIs */ 94 gicv2_spis_configure_defaults(driver_data->gicd_base); 95 96 /* Configure the G0 SPIs */ 97 gicv2_secure_spis_configure(driver_data->gicd_base, 98 driver_data->g0_interrupt_num, 99 driver_data->g0_interrupt_array); 100 101 /* Re-enable the secure SPIs now that they have been configured */ 102 gicd_write_ctlr(driver_data->gicd_base, ctlr | CTLR_ENABLE_G0_BIT); 103 } 104 105 /******************************************************************************* 106 * Initialize the ARM GICv2 driver with the provided platform inputs 107 ******************************************************************************/ 108 void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data) 109 { 110 unsigned int gic_version; 111 assert(plat_driver_data); 112 assert(plat_driver_data->gicd_base); 113 assert(plat_driver_data->gicc_base); 114 115 /* 116 * The platform should provide a list of atleast one type of 117 * interrupts 118 */ 119 assert(plat_driver_data->g0_interrupt_array); 120 121 /* 122 * If there are no interrupts of a particular type, then the number of 123 * interrupts of that type should be 0 and vice-versa. 124 */ 125 assert(plat_driver_data->g0_interrupt_array ? 126 plat_driver_data->g0_interrupt_num : 127 plat_driver_data->g0_interrupt_num == 0); 128 129 /* Ensure that this is a GICv2 system */ 130 gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); 131 gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT) 132 & PIDR2_ARCH_REV_MASK; 133 assert(gic_version == ARCH_REV_GICV2); 134 135 driver_data = plat_driver_data; 136 137 /* 138 * The GIC driver data is initialized by the primary CPU with caches 139 * enabled. When the secondary CPU boots up, it initializes the 140 * GICC/GICR interface with the caches disabled. Hence flush the 141 * driver_data to ensure coherency. This is not required if the 142 * platform has HW_ASSISTED_COHERENCY enabled. 143 */ 144 #if !HW_ASSISTED_COHERENCY 145 flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data)); 146 flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data)); 147 #endif 148 INFO("ARM GICv2 driver initialized\n"); 149 } 150 151 /****************************************************************************** 152 * This function returns whether FIQ is enabled in the GIC CPU interface. 153 *****************************************************************************/ 154 unsigned int gicv2_is_fiq_enabled(void) 155 { 156 unsigned int gicc_ctlr; 157 158 assert(driver_data); 159 assert(driver_data->gicc_base); 160 161 gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base); 162 return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1; 163 } 164 165 /******************************************************************************* 166 * This function returns the type of the highest priority pending interrupt at 167 * the GIC cpu interface. The return values can be one of the following : 168 * PENDING_G1_INTID : The interrupt type is non secure Group 1. 169 * 0 - 1019 : The interrupt type is secure Group 0. 170 * GIC_SPURIOUS_INTERRUPT : there is no pending interrupt with 171 * sufficient priority to be signaled 172 ******************************************************************************/ 173 unsigned int gicv2_get_pending_interrupt_type(void) 174 { 175 assert(driver_data); 176 assert(driver_data->gicc_base); 177 178 return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 179 } 180 181 /******************************************************************************* 182 * This function returns the id of the highest priority pending interrupt at 183 * the GIC cpu interface. GIC_SPURIOUS_INTERRUPT is returned when there is no 184 * interrupt pending. 185 ******************************************************************************/ 186 unsigned int gicv2_get_pending_interrupt_id(void) 187 { 188 unsigned int id; 189 190 assert(driver_data); 191 assert(driver_data->gicc_base); 192 193 id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 194 195 /* 196 * Find out which non-secure interrupt it is under the assumption that 197 * the GICC_CTLR.AckCtl bit is 0. 198 */ 199 if (id == PENDING_G1_INTID) 200 id = gicc_read_ahppir(driver_data->gicc_base) & INT_ID_MASK; 201 202 return id; 203 } 204 205 /******************************************************************************* 206 * This functions reads the GIC cpu interface Interrupt Acknowledge register 207 * to start handling the pending secure 0 interrupt. It returns the 208 * contents of the IAR. 209 ******************************************************************************/ 210 unsigned int gicv2_acknowledge_interrupt(void) 211 { 212 assert(driver_data); 213 assert(driver_data->gicc_base); 214 215 return gicc_read_IAR(driver_data->gicc_base); 216 } 217 218 /******************************************************************************* 219 * This functions writes the GIC cpu interface End Of Interrupt register with 220 * the passed value to finish handling the active secure group 0 interrupt. 221 ******************************************************************************/ 222 void gicv2_end_of_interrupt(unsigned int id) 223 { 224 assert(driver_data); 225 assert(driver_data->gicc_base); 226 227 gicc_write_EOIR(driver_data->gicc_base, id); 228 } 229 230 /******************************************************************************* 231 * This function returns the type of the interrupt id depending upon the group 232 * this interrupt has been configured under by the interrupt controller i.e. 233 * group0 secure or group1 non secure. It returns zero for Group 0 secure and 234 * one for Group 1 non secure interrupt. 235 ******************************************************************************/ 236 unsigned int gicv2_get_interrupt_group(unsigned int id) 237 { 238 assert(driver_data); 239 assert(driver_data->gicd_base); 240 241 return gicd_get_igroupr(driver_data->gicd_base, id); 242 } 243