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