1 /* 2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arch.h> 32 #include <arch_helpers.h> 33 #include <assert.h> 34 #include <debug.h> 35 #include <gic_common.h> 36 #include "gicv3_private.h" 37 38 /* 39 * Accessor to read the GIC Distributor IGRPMODR corresponding to the 40 * interrupt `id`, 32 interrupt IDs at a time. 41 */ 42 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) 43 { 44 unsigned n = id >> IGRPMODR_SHIFT; 45 return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); 46 } 47 48 /* 49 * Accessor to write the GIC Distributor IGRPMODR corresponding to the 50 * interrupt `id`, 32 interrupt IDs at a time. 51 */ 52 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) 53 { 54 unsigned n = id >> IGRPMODR_SHIFT; 55 mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); 56 } 57 58 /* 59 * Accessor to get the bit corresponding to interrupt ID 60 * in GIC Distributor IGRPMODR. 61 */ 62 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) 63 { 64 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 65 unsigned int reg_val = gicd_read_igrpmodr(base, id); 66 67 return (reg_val >> bit_num) & 0x1; 68 } 69 70 /* 71 * Accessor to set the bit corresponding to interrupt ID 72 * in GIC Distributor IGRPMODR. 73 */ 74 void gicd_set_igrpmodr(uintptr_t base, unsigned int id) 75 { 76 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 77 unsigned int reg_val = gicd_read_igrpmodr(base, id); 78 79 gicd_write_igrpmodr(base, id, reg_val | (1 << bit_num)); 80 } 81 82 /* 83 * Accessor to clear the bit corresponding to interrupt ID 84 * in GIC Distributor IGRPMODR. 85 */ 86 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) 87 { 88 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 89 unsigned int reg_val = gicd_read_igrpmodr(base, id); 90 91 gicd_write_igrpmodr(base, id, reg_val & ~(1 << bit_num)); 92 } 93 94 /* 95 * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the 96 * interrupt `id`, 4 interrupts IDs at a time. 97 */ 98 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) 99 { 100 unsigned n = id >> IPRIORITYR_SHIFT; 101 return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); 102 } 103 104 /* 105 * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the 106 * interrupt `id`, 4 interrupts IDs at a time. 107 */ 108 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) 109 { 110 unsigned n = id >> IPRIORITYR_SHIFT; 111 mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); 112 } 113 114 /* 115 * Accessor to get the bit corresponding to interrupt ID 116 * from GIC Re-distributor IGROUPR0. 117 */ 118 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) 119 { 120 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 121 unsigned int reg_val = gicr_read_igroupr0(base); 122 123 return (reg_val >> bit_num) & 0x1; 124 } 125 126 /* 127 * Accessor to set the bit corresponding to interrupt ID 128 * in GIC Re-distributor IGROUPR0. 129 */ 130 void gicr_set_igroupr0(uintptr_t base, unsigned int id) 131 { 132 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 133 unsigned int reg_val = gicr_read_igroupr0(base); 134 135 gicr_write_igroupr0(base, reg_val | (1 << bit_num)); 136 } 137 138 /* 139 * Accessor to clear the bit corresponding to interrupt ID 140 * in GIC Re-distributor IGROUPR0. 141 */ 142 void gicr_clr_igroupr0(uintptr_t base, unsigned int id) 143 { 144 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1); 145 unsigned int reg_val = gicr_read_igroupr0(base); 146 147 gicr_write_igroupr0(base, reg_val & ~(1 << bit_num)); 148 } 149 150 /* 151 * Accessor to get the bit corresponding to interrupt ID 152 * from GIC Re-distributor IGRPMODR0. 153 */ 154 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) 155 { 156 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 157 unsigned int reg_val = gicr_read_igrpmodr0(base); 158 159 return (reg_val >> bit_num) & 0x1; 160 } 161 162 /* 163 * Accessor to set the bit corresponding to interrupt ID 164 * in GIC Re-distributor IGRPMODR0. 165 */ 166 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) 167 { 168 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 169 unsigned int reg_val = gicr_read_igrpmodr0(base); 170 171 gicr_write_igrpmodr0(base, reg_val | (1 << bit_num)); 172 } 173 174 /* 175 * Accessor to clear the bit corresponding to interrupt ID 176 * in GIC Re-distributor IGRPMODR0. 177 */ 178 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) 179 { 180 unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1); 181 unsigned int reg_val = gicr_read_igrpmodr0(base); 182 183 gicr_write_igrpmodr0(base, reg_val & ~(1 << bit_num)); 184 } 185 186 /* 187 * Accessor to set the bit corresponding to interrupt ID 188 * in GIC Re-distributor ISENABLER0. 189 */ 190 void gicr_set_isenabler0(uintptr_t base, unsigned int id) 191 { 192 unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1); 193 194 gicr_write_isenabler0(base, (1 << bit_num)); 195 } 196 197 /****************************************************************************** 198 * This function marks the core as awake in the re-distributor and 199 * ensures that the interface is active. 200 *****************************************************************************/ 201 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) 202 { 203 /* 204 * The WAKER_PS_BIT should be changed to 0 205 * only when WAKER_CA_BIT is 1. 206 */ 207 assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); 208 209 /* Mark the connected core as awake */ 210 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT); 211 212 /* Wait till the WAKER_CA_BIT changes to 0 */ 213 while (gicr_read_waker(gicr_base) & WAKER_CA_BIT) 214 ; 215 } 216 217 218 /****************************************************************************** 219 * This function marks the core as asleep in the re-distributor and ensures 220 * that the interface is quiescent. 221 *****************************************************************************/ 222 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base) 223 { 224 /* Mark the connected core as asleep */ 225 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT); 226 227 /* Wait till the WAKER_CA_BIT changes to 1 */ 228 while (!(gicr_read_waker(gicr_base) & WAKER_CA_BIT)) 229 ; 230 } 231 232 233 /******************************************************************************* 234 * This function probes the Redistributor frames when the driver is initialised 235 * and saves their base addresses. These base addresses are used later to 236 * initialise each Redistributor interface. 237 ******************************************************************************/ 238 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 239 unsigned int rdistif_num, 240 uintptr_t gicr_base, 241 mpidr_hash_fn mpidr_to_core_pos) 242 { 243 unsigned long mpidr; 244 unsigned int proc_num; 245 unsigned long long typer_val; 246 uintptr_t rdistif_base = gicr_base; 247 248 assert(rdistif_base_addrs); 249 250 /* 251 * Iterate over the Redistributor frames. Store the base address of each 252 * frame in the platform provided array. Use the "Processor Number" 253 * field to index into the array if the platform has not provided a hash 254 * function to convert an MPIDR (obtained from the "Affinity Value" 255 * field into a linear index. 256 */ 257 do { 258 typer_val = gicr_read_typer(rdistif_base); 259 if (mpidr_to_core_pos) { 260 mpidr = mpidr_from_gicr_typer(typer_val); 261 proc_num = mpidr_to_core_pos(mpidr); 262 } else { 263 proc_num = (typer_val >> TYPER_PROC_NUM_SHIFT) & 264 TYPER_PROC_NUM_MASK; 265 } 266 assert(proc_num < rdistif_num); 267 rdistif_base_addrs[proc_num] = rdistif_base; 268 rdistif_base += (1 << GICR_PCPUBASE_SHIFT); 269 } while (!(typer_val & TYPER_LAST_BIT)); 270 } 271 272 /******************************************************************************* 273 * Helper function to configure the default attributes of SPIs. 274 ******************************************************************************/ 275 void gicv3_spis_configure_defaults(uintptr_t gicd_base) 276 { 277 unsigned int index, num_ints; 278 279 num_ints = gicd_read_typer(gicd_base); 280 num_ints &= TYPER_IT_LINES_NO_MASK; 281 num_ints = (num_ints + 1) << 5; 282 283 /* 284 * Treat all SPIs as G1NS by default. The number of interrupts is 285 * calculated as 32 * (IT_LINES + 1). We do 32 at a time. 286 */ 287 for (index = MIN_SPI_ID; index < num_ints; index += 32) 288 gicd_write_igroupr(gicd_base, index, ~0U); 289 290 /* Setup the default SPI priorities doing four at a time */ 291 for (index = MIN_SPI_ID; index < num_ints; index += 4) 292 gicd_write_ipriorityr(gicd_base, 293 index, 294 GICD_IPRIORITYR_DEF_VAL); 295 296 /* 297 * Treat all SPIs as level triggered by default, write 16 at 298 * a time 299 */ 300 for (index = MIN_SPI_ID; index < num_ints; index += 16) 301 gicd_write_icfgr(gicd_base, index, 0); 302 } 303 304 /******************************************************************************* 305 * Helper function to configure secure G0 and G1S SPIs. 306 ******************************************************************************/ 307 void gicv3_secure_spis_configure(uintptr_t gicd_base, 308 unsigned int num_ints, 309 const unsigned int *sec_intr_list, 310 unsigned int int_grp) 311 { 312 unsigned int index, irq_num; 313 uint64_t gic_affinity_val; 314 315 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 316 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 317 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 318 319 for (index = 0; index < num_ints; index++) { 320 irq_num = sec_intr_list[index]; 321 if (irq_num >= MIN_SPI_ID) { 322 323 /* Configure this interrupt as a secure interrupt */ 324 gicd_clr_igroupr(gicd_base, irq_num); 325 326 /* Configure this interrupt as G0 or a G1S interrupt */ 327 if (int_grp == INTR_GROUP1S) 328 gicd_set_igrpmodr(gicd_base, irq_num); 329 else 330 gicd_clr_igrpmodr(gicd_base, irq_num); 331 332 /* Set the priority of this interrupt */ 333 gicd_write_ipriorityr(gicd_base, 334 irq_num, 335 GIC_HIGHEST_SEC_PRIORITY); 336 337 /* Target SPIs to the primary CPU */ 338 gic_affinity_val = 339 gicd_irouter_val_from_mpidr(read_mpidr(), 0); 340 gicd_write_irouter(gicd_base, 341 irq_num, 342 gic_affinity_val); 343 344 /* Enable this interrupt */ 345 gicd_set_isenabler(gicd_base, irq_num); 346 } 347 } 348 349 } 350 351 /******************************************************************************* 352 * Helper function to configure the default attributes of SPIs. 353 ******************************************************************************/ 354 void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base) 355 { 356 unsigned int index; 357 358 /* 359 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a 360 * more scalable approach as it avoids clearing the enable bits in the 361 * GICD_CTLR 362 */ 363 gicr_write_icenabler0(gicr_base, ~0); 364 gicr_wait_for_pending_write(gicr_base); 365 366 /* Treat all SGIs/PPIs as G1NS by default. */ 367 gicr_write_igroupr0(gicr_base, ~0U); 368 369 /* Setup the default PPI/SGI priorities doing four at a time */ 370 for (index = 0; index < MIN_SPI_ID; index += 4) 371 gicr_write_ipriorityr(gicr_base, 372 index, 373 GICD_IPRIORITYR_DEF_VAL); 374 375 /* Configure all PPIs as level triggered by default */ 376 gicr_write_icfgr1(gicr_base, 0); 377 } 378 379 /******************************************************************************* 380 * Helper function to configure secure G0 and G1S SPIs. 381 ******************************************************************************/ 382 void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, 383 unsigned int num_ints, 384 const unsigned int *sec_intr_list, 385 unsigned int int_grp) 386 { 387 unsigned int index, irq_num; 388 389 assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0)); 390 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 391 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 392 393 for (index = 0; index < num_ints; index++) { 394 irq_num = sec_intr_list[index]; 395 if (irq_num < MIN_SPI_ID) { 396 397 /* Configure this interrupt as a secure interrupt */ 398 gicr_clr_igroupr0(gicr_base, irq_num); 399 400 /* Configure this interrupt as G0 or a G1S interrupt */ 401 if (int_grp == INTR_GROUP1S) 402 gicr_set_igrpmodr0(gicr_base, irq_num); 403 else 404 gicr_clr_igrpmodr0(gicr_base, irq_num); 405 406 /* Set the priority of this interrupt */ 407 gicr_write_ipriorityr(gicr_base, 408 irq_num, 409 GIC_HIGHEST_SEC_PRIORITY); 410 411 /* Enable this interrupt */ 412 gicr_set_isenabler0(gicr_base, irq_num); 413 } 414 } 415 } 416