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 <spinlock.h> 14 #include "../common/gic_common_private.h" 15 #include "gicv2_private.h" 16 17 static const gicv2_driver_data_t *driver_data; 18 19 /* 20 * Spinlock to guard registers needing read-modify-write. APIs protected by this 21 * spinlock are used either at boot time (when only a single CPU is active), or 22 * when the system is fully coherent. 23 */ 24 spinlock_t gic_lock; 25 26 /******************************************************************************* 27 * Enable secure interrupts and use FIQs to route them. Disable legacy bypass 28 * and set the priority mask register to allow all interrupts to trickle in. 29 ******************************************************************************/ 30 void gicv2_cpuif_enable(void) 31 { 32 unsigned int val; 33 34 assert(driver_data); 35 assert(driver_data->gicc_base); 36 37 /* 38 * Enable the Group 0 interrupts, FIQEn and disable Group 0/1 39 * bypass. 40 */ 41 val = CTLR_ENABLE_G0_BIT | FIQ_EN_BIT | FIQ_BYP_DIS_GRP0; 42 val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; 43 44 /* Program the idle priority in the PMR */ 45 gicc_write_pmr(driver_data->gicc_base, GIC_PRI_MASK); 46 gicc_write_ctlr(driver_data->gicc_base, val); 47 } 48 49 /******************************************************************************* 50 * Place the cpu interface in a state where it can never make a cpu exit wfi as 51 * as result of an asserted interrupt. This is critical for powering down a cpu 52 ******************************************************************************/ 53 void gicv2_cpuif_disable(void) 54 { 55 unsigned int val; 56 57 assert(driver_data); 58 assert(driver_data->gicc_base); 59 60 /* Disable secure, non-secure interrupts and disable their bypass */ 61 val = gicc_read_ctlr(driver_data->gicc_base); 62 val &= ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT); 63 val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; 64 val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; 65 gicc_write_ctlr(driver_data->gicc_base, val); 66 } 67 68 /******************************************************************************* 69 * Per cpu gic distributor setup which will be done by all cpus after a cold 70 * boot/hotplug. This marks out the secure SPIs and PPIs & enables them. 71 ******************************************************************************/ 72 void gicv2_pcpu_distif_init(void) 73 { 74 assert(driver_data); 75 assert(driver_data->gicd_base); 76 assert(driver_data->g0_interrupt_array); 77 78 gicv2_secure_ppi_sgi_setup(driver_data->gicd_base, 79 driver_data->g0_interrupt_num, 80 driver_data->g0_interrupt_array); 81 } 82 83 /******************************************************************************* 84 * Global gic distributor init which will be done by the primary cpu after a 85 * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It 86 * then enables the secure GIC distributor interface. 87 ******************************************************************************/ 88 void gicv2_distif_init(void) 89 { 90 unsigned int ctlr; 91 92 assert(driver_data); 93 assert(driver_data->gicd_base); 94 assert(driver_data->g0_interrupt_array); 95 96 /* Disable the distributor before going further */ 97 ctlr = gicd_read_ctlr(driver_data->gicd_base); 98 gicd_write_ctlr(driver_data->gicd_base, 99 ctlr & ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT)); 100 101 /* Set the default attribute of all SPIs */ 102 gicv2_spis_configure_defaults(driver_data->gicd_base); 103 104 /* Configure the G0 SPIs */ 105 gicv2_secure_spis_configure(driver_data->gicd_base, 106 driver_data->g0_interrupt_num, 107 driver_data->g0_interrupt_array); 108 109 /* Re-enable the secure SPIs now that they have been configured */ 110 gicd_write_ctlr(driver_data->gicd_base, ctlr | CTLR_ENABLE_G0_BIT); 111 } 112 113 /******************************************************************************* 114 * Initialize the ARM GICv2 driver with the provided platform inputs 115 ******************************************************************************/ 116 void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data) 117 { 118 unsigned int gic_version; 119 assert(plat_driver_data); 120 assert(plat_driver_data->gicd_base); 121 assert(plat_driver_data->gicc_base); 122 123 /* 124 * The platform should provide a list of atleast one type of 125 * interrupts 126 */ 127 assert(plat_driver_data->g0_interrupt_array); 128 129 /* 130 * If there are no interrupts of a particular type, then the number of 131 * interrupts of that type should be 0 and vice-versa. 132 */ 133 assert(plat_driver_data->g0_interrupt_array ? 134 plat_driver_data->g0_interrupt_num : 135 plat_driver_data->g0_interrupt_num == 0); 136 137 /* Ensure that this is a GICv2 system */ 138 gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); 139 gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT) 140 & PIDR2_ARCH_REV_MASK; 141 assert(gic_version == ARCH_REV_GICV2); 142 143 driver_data = plat_driver_data; 144 145 /* 146 * The GIC driver data is initialized by the primary CPU with caches 147 * enabled. When the secondary CPU boots up, it initializes the 148 * GICC/GICR interface with the caches disabled. Hence flush the 149 * driver_data to ensure coherency. This is not required if the 150 * platform has HW_ASSISTED_COHERENCY enabled. 151 */ 152 #if !HW_ASSISTED_COHERENCY 153 flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data)); 154 flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data)); 155 #endif 156 INFO("ARM GICv2 driver initialized\n"); 157 } 158 159 /****************************************************************************** 160 * This function returns whether FIQ is enabled in the GIC CPU interface. 161 *****************************************************************************/ 162 unsigned int gicv2_is_fiq_enabled(void) 163 { 164 unsigned int gicc_ctlr; 165 166 assert(driver_data); 167 assert(driver_data->gicc_base); 168 169 gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base); 170 return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1; 171 } 172 173 /******************************************************************************* 174 * This function returns the type of the highest priority pending interrupt at 175 * the GIC cpu interface. The return values can be one of the following : 176 * PENDING_G1_INTID : The interrupt type is non secure Group 1. 177 * 0 - 1019 : The interrupt type is secure Group 0. 178 * GIC_SPURIOUS_INTERRUPT : there is no pending interrupt with 179 * sufficient priority to be signaled 180 ******************************************************************************/ 181 unsigned int gicv2_get_pending_interrupt_type(void) 182 { 183 assert(driver_data); 184 assert(driver_data->gicc_base); 185 186 return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 187 } 188 189 /******************************************************************************* 190 * This function returns the id of the highest priority pending interrupt at 191 * the GIC cpu interface. GIC_SPURIOUS_INTERRUPT is returned when there is no 192 * interrupt pending. 193 ******************************************************************************/ 194 unsigned int gicv2_get_pending_interrupt_id(void) 195 { 196 unsigned int id; 197 198 assert(driver_data); 199 assert(driver_data->gicc_base); 200 201 id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 202 203 /* 204 * Find out which non-secure interrupt it is under the assumption that 205 * the GICC_CTLR.AckCtl bit is 0. 206 */ 207 if (id == PENDING_G1_INTID) 208 id = gicc_read_ahppir(driver_data->gicc_base) & INT_ID_MASK; 209 210 return id; 211 } 212 213 /******************************************************************************* 214 * This functions reads the GIC cpu interface Interrupt Acknowledge register 215 * to start handling the pending secure 0 interrupt. It returns the 216 * contents of the IAR. 217 ******************************************************************************/ 218 unsigned int gicv2_acknowledge_interrupt(void) 219 { 220 assert(driver_data); 221 assert(driver_data->gicc_base); 222 223 return gicc_read_IAR(driver_data->gicc_base); 224 } 225 226 /******************************************************************************* 227 * This functions writes the GIC cpu interface End Of Interrupt register with 228 * the passed value to finish handling the active secure group 0 interrupt. 229 ******************************************************************************/ 230 void gicv2_end_of_interrupt(unsigned int id) 231 { 232 assert(driver_data); 233 assert(driver_data->gicc_base); 234 235 gicc_write_EOIR(driver_data->gicc_base, id); 236 } 237 238 /******************************************************************************* 239 * This function returns the type of the interrupt id depending upon the group 240 * this interrupt has been configured under by the interrupt controller i.e. 241 * group0 secure or group1 non secure. It returns zero for Group 0 secure and 242 * one for Group 1 non secure interrupt. 243 ******************************************************************************/ 244 unsigned int gicv2_get_interrupt_group(unsigned int id) 245 { 246 assert(driver_data); 247 assert(driver_data->gicd_base); 248 249 return gicd_get_igroupr(driver_data->gicd_base, id); 250 } 251 252 /******************************************************************************* 253 * This function returns the priority of the interrupt the processor is 254 * currently servicing. 255 ******************************************************************************/ 256 unsigned int gicv2_get_running_priority(void) 257 { 258 assert(driver_data); 259 assert(driver_data->gicc_base); 260 261 return gicc_read_rpr(driver_data->gicc_base); 262 } 263 264 /******************************************************************************* 265 * This function sets the GICv2 target mask pattern for the current PE. The PE 266 * target mask is used to translate linear PE index (returned by platform core 267 * position) to a bit mask used when targeting interrupts to a PE, viz. when 268 * raising SGIs and routing SPIs. 269 ******************************************************************************/ 270 void gicv2_set_pe_target_mask(unsigned int proc_num) 271 { 272 assert(driver_data); 273 assert(driver_data->gicd_base); 274 assert(driver_data->target_masks); 275 assert(proc_num < GICV2_MAX_TARGET_PE); 276 assert(proc_num < driver_data->target_masks_num); 277 278 /* Return if the target mask is already populated */ 279 if (driver_data->target_masks[proc_num]) 280 return; 281 282 /* Read target register corresponding to this CPU */ 283 driver_data->target_masks[proc_num] = 284 gicv2_get_cpuif_id(driver_data->gicd_base); 285 } 286 287 /******************************************************************************* 288 * This function returns the active status of the interrupt (either because the 289 * state is active, or active and pending). 290 ******************************************************************************/ 291 unsigned int gicv2_get_interrupt_active(unsigned int id) 292 { 293 assert(driver_data); 294 assert(driver_data->gicd_base); 295 assert(id <= MAX_SPI_ID); 296 297 return gicd_get_isactiver(driver_data->gicd_base, id); 298 } 299 300 /******************************************************************************* 301 * This function enables the interrupt identified by id. 302 ******************************************************************************/ 303 void gicv2_enable_interrupt(unsigned int id) 304 { 305 assert(driver_data); 306 assert(driver_data->gicd_base); 307 assert(id <= MAX_SPI_ID); 308 309 /* 310 * Ensure that any shared variable updates depending on out of band 311 * interrupt trigger are observed before enabling interrupt. 312 */ 313 dsbishst(); 314 gicd_set_isenabler(driver_data->gicd_base, id); 315 } 316 317 /******************************************************************************* 318 * This function disables the interrupt identified by id. 319 ******************************************************************************/ 320 void gicv2_disable_interrupt(unsigned int id) 321 { 322 assert(driver_data); 323 assert(driver_data->gicd_base); 324 assert(id <= MAX_SPI_ID); 325 326 /* 327 * Disable interrupt, and ensure that any shared variable updates 328 * depending on out of band interrupt trigger are observed afterwards. 329 */ 330 gicd_set_icenabler(driver_data->gicd_base, id); 331 dsbishst(); 332 } 333 334 /******************************************************************************* 335 * This function sets the interrupt priority as supplied for the given interrupt 336 * id. 337 ******************************************************************************/ 338 void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority) 339 { 340 assert(driver_data); 341 assert(driver_data->gicd_base); 342 assert(id <= MAX_SPI_ID); 343 344 gicd_set_ipriorityr(driver_data->gicd_base, id, priority); 345 } 346 347 /******************************************************************************* 348 * This function assigns group for the interrupt identified by id. The group can 349 * be any of GICV2_INTR_GROUP* 350 ******************************************************************************/ 351 void gicv2_set_interrupt_type(unsigned int id, unsigned int type) 352 { 353 assert(driver_data); 354 assert(driver_data->gicd_base); 355 assert(id <= MAX_SPI_ID); 356 357 /* Serialize read-modify-write to Distributor registers */ 358 spin_lock(&gic_lock); 359 switch (type) { 360 case GICV2_INTR_GROUP1: 361 gicd_set_igroupr(driver_data->gicd_base, id); 362 break; 363 case GICV2_INTR_GROUP0: 364 gicd_clr_igroupr(driver_data->gicd_base, id); 365 break; 366 default: 367 assert(0); 368 } 369 spin_unlock(&gic_lock); 370 } 371 372 /******************************************************************************* 373 * This function raises the specified SGI to requested targets. 374 * 375 * The proc_num parameter must be the linear index of the target PE in the 376 * system. 377 ******************************************************************************/ 378 void gicv2_raise_sgi(int sgi_num, int proc_num) 379 { 380 unsigned int sgir_val, target; 381 382 assert(driver_data); 383 assert(proc_num < GICV2_MAX_TARGET_PE); 384 assert(driver_data->gicd_base); 385 386 /* 387 * Target masks array must have been supplied, and the core position 388 * should be valid. 389 */ 390 assert(driver_data->target_masks); 391 assert(proc_num < driver_data->target_masks_num); 392 393 /* Don't raise SGI if the mask hasn't been populated */ 394 target = driver_data->target_masks[proc_num]; 395 assert(target != 0); 396 397 sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num); 398 399 /* 400 * Ensure that any shared variable updates depending on out of band 401 * interrupt trigger are observed before raising SGI. 402 */ 403 dsbishst(); 404 gicd_write_sgir(driver_data->gicd_base, sgir_val); 405 } 406 407 /******************************************************************************* 408 * This function sets the interrupt routing for the given SPI interrupt id. 409 * The interrupt routing is specified in routing mode. The proc_num parameter is 410 * linear index of the PE to target SPI. When proc_num < 0, the SPI may target 411 * all PEs. 412 ******************************************************************************/ 413 void gicv2_set_spi_routing(unsigned int id, int proc_num) 414 { 415 int target; 416 417 assert(driver_data); 418 assert(driver_data->gicd_base); 419 420 assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID); 421 422 /* 423 * Target masks array must have been supplied, and the core position 424 * should be valid. 425 */ 426 assert(driver_data->target_masks); 427 assert(proc_num < GICV2_MAX_TARGET_PE); 428 assert(proc_num < driver_data->target_masks_num); 429 430 if (proc_num < 0) { 431 /* Target all PEs */ 432 target = GIC_TARGET_CPU_MASK; 433 } else { 434 /* Don't route interrupt if the mask hasn't been populated */ 435 target = driver_data->target_masks[proc_num]; 436 assert(target != 0); 437 } 438 439 gicd_set_itargetsr(driver_data->gicd_base, id, target); 440 } 441