1 /* 2 * Copyright (c) 2015-2018, 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 /* Interrupt configuration is a 2-bit field */ 236 unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1); 237 unsigned int bit_shift = bit_num << 1; 238 239 uint32_t reg_val = gicr_read_icfgr0(base); 240 241 /* Clear the field, and insert required configuration */ 242 reg_val &= ~(GIC_CFG_MASK << bit_shift); 243 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); 244 245 gicr_write_icfgr0(base, reg_val); 246 } 247 248 /* 249 * Accessor to set the bit fields corresponding to interrupt ID 250 * in GIC Re-distributor ICFGR1. 251 */ 252 void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) 253 { 254 /* Interrupt configuration is a 2-bit field */ 255 unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1); 256 unsigned int bit_shift = bit_num << 1; 257 258 uint32_t reg_val = gicr_read_icfgr1(base); 259 260 /* Clear the field, and insert required configuration */ 261 reg_val &= ~(GIC_CFG_MASK << bit_shift); 262 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); 263 264 gicr_write_icfgr1(base, reg_val); 265 } 266 267 /****************************************************************************** 268 * This function marks the core as awake in the re-distributor and 269 * ensures that the interface is active. 270 *****************************************************************************/ 271 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) 272 { 273 /* 274 * The WAKER_PS_BIT should be changed to 0 275 * only when WAKER_CA_BIT is 1. 276 */ 277 assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); 278 279 /* Mark the connected core as awake */ 280 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); 281 282 /* Wait till the WAKER_CA_BIT changes to 0 */ 283 while (gicr_read_waker(gicr_base) & WAKER_CA_BIT) 284 ; 285 } 286 287 288 /****************************************************************************** 289 * This function marks the core as asleep in the re-distributor and ensures 290 * that the interface is quiescent. 291 *****************************************************************************/ 292 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) 293 { 294 /* Mark the connected core as asleep */ 295 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); 296 297 /* Wait till the WAKER_CA_BIT changes to 1 */ 298 while (!(gicr_read_waker(gicr_base) & WAKER_CA_BIT)) 299 ; 300 } 301 302 303 /******************************************************************************* 304 * This function probes the Redistributor frames when the driver is initialised 305 * and saves their base addresses. These base addresses are used later to 306 * initialise each Redistributor interface. 307 ******************************************************************************/ 308 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 309 unsigned int rdistif_num, 310 uintptr_t gicr_base, 311 mpidr_hash_fn mpidr_to_core_pos) 312 { 313 u_register_t mpidr; 314 unsigned int proc_num; 315 unsigned long long typer_val; 316 uintptr_t rdistif_base = gicr_base; 317 318 assert(rdistif_base_addrs); 319 320 /* 321 * Iterate over the Redistributor frames. Store the base address of each 322 * frame in the platform provided array. Use the "Processor Number" 323 * field to index into the array if the platform has not provided a hash 324 * function to convert an MPIDR (obtained from the "Affinity Value" 325 * field into a linear index. 326 */ 327 do { 328 typer_val = gicr_read_typer(rdistif_base); 329 if (mpidr_to_core_pos) { 330 mpidr = mpidr_from_gicr_typer(typer_val); 331 proc_num = mpidr_to_core_pos(mpidr); 332 } else { 333 proc_num = (typer_val >> TYPER_PROC_NUM_SHIFT) & 334 TYPER_PROC_NUM_MASK; 335 } 336 assert(proc_num < rdistif_num); 337 rdistif_base_addrs[proc_num] = rdistif_base; 338 rdistif_base += (1 << GICR_PCPUBASE_SHIFT); 339 } while (!(typer_val & TYPER_LAST_BIT)); 340 } 341 342 /******************************************************************************* 343 * Helper function to configure the default attributes of SPIs. 344 ******************************************************************************/ 345 void gicv3_spis_config_defaults(uintptr_t gicd_base) 346 { 347 unsigned int index, num_ints; 348 349 num_ints = gicd_read_typer(gicd_base); 350 num_ints &= TYPER_IT_LINES_NO_MASK; 351 num_ints = (num_ints + 1) << 5; 352 353 /* 354 * Treat all SPIs as G1NS by default. The number of interrupts is 355 * calculated as 32 * (IT_LINES + 1). We do 32 at a time. 356 */ 357 for (index = MIN_SPI_ID; index < num_ints; index += 32) 358 gicd_write_igroupr(gicd_base, index, ~0U); 359 360 /* Setup the default SPI priorities doing four at a time */ 361 for (index = MIN_SPI_ID; index < num_ints; index += 4) 362 gicd_write_ipriorityr(gicd_base, 363 index, 364 GICD_IPRIORITYR_DEF_VAL); 365 366 /* 367 * Treat all SPIs as level triggered by default, write 16 at 368 * a time 369 */ 370 for (index = MIN_SPI_ID; index < num_ints; index += 16) 371 gicd_write_icfgr(gicd_base, index, 0); 372 } 373 374 #if !ERROR_DEPRECATED 375 /******************************************************************************* 376 * Helper function to configure secure G0 and G1S SPIs. 377 ******************************************************************************/ 378 void gicv3_secure_spis_config(uintptr_t gicd_base, 379 unsigned int num_ints, 380 const unsigned int *sec_intr_list, 381 unsigned int int_grp) 382 { 383 unsigned int index, irq_num; 384 unsigned long long gic_affinity_val; 385 386 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 387 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 388 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 389 390 for (index = 0; index < num_ints; index++) { 391 irq_num = sec_intr_list[index]; 392 if (irq_num >= MIN_SPI_ID) { 393 394 /* Configure this interrupt as a secure interrupt */ 395 gicd_clr_igroupr(gicd_base, irq_num); 396 397 /* Configure this interrupt as G0 or a G1S interrupt */ 398 if (int_grp == INTR_GROUP1S) 399 gicd_set_igrpmodr(gicd_base, irq_num); 400 else 401 gicd_clr_igrpmodr(gicd_base, irq_num); 402 403 /* Set the priority of this interrupt */ 404 gicd_set_ipriorityr(gicd_base, 405 irq_num, 406 GIC_HIGHEST_SEC_PRIORITY); 407 408 /* Target SPIs to the primary CPU */ 409 gic_affinity_val = 410 gicd_irouter_val_from_mpidr(read_mpidr(), 0); 411 gicd_write_irouter(gicd_base, 412 irq_num, 413 gic_affinity_val); 414 415 /* Enable this interrupt */ 416 gicd_set_isenabler(gicd_base, irq_num); 417 } 418 } 419 420 } 421 #endif 422 423 /******************************************************************************* 424 * Helper function to configure properties of secure SPIs 425 ******************************************************************************/ 426 unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, 427 const interrupt_prop_t *interrupt_props, 428 unsigned int interrupt_props_num) 429 { 430 unsigned int i; 431 const interrupt_prop_t *current_prop; 432 unsigned long long gic_affinity_val; 433 unsigned int ctlr_enable = 0; 434 435 /* Make sure there's a valid property array */ 436 assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1); 437 438 for (i = 0; i < interrupt_props_num; i++) { 439 current_prop = &interrupt_props[i]; 440 441 if (current_prop->intr_num < MIN_SPI_ID) 442 continue; 443 444 /* Configure this interrupt as a secure interrupt */ 445 gicd_clr_igroupr(gicd_base, current_prop->intr_num); 446 447 /* Configure this interrupt as G0 or a G1S interrupt */ 448 assert((current_prop->intr_grp == INTR_GROUP0) || 449 (current_prop->intr_grp == INTR_GROUP1S)); 450 if (current_prop->intr_grp == INTR_GROUP1S) { 451 gicd_set_igrpmodr(gicd_base, current_prop->intr_num); 452 ctlr_enable |= CTLR_ENABLE_G1S_BIT; 453 } else { 454 gicd_clr_igrpmodr(gicd_base, current_prop->intr_num); 455 ctlr_enable |= CTLR_ENABLE_G0_BIT; 456 } 457 458 /* Set interrupt configuration */ 459 gicd_set_icfgr(gicd_base, current_prop->intr_num, 460 current_prop->intr_cfg); 461 462 /* Set the priority of this interrupt */ 463 gicd_set_ipriorityr(gicd_base, current_prop->intr_num, 464 current_prop->intr_pri); 465 466 /* Target SPIs to the primary CPU */ 467 gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0); 468 gicd_write_irouter(gicd_base, current_prop->intr_num, 469 gic_affinity_val); 470 471 /* Enable this interrupt */ 472 gicd_set_isenabler(gicd_base, current_prop->intr_num); 473 } 474 475 return ctlr_enable; 476 } 477 478 /******************************************************************************* 479 * Helper function to configure the default attributes of SPIs. 480 ******************************************************************************/ 481 void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base) 482 { 483 unsigned int index; 484 485 /* 486 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a 487 * more scalable approach as it avoids clearing the enable bits in the 488 * GICD_CTLR 489 */ 490 gicr_write_icenabler0(gicr_base, ~0); 491 gicr_wait_for_pending_write(gicr_base); 492 493 /* Treat all SGIs/PPIs as G1NS by default. */ 494 gicr_write_igroupr0(gicr_base, ~0U); 495 496 /* Setup the default PPI/SGI priorities doing four at a time */ 497 for (index = 0; index < MIN_SPI_ID; index += 4) 498 gicr_write_ipriorityr(gicr_base, 499 index, 500 GICD_IPRIORITYR_DEF_VAL); 501 502 /* Configure all PPIs as level triggered by default */ 503 gicr_write_icfgr1(gicr_base, 0); 504 } 505 506 #if !ERROR_DEPRECATED 507 /******************************************************************************* 508 * Helper function to configure secure G0 and G1S SPIs. 509 ******************************************************************************/ 510 void gicv3_secure_ppi_sgi_config(uintptr_t gicr_base, 511 unsigned int num_ints, 512 const unsigned int *sec_intr_list, 513 unsigned int int_grp) 514 { 515 unsigned int index, irq_num; 516 517 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 518 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 519 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 520 521 for (index = 0; index < num_ints; index++) { 522 irq_num = sec_intr_list[index]; 523 if (irq_num < MIN_SPI_ID) { 524 525 /* Configure this interrupt as a secure interrupt */ 526 gicr_clr_igroupr0(gicr_base, irq_num); 527 528 /* Configure this interrupt as G0 or a G1S interrupt */ 529 if (int_grp == INTR_GROUP1S) 530 gicr_set_igrpmodr0(gicr_base, irq_num); 531 else 532 gicr_clr_igrpmodr0(gicr_base, irq_num); 533 534 /* Set the priority of this interrupt */ 535 gicr_set_ipriorityr(gicr_base, 536 irq_num, 537 GIC_HIGHEST_SEC_PRIORITY); 538 539 /* Enable this interrupt */ 540 gicr_set_isenabler0(gicr_base, irq_num); 541 } 542 } 543 } 544 #endif 545 546 /******************************************************************************* 547 * Helper function to configure properties of secure G0 and G1S PPIs and SGIs. 548 ******************************************************************************/ 549 unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, 550 const interrupt_prop_t *interrupt_props, 551 unsigned int interrupt_props_num) 552 { 553 unsigned int i; 554 const interrupt_prop_t *current_prop; 555 unsigned int ctlr_enable = 0; 556 557 /* Make sure there's a valid property array */ 558 assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1); 559 560 for (i = 0; i < interrupt_props_num; i++) { 561 current_prop = &interrupt_props[i]; 562 563 if (current_prop->intr_num >= MIN_SPI_ID) 564 continue; 565 566 /* Configure this interrupt as a secure interrupt */ 567 gicr_clr_igroupr0(gicr_base, current_prop->intr_num); 568 569 /* Configure this interrupt as G0 or a G1S interrupt */ 570 assert((current_prop->intr_grp == INTR_GROUP0) || 571 (current_prop->intr_grp == INTR_GROUP1S)); 572 if (current_prop->intr_grp == INTR_GROUP1S) { 573 gicr_set_igrpmodr0(gicr_base, current_prop->intr_num); 574 ctlr_enable |= CTLR_ENABLE_G1S_BIT; 575 } else { 576 gicr_clr_igrpmodr0(gicr_base, current_prop->intr_num); 577 ctlr_enable |= CTLR_ENABLE_G0_BIT; 578 } 579 580 /* Set the priority of this interrupt */ 581 gicr_set_ipriorityr(gicr_base, current_prop->intr_num, 582 current_prop->intr_pri); 583 584 /* 585 * Set interrupt configuration for PPIs. Configuration for SGIs 586 * are ignored. 587 */ 588 if ((current_prop->intr_num >= MIN_PPI_ID) && 589 (current_prop->intr_num < MIN_SPI_ID)) { 590 gicr_set_icfgr1(gicr_base, current_prop->intr_num, 591 current_prop->intr_cfg); 592 } 593 594 /* Enable this interrupt */ 595 gicr_set_isenabler0(gicr_base, current_prop->intr_num); 596 } 597 598 return ctlr_enable; 599 } 600