blob: c5d027da291b3f30c320422b681b5876ef4489ec [file] [log] [blame]
Achin Gupta92712a52015-09-03 14:18:02 +01001/*
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +00002 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
Achin Gupta92712a52015-09-03 14:18:02 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Achin Gupta92712a52015-09-03 14:18:02 +01005 */
6
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +00007#ifndef GICV3_PRIVATE_H
8#define GICV3_PRIVATE_H
Achin Gupta92712a52015-09-03 14:18:02 +01009
Soby Mathew327548c2017-07-13 15:19:51 +010010#include <assert.h>
Achin Gupta92712a52015-09-03 14:18:02 +010011#include <stdint.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000012
13#include <drivers/arm/gic_common.h>
14#include <drivers/arm/gicv3.h>
15#include <lib/mmio.h>
16
Jeenu Viswambharand7a901e2016-12-06 16:15:22 +000017#include "../common/gic_common_private.h"
Achin Gupta92712a52015-09-03 14:18:02 +010018
19/*******************************************************************************
20 * GICv3 private macro definitions
21 ******************************************************************************/
22
23/* Constants to indicate the status of the RWP bit */
Antonio Nino Diaz2e590712018-08-24 11:46:33 +010024#define RWP_TRUE U(1)
25#define RWP_FALSE U(0)
Achin Gupta92712a52015-09-03 14:18:02 +010026
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000027/* Calculate GIC register bit number corresponding to its interrupt ID */
28#define BIT_NUM(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010029 ((id) & ((1U << REG##R_SHIFT) - 1U))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000030
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010031/*
32 * Calculate 8, 32 and 64-bit GICD register offset
33 * corresponding to its interrupt ID
34 */
35#if GIC_EXT_INTID
36 /* GICv3.1 */
37#define GICD_OFFSET_8(REG, id) \
38 (((id) <= MAX_SPI_ID) ? \
39 GICD_##REG##R + (uintptr_t)(id) : \
40 GICD_##REG##RE + (uintptr_t)(id) - MIN_ESPI_ID)
41
42#define GICD_OFFSET(REG, id) \
43 (((id) <= MAX_SPI_ID) ? \
44 GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \
45 GICD_##REG##RE + ((((uintptr_t)(id) - MIN_ESPI_ID) >> \
46 REG##R_SHIFT) << 2))
47
48#define GICD_OFFSET_64(REG, id) \
49 (((id) <= MAX_SPI_ID) ? \
50 GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3) : \
51 GICD_##REG##RE + (((uintptr_t)(id) - MIN_ESPI_ID) << 3))
52
53#else /* GICv3 */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000054#define GICD_OFFSET_8(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010055 (GICD_##REG##R + (uintptr_t)(id))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000056
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000057#define GICD_OFFSET(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010058 (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000059
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000060#define GICD_OFFSET_64(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010061 (GICD_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 3))
62#endif /* GIC_EXT_INTID */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000063
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010064/*
65 * Read/Write 8, 32 and 64-bit GIC Distributor register
66 * corresponding to its interrupt ID
67 */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000068#define GICD_READ(REG, base, id) \
69 mmio_read_32((base) + GICD_OFFSET(REG, (id)))
70
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000071#define GICD_READ_64(REG, base, id) \
72 mmio_read_64((base) + GICD_OFFSET_64(REG, (id)))
73
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010074#define GICD_WRITE_8(REG, base, id, val) \
75 mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000076
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010077#define GICD_WRITE(REG, base, id, val) \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000078 mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val))
79
Alexei Fedorova6e6ae02020-04-06 16:27:54 +010080#define GICD_WRITE_64(REG, base, id, val) \
81 mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +000082
83/*
84 * Bit operations on GIC Distributor register corresponding
85 * to its interrupt ID
86 */
87/* Get bit in GIC Distributor register */
88#define GICD_GET_BIT(REG, base, id) \
89 ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \
90 BIT_NUM(REG, (id))) & 1U)
91
92/* Set bit in GIC Distributor register */
93#define GICD_SET_BIT(REG, base, id) \
94 mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \
95 ((uint32_t)1 << BIT_NUM(REG, (id))))
96
97/* Clear bit in GIC Distributor register */
98#define GICD_CLR_BIT(REG, base, id) \
99 mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \
100 ((uint32_t)1 << BIT_NUM(REG, (id))))
101
102/* Write bit in GIC Distributor register */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100103#define GICD_WRITE_BIT(REG, base, id) \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000104 mmio_write_32((base) + GICD_OFFSET(REG, (id)), \
105 ((uint32_t)1 << BIT_NUM(REG, (id))))
106
107/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100108 * Calculate 8 and 32-bit GICR register offset
109 * corresponding to its interrupt ID
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000110 */
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100111#if GIC_EXT_INTID
112 /* GICv3.1 */
113#define GICR_OFFSET_8(REG, id) \
114 (((id) <= MAX_PPI_ID) ? \
115 GICR_##REG##R + (uintptr_t)(id) : \
116 GICR_##REG##R + (uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))
117
118#define GICR_OFFSET(REG, id) \
119 (((id) <= MAX_PPI_ID) ? \
120 GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2) : \
121 GICR_##REG##R + ((((uintptr_t)(id) - (MIN_EPPI_ID - MIN_SPI_ID))\
122 >> REG##R_SHIFT) << 2))
123#else /* GICv3 */
124#define GICR_OFFSET_8(REG, id) \
125 (GICR_##REG##R + (uintptr_t)(id))
126
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000127#define GICR_OFFSET(REG, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100128 (GICR_##REG##R + (((uintptr_t)(id) >> REG##R_SHIFT) << 2))
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100129#endif /* GIC_EXT_INTID */
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000130
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100131/* Read/Write GIC Redistributor register corresponding to its interrupt ID */
132#define GICR_READ(REG, base, id) \
133 mmio_read_32((base) + GICR_OFFSET(REG, (id)))
134
135#define GICR_WRITE_8(REG, base, id, val) \
136 mmio_write_8((base) + GICR_OFFSET_8(REG, (id)), (val))
137
138#define GICR_WRITE(REG, base, id, val) \
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100139 mmio_write_32((base) + GICR_OFFSET(REG, (id)), (val))
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000140
141/*
142 * Bit operations on GIC Redistributor register
143 * corresponding to its interrupt ID
144 */
145/* Get bit in GIC Redistributor register */
146#define GICR_GET_BIT(REG, base, id) \
147 ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \
148 BIT_NUM(REG, (id))) & 1U)
149
150/* Write bit in GIC Redistributor register */
151#define GICR_WRITE_BIT(REG, base, id) \
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100152 mmio_write_32((base) + GICR_OFFSET(REG, (id)), \
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000153 ((uint32_t)1 << BIT_NUM(REG, (id))))
154
155/* Set bit in GIC Redistributor register */
156#define GICR_SET_BIT(REG, base, id) \
157 mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \
158 ((uint32_t)1 << BIT_NUM(REG, (id))))
159
160/* Clear bit in GIC Redistributor register */
161#define GICR_CLR_BIT(REG, base, id) \
162 mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \
163 ((uint32_t)1 << BIT_NUM(REG, (id))))
164
Achin Gupta92712a52015-09-03 14:18:02 +0100165/*
Achin Gupta92712a52015-09-03 14:18:02 +0100166 * Macro to convert an mpidr to a value suitable for programming into a
167 * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
168 * to GICv3.
169 */
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100170static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr,
171 unsigned int irm)
172{
173 return (mpidr & ~(U(0xff) << 24)) |
174 ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT);
175}
Achin Gupta92712a52015-09-03 14:18:02 +0100176
177/*
Achin Gupta92712a52015-09-03 14:18:02 +0100178 * Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
179 * are zeroes.
180 */
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700181#ifdef __aarch64__
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100182static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
183{
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700184 return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) |
185 ((typer_val >> 32) & U(0xffffff));
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100186}
Soby Mathewd6452322016-05-05 13:59:07 +0100187#else
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100188static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
189{
Julius Werner8e0ef0f2019-07-09 14:02:43 -0700190 return (((typer_val) >> 32) & U(0xffffff));
Antonio Nino Diazdd4e59e2018-08-13 15:29:29 +0100191}
Soby Mathewd6452322016-05-05 13:59:07 +0100192#endif
Achin Gupta92712a52015-09-03 14:18:02 +0100193
194/*******************************************************************************
Soby Mathew327548c2017-07-13 15:19:51 +0100195 * GICv3 private global variables declarations
196 ******************************************************************************/
197extern const gicv3_driver_data_t *gicv3_driver_data;
198
199/*******************************************************************************
Soby Mathew50f6fe42016-02-01 17:59:22 +0000200 * Private GICv3 function prototypes for accessing entire registers.
201 * Note: The raw register values correspond to multiple interrupt IDs and
202 * the number of interrupt IDs involved depends on the register accessed.
Achin Gupta92712a52015-09-03 14:18:02 +0100203 ******************************************************************************/
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100204unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100205unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100206void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val);
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100207void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000208
209/*******************************************************************************
210 * Private GICv3 function prototypes for accessing the GIC registers
211 * corresponding to a single interrupt ID. These functions use bitwise
212 * operations or appropriate register accesses to modify or return
213 * the bit-field corresponding the single interrupt ID.
214 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100215unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100216unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id);
217unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id);
218unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100219void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100220void gicr_set_igrpmodr(uintptr_t base, unsigned int id);
221void gicr_set_isenabler(uintptr_t base, unsigned int id);
222void gicr_set_icenabler(uintptr_t base, unsigned int id);
223void gicr_set_ispendr(uintptr_t base, unsigned int id);
224void gicr_set_icpendr(uintptr_t base, unsigned int id);
225void gicr_set_igroupr(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100226void gicd_clr_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100227void gicr_clr_igrpmodr(uintptr_t base, unsigned int id);
228void gicr_clr_igroupr(uintptr_t base, unsigned int id);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000229void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100230void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000231
232/*******************************************************************************
233 * Private GICv3 helper function prototypes
234 ******************************************************************************/
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100235void gicv3_spis_config_defaults(uintptr_t gicd_base);
236void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100237unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100238 const interrupt_prop_t *interrupt_props,
239 unsigned int interrupt_props_num);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100240unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100241 const interrupt_prop_t *interrupt_props,
242 unsigned int interrupt_props_num);
Achin Gupta92712a52015-09-03 14:18:02 +0100243void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
244 unsigned int rdistif_num,
245 uintptr_t gicr_base,
246 mpidr_hash_fn mpidr_to_core_pos);
247void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base);
248void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base);
249
250/*******************************************************************************
251 * GIC Distributor interface accessors
252 ******************************************************************************/
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100253/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100254 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100255 * GICD_CTLR[2:0] - the Group Enables
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100256 * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit
257 * GICD_ICENABLER<n> - the clearing of enable state for SPIs
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100258 */
259static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
260{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000261 while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) {
262 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100263}
264
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000265static inline uint32_t gicd_read_pidr2(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100266{
267 return mmio_read_32(base + GICD_PIDR2_GICV3);
268}
269
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000270static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id)
Achin Gupta92712a52015-09-03 14:18:02 +0100271{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100272 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100273 return GICD_READ_64(IROUTE, base, id);
Achin Gupta92712a52015-09-03 14:18:02 +0100274}
275
276static inline void gicd_write_irouter(uintptr_t base,
277 unsigned int id,
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000278 uint64_t affinity)
Achin Gupta92712a52015-09-03 14:18:02 +0100279{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100280 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100281 GICD_WRITE_64(IROUTE, base, id, affinity);
Achin Gupta92712a52015-09-03 14:18:02 +0100282}
283
284static inline void gicd_clr_ctlr(uintptr_t base,
285 unsigned int bitmap,
286 unsigned int rwp)
287{
288 gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000289 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100290 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000291 }
Achin Gupta92712a52015-09-03 14:18:02 +0100292}
293
294static inline void gicd_set_ctlr(uintptr_t base,
295 unsigned int bitmap,
296 unsigned int rwp)
297{
298 gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000299 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100300 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000301 }
Achin Gupta92712a52015-09-03 14:18:02 +0100302}
303
304/*******************************************************************************
305 * GIC Redistributor interface accessors
306 ******************************************************************************/
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100307static inline uint32_t gicr_read_ctlr(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100308{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100309 return mmio_read_32(base + GICR_CTLR);
Achin Gupta92712a52015-09-03 14:18:02 +0100310}
311
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100312static inline void gicr_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100313{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100314 mmio_write_32(base + GICR_CTLR, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100315}
316
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000317static inline uint64_t gicr_read_typer(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100318{
319 return mmio_read_64(base + GICR_TYPER);
320}
321
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000322static inline uint32_t gicr_read_waker(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100323{
324 return mmio_read_32(base + GICR_WAKER);
325}
326
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000327static inline void gicr_write_waker(uintptr_t base, uint32_t val)
Achin Gupta92712a52015-09-03 14:18:02 +0100328{
329 mmio_write_32(base + GICR_WAKER, val);
330}
331
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100332/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100333 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100334 * GICR_ICENABLER0
335 * GICR_CTLR.DPG1S
336 * GICR_CTLR.DPG1NS
337 * GICR_CTLR.DPG0
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100338 * GICR_CTLR, which clears EnableLPIs from 1 to 0
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100339 */
340static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
341{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000342 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) {
343 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100344}
345
Soby Mathew327548c2017-07-13 15:19:51 +0100346static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
347{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000348 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) {
349 }
Soby Mathew327548c2017-07-13 15:19:51 +0100350}
351
352/* Private implementation of Distributor power control hooks */
353void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num);
354void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
355
Soby Mathew50f6fe42016-02-01 17:59:22 +0000356/*******************************************************************************
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000357 * GIC Redistributor functions for accessing entire registers.
Soby Mathew50f6fe42016-02-01 17:59:22 +0000358 * Note: The raw register values correspond to multiple interrupt IDs and
359 * the number of interrupt IDs involved depends on the register accessed.
360 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100361
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100362/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100363 * Accessors to read/write GIC Redistributor ICENABLER0 register
364 */
365static inline unsigned int gicr_read_icenabler0(uintptr_t base)
366{
367 return mmio_read_32(base + GICR_ICENABLER0);
368}
369
370static inline void gicr_write_icenabler0(uintptr_t base, unsigned int val)
371{
372 mmio_write_32(base + GICR_ICENABLER0, val);
373}
374
375/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100376 * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE
377 * register corresponding to its number
378 */
379static inline unsigned int gicr_read_icenabler(uintptr_t base,
380 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100381{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100382 return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100383}
384
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100385static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num,
386 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100387{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100388 mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100389}
390
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100391/*
392 * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 registers
393 */
394static inline unsigned int gicr_read_icfgr0(uintptr_t base)
395{
396 return mmio_read_32(base + GICR_ICFGR0);
397}
398
399static inline unsigned int gicr_read_icfgr1(uintptr_t base)
400{
401 return mmio_read_32(base + GICR_ICFGR1);
402}
403
404static inline void gicr_write_icfgr0(uintptr_t base, unsigned int val)
405{
406 mmio_write_32(base + GICR_ICFGR0, val);
407}
408
409static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val)
410{
411 mmio_write_32(base + GICR_ICFGR1, val);
412}
413
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100414/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100415 * Accessors to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100416 * register corresponding to its number
417 */
418static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num)
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100419{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100420 return mmio_read_32(base + GICR_ICFGR + (reg_num << 2));
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100421}
422
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100423static inline void gicr_write_icfgr(uintptr_t base, unsigned int reg_num,
424 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100425{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100426 mmio_write_32(base + GICR_ICFGR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100427}
428
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100429/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100430 * Accessor to write GIC Redistributor ICPENDR0 register
431 */
432static inline void gicr_write_icpendr0(uintptr_t base, unsigned int val)
433{
434 mmio_write_32(base + GICR_ICPENDR0, val);
435}
436
437/*
438 * Accessor to write GIC Redistributor ICPENDR0 and ICPENDRE
439 * register corresponding to its number
440 */
441static inline void gicr_write_icpendr(uintptr_t base, unsigned int reg_num,
442 unsigned int val)
443{
444 mmio_write_32(base + GICR_ICPENDR + (reg_num << 2), val);
445}
446
447/*
448 * Accessors to read/write GIC Redistributor IGROUPR0 register
449 */
450static inline unsigned int gicr_read_igroupr0(uintptr_t base)
451{
452 return mmio_read_32(base + GICR_IGROUPR0);
453}
454
455static inline void gicr_write_igroupr0(uintptr_t base, unsigned int val)
456{
457 mmio_write_32(base + GICR_IGROUPR0, val);
458}
459
460/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100461 * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE
462 * register corresponding to its number
463 */
464static inline unsigned int gicr_read_igroupr(uintptr_t base,
465 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100466{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100467 return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100468}
469
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100470static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num,
471 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100472{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100473 mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100474}
475
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100476/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100477 * Accessors to read/write GIC Redistributor IGRPMODR0 register
478 */
479static inline unsigned int gicr_read_igrpmodr0(uintptr_t base)
480{
481 return mmio_read_32(base + GICR_IGRPMODR0);
482}
483
484static inline void gicr_write_igrpmodr0(uintptr_t base, unsigned int val)
485{
486 mmio_write_32(base + GICR_IGRPMODR0, val);
487}
488
489/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100490 * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE
491 * register corresponding to its number
492 */
493static inline unsigned int gicr_read_igrpmodr(uintptr_t base,
494 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100495{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100496 return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100497}
498
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100499static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num,
500 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100501{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100502 mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100503}
504
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100505/*
506 * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register
507 * corresponding to its number, 4 interrupts IDs at a time.
508 */
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100509static inline unsigned int gicr_ipriorityr_read(uintptr_t base,
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100510 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100511{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100512 return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100513}
514
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100515static inline void gicr_ipriorityr_write(uintptr_t base, unsigned int reg_num,
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100516 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100517{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100518 mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100519}
520
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100521/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100522 * Accessors to read/write GIC Redistributor ISACTIVER0 register
523 */
524static inline unsigned int gicr_read_isactiver0(uintptr_t base)
525{
526 return mmio_read_32(base + GICR_ISACTIVER0);
527}
528
529static inline void gicr_write_isactiver0(uintptr_t base, unsigned int val)
530{
531 mmio_write_32(base + GICR_ISACTIVER0, val);
532}
533
534/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100535 * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE
536 * register corresponding to its number
537 */
538static inline unsigned int gicr_read_isactiver(uintptr_t base,
539 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100540{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100541 return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100542}
543
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100544static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num,
545 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100546{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100547 mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100548}
549
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100550/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100551 * Accessors to read/write GIC Redistributor ISENABLER0 register
552 */
553static inline unsigned int gicr_read_isenabler0(uintptr_t base)
554{
555 return mmio_read_32(base + GICR_ISENABLER0);
556}
557
558static inline void gicr_write_isenabler0(uintptr_t base, unsigned int val)
559{
560 mmio_write_32(base + GICR_ISENABLER0, val);
561}
562
563/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100564 * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE
565 * register corresponding to its number
566 */
567static inline unsigned int gicr_read_isenabler(uintptr_t base,
568 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100569{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100570 return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100571}
572
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100573static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num,
574 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100575{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100576 mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100577}
578
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100579/*
Alexei Fedorovc7510c52020-04-07 18:16:18 +0100580 * Accessors to read/write GIC Redistributor ISPENDR0 register
581 */
582static inline unsigned int gicr_read_ispendr0(uintptr_t base)
583{
584 return mmio_read_32(base + GICR_ISPENDR0);
585}
586
587static inline void gicr_write_ispendr0(uintptr_t base, unsigned int val)
588{
589 mmio_write_32(base + GICR_ISPENDR0, val);
590}
591
592/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100593 * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE
594 * register corresponding to its number
595 */
596static inline unsigned int gicr_read_ispendr(uintptr_t base,
597 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100598{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100599 return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100600}
601
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100602static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num,
603 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100604{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100605 mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100606}
607
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100608/*
609 * Accessors to read/write GIC Redistributor NSACR register
610 */
611static inline unsigned int gicr_read_nsacr(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100612{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100613 return mmio_read_32(base + GICR_NSACR);
Soby Mathew327548c2017-07-13 15:19:51 +0100614}
615
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100616static inline void gicr_write_nsacr(uintptr_t base, unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100617{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100618 mmio_write_32(base + GICR_NSACR, val);
Achin Gupta92712a52015-09-03 14:18:02 +0100619}
620
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100621/*
622 * Accessors to read/write GIC Redistributor PROPBASER register
623 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100624static inline uint64_t gicr_read_propbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100625{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100626 return mmio_read_64(base + GICR_PROPBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100627}
628
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100629static inline void gicr_write_propbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100630{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100631 mmio_write_64(base + GICR_PROPBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100632}
633
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100634/*
635 * Accessors to read/write GIC Redistributor PENDBASER register
636 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100637static inline uint64_t gicr_read_pendbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100638{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100639 return mmio_read_64(base + GICR_PENDBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100640}
641
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100642static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100643{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100644 mmio_write_64(base + GICR_PENDBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100645}
646
Soby Mathewf6f1a322017-07-18 16:12:45 +0100647/*******************************************************************************
648 * GIC ITS functions to read and write entire ITS registers.
649 ******************************************************************************/
650static inline uint32_t gits_read_ctlr(uintptr_t base)
651{
652 return mmio_read_32(base + GITS_CTLR);
653}
654
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000655static inline void gits_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100656{
657 mmio_write_32(base + GITS_CTLR, val);
658}
659
660static inline uint64_t gits_read_cbaser(uintptr_t base)
661{
662 return mmio_read_64(base + GITS_CBASER);
663}
664
665static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
666{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100667 mmio_write_64(base + GITS_CBASER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100668}
669
670static inline uint64_t gits_read_cwriter(uintptr_t base)
671{
672 return mmio_read_64(base + GITS_CWRITER);
673}
674
675static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
676{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100677 mmio_write_64(base + GITS_CWRITER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100678}
679
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000680static inline uint64_t gits_read_baser(uintptr_t base,
681 unsigned int its_table_id)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100682{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100683 assert(its_table_id < 8U);
684 return mmio_read_64(base + GITS_BASER + (8U * its_table_id));
Soby Mathewf6f1a322017-07-18 16:12:45 +0100685}
686
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000687static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id,
688 uint64_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100689{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100690 assert(its_table_id < 8U);
691 mmio_write_64(base + GITS_BASER + (8U * its_table_id), val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100692}
693
694/*
695 * Wait for Quiescent bit when GIC ITS is disabled
696 */
697static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
698{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100699 assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000700 while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) {
701 }
Soby Mathewf6f1a322017-07-18 16:12:45 +0100702}
703
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000704#endif /* GICV3_PRIVATE_H */