blob: 26c8de53cec9f8221c29f0fb9d2f3e0257c584f8 [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))
129#endif
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) \
139 mmio_write((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);
205void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000206
207/*******************************************************************************
208 * Private GICv3 function prototypes for accessing the GIC registers
209 * corresponding to a single interrupt ID. These functions use bitwise
210 * operations or appropriate register accesses to modify or return
211 * the bit-field corresponding the single interrupt ID.
212 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100213unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100214unsigned int gicr_get_igrpmodr(uintptr_t base, unsigned int id);
215unsigned int gicr_get_igroupr(uintptr_t base, unsigned int id);
216unsigned int gicr_get_isactiver(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100217void gicd_set_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100218void gicr_set_igrpmodr(uintptr_t base, unsigned int id);
219void gicr_set_isenabler(uintptr_t base, unsigned int id);
220void gicr_set_icenabler(uintptr_t base, unsigned int id);
221void gicr_set_ispendr(uintptr_t base, unsigned int id);
222void gicr_set_icpendr(uintptr_t base, unsigned int id);
223void gicr_set_igroupr(uintptr_t base, unsigned int id);
Achin Gupta92712a52015-09-03 14:18:02 +0100224void gicd_clr_igrpmodr(uintptr_t base, unsigned int id);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100225void gicr_clr_igrpmodr(uintptr_t base, unsigned int id);
226void gicr_clr_igroupr(uintptr_t base, unsigned int id);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000227void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100228void gicr_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg);
Soby Mathew50f6fe42016-02-01 17:59:22 +0000229
230/*******************************************************************************
231 * Private GICv3 helper function prototypes
232 ******************************************************************************/
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100233void gicv3_spis_config_defaults(uintptr_t gicd_base);
234void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100235unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100236 const interrupt_prop_t *interrupt_props,
237 unsigned int interrupt_props_num);
Daniel Boulby4e83abb2018-05-01 15:15:34 +0100238unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
Jeenu Viswambharanaeb267c2017-09-22 08:32:09 +0100239 const interrupt_prop_t *interrupt_props,
240 unsigned int interrupt_props_num);
Achin Gupta92712a52015-09-03 14:18:02 +0100241void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
242 unsigned int rdistif_num,
243 uintptr_t gicr_base,
244 mpidr_hash_fn mpidr_to_core_pos);
245void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base);
246void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base);
247
248/*******************************************************************************
249 * GIC Distributor interface accessors
250 ******************************************************************************/
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100251/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100252 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100253 * GICD_CTLR[2:0] - the Group Enables
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100254 * GICD_CTLR[7:4] - the ARE bits, E1NWF bit and DS bit
255 * GICD_ICENABLER<n> - the clearing of enable state for SPIs
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100256 */
257static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
258{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000259 while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) {
260 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100261}
262
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000263static inline uint32_t gicd_read_pidr2(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100264{
265 return mmio_read_32(base + GICD_PIDR2_GICV3);
266}
267
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000268static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id)
Achin Gupta92712a52015-09-03 14:18:02 +0100269{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100270 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100271 return GICD_READ_64(IROUTE, base, id);
Achin Gupta92712a52015-09-03 14:18:02 +0100272}
273
274static inline void gicd_write_irouter(uintptr_t base,
275 unsigned int id,
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000276 uint64_t affinity)
Achin Gupta92712a52015-09-03 14:18:02 +0100277{
Soby Mathewaaf71c82016-07-26 17:46:56 +0100278 assert(id >= MIN_SPI_ID);
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100279 GICD_WRITE_64(IROUTE, base, id, affinity);
Achin Gupta92712a52015-09-03 14:18:02 +0100280}
281
282static inline void gicd_clr_ctlr(uintptr_t base,
283 unsigned int bitmap,
284 unsigned int rwp)
285{
286 gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000287 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100288 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000289 }
Achin Gupta92712a52015-09-03 14:18:02 +0100290}
291
292static inline void gicd_set_ctlr(uintptr_t base,
293 unsigned int bitmap,
294 unsigned int rwp)
295{
296 gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000297 if (rwp != 0U) {
Achin Gupta92712a52015-09-03 14:18:02 +0100298 gicd_wait_for_pending_write(base);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000299 }
Achin Gupta92712a52015-09-03 14:18:02 +0100300}
301
302/*******************************************************************************
303 * GIC Redistributor interface accessors
304 ******************************************************************************/
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100305static inline uint32_t gicr_read_ctlr(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100306{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100307 return mmio_read_32(base + GICR_CTLR);
Achin Gupta92712a52015-09-03 14:18:02 +0100308}
309
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100310static inline void gicr_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100311{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100312 mmio_write_32(base + GICR_CTLR, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100313}
314
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000315static inline uint64_t gicr_read_typer(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100316{
317 return mmio_read_64(base + GICR_TYPER);
318}
319
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000320static inline uint32_t gicr_read_waker(uintptr_t base)
Achin Gupta92712a52015-09-03 14:18:02 +0100321{
322 return mmio_read_32(base + GICR_WAKER);
323}
324
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000325static inline void gicr_write_waker(uintptr_t base, uint32_t val)
Achin Gupta92712a52015-09-03 14:18:02 +0100326{
327 mmio_write_32(base + GICR_WAKER, val);
328}
329
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100330/*
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100331 * Wait for updates to:
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100332 * GICR_ICENABLER0
333 * GICR_CTLR.DPG1S
334 * GICR_CTLR.DPG1NS
335 * GICR_CTLR.DPG0
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100336 * GICR_CTLR, which clears EnableLPIs from 1 to 0
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100337 */
338static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
339{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000340 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) {
341 }
Douglas Raillarda1b1da82017-07-26 13:51:00 +0100342}
343
Soby Mathew327548c2017-07-13 15:19:51 +0100344static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
345{
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000346 while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) {
347 }
Soby Mathew327548c2017-07-13 15:19:51 +0100348}
349
350/* Private implementation of Distributor power control hooks */
351void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num);
352void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num);
353
Soby Mathew50f6fe42016-02-01 17:59:22 +0000354/*******************************************************************************
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000355 * GIC Redistributor functions for accessing entire registers.
Soby Mathew50f6fe42016-02-01 17:59:22 +0000356 * Note: The raw register values correspond to multiple interrupt IDs and
357 * the number of interrupt IDs involved depends on the register accessed.
358 ******************************************************************************/
Achin Gupta92712a52015-09-03 14:18:02 +0100359
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100360/*
361 * Accessors to read/write GIC Redistributor ICENABLER0 and ICENABLERE
362 * register corresponding to its number
363 */
364static inline unsigned int gicr_read_icenabler(uintptr_t base,
365 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100366{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100367 return mmio_read_32(base + GICR_ICENABLER + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100368}
369
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100370static inline void gicr_write_icenabler(uintptr_t base, unsigned int reg_num,
371 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100372{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100373 mmio_write_32(base + GICR_ICENABLER + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100374}
375
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100376/*
377 * Accessor to read/write GIC Redistributor ICFGR0, ICFGR1 and ICFGRE
378 * register corresponding to its number
379 */
380static inline unsigned int gicr_read_icfgr(uintptr_t base, unsigned int reg_num)
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100381{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100382 return mmio_read_32(base + GICR_ICFGR + (reg_num << 2));
Jeenu Viswambharaneb1c12c2017-09-22 08:32:09 +0100383}
384
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100385static inline void gicr_write_icfgr(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_ICFGR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100389}
390
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100391/*
392 * Accessors to read/write GIC Redistributor IGROUPR0 and IGROUPRE
393 * register corresponding to its number
394 */
395static inline unsigned int gicr_read_igroupr(uintptr_t base,
396 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100397{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100398 return mmio_read_32(base + GICR_IGROUPR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100399}
400
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100401static inline void gicr_write_igroupr(uintptr_t base, unsigned int reg_num,
402 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100403{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100404 mmio_write_32(base + GICR_IGROUPR + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100405}
406
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100407/*
408 * Accessors to read/write GIC Redistributor IGRPMODR0 and IGRPMODRE
409 * register corresponding to its number
410 */
411static inline unsigned int gicr_read_igrpmodr(uintptr_t base,
412 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100413{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100414 return mmio_read_32(base + GICR_IGRPMODR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100415}
416
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100417static inline void gicr_write_igrpmodr(uintptr_t base, unsigned int reg_num,
418 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100419{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100420 mmio_write_32(base + GICR_IGRPMODR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100421}
422
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100423/*
424 * Accessors to read/write the GIC Redistributor IPRIORITYR(E) register
425 * corresponding to its number, 4 interrupts IDs at a time.
426 */
427static inline unsigned int gicr_read_ipriorityr(uintptr_t base,
428 unsigned int reg_num)
Achin Gupta92712a52015-09-03 14:18:02 +0100429{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100430 return mmio_read_32(base + GICR_IPRIORITYR + (reg_num << 2));
Achin Gupta92712a52015-09-03 14:18:02 +0100431}
432
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100433static inline void gicr_write_ipriorityr(uintptr_t base, unsigned int reg_num,
434 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100435{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100436 mmio_write_32(base + GICR_IPRIORITYR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100437}
438
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100439/*
440 * Accessors to read/write GIC Redistributor ISACTIVER0 and ISACTIVERE
441 * register corresponding to its number
442 */
443static inline unsigned int gicr_read_isactiver(uintptr_t base,
444 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100445{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100446 return mmio_read_32(base + GICR_ISACTIVER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100447}
448
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100449static inline void gicr_write_isactiver(uintptr_t base, unsigned int reg_num,
450 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100451{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100452 mmio_write_32(base + GICR_ISACTIVER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100453}
454
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100455/*
456 * Accessors to read/write GIC Redistributor ISENABLER0 and ISENABLERE
457 * register corresponding to its number
458 */
459static inline unsigned int gicr_read_isenabler(uintptr_t base,
460 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100461{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100462 return mmio_read_32(base + GICR_ISENABLER + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100463}
464
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100465static inline void gicr_write_isenabler(uintptr_t base, unsigned int reg_num,
466 unsigned int val)
Soby Mathew327548c2017-07-13 15:19:51 +0100467{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100468 mmio_write_32(base + GICR_ISENABLER + (reg_num << 2), val);
Soby Mathew327548c2017-07-13 15:19:51 +0100469}
470
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100471/*
472 * Accessors to read/write GIC Redistributor ISPENDR0 and ISPENDRE
473 * register corresponding to its number
474 */
475static inline unsigned int gicr_read_ispendr(uintptr_t base,
476 unsigned int reg_num)
Soby Mathew327548c2017-07-13 15:19:51 +0100477{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100478 return mmio_read_32(base + GICR_ISPENDR + (reg_num << 2));
Soby Mathew327548c2017-07-13 15:19:51 +0100479}
480
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100481static inline void gicr_write_ispendr(uintptr_t base, unsigned int reg_num,
482 unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100483{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100484 mmio_write_32(base + GICR_ISPENDR + (reg_num << 2), val);
Achin Gupta92712a52015-09-03 14:18:02 +0100485}
486
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100487/*
488 * Accessors to read/write GIC Redistributor NSACR register
489 */
490static inline unsigned int gicr_read_nsacr(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100491{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100492 return mmio_read_32(base + GICR_NSACR);
Soby Mathew327548c2017-07-13 15:19:51 +0100493}
494
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100495static inline void gicr_write_nsacr(uintptr_t base, unsigned int val)
Achin Gupta92712a52015-09-03 14:18:02 +0100496{
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100497 mmio_write_32(base + GICR_NSACR, val);
Achin Gupta92712a52015-09-03 14:18:02 +0100498}
499
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100500/*
501 * Accessors to read/write GIC Redistributor PROPBASER register
502 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100503static inline uint64_t gicr_read_propbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100504{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100505 return mmio_read_64(base + GICR_PROPBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100506}
507
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100508static inline void gicr_write_propbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100509{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100510 mmio_write_64(base + GICR_PROPBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100511}
512
Alexei Fedorova6e6ae02020-04-06 16:27:54 +0100513/*
514 * Accessors to read/write GIC Redistributor PENDBASER register
515 */
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100516static inline uint64_t gicr_read_pendbaser(uintptr_t base)
Soby Mathew327548c2017-07-13 15:19:51 +0100517{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100518 return mmio_read_64(base + GICR_PENDBASER);
Soby Mathew327548c2017-07-13 15:19:51 +0100519}
520
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100521static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val)
Soby Mathew327548c2017-07-13 15:19:51 +0100522{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100523 mmio_write_64(base + GICR_PENDBASER, val);
Soby Mathew327548c2017-07-13 15:19:51 +0100524}
525
Soby Mathewf6f1a322017-07-18 16:12:45 +0100526/*******************************************************************************
527 * GIC ITS functions to read and write entire ITS registers.
528 ******************************************************************************/
529static inline uint32_t gits_read_ctlr(uintptr_t base)
530{
531 return mmio_read_32(base + GITS_CTLR);
532}
533
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000534static inline void gits_write_ctlr(uintptr_t base, uint32_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100535{
536 mmio_write_32(base + GITS_CTLR, val);
537}
538
539static inline uint64_t gits_read_cbaser(uintptr_t base)
540{
541 return mmio_read_64(base + GITS_CBASER);
542}
543
544static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
545{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100546 mmio_write_64(base + GITS_CBASER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100547}
548
549static inline uint64_t gits_read_cwriter(uintptr_t base)
550{
551 return mmio_read_64(base + GITS_CWRITER);
552}
553
554static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
555{
Antonio Nino Diazbab39e82018-08-21 10:03:07 +0100556 mmio_write_64(base + GITS_CWRITER, val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100557}
558
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000559static inline uint64_t gits_read_baser(uintptr_t base,
560 unsigned int its_table_id)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100561{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100562 assert(its_table_id < 8U);
563 return mmio_read_64(base + GITS_BASER + (8U * its_table_id));
Soby Mathewf6f1a322017-07-18 16:12:45 +0100564}
565
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000566static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id,
567 uint64_t val)
Soby Mathewf6f1a322017-07-18 16:12:45 +0100568{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100569 assert(its_table_id < 8U);
570 mmio_write_64(base + GITS_BASER + (8U * its_table_id), val);
Soby Mathewf6f1a322017-07-18 16:12:45 +0100571}
572
573/*
574 * Wait for Quiescent bit when GIC ITS is disabled
575 */
576static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
577{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100578 assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
Alexei Fedorov2f13d6c2020-02-21 10:17:26 +0000579 while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) {
580 }
Soby Mathewf6f1a322017-07-18 16:12:45 +0100581}
582
Antonio Nino Diaz5eb88372018-11-08 10:20:19 +0000583#endif /* GICV3_PRIVATE_H */