xref: /arm-trusted-firmware/drivers/arm/gic/v3/gicv3_private.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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