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