1 /* 2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef GICV3_PRIVATE_H 8 #define GICV3_PRIVATE_H 9 10 #include <assert.h> 11 #include <stdint.h> 12 13 #include <drivers/arm/gic_common.h> 14 #include <drivers/arm/gicv3.h> 15 #include <lib/mmio.h> 16 17 #include "../common/gic_common_private.h" 18 19 /******************************************************************************* 20 * GICv3 private macro definitions 21 ******************************************************************************/ 22 23 /* Constants to indicate the status of the RWP bit */ 24 #define RWP_TRUE U(1) 25 #define RWP_FALSE U(0) 26 27 /* Calculate GIC register bit number corresponding to its interrupt ID */ 28 #define BIT_NUM(REG, id) \ 29 ((id) & ((1U << REG##_SHIFT) - 1U)) 30 31 /* Calculate 8-bit GICD register offset corresponding to its interrupt ID */ 32 #define GICD_OFFSET_8(REG, id) \ 33 GICD_##REG + (id) 34 35 /* Calculate 32-bit GICD register offset corresponding to its interrupt ID */ 36 #define GICD_OFFSET(REG, id) \ 37 GICD_##REG + (((id) >> REG##_SHIFT) << 2) 38 39 /* Calculate 64-bit GICD register offset corresponding to its interrupt ID */ 40 #define GICD_OFFSET_64(REG, id) \ 41 GICD_##REG + (((id) >> REG##_SHIFT) << 3) 42 43 /* Read 32-bit GIC Distributor register corresponding to its interrupt ID */ 44 #define GICD_READ(REG, base, id) \ 45 mmio_read_32((base) + GICD_OFFSET(REG, (id))) 46 47 /* Read 64-bit GIC Distributor register corresponding to its interrupt ID */ 48 #define GICD_READ_64(REG, base, id) \ 49 mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) 50 51 /* Write to 64-bit GIC Distributor register corresponding to its interrupt ID */ 52 #define GICD_WRITE_64(REG, base, id, val) \ 53 mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) 54 55 /* Write to 32-bit GIC Distributor register corresponding to its interrupt ID */ 56 #define GICD_WRITE(REG, base, id, val) \ 57 mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) 58 59 /* Write to 8-bit GIC Distributor register corresponding to its interrupt ID */ 60 #define GICD_WRITE_8(REG, base, id, val) \ 61 mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) 62 63 /* 64 * Bit operations on GIC Distributor register corresponding 65 * to its interrupt ID 66 */ 67 /* Get bit in GIC Distributor register */ 68 #define GICD_GET_BIT(REG, base, id) \ 69 ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \ 70 BIT_NUM(REG, (id))) & 1U) 71 72 /* Set bit in GIC Distributor register */ 73 #define GICD_SET_BIT(REG, base, id) \ 74 mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \ 75 ((uint32_t)1 << BIT_NUM(REG, (id)))) 76 77 /* Clear bit in GIC Distributor register */ 78 #define GICD_CLR_BIT(REG, base, id) \ 79 mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \ 80 ((uint32_t)1 << BIT_NUM(REG, (id)))) 81 82 /* Write bit in GIC Distributor register */ 83 #define GICD_WRITE_BIT(REG, base, id) \ 84 mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ 85 ((uint32_t)1 << BIT_NUM(REG, (id)))) 86 87 /* 88 * Calculate GICv3 GICR register offset 89 */ 90 #define GICR_OFFSET(REG, id) \ 91 GICR_##REG + (((id) >> REG##_SHIFT) << 2) 92 93 /* Write to GIC Redistributor register corresponding to its interrupt ID */ 94 #define GICR_WRITE_8(REG, base, id, val) \ 95 mmio_write_8((base) + GICR_##REG + (id), (val)) 96 97 /* 98 * Bit operations on GIC Redistributor register 99 * corresponding to its interrupt ID 100 */ 101 /* Get bit in GIC Redistributor register */ 102 #define GICR_GET_BIT(REG, base, id) \ 103 ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \ 104 BIT_NUM(REG, (id))) & 1U) 105 106 /* Write bit in GIC Redistributor register */ 107 #define GICR_WRITE_BIT(REG, base, id) \ 108 mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ 109 ((uint32_t)1 << BIT_NUM(REG, (id)))) 110 111 /* Set bit in GIC Redistributor register */ 112 #define GICR_SET_BIT(REG, base, id) \ 113 mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \ 114 ((uint32_t)1 << BIT_NUM(REG, (id)))) 115 116 /* Clear bit in GIC Redistributor register */ 117 #define GICR_CLR_BIT(REG, base, id) \ 118 mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \ 119 ((uint32_t)1 << BIT_NUM(REG, (id)))) 120 121 /* 122 * Macro to convert an mpidr to a value suitable for programming into a 123 * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant 124 * to GICv3. 125 */ 126 static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr, 127 unsigned int irm) 128 { 129 return (mpidr & ~(U(0xff) << 24)) | 130 ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT); 131 } 132 133 /* 134 * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] 135 * are zeroes. 136 */ 137 #ifdef __aarch64__ 138 static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) 139 { 140 return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | 141 ((typer_val >> 32) & U(0xffffff)); 142 } 143 #else 144 static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) 145 { 146 return (((typer_val) >> 32) & U(0xffffff)); 147 } 148 #endif 149 150 /******************************************************************************* 151 * GICv3 private global variables declarations 152 ******************************************************************************/ 153 extern const gicv3_driver_data_t *gicv3_driver_data; 154 155 /******************************************************************************* 156 * Private GICv3 function prototypes for accessing entire registers. 157 * Note: The raw register values correspond to multiple interrupt IDs and 158 * the number of interrupt IDs involved depends on the register accessed. 159 ******************************************************************************/ 160 uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id); 161 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); 162 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val); 163 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); 164 165 /******************************************************************************* 166 * Private GICv3 function prototypes for accessing the GIC registers 167 * corresponding to a single interrupt ID. These functions use bitwise 168 * operations or appropriate register accesses to modify or return 169 * the bit-field corresponding the single interrupt ID. 170 ******************************************************************************/ 171 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); 172 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id); 173 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id); 174 unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id); 175 void gicd_set_igrpmodr(uintptr_t base, unsigned int id); 176 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); 177 void gicr_set_isenabler0(uintptr_t base, unsigned int id); 178 void gicr_set_icenabler0(uintptr_t base, unsigned int id); 179 void gicr_set_ispendr0(uintptr_t base, unsigned int id); 180 void gicr_set_icpendr0(uintptr_t base, unsigned int id); 181 void gicr_set_igroupr0(uintptr_t base, unsigned int id); 182 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); 183 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); 184 void gicr_clr_igroupr0(uintptr_t base, unsigned int id); 185 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); 186 void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg); 187 void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg); 188 189 /******************************************************************************* 190 * Private GICv3 helper function prototypes 191 ******************************************************************************/ 192 void gicv3_spis_config_defaults(uintptr_t gicd_base); 193 void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base); 194 unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, 195 const interrupt_prop_t *interrupt_props, 196 unsigned int interrupt_props_num); 197 unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, 198 const interrupt_prop_t *interrupt_props, 199 unsigned int interrupt_props_num); 200 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 201 unsigned int rdistif_num, 202 uintptr_t gicr_base, 203 mpidr_hash_fn mpidr_to_core_pos); 204 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base); 205 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); 206 207 /******************************************************************************* 208 * GIC Distributor interface accessors 209 ******************************************************************************/ 210 /* 211 * Wait for updates to : 212 * GICD_CTLR[2:0] - the Group Enables 213 * GICD_CTLR[5:4] - the ARE bits 214 * GICD_ICENABLERn - the clearing of enable state for SPIs 215 */ 216 static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) 217 { 218 while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) { 219 } 220 } 221 222 static inline uint32_t gicd_read_pidr2(uintptr_t base) 223 { 224 return mmio_read_32(base + GICD_PIDR2_GICV3); 225 } 226 227 static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) 228 { 229 assert(id >= MIN_SPI_ID); 230 return GICD_READ_64(IROUTER, base, id); 231 } 232 233 static inline void gicd_write_irouter(uintptr_t base, 234 unsigned int id, 235 uint64_t affinity) 236 { 237 assert(id >= MIN_SPI_ID); 238 GICD_WRITE_64(IROUTER, base, id, affinity); 239 } 240 241 static inline void gicd_clr_ctlr(uintptr_t base, 242 unsigned int bitmap, 243 unsigned int rwp) 244 { 245 gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); 246 if (rwp != 0U) { 247 gicd_wait_for_pending_write(base); 248 } 249 } 250 251 static inline void gicd_set_ctlr(uintptr_t base, 252 unsigned int bitmap, 253 unsigned int rwp) 254 { 255 gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); 256 if (rwp != 0U) { 257 gicd_wait_for_pending_write(base); 258 } 259 } 260 261 /******************************************************************************* 262 * GIC Redistributor interface accessors 263 ******************************************************************************/ 264 static inline uint32_t gicr_read_ctlr(uintptr_t base) 265 { 266 return mmio_read_32(base + GICR_CTLR); 267 } 268 269 static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) 270 { 271 mmio_write_32(base + GICR_CTLR, val); 272 } 273 274 static inline uint64_t gicr_read_typer(uintptr_t base) 275 { 276 return mmio_read_64(base + GICR_TYPER); 277 } 278 279 static inline uint32_t gicr_read_waker(uintptr_t base) 280 { 281 return mmio_read_32(base + GICR_WAKER); 282 } 283 284 static inline void gicr_write_waker(uintptr_t base, uint32_t val) 285 { 286 mmio_write_32(base + GICR_WAKER, val); 287 } 288 289 /* 290 * Wait for updates to : 291 * GICR_ICENABLER0 292 * GICR_CTLR.DPG1S 293 * GICR_CTLR.DPG1NS 294 * GICR_CTLR.DPG0 295 */ 296 static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) 297 { 298 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) { 299 } 300 } 301 302 static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) 303 { 304 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) { 305 } 306 } 307 308 /* Private implementation of Distributor power control hooks */ 309 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); 310 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); 311 312 /******************************************************************************* 313 * GIC Redistributor functions for accessing entire registers. 314 * Note: The raw register values correspond to multiple interrupt IDs and 315 * the number of interrupt IDs involved depends on the register accessed. 316 ******************************************************************************/ 317 static inline unsigned int gicr_read_icenabler0(uintptr_t base) 318 { 319 return mmio_read_32(base + GICR_ICENABLER0); 320 } 321 322 static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) 323 { 324 mmio_write_32(base + GICR_ICENABLER0, val); 325 } 326 327 static inline unsigned int gicr_read_isenabler0(uintptr_t base) 328 { 329 return mmio_read_32(base + GICR_ISENABLER0); 330 } 331 332 static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val) 333 { 334 mmio_write_32(base + GICR_ICPENDR0, val); 335 } 336 337 static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) 338 { 339 mmio_write_32(base + GICR_ISENABLER0, val); 340 } 341 342 static inline unsigned int gicr_read_igroupr0(uintptr_t base) 343 { 344 return mmio_read_32(base + GICR_IGROUPR0); 345 } 346 347 static inline unsigned int gicr_read_ispendr0(uintptr_t base) 348 { 349 return mmio_read_32(base + GICR_ISPENDR0); 350 } 351 352 static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) 353 { 354 mmio_write_32(base + GICR_ISPENDR0, val); 355 } 356 357 static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) 358 { 359 mmio_write_32(base + GICR_IGROUPR0, val); 360 } 361 362 static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) 363 { 364 return mmio_read_32(base + GICR_IGRPMODR0); 365 } 366 367 static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) 368 { 369 mmio_write_32(base + GICR_IGRPMODR0, val); 370 } 371 372 static inline unsigned int gicr_read_nsacr(uintptr_t base) 373 { 374 return mmio_read_32(base + GICR_NSACR); 375 } 376 377 static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) 378 { 379 mmio_write_32(base + GICR_NSACR, val); 380 } 381 382 static inline unsigned int gicr_read_isactiver0(uintptr_t base) 383 { 384 return mmio_read_32(base + GICR_ISACTIVER0); 385 } 386 387 static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) 388 { 389 mmio_write_32(base + GICR_ISACTIVER0, val); 390 } 391 392 static inline unsigned int gicr_read_icfgr0(uintptr_t base) 393 { 394 return mmio_read_32(base + GICR_ICFGR0); 395 } 396 397 static inline unsigned int gicr_read_icfgr1(uintptr_t base) 398 { 399 return mmio_read_32(base + GICR_ICFGR1); 400 } 401 402 static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) 403 { 404 mmio_write_32(base + GICR_ICFGR0, val); 405 } 406 407 static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) 408 { 409 mmio_write_32(base + GICR_ICFGR1, val); 410 } 411 412 static inline uint64_t gicr_read_propbaser(uintptr_t base) 413 { 414 return mmio_read_64(base + GICR_PROPBASER); 415 } 416 417 static inline void gicr_write_propbaser(uintptr_t base, uint64_t val) 418 { 419 mmio_write_64(base + GICR_PROPBASER, val); 420 } 421 422 static inline uint64_t gicr_read_pendbaser(uintptr_t base) 423 { 424 return mmio_read_64(base + GICR_PENDBASER); 425 } 426 427 static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val) 428 { 429 mmio_write_64(base + GICR_PENDBASER, val); 430 } 431 432 /******************************************************************************* 433 * GIC ITS functions to read and write entire ITS registers. 434 ******************************************************************************/ 435 static inline uint32_t gits_read_ctlr(uintptr_t base) 436 { 437 return mmio_read_32(base + GITS_CTLR); 438 } 439 440 static inline void gits_write_ctlr(uintptr_t base, uint32_t val) 441 { 442 mmio_write_32(base + GITS_CTLR, val); 443 } 444 445 static inline uint64_t gits_read_cbaser(uintptr_t base) 446 { 447 return mmio_read_64(base + GITS_CBASER); 448 } 449 450 static inline void gits_write_cbaser(uintptr_t base, uint64_t val) 451 { 452 mmio_write_64(base + GITS_CBASER, val); 453 } 454 455 static inline uint64_t gits_read_cwriter(uintptr_t base) 456 { 457 return mmio_read_64(base + GITS_CWRITER); 458 } 459 460 static inline void gits_write_cwriter(uintptr_t base, uint64_t val) 461 { 462 mmio_write_64(base + GITS_CWRITER, val); 463 } 464 465 static inline uint64_t gits_read_baser(uintptr_t base, 466 unsigned int its_table_id) 467 { 468 assert(its_table_id < 8U); 469 return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); 470 } 471 472 static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, 473 uint64_t val) 474 { 475 assert(its_table_id < 8U); 476 mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); 477 } 478 479 /* 480 * Wait for Quiescent bit when GIC ITS is disabled 481 */ 482 static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) 483 { 484 assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); 485 while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) { 486 } 487 } 488 489 #endif /* GICV3_PRIVATE_H */ 490