blob: 8ad251bf8f8bb6caf5c6f086a4c38cc63c73e696 [file] [log] [blame]
Achin Gupta92712a52015-09-03 14:18:02 +01001/*
Heyi Guo691b49d2020-05-19 16:45:17 +08002 * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
Varun Wadekar61286d22023-03-08 16:47:38 +00003 * Copyright (c) 2023, NVIDIA Corporation. All rights reserved.
Achin Gupta92712a52015-09-03 14:18:02 +01004 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta92712a52015-09-03 14:18:02 +01006 */
7
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00008#ifndef GICV3_PRIVATE_H
9#define GICV3_PRIVATE_H
Achin Gupta92712a52015-09-03 14:18:02 +010010
Soby Mathew327548c2017-07-13 15:19:51 +010011#include <assert.h>
Achin Gupta92712a52015-09-03 14:18:02 +010012#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013
14#include <drivers/arm/gic_common.h>
15#include <drivers/arm/gicv3.h>
16#include <lib/mmio.h>
17
Jeenu Viswambharand7a901e2016-12-06 16:15:22 +000018#include "../common/gic_common_private.h"
Achin Gupta92712a52015-09-03 14:18:02 +010019
20/*******************************************************************************
21 * GICv3 private macro definitions
22 ******************************************************************************/
23
24/* Constants to indicate the status of the RWP bit */
Antonio Nino Diaz2e590712018-08-24 11:46:33 +010025#define RWP_TRUE U(1)
26#define RWP_FALSE U(0)
Achin Gupta92712a52015-09-03 14:18:02 +010027
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000028/* Calculate GIC register bit number corresponding to its interrupt ID */
29#define BIT_NUM(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010030 ((id) & ((1U << REG##R_SHIFT) - 1U))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000031
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010032/*
33 * Calculate 8, 32 and 64-bit GICD register offset
34 * corresponding to its interrupt ID
35 */
36#if GIC_EXT_INTID
37 /* GICv3.1 */
38#define GICD_OFFSET_8(REG, id) \
39 (((id) <= MAX_SPI_ID) ? \
40 GICD_##REG##R + (uintptr_t)(id) : \
41 GICD_##REG##RE + (uintptr_t)(id) - MIN_ESPI_ID)
42
43#define GICD_OFFSET(REG, id) \
44 (((id) <= MAX_SPI_ID) ? \
45 GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \
46 GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \
47 REG##R_SHIFT) << 2))
48
49#define GICD_OFFSET_64(REG, id) \
50 (((id) <= MAX_SPI_ID) ? \
51 GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3) : \
Heyi Guo691b49d2020-05-19 16:45:17 +080052 GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \
53 REG##R_SHIFT) << 3))
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010054
55#else /* GICv3 */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000056#define GICD_OFFSET_8(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010057 (GICD_##REG##R + (uintptr_t)(id))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000058
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000059#define GICD_OFFSET(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010060 (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000061
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000062#define GICD_OFFSET_64(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010063 (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3))
64#endif /* GIC_EXT_INTID */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000065
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010066/*
67 * Read/Write 8, 32 and 64-bit GIC Distributor register
68 * corresponding to its interrupt ID
69 */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000070#define GICD_READ(REG, base, id) \
71 mmio_read_32((base) + GICD_OFFSET(REG, (id)))
72
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000073#define GICD_READ_64(REG, base, id) \
74 mmio_read_64((base) + GICD_OFFSET_64(REG, (id)))
75
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010076#define GICD_WRITE_8(REG, base, id, val) \
77 mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000078
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010079#define GICD_WRITE(REG, base, id, val) \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000080 mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val))
81
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010082#define GICD_WRITE_64(REG, base, id, val) \
83 mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000084
85/*
86 * Bit operations on GIC Distributor register corresponding
87 * to its interrupt ID
88 */
89/* Get bit in GIC Distributor register */
90#define GICD_GET_BIT(REG, base, id) \
91 ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \
92 BIT_NUM(REG, (id))) & 1U)
93
94/* Set bit in GIC Distributor register */
95#define GICD_SET_BIT(REG, base, id) \
96 mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \
97 ((uint32_t)1 << BIT_NUM(REG, (id))))
98
99/* Clear bit in GIC Distributor register */
100#define GICD_CLR_BIT(REG, base, id) \
101 mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \
102 ((uint32_t)1 << BIT_NUM(REG, (id))))
103
104/* Write bit in GIC Distributor register */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100105#define GICD_WRITE_BIT(REG, base, id) \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000106 mmio_write_32((base) + GICD_OFFSET(REG, (id)), \
107 ((uint32_t)1 << BIT_NUM(REG, (id))))
108
109/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100110 * Calculate 8 and 32-bit GICR register offset
111 * corresponding to its interrupt ID
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000112 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100113#if GIC_EXT_INTID
114 /* GICv3.1 */
115#define GICR_OFFSET_8(REG, id) \
116 (((id) <= MAX_PPI_ID) ? \
117 GICR_##REG##R + (uintptr_t)(id) : \
118 GICR_##REG##R + (uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))
119
120#define GICR_OFFSET(REG, id) \
121 (((id) <= MAX_PPI_ID) ? \
122 GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \
123 GICR_##REG##R + ((((uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))\
124 >> REG##R_SHIFT) << 2))
125#else /* GICv3 */
126#define GICR_OFFSET_8(REG, id) \
127 (GICR_##REG##R + (uintptr_t)(id))
128
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000129#define GICR_OFFSET(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100130 (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2))
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100131#endif /* GIC_EXT_INTID */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000132
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100133/* Read/Write GIC Redistributor register corresponding to its interrupt ID */
134#define GICR_READ(REG, base, id) \
135 mmio_read_32((base) + GICR_OFFSET(REG, (id)))
136
137#define GICR_WRITE_8(REG, base, id, val) \
138 mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val))
139
140#define GICR_WRITE(REG, base, id, val) \
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100141 mmio_write_32((base) + GICR_OFFSET(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000142
143/*
144 * Bit operations on GIC Redistributor register
145 * corresponding to its interrupt ID
146 */
147/* Get bit in GIC Redistributor register */
148#define GICR_GET_BIT(REG, base, id) \
149 ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \
150 BIT_NUM(REG, (id))) & 1U)
151
152/* Write bit in GIC Redistributor register */
153#define GICR_WRITE_BIT(REG, base, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100154 mmio_write_32((base) + GICR_OFFSET(REG, (id)), \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000155 ((uint32_t)1 << BIT_NUM(REG, (id))))
156
157/* Set bit in GIC Redistributor register */
158#define GICR_SET_BIT(REG, base, id) \
159 mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \
160 ((uint32_t)1 << BIT_NUM(REG, (id))))
161
162/* Clear bit in GIC Redistributor register */
163#define GICR_CLR_BIT(REG, base, id) \
164 mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \
165 ((uint32_t)1 << BIT_NUM(REG, (id))))
166
Achin Gupta92712a52015-09-03 14:18:02 +0100167/*
Achin Gupta92712a52015-09-03 14:18:02 +0100168 * Macro to convert an mpidr to a value suitable for programming into a
169 * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
170 * to GICv3.
171 */
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100172static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr,
173 unsigned int irm)
174{
Ming Huangddb0b942021-10-27 11:41:04 +0800175 return (mpidr & MPIDR_AFFINITY_MASK) |
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100176 ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT);
177}
Achin Gupta92712a52015-09-03 14:18:02 +0100178
179/*
Achin Gupta92712a52015-09-03 14:18:02 +0100180 * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
181 * are zeroes.
182 */
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700183#ifdef __aarch64__
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100184static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
185{
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700186 return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) |
187 ((typer_val >> 32) & U(0xffffff));
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100188}
Soby Mathewd6452322016-05-05 13:59:07 +0100189#else
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100190static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
191{
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700192 return (((typer_val) >> 32) & U(0xffffff));
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100193}
Soby Mathewd6452322016-05-05 13:59:07 +0100194#endif
Achin Gupta92712a52015-09-03 14:18:02 +0100195
196/*******************************************************************************
Soby Mathew327548c2017-07-13 15:19:51 +0100197 * GICv3 private global variables declarations
198 ******************************************************************************/
199extern const gicv3_driver_data_t *gicv3_driver_data;
200
201/*******************************************************************************
Soby Mathew50f6fe42016-02-01 17:59:22 +0000202 * Private GICv3 function prototypes for accessing entire registers.
203 * Note: The raw register values correspond to multiple interrupt IDs and
204 * the number of interrupt IDs involved depends on the register accessed.
Achin Gupta92712a52015-09-03 14:18:02 +0100205 ******************************************************************************/
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100206unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100207unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100208void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val);
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100209void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000210
211/*******************************************************************************
212 * Private GICv3 function prototypes for accessing the GIC registers
213 * corresponding to a single interrupt ID. These functions use bitwise
214 * operations or appropriate register accesses to modify or return
215 * the bit-field corresponding the single interrupt ID.
216 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100217unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100218unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id);
219unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id);
220unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100221void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100222void gicr_set_igrpmodr(uintptr_t base, unsigned int id);
223void gicr_set_isenabler(uintptr_t base, unsigned int id);
224void gicr_set_icenabler(uintptr_t base, unsigned int id);
225void gicr_set_ispendr(uintptr_t base, unsigned int id);
226void gicr_set_icpendr(uintptr_t base, unsigned int id);
227void gicr_set_igroupr(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100228void gicd_clr_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100229void gicr_clr_igrpmodr(uintptr_t base, unsigned int id);
230void gicr_clr_igroupr(uintptr_t base, unsigned int id);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000231void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100232void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000233
234/*******************************************************************************
235 * Private GICv3 helper function prototypes
236 ******************************************************************************/
Varun Wadekar61286d22023-03-08 16:47:38 +0000237uintptr_t gicv3_get_multichip_base(uint32_t spi_id, uintptr_t gicd_base);
Heyi Guo06f85b42021-01-20 18:50:16 +0800238unsigned int gicv3_get_spi_limit(uintptr_t gicd_base);
Heyi Guo60ce8252021-01-20 18:50:16 +0800239unsigned int gicv3_get_espi_limit(uintptr_t gicd_base);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100240void gicv3_spis_config_defaults(uintptr_t gicd_base);
241void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100242unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100243 const interrupt_prop_t *interrupt_props,
244 unsigned int interrupt_props_num);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100245unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100246 const interrupt_prop_t *interrupt_props,
247 unsigned int interrupt_props_num);
Achin Gupta92712a52015-09-03 14:18:02 +0100248void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
249 unsigned int rdistif_num,
250 uintptr_t gicr_base,
251 mpidr_hash_fn mpidr_to_core_pos);
252void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base);
253void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base);
254
255/*******************************************************************************
256 * GIC Distributor interface accessors
257 ******************************************************************************/
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100258/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100259 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100260 * GICD_CTLR[2:0] - the Group Enables
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100261 * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit
262 * GICD_ICENABLER<n> - the clearing of enable state for SPIs
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100263 */
264static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
265{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000266 while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) {
267 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100268}
269
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000270static inline uint32_t gicd_read_pidr2(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100271{
272 return mmio_read_32(base + GICD_PIDR2_GICV3);
273}
274
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000275static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id)
Achin Gupta92712a52015-09-03 14:18:02 +0100276{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100277 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100278 return GICD_READ_64(IROUTE, base, id);
Achin Gupta92712a52015-09-03 14:18:02 +0100279}
280
281static inline void gicd_write_irouter(uintptr_t base,
282 unsigned int id,
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000283 uint64_t affinity)
Achin Gupta92712a52015-09-03 14:18:02 +0100284{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100285 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100286 GICD_WRITE_64(IROUTE, base, id, affinity);
Achin Gupta92712a52015-09-03 14:18:02 +0100287}
288
289static inline void gicd_clr_ctlr(uintptr_t base,
290 unsigned int bitmap,
291 unsigned int rwp)
292{
293 gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000294 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100295 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000296 }
Achin Gupta92712a52015-09-03 14:18:02 +0100297}
298
299static inline void gicd_set_ctlr(uintptr_t base,
300 unsigned int bitmap,
301 unsigned int rwp)
302{
303 gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000304 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100305 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000306 }
Achin Gupta92712a52015-09-03 14:18:02 +0100307}
308
309/*******************************************************************************
310 * GIC Redistributor interface accessors
311 ******************************************************************************/
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100312static inline uint32_t gicr_read_ctlr(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100313{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100314 return mmio_read_32(base + GICR_CTLR);
Achin Gupta92712a52015-09-03 14:18:02 +0100315}
316
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100317static inline void gicr_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100318{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100319 mmio_write_32(base + GICR_CTLR, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100320}
321
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000322static inline uint64_t gicr_read_typer(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100323{
324 return mmio_read_64(base + GICR_TYPER);
325}
326
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000327static inline uint32_t gicr_read_waker(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100328{
329 return mmio_read_32(base + GICR_WAKER);
330}
331
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000332static inline void gicr_write_waker(uintptr_t base, uint32_t val)
Achin Gupta92712a52015-09-03 14:18:02 +0100333{
334 mmio_write_32(base + GICR_WAKER, val);
335}
336
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100337/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100338 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100339 * GICR_ICENABLER0
340 * GICR_CTLR.DPG1S
341 * GICR_CTLR.DPG1NS
342 * GICR_CTLR.DPG0
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100343 * GICR_CTLR, which clears EnableLPIs from 1 to 0
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100344 */
345static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
346{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000347 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) {
348 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100349}
350
Soby Mathew327548c2017-07-13 15:19:51 +0100351static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
352{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000353 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) {
354 }
Soby Mathew327548c2017-07-13 15:19:51 +0100355}
356
357/* Private implementation of Distributor power control hooks */
358void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num);
359void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
360
Soby Mathew50f6fe42016-02-01 17:59:22 +0000361/*******************************************************************************
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000362 * GIC Redistributor functions for accessing entire registers.
Soby Mathew50f6fe42016-02-01 17:59:22 +0000363 * Note: The raw register values correspond to multiple interrupt IDs and
364 * the number of interrupt IDs involved depends on the register accessed.
365 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100366
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100367/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100368 * Accessors to read/write GIC Redistributor ICENABLER0 register
369 */
370static inline unsigned int gicr_read_icenabler0(uintptr_t base)
371{
372 return mmio_read_32(base + GICR_ICENABLER0);
373}
374
375static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val)
376{
377 mmio_write_32(base + GICR_ICENABLER0, val);
378}
379
380/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100381 * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE
382 * register corresponding to its number
383 */
384static inline unsigned int gicr_read_icenabler(uintptr_t base,
385 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100386{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100387 return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100388}
389
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100390static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num,
391 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100392{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100393 mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100394}
395
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100396/*
397 * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 registers
398 */
399static inline unsigned int gicr_read_icfgr0(uintptr_t base)
400{
401 return mmio_read_32(base + GICR_ICFGR0);
402}
403
404static inline unsigned int gicr_read_icfgr1(uintptr_t base)
405{
406 return mmio_read_32(base + GICR_ICFGR1);
407}
408
409static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val)
410{
411 mmio_write_32(base + GICR_ICFGR0, val);
412}
413
414static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val)
415{
416 mmio_write_32(base + GICR_ICFGR1, val);
417}
418
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100419/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100420 * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100421 * register corresponding to its number
422 */
423static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num)
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100424{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100425 return mmio_read_32(base + GICR_ICFGR + (reg_num << 2));
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100426}
427
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100428static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num,
429 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100430{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100431 mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100432}
433
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100434/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100435 * Accessor to write GIC Redistributor ICPENDR0 register
436 */
437static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val)
438{
439 mmio_write_32(base + GICR_ICPENDR0, val);
440}
441
442/*
443 * Accessor to write GIC Redistributor ICPENDR0 and ICPENDRE
444 * register corresponding to its number
445 */
446static inline void gicr_write_icpendr(uintptr_t base, unsigned int reg_num,
447 unsigned int val)
448{
449 mmio_write_32(base + GICR_ICPENDR + (reg_num << 2), val);
450}
451
452/*
453 * Accessors to read/write GIC Redistributor IGROUPR0 register
454 */
455static inline unsigned int gicr_read_igroupr0(uintptr_t base)
456{
457 return mmio_read_32(base + GICR_IGROUPR0);
458}
459
460static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val)
461{
462 mmio_write_32(base + GICR_IGROUPR0, val);
463}
464
465/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100466 * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE
467 * register corresponding to its number
468 */
469static inline unsigned int gicr_read_igroupr(uintptr_t base,
470 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100471{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100472 return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100473}
474
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100475static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num,
476 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100477{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100478 mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100479}
480
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100481/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100482 * Accessors to read/write GIC Redistributor IGRPMODR0 register
483 */
484static inline unsigned int gicr_read_igrpmodr0(uintptr_t base)
485{
486 return mmio_read_32(base + GICR_IGRPMODR0);
487}
488
489static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val)
490{
491 mmio_write_32(base + GICR_IGRPMODR0, val);
492}
493
494/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100495 * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE
496 * register corresponding to its number
497 */
498static inline unsigned int gicr_read_igrpmodr(uintptr_t base,
499 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100500{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100501 return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100502}
503
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100504static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num,
505 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100506{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100507 mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100508}
509
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100510/*
511 * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register
512 * corresponding to its number, 4 interrupts IDs at a time.
513 */
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100514static inline unsigned int gicr_ipriorityr_read(uintptr_t base,
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100515 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100516{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100517 return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100518}
519
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100520static inline void gicr_ipriorityr_write(uintptr_t base, unsigned int reg_num,
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100521 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100522{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100523 mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100524}
525
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100526/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100527 * Accessors to read/write GIC Redistributor ISACTIVER0 register
528 */
529static inline unsigned int gicr_read_isactiver0(uintptr_t base)
530{
531 return mmio_read_32(base + GICR_ISACTIVER0);
532}
533
534static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val)
535{
536 mmio_write_32(base + GICR_ISACTIVER0, val);
537}
538
539/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100540 * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE
541 * register corresponding to its number
542 */
543static inline unsigned int gicr_read_isactiver(uintptr_t base,
544 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100545{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100546 return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100547}
548
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100549static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num,
550 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100551{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100552 mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100553}
554
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100555/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100556 * Accessors to read/write GIC Redistributor ISENABLER0 register
557 */
558static inline unsigned int gicr_read_isenabler0(uintptr_t base)
559{
560 return mmio_read_32(base + GICR_ISENABLER0);
561}
562
563static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val)
564{
565 mmio_write_32(base + GICR_ISENABLER0, val);
566}
567
568/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100569 * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE
570 * register corresponding to its number
571 */
572static inline unsigned int gicr_read_isenabler(uintptr_t base,
573 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100574{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100575 return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100576}
577
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100578static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num,
579 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100580{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100581 mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100582}
583
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100584/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100585 * Accessors to read/write GIC Redistributor ISPENDR0 register
586 */
587static inline unsigned int gicr_read_ispendr0(uintptr_t base)
588{
589 return mmio_read_32(base + GICR_ISPENDR0);
590}
591
592static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val)
593{
594 mmio_write_32(base + GICR_ISPENDR0, val);
595}
596
597/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100598 * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE
599 * register corresponding to its number
600 */
601static inline unsigned int gicr_read_ispendr(uintptr_t base,
602 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100603{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100604 return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100605}
606
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100607static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num,
608 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100609{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100610 mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100611}
612
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100613/*
614 * Accessors to read/write GIC Redistributor NSACR register
615 */
616static inline unsigned int gicr_read_nsacr(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100617{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100618 return mmio_read_32(base + GICR_NSACR);
Soby Mathew327548c2017-07-13 15:19:51 +0100619}
620
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100621static inline void gicr_write_nsacr(uintptr_t base, unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100622{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100623 mmio_write_32(base + GICR_NSACR, val);
Achin Gupta92712a52015-09-03 14:18:02 +0100624}
625
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100626/*
627 * Accessors to read/write GIC Redistributor PROPBASER register
628 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100629static inline uint64_t gicr_read_propbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100630{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100631 return mmio_read_64(base + GICR_PROPBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100632}
633
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100634static inline void gicr_write_propbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100635{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100636 mmio_write_64(base + GICR_PROPBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100637}
638
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100639/*
640 * Accessors to read/write GIC Redistributor PENDBASER register
641 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100642static inline uint64_t gicr_read_pendbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100643{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100644 return mmio_read_64(base + GICR_PENDBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100645}
646
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100647static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100648{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100649 mmio_write_64(base + GICR_PENDBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100650}
651
Soby Mathewf6f1a322017-07-18 16:12:45 +0100652/*******************************************************************************
653 * GIC ITS functions to read and write entire ITS registers.
654 ******************************************************************************/
655static inline uint32_t gits_read_ctlr(uintptr_t base)
656{
657 return mmio_read_32(base + GITS_CTLR);
658}
659
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000660static inline void gits_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100661{
662 mmio_write_32(base + GITS_CTLR, val);
663}
664
665static inline uint64_t gits_read_cbaser(uintptr_t base)
666{
667 return mmio_read_64(base + GITS_CBASER);
668}
669
670static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
671{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100672 mmio_write_64(base + GITS_CBASER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100673}
674
675static inline uint64_t gits_read_cwriter(uintptr_t base)
676{
677 return mmio_read_64(base + GITS_CWRITER);
678}
679
680static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
681{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100682 mmio_write_64(base + GITS_CWRITER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100683}
684
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000685static inline uint64_t gits_read_baser(uintptr_t base,
686 unsigned int its_table_id)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100687{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100688 assert(its_table_id < 8U);
689 return mmio_read_64(base + GITS_BASER + (8U * its_table_id));
Soby Mathewf6f1a322017-07-18 16:12:45 +0100690}
691
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000692static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id,
693 uint64_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100694{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100695 assert(its_table_id < 8U);
696 mmio_write_64(base + GITS_BASER + (8U * its_table_id), val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100697}
698
699/*
700 * Wait for Quiescent bit when GIC ITS is disabled
701 */
702static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
703{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100704 assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000705 while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) {
706 }
Soby Mathewf6f1a322017-07-18 16:12:45 +0100707}
708
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000709#endif /* GICV3_PRIVATE_H */