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 "../common/gic_common_private.h" 13 #include "gicv3_private.h" 14 15 /* 16 * Accessor to read the GIC Distributor IGRPMODR corresponding to the 17 * interrupt `id`, 32 interrupt IDs at a time. 18 */ 19 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) 20 { 21 unsigned n = id >> IGRPMODR_SHIFT; 22 return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); 23 } 24 25 /* 26 * Accessor to write the GIC Distributor IGRPMODR corresponding to the 27 * interrupt `id`, 32 interrupt IDs at a time. 28 */ 29 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) 30 { 31 unsigned n = id >> IGRPMODR_SHIFT; 32 mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); 33 } 34 35 /* 36 * Accessor to get the bit corresponding to interrupt ID 37 * in GIC Distributor IGRPMODR. 38 */ 39 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) 40 { 41 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 42 unsigned int reg_val = gicd_read_igrpmodr(base, id); 43 44 return (reg_val >> bit_num) & 0x1; 45 } 46 47 /* 48 * Accessor to set the bit corresponding to interrupt ID 49 * in GIC Distributor IGRPMODR. 50 */ 51 void gicd_set_igrpmodr(uintptr_t base, unsigned int id) 52 { 53 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 54 unsigned int reg_val = gicd_read_igrpmodr(base, id); 55 56 gicd_write_igrpmodr(base, id, reg_val | (1 << bit_num)); 57 } 58 59 /* 60 * Accessor to clear the bit corresponding to interrupt ID 61 * in GIC Distributor IGRPMODR. 62 */ 63 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) 64 { 65 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 66 unsigned int reg_val = gicd_read_igrpmodr(base, id); 67 68 gicd_write_igrpmodr(base, id, reg_val & ~(1 << bit_num)); 69 } 70 71 /* 72 * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the 73 * interrupt `id`, 4 interrupts IDs at a time. 74 */ 75 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) 76 { 77 unsigned n = id >> IPRIORITYR_SHIFT; 78 return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); 79 } 80 81 /* 82 * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the 83 * interrupt `id`, 4 interrupts IDs at a time. 84 */ 85 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 86 { 87 unsigned n = id >> IPRIORITYR_SHIFT; 88 mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); 89 } 90 91 /* 92 * Accessor to get the bit corresponding to interrupt ID 93 * from GIC Re-distributor IGROUPR0. 94 */ 95 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) 96 { 97 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 98 unsigned int reg_val = gicr_read_igroupr0(base); 99 100 return (reg_val >> bit_num) & 0x1; 101 } 102 103 /* 104 * Accessor to set the bit corresponding to interrupt ID 105 * in GIC Re-distributor IGROUPR0. 106 */ 107 void gicr_set_igroupr0(uintptr_t base, unsigned int id) 108 { 109 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 110 unsigned int reg_val = gicr_read_igroupr0(base); 111 112 gicr_write_igroupr0(base, reg_val | (1 << bit_num)); 113 } 114 115 /* 116 * Accessor to clear the bit corresponding to interrupt ID 117 * in GIC Re-distributor IGROUPR0. 118 */ 119 void gicr_clr_igroupr0(uintptr_t base, unsigned int id) 120 { 121 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 122 unsigned int reg_val = gicr_read_igroupr0(base); 123 124 gicr_write_igroupr0(base, reg_val & ~(1 << bit_num)); 125 } 126 127 /* 128 * Accessor to get the bit corresponding to interrupt ID 129 * from GIC Re-distributor IGRPMODR0. 130 */ 131 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) 132 { 133 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 134 unsigned int reg_val = gicr_read_igrpmodr0(base); 135 136 return (reg_val >> bit_num) & 0x1; 137 } 138 139 /* 140 * Accessor to set the bit corresponding to interrupt ID 141 * in GIC Re-distributor IGRPMODR0. 142 */ 143 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) 144 { 145 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 146 unsigned int reg_val = gicr_read_igrpmodr0(base); 147 148 gicr_write_igrpmodr0(base, reg_val | (1 << bit_num)); 149 } 150 151 /* 152 * Accessor to clear the bit corresponding to interrupt ID 153 * in GIC Re-distributor IGRPMODR0. 154 */ 155 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) 156 { 157 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 158 unsigned int reg_val = gicr_read_igrpmodr0(base); 159 160 gicr_write_igrpmodr0(base, reg_val & ~(1 << bit_num)); 161 } 162 163 /* 164 * Accessor to set the bit corresponding to interrupt ID 165 * in GIC Re-distributor ISENABLER0. 166 */ 167 void gicr_set_isenabler0(uintptr_t base, unsigned int id) 168 { 169 unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); 170 171 gicr_write_isenabler0(base, (1 << bit_num)); 172 } 173 174 /* 175 * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor 176 * ICENABLER0. 177 */ 178 void gicr_set_icenabler0(uintptr_t base, unsigned int id) 179 { 180 unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); 181 182 gicr_write_icenabler0(base, (1 << bit_num)); 183 } 184 185 /* 186 * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor 187 * ISACTIVER0. 188 */ 189 unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) 190 { 191 unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1); 192 unsigned int reg_val = gicr_read_isactiver0(base); 193 194 return (reg_val >> bit_num) & 0x1; 195 } 196 197 /* 198 * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor 199 * ICPENDRR0. 200 */ 201 void gicr_set_icpendr0(uintptr_t base, unsigned int id) 202 { 203 unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1); 204 205 gicr_write_icpendr0(base, (1 << bit_num)); 206 } 207 208 /* 209 * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor 210 * ISPENDR0. 211 */ 212 void gicr_set_ispendr0(uintptr_t base, unsigned int id) 213 { 214 unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1); 215 216 gicr_write_ispendr0(base, (1 << bit_num)); 217 } 218 219 /* 220 * Accessor to set the byte corresponding to interrupt ID 221 * in GIC Re-distributor IPRIORITYR. 222 */ 223 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) 224 { 225 mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK); 226 } 227 228 /* 229 * Accessor to set the bit fields corresponding to interrupt ID 230 * in GIC Re-distributor ICFGR0. 231 */ 232 void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) 233 { 234 unsigned bit_num = id & ((1 << ICFGR_SHIFT) - 1); 235 uint32_t reg_val = gicr_read_icfgr0(base); 236 237 /* Clear the field, and insert required configuration */ 238 reg_val &= ~(GIC_CFG_MASK << bit_num); 239 reg_val |= ((cfg & GIC_CFG_MASK) << bit_num); 240 241 gicr_write_icfgr0(base, reg_val); 242 } 243 244 /* 245 * Accessor to set the bit fields corresponding to interrupt ID 246 * in GIC Re-distributor ICFGR1. 247 */ 248 void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) 249 { 250 unsigned bit_num = id & ((1 << ICFGR_SHIFT) - 1); 251 uint32_t reg_val = gicr_read_icfgr1(base); 252 253 /* Clear the field, and insert required configuration */ 254 reg_val &= ~(GIC_CFG_MASK << bit_num); 255 reg_val |= ((cfg & GIC_CFG_MASK) << bit_num); 256 257 gicr_write_icfgr1(base, reg_val); 258 } 259 260 /****************************************************************************** 261 * This function marks the core as awake in the re-distributor and 262 * ensures that the interface is active. 263 *****************************************************************************/ 264 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) 265 { 266 /* 267 * The WAKER_PS_BIT should be changed to 0 268 * only when WAKER_CA_BIT is 1. 269 */ 270 assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); 271 272 /* Mark the connected core as awake */ 273 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); 274 275 /* Wait till the WAKER_CA_BIT changes to 0 */ 276 while (gicr_read_waker(gicr_base) & WAKER_CA_BIT) 277 ; 278 } 279 280 281 /****************************************************************************** 282 * This function marks the core as asleep in the re-distributor and ensures 283 * that the interface is quiescent. 284 *****************************************************************************/ 285 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) 286 { 287 /* Mark the connected core as asleep */ 288 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); 289 290 /* Wait till the WAKER_CA_BIT changes to 1 */ 291 while (!(gicr_read_waker(gicr_base) & WAKER_CA_BIT)) 292 ; 293 } 294 295 296 /******************************************************************************* 297 * This function probes the Redistributor frames when the driver is initialised 298 * and saves their base addresses. These base addresses are used later to 299 * initialise each Redistributor interface. 300 ******************************************************************************/ 301 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 302 unsigned int rdistif_num, 303 uintptr_t gicr_base, 304 mpidr_hash_fn mpidr_to_core_pos) 305 { 306 u_register_t mpidr; 307 unsigned int proc_num; 308 unsigned long long typer_val; 309 uintptr_t rdistif_base = gicr_base; 310 311 assert(rdistif_base_addrs); 312 313 /* 314 * Iterate over the Redistributor frames. Store the base address of each 315 * frame in the platform provided array. Use the "Processor Number" 316 * field to index into the array if the platform has not provided a hash 317 * function to convert an MPIDR (obtained from the "Affinity Value" 318 * field into a linear index. 319 */ 320 do { 321 typer_val = gicr_read_typer(rdistif_base); 322 if (mpidr_to_core_pos) { 323 mpidr = mpidr_from_gicr_typer(typer_val); 324 proc_num = mpidr_to_core_pos(mpidr); 325 } else { 326 proc_num = (typer_val >> TYPER_PROC_NUM_SHIFT) & 327 TYPER_PROC_NUM_MASK; 328 } 329 assert(proc_num < rdistif_num); 330 rdistif_base_addrs[proc_num] = rdistif_base; 331 rdistif_base += (1 << GICR_PCPUBASE_SHIFT); 332 } while (!(typer_val & TYPER_LAST_BIT)); 333 } 334 335 /******************************************************************************* 336 * Helper function to configure the default attributes of SPIs. 337 ******************************************************************************/ 338 void gicv3_spis_configure_defaults(uintptr_t gicd_base) 339 { 340 unsigned int index, num_ints; 341 342 num_ints = gicd_read_typer(gicd_base); 343 num_ints &= TYPER_IT_LINES_NO_MASK; 344 num_ints = (num_ints + 1) << 5; 345 346 /* 347 * Treat all SPIs as G1NS by default. The number of interrupts is 348 * calculated as 32 * (IT_LINES + 1). We do 32 at a time. 349 */ 350 for (index = MIN_SPI_ID; index < num_ints; index += 32) 351 gicd_write_igroupr(gicd_base, index, ~0U); 352 353 /* Setup the default SPI priorities doing four at a time */ 354 for (index = MIN_SPI_ID; index < num_ints; index += 4) 355 gicd_write_ipriorityr(gicd_base, 356 index, 357 GICD_IPRIORITYR_DEF_VAL); 358 359 /* 360 * Treat all SPIs as level triggered by default, write 16 at 361 * a time 362 */ 363 for (index = MIN_SPI_ID; index < num_ints; index += 16) 364 gicd_write_icfgr(gicd_base, index, 0); 365 } 366 367 /******************************************************************************* 368 * Helper function to configure secure G0 and G1S SPIs. 369 ******************************************************************************/ 370 void gicv3_secure_spis_configure(uintptr_t gicd_base, 371 unsigned int num_ints, 372 const unsigned int *sec_intr_list, 373 unsigned int int_grp) 374 { 375 unsigned int index, irq_num; 376 unsigned long long gic_affinity_val; 377 378 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 379 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 380 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 381 382 for (index = 0; index < num_ints; index++) { 383 irq_num = sec_intr_list[index]; 384 if (irq_num >= MIN_SPI_ID) { 385 386 /* Configure this interrupt as a secure interrupt */ 387 gicd_clr_igroupr(gicd_base, irq_num); 388 389 /* Configure this interrupt as G0 or a G1S interrupt */ 390 if (int_grp == INTR_GROUP1S) 391 gicd_set_igrpmodr(gicd_base, irq_num); 392 else 393 gicd_clr_igrpmodr(gicd_base, irq_num); 394 395 /* Set the priority of this interrupt */ 396 gicd_set_ipriorityr(gicd_base, 397 irq_num, 398 GIC_HIGHEST_SEC_PRIORITY); 399 400 /* Target SPIs to the primary CPU */ 401 gic_affinity_val = 402 gicd_irouter_val_from_mpidr(read_mpidr(), 0); 403 gicd_write_irouter(gicd_base, 404 irq_num, 405 gic_affinity_val); 406 407 /* Enable this interrupt */ 408 gicd_set_isenabler(gicd_base, irq_num); 409 } 410 } 411 412 } 413 414 /******************************************************************************* 415 * Helper function to configure the default attributes of SPIs. 416 ******************************************************************************/ 417 void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base) 418 { 419 unsigned int index; 420 421 /* 422 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a 423 * more scalable approach as it avoids clearing the enable bits in the 424 * GICD_CTLR 425 */ 426 gicr_write_icenabler0(gicr_base, ~0); 427 gicr_wait_for_pending_write(gicr_base); 428 429 /* Treat all SGIs/PPIs as G1NS by default. */ 430 gicr_write_igroupr0(gicr_base, ~0U); 431 432 /* Setup the default PPI/SGI priorities doing four at a time */ 433 for (index = 0; index < MIN_SPI_ID; index += 4) 434 gicr_write_ipriorityr(gicr_base, 435 index, 436 GICD_IPRIORITYR_DEF_VAL); 437 438 /* Configure all PPIs as level triggered by default */ 439 gicr_write_icfgr1(gicr_base, 0); 440 } 441 442 /******************************************************************************* 443 * Helper function to configure secure G0 and G1S SPIs. 444 ******************************************************************************/ 445 void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, 446 unsigned int num_ints, 447 const unsigned int *sec_intr_list, 448 unsigned int int_grp) 449 { 450 unsigned int index, irq_num; 451 452 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 453 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 454 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 455 456 for (index = 0; index < num_ints; index++) { 457 irq_num = sec_intr_list[index]; 458 if (irq_num < MIN_SPI_ID) { 459 460 /* Configure this interrupt as a secure interrupt */ 461 gicr_clr_igroupr0(gicr_base, irq_num); 462 463 /* Configure this interrupt as G0 or a G1S interrupt */ 464 if (int_grp == INTR_GROUP1S) 465 gicr_set_igrpmodr0(gicr_base, irq_num); 466 else 467 gicr_clr_igrpmodr0(gicr_base, irq_num); 468 469 /* Set the priority of this interrupt */ 470 gicr_set_ipriorityr(gicr_base, 471 irq_num, 472 GIC_HIGHEST_SEC_PRIORITY); 473 474 /* Enable this interrupt */ 475 gicr_set_isenabler0(gicr_base, irq_num); 476 } 477 } 478 } 479