1 /* 2 * Copyright (c) 2015-2017, 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 <gic_common.h> 12 #include <gicv3.h> 13 #include <mmio.h> 14 #include <stdint.h> 15 #include "../common/gic_common_private.h" 16 17 /******************************************************************************* 18 * GICv3 private macro definitions 19 ******************************************************************************/ 20 21 /* Constants to indicate the status of the RWP bit */ 22 #define RWP_TRUE 1 23 #define RWP_FALSE 0 24 25 /* 26 * Macro to convert an mpidr to a value suitable for programming into a 27 * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant 28 * to GICv3. 29 */ 30 #define gicd_irouter_val_from_mpidr(mpidr, irm) \ 31 ((mpidr & ~(0xff << 24)) | \ 32 (irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT) 33 34 /* 35 * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] 36 * are zeroes. 37 */ 38 #ifdef AARCH32 39 #define mpidr_from_gicr_typer(typer_val) (((typer_val) >> 32) & 0xffffff) 40 #else 41 #define mpidr_from_gicr_typer(typer_val) \ 42 (((((typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \ 43 (((typer_val) >> 32) & 0xffffff)) 44 #endif 45 46 /******************************************************************************* 47 * GICv3 private global variables declarations 48 ******************************************************************************/ 49 extern const gicv3_driver_data_t *gicv3_driver_data; 50 51 /******************************************************************************* 52 * Private GICv3 function prototypes for accessing entire registers. 53 * Note: The raw register values correspond to multiple interrupt IDs and 54 * the number of interrupt IDs involved depends on the register accessed. 55 ******************************************************************************/ 56 unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); 57 unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); 58 void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); 59 void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); 60 61 /******************************************************************************* 62 * Private GICv3 function prototypes for accessing the GIC registers 63 * corresponding to a single interrupt ID. These functions use bitwise 64 * operations or appropriate register accesses to modify or return 65 * the bit-field corresponding the single interrupt ID. 66 ******************************************************************************/ 67 unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); 68 unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id); 69 unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id); 70 void gicd_set_igrpmodr(uintptr_t base, unsigned int id); 71 void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); 72 void gicr_set_isenabler0(uintptr_t base, unsigned int id); 73 void gicr_set_igroupr0(uintptr_t base, unsigned int id); 74 void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); 75 void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); 76 void gicr_clr_igroupr0(uintptr_t base, unsigned int id); 77 void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); 78 79 /******************************************************************************* 80 * Private GICv3 helper function prototypes 81 ******************************************************************************/ 82 void gicv3_spis_configure_defaults(uintptr_t gicd_base); 83 void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base); 84 void gicv3_secure_spis_configure(uintptr_t gicd_base, 85 unsigned int num_ints, 86 const unsigned int *sec_intr_list, 87 unsigned int int_grp); 88 void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, 89 unsigned int num_ints, 90 const unsigned int *sec_intr_list, 91 unsigned int int_grp); 92 void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 93 unsigned int rdistif_num, 94 uintptr_t gicr_base, 95 mpidr_hash_fn mpidr_to_core_pos); 96 void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base); 97 void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); 98 99 /******************************************************************************* 100 * GIC Distributor interface accessors 101 ******************************************************************************/ 102 /* 103 * Wait for updates to : 104 * GICD_CTLR[2:0] - the Group Enables 105 * GICD_CTLR[5:4] - the ARE bits 106 * GICD_ICENABLERn - the clearing of enable state for SPIs 107 */ 108 static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) 109 { 110 while (gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) 111 ; 112 } 113 114 static inline unsigned int gicd_read_pidr2(uintptr_t base) 115 { 116 return mmio_read_32(base + GICD_PIDR2_GICV3); 117 } 118 119 static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id) 120 { 121 assert(id >= MIN_SPI_ID); 122 return mmio_read_64(base + GICD_IROUTER + (id << 3)); 123 } 124 125 static inline void gicd_write_irouter(uintptr_t base, 126 unsigned int id, 127 unsigned long long affinity) 128 { 129 assert(id >= MIN_SPI_ID); 130 mmio_write_64(base + GICD_IROUTER + (id << 3), affinity); 131 } 132 133 static inline void gicd_clr_ctlr(uintptr_t base, 134 unsigned int bitmap, 135 unsigned int rwp) 136 { 137 gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); 138 if (rwp) 139 gicd_wait_for_pending_write(base); 140 } 141 142 static inline void gicd_set_ctlr(uintptr_t base, 143 unsigned int bitmap, 144 unsigned int rwp) 145 { 146 gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); 147 if (rwp) 148 gicd_wait_for_pending_write(base); 149 } 150 151 /******************************************************************************* 152 * GIC Redistributor interface accessors 153 ******************************************************************************/ 154 static inline unsigned long long gicr_read_ctlr(uintptr_t base) 155 { 156 return mmio_read_64(base + GICR_CTLR); 157 } 158 159 static inline void gicr_write_ctlr(uintptr_t base, uint64_t val) 160 { 161 mmio_write_64(base + GICR_CTLR, val); 162 } 163 164 static inline unsigned long long gicr_read_typer(uintptr_t base) 165 { 166 return mmio_read_64(base + GICR_TYPER); 167 } 168 169 static inline unsigned int gicr_read_waker(uintptr_t base) 170 { 171 return mmio_read_32(base + GICR_WAKER); 172 } 173 174 static inline void gicr_write_waker(uintptr_t base, unsigned int val) 175 { 176 mmio_write_32(base + GICR_WAKER, val); 177 } 178 179 /* 180 * Wait for updates to : 181 * GICR_ICENABLER0 182 * GICR_CTLR.DPG1S 183 * GICR_CTLR.DPG1NS 184 * GICR_CTLR.DPG0 185 */ 186 static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) 187 { 188 while (gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) 189 ; 190 } 191 192 static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) 193 { 194 while (gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) 195 ; 196 } 197 198 /* Private implementation of Distributor power control hooks */ 199 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); 200 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); 201 202 /******************************************************************************* 203 * GIC Re-distributor functions for accessing entire registers. 204 * Note: The raw register values correspond to multiple interrupt IDs and 205 * the number of interrupt IDs involved depends on the register accessed. 206 ******************************************************************************/ 207 static inline unsigned int gicr_read_icenabler0(uintptr_t base) 208 { 209 return mmio_read_32(base + GICR_ICENABLER0); 210 } 211 212 static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) 213 { 214 mmio_write_32(base + GICR_ICENABLER0, val); 215 } 216 217 static inline unsigned int gicr_read_isenabler0(uintptr_t base) 218 { 219 return mmio_read_32(base + GICR_ISENABLER0); 220 } 221 222 static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) 223 { 224 mmio_write_32(base + GICR_ISENABLER0, val); 225 } 226 227 static inline unsigned int gicr_read_igroupr0(uintptr_t base) 228 { 229 return mmio_read_32(base + GICR_IGROUPR0); 230 } 231 232 static inline unsigned int gicr_read_ispendr0(uintptr_t base) 233 { 234 return mmio_read_32(base + GICR_ISPENDR0); 235 } 236 237 static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) 238 { 239 mmio_write_32(base + GICR_ISPENDR0, val); 240 } 241 242 static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) 243 { 244 mmio_write_32(base + GICR_IGROUPR0, val); 245 } 246 247 static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) 248 { 249 return mmio_read_32(base + GICR_IGRPMODR0); 250 } 251 252 static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) 253 { 254 mmio_write_32(base + GICR_IGRPMODR0, val); 255 } 256 257 static inline unsigned int gicr_read_nsacr(uintptr_t base) 258 { 259 return mmio_read_32(base + GICR_NSACR); 260 } 261 262 static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) 263 { 264 mmio_write_32(base + GICR_NSACR, val); 265 } 266 267 static inline unsigned int gicr_read_isactiver0(uintptr_t base) 268 { 269 return mmio_read_32(base + GICR_ISACTIVER0); 270 } 271 272 static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) 273 { 274 mmio_write_32(base + GICR_ISACTIVER0, val); 275 } 276 277 static inline unsigned int gicr_read_icfgr0(uintptr_t base) 278 { 279 return mmio_read_32(base + GICR_ICFGR0); 280 } 281 282 static inline unsigned int gicr_read_icfgr1(uintptr_t base) 283 { 284 return mmio_read_32(base + GICR_ICFGR1); 285 } 286 287 static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) 288 { 289 mmio_write_32(base + GICR_ICFGR0, val); 290 } 291 292 static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) 293 { 294 mmio_write_32(base + GICR_ICFGR1, val); 295 } 296 297 static inline unsigned int gicr_read_propbaser(uintptr_t base) 298 { 299 return mmio_read_32(base + GICR_PROPBASER); 300 } 301 302 static inline void gicr_write_propbaser(uintptr_t base, unsigned int val) 303 { 304 mmio_write_32(base + GICR_PROPBASER, val); 305 } 306 307 static inline unsigned int gicr_read_pendbaser(uintptr_t base) 308 { 309 return mmio_read_32(base + GICR_PENDBASER); 310 } 311 312 static inline void gicr_write_pendbaser(uintptr_t base, unsigned int val) 313 { 314 mmio_write_32(base + GICR_PENDBASER, val); 315 } 316 317 /******************************************************************************* 318 * GIC ITS functions to read and write entire ITS registers. 319 ******************************************************************************/ 320 static inline uint32_t gits_read_ctlr(uintptr_t base) 321 { 322 return mmio_read_32(base + GITS_CTLR); 323 } 324 325 static inline void gits_write_ctlr(uintptr_t base, unsigned int val) 326 { 327 mmio_write_32(base + GITS_CTLR, val); 328 } 329 330 static inline uint64_t gits_read_cbaser(uintptr_t base) 331 { 332 return mmio_read_64(base + GITS_CBASER); 333 } 334 335 static inline void gits_write_cbaser(uintptr_t base, uint64_t val) 336 { 337 mmio_write_32(base + GITS_CBASER, val); 338 } 339 340 static inline uint64_t gits_read_cwriter(uintptr_t base) 341 { 342 return mmio_read_64(base + GITS_CWRITER); 343 } 344 345 static inline void gits_write_cwriter(uintptr_t base, uint64_t val) 346 { 347 mmio_write_32(base + GITS_CWRITER, val); 348 } 349 350 static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id) 351 { 352 assert(its_table_id < 8); 353 return mmio_read_64(base + GITS_BASER + (8 * its_table_id)); 354 } 355 356 static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val) 357 { 358 assert(its_table_id < 8); 359 mmio_write_64(base + GITS_BASER + (8 * its_table_id), val); 360 } 361 362 /* 363 * Wait for Quiescent bit when GIC ITS is disabled 364 */ 365 static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) 366 { 367 assert(!(gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT)); 368 while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0) 369 ; 370 } 371 372 373 #endif /* __GICV3_PRIVATE_H__ */ 374