1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * Copyright (c) 2023, NVIDIA Corporation. All rights reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #ifndef GICV3_PRIVATE_H 9*91f16700Schasinglulu #define GICV3_PRIVATE_H 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <assert.h> 12*91f16700Schasinglulu #include <stdint.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include <drivers/arm/gic_common.h> 15*91f16700Schasinglulu #include <drivers/arm/gicv3.h> 16*91f16700Schasinglulu #include <lib/mmio.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #include "../common/gic_common_private.h" 19*91f16700Schasinglulu 20*91f16700Schasinglulu /******************************************************************************* 21*91f16700Schasinglulu * GICv3 private macro definitions 22*91f16700Schasinglulu ******************************************************************************/ 23*91f16700Schasinglulu 24*91f16700Schasinglulu /* Constants to indicate the status of the RWP bit */ 25*91f16700Schasinglulu #define RWP_TRUE U(1) 26*91f16700Schasinglulu #define RWP_FALSE U(0) 27*91f16700Schasinglulu 28*91f16700Schasinglulu /* Calculate GIC register bit number corresponding to its interrupt ID */ 29*91f16700Schasinglulu #define BIT_NUM(REG, id) \ 30*91f16700Schasinglulu ((id) & ((1U << REG##R_SHIFT) - 1U)) 31*91f16700Schasinglulu 32*91f16700Schasinglulu /* 33*91f16700Schasinglulu * Calculate 8, 32 and 64-bit GICD register offset 34*91f16700Schasinglulu * corresponding to its interrupt ID 35*91f16700Schasinglulu */ 36*91f16700Schasinglulu #if GIC_EXT_INTID 37*91f16700Schasinglulu /* GICv3.1 */ 38*91f16700Schasinglulu #define GICD_OFFSET_8(REG, id) \ 39*91f16700Schasinglulu (((id) <= MAX_SPI_ID) ? \ 40*91f16700Schasinglulu GICD_##REG##R + (uintptr_t)(id) : \ 41*91f16700Schasinglulu GICD_##REG##RE + (uintptr_t)(id) - MIN_ESPI_ID) 42*91f16700Schasinglulu 43*91f16700Schasinglulu #define GICD_OFFSET(REG, id) \ 44*91f16700Schasinglulu (((id) <= MAX_SPI_ID) ? \ 45*91f16700Schasinglulu GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ 46*91f16700Schasinglulu GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \ 47*91f16700Schasinglulu REG##R_SHIFT) << 2)) 48*91f16700Schasinglulu 49*91f16700Schasinglulu #define GICD_OFFSET_64(REG, id) \ 50*91f16700Schasinglulu (((id) <= MAX_SPI_ID) ? \ 51*91f16700Schasinglulu GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3) : \ 52*91f16700Schasinglulu GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \ 53*91f16700Schasinglulu REG##R_SHIFT) << 3)) 54*91f16700Schasinglulu 55*91f16700Schasinglulu #else /* GICv3 */ 56*91f16700Schasinglulu #define GICD_OFFSET_8(REG, id) \ 57*91f16700Schasinglulu (GICD_##REG##R + (uintptr_t)(id)) 58*91f16700Schasinglulu 59*91f16700Schasinglulu #define GICD_OFFSET(REG, id) \ 60*91f16700Schasinglulu (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) 61*91f16700Schasinglulu 62*91f16700Schasinglulu #define GICD_OFFSET_64(REG, id) \ 63*91f16700Schasinglulu (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3)) 64*91f16700Schasinglulu #endif /* GIC_EXT_INTID */ 65*91f16700Schasinglulu 66*91f16700Schasinglulu /* 67*91f16700Schasinglulu * Read/Write 8, 32 and 64-bit GIC Distributor register 68*91f16700Schasinglulu * corresponding to its interrupt ID 69*91f16700Schasinglulu */ 70*91f16700Schasinglulu #define GICD_READ(REG, base, id) \ 71*91f16700Schasinglulu mmio_read_32((base) + GICD_OFFSET(REG, (id))) 72*91f16700Schasinglulu 73*91f16700Schasinglulu #define GICD_READ_64(REG, base, id) \ 74*91f16700Schasinglulu mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) 75*91f16700Schasinglulu 76*91f16700Schasinglulu #define GICD_WRITE_8(REG, base, id, val) \ 77*91f16700Schasinglulu mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) 78*91f16700Schasinglulu 79*91f16700Schasinglulu #define GICD_WRITE(REG, base, id, val) \ 80*91f16700Schasinglulu mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) 81*91f16700Schasinglulu 82*91f16700Schasinglulu #define GICD_WRITE_64(REG, base, id, val) \ 83*91f16700Schasinglulu mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) 84*91f16700Schasinglulu 85*91f16700Schasinglulu /* 86*91f16700Schasinglulu * Bit operations on GIC Distributor register corresponding 87*91f16700Schasinglulu * to its interrupt ID 88*91f16700Schasinglulu */ 89*91f16700Schasinglulu /* Get bit in GIC Distributor register */ 90*91f16700Schasinglulu #define GICD_GET_BIT(REG, base, id) \ 91*91f16700Schasinglulu ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \ 92*91f16700Schasinglulu BIT_NUM(REG, (id))) & 1U) 93*91f16700Schasinglulu 94*91f16700Schasinglulu /* Set bit in GIC Distributor register */ 95*91f16700Schasinglulu #define GICD_SET_BIT(REG, base, id) \ 96*91f16700Schasinglulu mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \ 97*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 98*91f16700Schasinglulu 99*91f16700Schasinglulu /* Clear bit in GIC Distributor register */ 100*91f16700Schasinglulu #define GICD_CLR_BIT(REG, base, id) \ 101*91f16700Schasinglulu mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \ 102*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 103*91f16700Schasinglulu 104*91f16700Schasinglulu /* Write bit in GIC Distributor register */ 105*91f16700Schasinglulu #define GICD_WRITE_BIT(REG, base, id) \ 106*91f16700Schasinglulu mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ 107*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 108*91f16700Schasinglulu 109*91f16700Schasinglulu /* 110*91f16700Schasinglulu * Calculate 8 and 32-bit GICR register offset 111*91f16700Schasinglulu * corresponding to its interrupt ID 112*91f16700Schasinglulu */ 113*91f16700Schasinglulu #if GIC_EXT_INTID 114*91f16700Schasinglulu /* GICv3.1 */ 115*91f16700Schasinglulu #define GICR_OFFSET_8(REG, id) \ 116*91f16700Schasinglulu (((id) <= MAX_PPI_ID) ? \ 117*91f16700Schasinglulu GICR_##REG##R + (uintptr_t)(id) : \ 118*91f16700Schasinglulu GICR_##REG##R + (uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID)) 119*91f16700Schasinglulu 120*91f16700Schasinglulu #define GICR_OFFSET(REG, id) \ 121*91f16700Schasinglulu (((id) <= MAX_PPI_ID) ? \ 122*91f16700Schasinglulu GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \ 123*91f16700Schasinglulu GICR_##REG##R + ((((uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))\ 124*91f16700Schasinglulu >> REG##R_SHIFT) << 2)) 125*91f16700Schasinglulu #else /* GICv3 */ 126*91f16700Schasinglulu #define GICR_OFFSET_8(REG, id) \ 127*91f16700Schasinglulu (GICR_##REG##R + (uintptr_t)(id)) 128*91f16700Schasinglulu 129*91f16700Schasinglulu #define GICR_OFFSET(REG, id) \ 130*91f16700Schasinglulu (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2)) 131*91f16700Schasinglulu #endif /* GIC_EXT_INTID */ 132*91f16700Schasinglulu 133*91f16700Schasinglulu /* Read/Write GIC Redistributor register corresponding to its interrupt ID */ 134*91f16700Schasinglulu #define GICR_READ(REG, base, id) \ 135*91f16700Schasinglulu mmio_read_32((base) + GICR_OFFSET(REG, (id))) 136*91f16700Schasinglulu 137*91f16700Schasinglulu #define GICR_WRITE_8(REG, base, id, val) \ 138*91f16700Schasinglulu mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val)) 139*91f16700Schasinglulu 140*91f16700Schasinglulu #define GICR_WRITE(REG, base, id, val) \ 141*91f16700Schasinglulu mmio_write_32((base) + GICR_OFFSET(REG, (id)), (val)) 142*91f16700Schasinglulu 143*91f16700Schasinglulu /* 144*91f16700Schasinglulu * Bit operations on GIC Redistributor register 145*91f16700Schasinglulu * corresponding to its interrupt ID 146*91f16700Schasinglulu */ 147*91f16700Schasinglulu /* Get bit in GIC Redistributor register */ 148*91f16700Schasinglulu #define GICR_GET_BIT(REG, base, id) \ 149*91f16700Schasinglulu ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \ 150*91f16700Schasinglulu BIT_NUM(REG, (id))) & 1U) 151*91f16700Schasinglulu 152*91f16700Schasinglulu /* Write bit in GIC Redistributor register */ 153*91f16700Schasinglulu #define GICR_WRITE_BIT(REG, base, id) \ 154*91f16700Schasinglulu mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ 155*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 156*91f16700Schasinglulu 157*91f16700Schasinglulu /* Set bit in GIC Redistributor register */ 158*91f16700Schasinglulu #define GICR_SET_BIT(REG, base, id) \ 159*91f16700Schasinglulu mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \ 160*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 161*91f16700Schasinglulu 162*91f16700Schasinglulu /* Clear bit in GIC Redistributor register */ 163*91f16700Schasinglulu #define GICR_CLR_BIT(REG, base, id) \ 164*91f16700Schasinglulu mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \ 165*91f16700Schasinglulu ((uint32_t)1 << BIT_NUM(REG, (id)))) 166*91f16700Schasinglulu 167*91f16700Schasinglulu /* 168*91f16700Schasinglulu * Macro to convert an mpidr to a value suitable for programming into a 169*91f16700Schasinglulu * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant 170*91f16700Schasinglulu * to GICv3. 171*91f16700Schasinglulu */ 172*91f16700Schasinglulu static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr, 173*91f16700Schasinglulu unsigned int irm) 174*91f16700Schasinglulu { 175*91f16700Schasinglulu return (mpidr & MPIDR_AFFINITY_MASK) | 176*91f16700Schasinglulu ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT); 177*91f16700Schasinglulu } 178*91f16700Schasinglulu 179*91f16700Schasinglulu /* 180*91f16700Schasinglulu * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24] 181*91f16700Schasinglulu * are zeroes. 182*91f16700Schasinglulu */ 183*91f16700Schasinglulu #ifdef __aarch64__ 184*91f16700Schasinglulu static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) 185*91f16700Schasinglulu { 186*91f16700Schasinglulu return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | 187*91f16700Schasinglulu ((typer_val >> 32) & U(0xffffff)); 188*91f16700Schasinglulu } 189*91f16700Schasinglulu #else 190*91f16700Schasinglulu static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val) 191*91f16700Schasinglulu { 192*91f16700Schasinglulu return (((typer_val) >> 32) & U(0xffffff)); 193*91f16700Schasinglulu } 194*91f16700Schasinglulu #endif 195*91f16700Schasinglulu 196*91f16700Schasinglulu /******************************************************************************* 197*91f16700Schasinglulu * GICv3 private global variables declarations 198*91f16700Schasinglulu ******************************************************************************/ 199*91f16700Schasinglulu extern const gicv3_driver_data_t *gicv3_driver_data; 200*91f16700Schasinglulu 201*91f16700Schasinglulu /******************************************************************************* 202*91f16700Schasinglulu * Private GICv3 function prototypes for accessing entire registers. 203*91f16700Schasinglulu * Note: The raw register values correspond to multiple interrupt IDs and 204*91f16700Schasinglulu * the number of interrupt IDs involved depends on the register accessed. 205*91f16700Schasinglulu ******************************************************************************/ 206*91f16700Schasinglulu unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); 207*91f16700Schasinglulu unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); 208*91f16700Schasinglulu void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); 209*91f16700Schasinglulu void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); 210*91f16700Schasinglulu 211*91f16700Schasinglulu /******************************************************************************* 212*91f16700Schasinglulu * Private GICv3 function prototypes for accessing the GIC registers 213*91f16700Schasinglulu * corresponding to a single interrupt ID. These functions use bitwise 214*91f16700Schasinglulu * operations or appropriate register accesses to modify or return 215*91f16700Schasinglulu * the bit-field corresponding the single interrupt ID. 216*91f16700Schasinglulu ******************************************************************************/ 217*91f16700Schasinglulu unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); 218*91f16700Schasinglulu unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id); 219*91f16700Schasinglulu unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id); 220*91f16700Schasinglulu unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id); 221*91f16700Schasinglulu void gicd_set_igrpmodr(uintptr_t base, unsigned int id); 222*91f16700Schasinglulu void gicr_set_igrpmodr(uintptr_t base, unsigned int id); 223*91f16700Schasinglulu void gicr_set_isenabler(uintptr_t base, unsigned int id); 224*91f16700Schasinglulu void gicr_set_icenabler(uintptr_t base, unsigned int id); 225*91f16700Schasinglulu void gicr_set_ispendr(uintptr_t base, unsigned int id); 226*91f16700Schasinglulu void gicr_set_icpendr(uintptr_t base, unsigned int id); 227*91f16700Schasinglulu void gicr_set_igroupr(uintptr_t base, unsigned int id); 228*91f16700Schasinglulu void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); 229*91f16700Schasinglulu void gicr_clr_igrpmodr(uintptr_t base, unsigned int id); 230*91f16700Schasinglulu void gicr_clr_igroupr(uintptr_t base, unsigned int id); 231*91f16700Schasinglulu void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); 232*91f16700Schasinglulu void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg); 233*91f16700Schasinglulu 234*91f16700Schasinglulu /******************************************************************************* 235*91f16700Schasinglulu * Private GICv3 helper function prototypes 236*91f16700Schasinglulu ******************************************************************************/ 237*91f16700Schasinglulu uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base); 238*91f16700Schasinglulu unsigned int gicv3_get_spi_limit(uintptr_t gicd_base); 239*91f16700Schasinglulu unsigned int gicv3_get_espi_limit(uintptr_t gicd_base); 240*91f16700Schasinglulu void gicv3_spis_config_defaults(uintptr_t gicd_base); 241*91f16700Schasinglulu void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base); 242*91f16700Schasinglulu unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base, 243*91f16700Schasinglulu const interrupt_prop_t *interrupt_props, 244*91f16700Schasinglulu unsigned int interrupt_props_num); 245*91f16700Schasinglulu unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base, 246*91f16700Schasinglulu const interrupt_prop_t *interrupt_props, 247*91f16700Schasinglulu unsigned int interrupt_props_num); 248*91f16700Schasinglulu void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs, 249*91f16700Schasinglulu unsigned int rdistif_num, 250*91f16700Schasinglulu uintptr_t gicr_base, 251*91f16700Schasinglulu mpidr_hash_fn mpidr_to_core_pos); 252*91f16700Schasinglulu void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base); 253*91f16700Schasinglulu void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); 254*91f16700Schasinglulu 255*91f16700Schasinglulu /******************************************************************************* 256*91f16700Schasinglulu * GIC Distributor interface accessors 257*91f16700Schasinglulu ******************************************************************************/ 258*91f16700Schasinglulu /* 259*91f16700Schasinglulu * Wait for updates to: 260*91f16700Schasinglulu * GICD_CTLR[2:0] - the Group Enables 261*91f16700Schasinglulu * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit 262*91f16700Schasinglulu * GICD_ICENABLER<n> - the clearing of enable state for SPIs 263*91f16700Schasinglulu */ 264*91f16700Schasinglulu static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) 265*91f16700Schasinglulu { 266*91f16700Schasinglulu while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) { 267*91f16700Schasinglulu } 268*91f16700Schasinglulu } 269*91f16700Schasinglulu 270*91f16700Schasinglulu static inline uint32_t gicd_read_pidr2(uintptr_t base) 271*91f16700Schasinglulu { 272*91f16700Schasinglulu return mmio_read_32(base + GICD_PIDR2_GICV3); 273*91f16700Schasinglulu } 274*91f16700Schasinglulu 275*91f16700Schasinglulu static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) 276*91f16700Schasinglulu { 277*91f16700Schasinglulu assert(id >= MIN_SPI_ID); 278*91f16700Schasinglulu return GICD_READ_64(IROUTE, base, id); 279*91f16700Schasinglulu } 280*91f16700Schasinglulu 281*91f16700Schasinglulu static inline void gicd_write_irouter(uintptr_t base, 282*91f16700Schasinglulu unsigned int id, 283*91f16700Schasinglulu uint64_t affinity) 284*91f16700Schasinglulu { 285*91f16700Schasinglulu assert(id >= MIN_SPI_ID); 286*91f16700Schasinglulu GICD_WRITE_64(IROUTE, base, id, affinity); 287*91f16700Schasinglulu } 288*91f16700Schasinglulu 289*91f16700Schasinglulu static inline void gicd_clr_ctlr(uintptr_t base, 290*91f16700Schasinglulu unsigned int bitmap, 291*91f16700Schasinglulu unsigned int rwp) 292*91f16700Schasinglulu { 293*91f16700Schasinglulu gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); 294*91f16700Schasinglulu if (rwp != 0U) { 295*91f16700Schasinglulu gicd_wait_for_pending_write(base); 296*91f16700Schasinglulu } 297*91f16700Schasinglulu } 298*91f16700Schasinglulu 299*91f16700Schasinglulu static inline void gicd_set_ctlr(uintptr_t base, 300*91f16700Schasinglulu unsigned int bitmap, 301*91f16700Schasinglulu unsigned int rwp) 302*91f16700Schasinglulu { 303*91f16700Schasinglulu gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); 304*91f16700Schasinglulu if (rwp != 0U) { 305*91f16700Schasinglulu gicd_wait_for_pending_write(base); 306*91f16700Schasinglulu } 307*91f16700Schasinglulu } 308*91f16700Schasinglulu 309*91f16700Schasinglulu /******************************************************************************* 310*91f16700Schasinglulu * GIC Redistributor interface accessors 311*91f16700Schasinglulu ******************************************************************************/ 312*91f16700Schasinglulu static inline uint32_t gicr_read_ctlr(uintptr_t base) 313*91f16700Schasinglulu { 314*91f16700Schasinglulu return mmio_read_32(base + GICR_CTLR); 315*91f16700Schasinglulu } 316*91f16700Schasinglulu 317*91f16700Schasinglulu static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) 318*91f16700Schasinglulu { 319*91f16700Schasinglulu mmio_write_32(base + GICR_CTLR, val); 320*91f16700Schasinglulu } 321*91f16700Schasinglulu 322*91f16700Schasinglulu static inline uint64_t gicr_read_typer(uintptr_t base) 323*91f16700Schasinglulu { 324*91f16700Schasinglulu return mmio_read_64(base + GICR_TYPER); 325*91f16700Schasinglulu } 326*91f16700Schasinglulu 327*91f16700Schasinglulu static inline uint32_t gicr_read_waker(uintptr_t base) 328*91f16700Schasinglulu { 329*91f16700Schasinglulu return mmio_read_32(base + GICR_WAKER); 330*91f16700Schasinglulu } 331*91f16700Schasinglulu 332*91f16700Schasinglulu static inline void gicr_write_waker(uintptr_t base, uint32_t val) 333*91f16700Schasinglulu { 334*91f16700Schasinglulu mmio_write_32(base + GICR_WAKER, val); 335*91f16700Schasinglulu } 336*91f16700Schasinglulu 337*91f16700Schasinglulu /* 338*91f16700Schasinglulu * Wait for updates to: 339*91f16700Schasinglulu * GICR_ICENABLER0 340*91f16700Schasinglulu * GICR_CTLR.DPG1S 341*91f16700Schasinglulu * GICR_CTLR.DPG1NS 342*91f16700Schasinglulu * GICR_CTLR.DPG0 343*91f16700Schasinglulu * GICR_CTLR, which clears EnableLPIs from 1 to 0 344*91f16700Schasinglulu */ 345*91f16700Schasinglulu static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) 346*91f16700Schasinglulu { 347*91f16700Schasinglulu while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) { 348*91f16700Schasinglulu } 349*91f16700Schasinglulu } 350*91f16700Schasinglulu 351*91f16700Schasinglulu static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) 352*91f16700Schasinglulu { 353*91f16700Schasinglulu while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) { 354*91f16700Schasinglulu } 355*91f16700Schasinglulu } 356*91f16700Schasinglulu 357*91f16700Schasinglulu /* Private implementation of Distributor power control hooks */ 358*91f16700Schasinglulu void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); 359*91f16700Schasinglulu void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); 360*91f16700Schasinglulu 361*91f16700Schasinglulu /******************************************************************************* 362*91f16700Schasinglulu * GIC Redistributor functions for accessing entire registers. 363*91f16700Schasinglulu * Note: The raw register values correspond to multiple interrupt IDs and 364*91f16700Schasinglulu * the number of interrupt IDs involved depends on the register accessed. 365*91f16700Schasinglulu ******************************************************************************/ 366*91f16700Schasinglulu 367*91f16700Schasinglulu /* 368*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ICENABLER0 register 369*91f16700Schasinglulu */ 370*91f16700Schasinglulu static inline unsigned int gicr_read_icenabler0(uintptr_t base) 371*91f16700Schasinglulu { 372*91f16700Schasinglulu return mmio_read_32(base + GICR_ICENABLER0); 373*91f16700Schasinglulu } 374*91f16700Schasinglulu 375*91f16700Schasinglulu static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val) 376*91f16700Schasinglulu { 377*91f16700Schasinglulu mmio_write_32(base + GICR_ICENABLER0, val); 378*91f16700Schasinglulu } 379*91f16700Schasinglulu 380*91f16700Schasinglulu /* 381*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE 382*91f16700Schasinglulu * register corresponding to its number 383*91f16700Schasinglulu */ 384*91f16700Schasinglulu static inline unsigned int gicr_read_icenabler(uintptr_t base, 385*91f16700Schasinglulu unsigned int reg_num) 386*91f16700Schasinglulu { 387*91f16700Schasinglulu return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2)); 388*91f16700Schasinglulu } 389*91f16700Schasinglulu 390*91f16700Schasinglulu static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num, 391*91f16700Schasinglulu unsigned int val) 392*91f16700Schasinglulu { 393*91f16700Schasinglulu mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val); 394*91f16700Schasinglulu } 395*91f16700Schasinglulu 396*91f16700Schasinglulu /* 397*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 registers 398*91f16700Schasinglulu */ 399*91f16700Schasinglulu static inline unsigned int gicr_read_icfgr0(uintptr_t base) 400*91f16700Schasinglulu { 401*91f16700Schasinglulu return mmio_read_32(base + GICR_ICFGR0); 402*91f16700Schasinglulu } 403*91f16700Schasinglulu 404*91f16700Schasinglulu static inline unsigned int gicr_read_icfgr1(uintptr_t base) 405*91f16700Schasinglulu { 406*91f16700Schasinglulu return mmio_read_32(base + GICR_ICFGR1); 407*91f16700Schasinglulu } 408*91f16700Schasinglulu 409*91f16700Schasinglulu static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val) 410*91f16700Schasinglulu { 411*91f16700Schasinglulu mmio_write_32(base + GICR_ICFGR0, val); 412*91f16700Schasinglulu } 413*91f16700Schasinglulu 414*91f16700Schasinglulu static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val) 415*91f16700Schasinglulu { 416*91f16700Schasinglulu mmio_write_32(base + GICR_ICFGR1, val); 417*91f16700Schasinglulu } 418*91f16700Schasinglulu 419*91f16700Schasinglulu /* 420*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE 421*91f16700Schasinglulu * register corresponding to its number 422*91f16700Schasinglulu */ 423*91f16700Schasinglulu static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num) 424*91f16700Schasinglulu { 425*91f16700Schasinglulu return mmio_read_32(base + GICR_ICFGR + (reg_num << 2)); 426*91f16700Schasinglulu } 427*91f16700Schasinglulu 428*91f16700Schasinglulu static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num, 429*91f16700Schasinglulu unsigned int val) 430*91f16700Schasinglulu { 431*91f16700Schasinglulu mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val); 432*91f16700Schasinglulu } 433*91f16700Schasinglulu 434*91f16700Schasinglulu /* 435*91f16700Schasinglulu * Accessor to write GIC Redistributor ICPENDR0 register 436*91f16700Schasinglulu */ 437*91f16700Schasinglulu static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val) 438*91f16700Schasinglulu { 439*91f16700Schasinglulu mmio_write_32(base + GICR_ICPENDR0, val); 440*91f16700Schasinglulu } 441*91f16700Schasinglulu 442*91f16700Schasinglulu /* 443*91f16700Schasinglulu * Accessor to write GIC Redistributor ICPENDR0 and ICPENDRE 444*91f16700Schasinglulu * register corresponding to its number 445*91f16700Schasinglulu */ 446*91f16700Schasinglulu static inline void gicr_write_icpendr(uintptr_t base, unsigned int reg_num, 447*91f16700Schasinglulu unsigned int val) 448*91f16700Schasinglulu { 449*91f16700Schasinglulu mmio_write_32(base + GICR_ICPENDR + (reg_num << 2), val); 450*91f16700Schasinglulu } 451*91f16700Schasinglulu 452*91f16700Schasinglulu /* 453*91f16700Schasinglulu * Accessors to read/write GIC Redistributor IGROUPR0 register 454*91f16700Schasinglulu */ 455*91f16700Schasinglulu static inline unsigned int gicr_read_igroupr0(uintptr_t base) 456*91f16700Schasinglulu { 457*91f16700Schasinglulu return mmio_read_32(base + GICR_IGROUPR0); 458*91f16700Schasinglulu } 459*91f16700Schasinglulu 460*91f16700Schasinglulu static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val) 461*91f16700Schasinglulu { 462*91f16700Schasinglulu mmio_write_32(base + GICR_IGROUPR0, val); 463*91f16700Schasinglulu } 464*91f16700Schasinglulu 465*91f16700Schasinglulu /* 466*91f16700Schasinglulu * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE 467*91f16700Schasinglulu * register corresponding to its number 468*91f16700Schasinglulu */ 469*91f16700Schasinglulu static inline unsigned int gicr_read_igroupr(uintptr_t base, 470*91f16700Schasinglulu unsigned int reg_num) 471*91f16700Schasinglulu { 472*91f16700Schasinglulu return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2)); 473*91f16700Schasinglulu } 474*91f16700Schasinglulu 475*91f16700Schasinglulu static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num, 476*91f16700Schasinglulu unsigned int val) 477*91f16700Schasinglulu { 478*91f16700Schasinglulu mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val); 479*91f16700Schasinglulu } 480*91f16700Schasinglulu 481*91f16700Schasinglulu /* 482*91f16700Schasinglulu * Accessors to read/write GIC Redistributor IGRPMODR0 register 483*91f16700Schasinglulu */ 484*91f16700Schasinglulu static inline unsigned int gicr_read_igrpmodr0(uintptr_t base) 485*91f16700Schasinglulu { 486*91f16700Schasinglulu return mmio_read_32(base + GICR_IGRPMODR0); 487*91f16700Schasinglulu } 488*91f16700Schasinglulu 489*91f16700Schasinglulu static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val) 490*91f16700Schasinglulu { 491*91f16700Schasinglulu mmio_write_32(base + GICR_IGRPMODR0, val); 492*91f16700Schasinglulu } 493*91f16700Schasinglulu 494*91f16700Schasinglulu /* 495*91f16700Schasinglulu * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE 496*91f16700Schasinglulu * register corresponding to its number 497*91f16700Schasinglulu */ 498*91f16700Schasinglulu static inline unsigned int gicr_read_igrpmodr(uintptr_t base, 499*91f16700Schasinglulu unsigned int reg_num) 500*91f16700Schasinglulu { 501*91f16700Schasinglulu return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2)); 502*91f16700Schasinglulu } 503*91f16700Schasinglulu 504*91f16700Schasinglulu static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num, 505*91f16700Schasinglulu unsigned int val) 506*91f16700Schasinglulu { 507*91f16700Schasinglulu mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val); 508*91f16700Schasinglulu } 509*91f16700Schasinglulu 510*91f16700Schasinglulu /* 511*91f16700Schasinglulu * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register 512*91f16700Schasinglulu * corresponding to its number, 4 interrupts IDs at a time. 513*91f16700Schasinglulu */ 514*91f16700Schasinglulu static inline unsigned int gicr_ipriorityr_read(uintptr_t base, 515*91f16700Schasinglulu unsigned int reg_num) 516*91f16700Schasinglulu { 517*91f16700Schasinglulu return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2)); 518*91f16700Schasinglulu } 519*91f16700Schasinglulu 520*91f16700Schasinglulu static inline void gicr_ipriorityr_write(uintptr_t base, unsigned int reg_num, 521*91f16700Schasinglulu unsigned int val) 522*91f16700Schasinglulu { 523*91f16700Schasinglulu mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val); 524*91f16700Schasinglulu } 525*91f16700Schasinglulu 526*91f16700Schasinglulu /* 527*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISACTIVER0 register 528*91f16700Schasinglulu */ 529*91f16700Schasinglulu static inline unsigned int gicr_read_isactiver0(uintptr_t base) 530*91f16700Schasinglulu { 531*91f16700Schasinglulu return mmio_read_32(base + GICR_ISACTIVER0); 532*91f16700Schasinglulu } 533*91f16700Schasinglulu 534*91f16700Schasinglulu static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val) 535*91f16700Schasinglulu { 536*91f16700Schasinglulu mmio_write_32(base + GICR_ISACTIVER0, val); 537*91f16700Schasinglulu } 538*91f16700Schasinglulu 539*91f16700Schasinglulu /* 540*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE 541*91f16700Schasinglulu * register corresponding to its number 542*91f16700Schasinglulu */ 543*91f16700Schasinglulu static inline unsigned int gicr_read_isactiver(uintptr_t base, 544*91f16700Schasinglulu unsigned int reg_num) 545*91f16700Schasinglulu { 546*91f16700Schasinglulu return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2)); 547*91f16700Schasinglulu } 548*91f16700Schasinglulu 549*91f16700Schasinglulu static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num, 550*91f16700Schasinglulu unsigned int val) 551*91f16700Schasinglulu { 552*91f16700Schasinglulu mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val); 553*91f16700Schasinglulu } 554*91f16700Schasinglulu 555*91f16700Schasinglulu /* 556*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISENABLER0 register 557*91f16700Schasinglulu */ 558*91f16700Schasinglulu static inline unsigned int gicr_read_isenabler0(uintptr_t base) 559*91f16700Schasinglulu { 560*91f16700Schasinglulu return mmio_read_32(base + GICR_ISENABLER0); 561*91f16700Schasinglulu } 562*91f16700Schasinglulu 563*91f16700Schasinglulu static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val) 564*91f16700Schasinglulu { 565*91f16700Schasinglulu mmio_write_32(base + GICR_ISENABLER0, val); 566*91f16700Schasinglulu } 567*91f16700Schasinglulu 568*91f16700Schasinglulu /* 569*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE 570*91f16700Schasinglulu * register corresponding to its number 571*91f16700Schasinglulu */ 572*91f16700Schasinglulu static inline unsigned int gicr_read_isenabler(uintptr_t base, 573*91f16700Schasinglulu unsigned int reg_num) 574*91f16700Schasinglulu { 575*91f16700Schasinglulu return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2)); 576*91f16700Schasinglulu } 577*91f16700Schasinglulu 578*91f16700Schasinglulu static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num, 579*91f16700Schasinglulu unsigned int val) 580*91f16700Schasinglulu { 581*91f16700Schasinglulu mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val); 582*91f16700Schasinglulu } 583*91f16700Schasinglulu 584*91f16700Schasinglulu /* 585*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISPENDR0 register 586*91f16700Schasinglulu */ 587*91f16700Schasinglulu static inline unsigned int gicr_read_ispendr0(uintptr_t base) 588*91f16700Schasinglulu { 589*91f16700Schasinglulu return mmio_read_32(base + GICR_ISPENDR0); 590*91f16700Schasinglulu } 591*91f16700Schasinglulu 592*91f16700Schasinglulu static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val) 593*91f16700Schasinglulu { 594*91f16700Schasinglulu mmio_write_32(base + GICR_ISPENDR0, val); 595*91f16700Schasinglulu } 596*91f16700Schasinglulu 597*91f16700Schasinglulu /* 598*91f16700Schasinglulu * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE 599*91f16700Schasinglulu * register corresponding to its number 600*91f16700Schasinglulu */ 601*91f16700Schasinglulu static inline unsigned int gicr_read_ispendr(uintptr_t base, 602*91f16700Schasinglulu unsigned int reg_num) 603*91f16700Schasinglulu { 604*91f16700Schasinglulu return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2)); 605*91f16700Schasinglulu } 606*91f16700Schasinglulu 607*91f16700Schasinglulu static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num, 608*91f16700Schasinglulu unsigned int val) 609*91f16700Schasinglulu { 610*91f16700Schasinglulu mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val); 611*91f16700Schasinglulu } 612*91f16700Schasinglulu 613*91f16700Schasinglulu /* 614*91f16700Schasinglulu * Accessors to read/write GIC Redistributor NSACR register 615*91f16700Schasinglulu */ 616*91f16700Schasinglulu static inline unsigned int gicr_read_nsacr(uintptr_t base) 617*91f16700Schasinglulu { 618*91f16700Schasinglulu return mmio_read_32(base + GICR_NSACR); 619*91f16700Schasinglulu } 620*91f16700Schasinglulu 621*91f16700Schasinglulu static inline void gicr_write_nsacr(uintptr_t base, unsigned int val) 622*91f16700Schasinglulu { 623*91f16700Schasinglulu mmio_write_32(base + GICR_NSACR, val); 624*91f16700Schasinglulu } 625*91f16700Schasinglulu 626*91f16700Schasinglulu /* 627*91f16700Schasinglulu * Accessors to read/write GIC Redistributor PROPBASER register 628*91f16700Schasinglulu */ 629*91f16700Schasinglulu static inline uint64_t gicr_read_propbaser(uintptr_t base) 630*91f16700Schasinglulu { 631*91f16700Schasinglulu return mmio_read_64(base + GICR_PROPBASER); 632*91f16700Schasinglulu } 633*91f16700Schasinglulu 634*91f16700Schasinglulu static inline void gicr_write_propbaser(uintptr_t base, uint64_t val) 635*91f16700Schasinglulu { 636*91f16700Schasinglulu mmio_write_64(base + GICR_PROPBASER, val); 637*91f16700Schasinglulu } 638*91f16700Schasinglulu 639*91f16700Schasinglulu /* 640*91f16700Schasinglulu * Accessors to read/write GIC Redistributor PENDBASER register 641*91f16700Schasinglulu */ 642*91f16700Schasinglulu static inline uint64_t gicr_read_pendbaser(uintptr_t base) 643*91f16700Schasinglulu { 644*91f16700Schasinglulu return mmio_read_64(base + GICR_PENDBASER); 645*91f16700Schasinglulu } 646*91f16700Schasinglulu 647*91f16700Schasinglulu static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val) 648*91f16700Schasinglulu { 649*91f16700Schasinglulu mmio_write_64(base + GICR_PENDBASER, val); 650*91f16700Schasinglulu } 651*91f16700Schasinglulu 652*91f16700Schasinglulu /******************************************************************************* 653*91f16700Schasinglulu * GIC ITS functions to read and write entire ITS registers. 654*91f16700Schasinglulu ******************************************************************************/ 655*91f16700Schasinglulu static inline uint32_t gits_read_ctlr(uintptr_t base) 656*91f16700Schasinglulu { 657*91f16700Schasinglulu return mmio_read_32(base + GITS_CTLR); 658*91f16700Schasinglulu } 659*91f16700Schasinglulu 660*91f16700Schasinglulu static inline void gits_write_ctlr(uintptr_t base, uint32_t val) 661*91f16700Schasinglulu { 662*91f16700Schasinglulu mmio_write_32(base + GITS_CTLR, val); 663*91f16700Schasinglulu } 664*91f16700Schasinglulu 665*91f16700Schasinglulu static inline uint64_t gits_read_cbaser(uintptr_t base) 666*91f16700Schasinglulu { 667*91f16700Schasinglulu return mmio_read_64(base + GITS_CBASER); 668*91f16700Schasinglulu } 669*91f16700Schasinglulu 670*91f16700Schasinglulu static inline void gits_write_cbaser(uintptr_t base, uint64_t val) 671*91f16700Schasinglulu { 672*91f16700Schasinglulu mmio_write_64(base + GITS_CBASER, val); 673*91f16700Schasinglulu } 674*91f16700Schasinglulu 675*91f16700Schasinglulu static inline uint64_t gits_read_cwriter(uintptr_t base) 676*91f16700Schasinglulu { 677*91f16700Schasinglulu return mmio_read_64(base + GITS_CWRITER); 678*91f16700Schasinglulu } 679*91f16700Schasinglulu 680*91f16700Schasinglulu static inline void gits_write_cwriter(uintptr_t base, uint64_t val) 681*91f16700Schasinglulu { 682*91f16700Schasinglulu mmio_write_64(base + GITS_CWRITER, val); 683*91f16700Schasinglulu } 684*91f16700Schasinglulu 685*91f16700Schasinglulu static inline uint64_t gits_read_baser(uintptr_t base, 686*91f16700Schasinglulu unsigned int its_table_id) 687*91f16700Schasinglulu { 688*91f16700Schasinglulu assert(its_table_id < 8U); 689*91f16700Schasinglulu return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); 690*91f16700Schasinglulu } 691*91f16700Schasinglulu 692*91f16700Schasinglulu static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, 693*91f16700Schasinglulu uint64_t val) 694*91f16700Schasinglulu { 695*91f16700Schasinglulu assert(its_table_id < 8U); 696*91f16700Schasinglulu mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); 697*91f16700Schasinglulu } 698*91f16700Schasinglulu 699*91f16700Schasinglulu /* 700*91f16700Schasinglulu * Wait for Quiescent bit when GIC ITS is disabled 701*91f16700Schasinglulu */ 702*91f16700Schasinglulu static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) 703*91f16700Schasinglulu { 704*91f16700Schasinglulu assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); 705*91f16700Schasinglulu while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) { 706*91f16700Schasinglulu } 707*91f16700Schasinglulu } 708*91f16700Schasinglulu 709*91f16700Schasinglulu #endif /* GICV3_PRIVATE_H */ 710