blob: 589de5da40b50e89914dfee6a2f4ca38ababf596 [file] [log] [blame]
Achin Gupta92712a52015-09-03 14:18:02 +01001/*
Jeenu Viswambharanb6982c02018-03-22 08:57:52 +00002 * Copyright (c) 2015-2018, 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
7#include <assert.h>
8#include <gic_common.h>
9#include <mmio.h>
Soby Mathew50f6fe42016-02-01 17:59:22 +000010#include "gic_common_private.h"
Achin Gupta92712a52015-09-03 14:18:02 +010011
12/*******************************************************************************
13 * GIC Distributor interface accessors for reading entire registers
14 ******************************************************************************/
15/*
16 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
17 * `id`, 32 interrupt ids at a time.
18 */
19unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
20{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010021 unsigned int n = id >> IGROUPR_SHIFT;
22
Achin Gupta92712a52015-09-03 14:18:02 +010023 return mmio_read_32(base + GICD_IGROUPR + (n << 2));
24}
25
26/*
27 * Accessor to read the GIC Distributor ISENABLER corresponding to the
28 * interrupt `id`, 32 interrupt ids at a time.
29 */
30unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
31{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010032 unsigned int n = id >> ISENABLER_SHIFT;
33
Achin Gupta92712a52015-09-03 14:18:02 +010034 return mmio_read_32(base + GICD_ISENABLER + (n << 2));
35}
36
37/*
38 * Accessor to read the GIC Distributor ICENABLER corresponding to the
39 * interrupt `id`, 32 interrupt IDs at a time.
40 */
41unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
42{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010043 unsigned int n = id >> ICENABLER_SHIFT;
44
Achin Gupta92712a52015-09-03 14:18:02 +010045 return mmio_read_32(base + GICD_ICENABLER + (n << 2));
46}
47
48/*
49 * Accessor to read the GIC Distributor ISPENDR corresponding to the
50 * interrupt `id`, 32 interrupt IDs at a time.
51 */
52unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
53{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010054 unsigned int n = id >> ISPENDR_SHIFT;
55
Achin Gupta92712a52015-09-03 14:18:02 +010056 return mmio_read_32(base + GICD_ISPENDR + (n << 2));
57}
58
59/*
60 * Accessor to read the GIC Distributor ICPENDR corresponding to the
61 * interrupt `id`, 32 interrupt IDs at a time.
62 */
63unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
64{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010065 unsigned int n = id >> ICPENDR_SHIFT;
66
Achin Gupta92712a52015-09-03 14:18:02 +010067 return mmio_read_32(base + GICD_ICPENDR + (n << 2));
68}
69
70/*
71 * Accessor to read the GIC Distributor ISACTIVER corresponding to the
72 * interrupt `id`, 32 interrupt IDs at a time.
73 */
74unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
75{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010076 unsigned int n = id >> ISACTIVER_SHIFT;
77
Achin Gupta92712a52015-09-03 14:18:02 +010078 return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
79}
80
81/*
82 * Accessor to read the GIC Distributor ICACTIVER corresponding to the
83 * interrupt `id`, 32 interrupt IDs at a time.
84 */
85unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
86{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010087 unsigned int n = id >> ICACTIVER_SHIFT;
88
Achin Gupta92712a52015-09-03 14:18:02 +010089 return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
90}
91
92/*
93 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
94 * interrupt `id`, 4 interrupt IDs at a time.
95 */
96unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
97{
Antonio Nino Diazca994e72018-08-21 10:02:33 +010098 unsigned int n = id >> IPRIORITYR_SHIFT;
99
Achin Gupta92712a52015-09-03 14:18:02 +0100100 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
101}
102
103/*
104 * Accessor to read the GIC Distributor ICGFR corresponding to the
105 * interrupt `id`, 16 interrupt IDs at a time.
106 */
107unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
108{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100109 unsigned int n = id >> ICFGR_SHIFT;
110
Achin Gupta92712a52015-09-03 14:18:02 +0100111 return mmio_read_32(base + GICD_ICFGR + (n << 2));
112}
113
114/*
115 * Accessor to read the GIC Distributor NSACR corresponding to the
116 * interrupt `id`, 16 interrupt IDs at a time.
117 */
118unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
119{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100120 unsigned int n = id >> NSACR_SHIFT;
121
Achin Gupta92712a52015-09-03 14:18:02 +0100122 return mmio_read_32(base + GICD_NSACR + (n << 2));
123}
124
125/*******************************************************************************
126 * GIC Distributor interface accessors for writing entire registers
127 ******************************************************************************/
128/*
129 * Accessor to write the GIC Distributor IGROUPR corresponding to the
130 * interrupt `id`, 32 interrupt IDs at a time.
131 */
132void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
133{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100134 unsigned int n = id >> IGROUPR_SHIFT;
135
Achin Gupta92712a52015-09-03 14:18:02 +0100136 mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
137}
138
139/*
140 * Accessor to write the GIC Distributor ISENABLER corresponding to the
141 * interrupt `id`, 32 interrupt IDs at a time.
142 */
143void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
144{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100145 unsigned int n = id >> ISENABLER_SHIFT;
146
Achin Gupta92712a52015-09-03 14:18:02 +0100147 mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
148}
149
150/*
151 * Accessor to write the GIC Distributor ICENABLER corresponding to the
152 * interrupt `id`, 32 interrupt IDs at a time.
153 */
154void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
155{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100156 unsigned int n = id >> ICENABLER_SHIFT;
157
Achin Gupta92712a52015-09-03 14:18:02 +0100158 mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
159}
160
161/*
162 * Accessor to write the GIC Distributor ISPENDR corresponding to the
163 * interrupt `id`, 32 interrupt IDs at a time.
164 */
165void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
166{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100167 unsigned int n = id >> ISPENDR_SHIFT;
168
Achin Gupta92712a52015-09-03 14:18:02 +0100169 mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
170}
171
172/*
173 * Accessor to write the GIC Distributor ICPENDR corresponding to the
174 * interrupt `id`, 32 interrupt IDs at a time.
175 */
176void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
177{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100178 unsigned int n = id >> ICPENDR_SHIFT;
179
Achin Gupta92712a52015-09-03 14:18:02 +0100180 mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
181}
182
183/*
184 * Accessor to write the GIC Distributor ISACTIVER corresponding to the
185 * interrupt `id`, 32 interrupt IDs at a time.
186 */
187void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
188{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100189 unsigned int n = id >> ISACTIVER_SHIFT;
190
Achin Gupta92712a52015-09-03 14:18:02 +0100191 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
192}
193
194/*
195 * Accessor to write the GIC Distributor ICACTIVER corresponding to the
196 * interrupt `id`, 32 interrupt IDs at a time.
197 */
198void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
199{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100200 unsigned int n = id >> ICACTIVER_SHIFT;
201
Achin Gupta92712a52015-09-03 14:18:02 +0100202 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
203}
204
205/*
206 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
207 * interrupt `id`, 4 interrupt IDs at a time.
208 */
209void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
210{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100211 unsigned int n = id >> IPRIORITYR_SHIFT;
212
Achin Gupta92712a52015-09-03 14:18:02 +0100213 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
214}
215
216/*
217 * Accessor to write the GIC Distributor ICFGR corresponding to the
218 * interrupt `id`, 16 interrupt IDs at a time.
219 */
220void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
221{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100222 unsigned int n = id >> ICFGR_SHIFT;
223
Achin Gupta92712a52015-09-03 14:18:02 +0100224 mmio_write_32(base + GICD_ICFGR + (n << 2), val);
225}
226
227/*
228 * Accessor to write the GIC Distributor NSACR corresponding to the
229 * interrupt `id`, 16 interrupt IDs at a time.
230 */
231void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
232{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100233 unsigned int n = id >> NSACR_SHIFT;
234
Achin Gupta92712a52015-09-03 14:18:02 +0100235 mmio_write_32(base + GICD_NSACR + (n << 2), val);
236}
237
238/*******************************************************************************
Soby Mathew50f6fe42016-02-01 17:59:22 +0000239 * GIC Distributor functions for accessing the GIC registers
240 * corresponding to a single interrupt ID. These functions use bitwise
241 * operations or appropriate register accesses to modify or return
242 * the bit-field corresponding the single interrupt ID.
Achin Gupta92712a52015-09-03 14:18:02 +0100243 ******************************************************************************/
244unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
245{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100246 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100247 unsigned int reg_val = gicd_read_igroupr(base, id);
248
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100249 return (reg_val >> bit_num) & 0x1U;
Achin Gupta92712a52015-09-03 14:18:02 +0100250}
251
252void gicd_set_igroupr(uintptr_t base, unsigned int id)
253{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100254 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100255 unsigned int reg_val = gicd_read_igroupr(base, id);
256
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100257 gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100258}
259
260void gicd_clr_igroupr(uintptr_t base, unsigned int id)
261{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100262 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100263 unsigned int reg_val = gicd_read_igroupr(base, id);
264
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100265 gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100266}
267
268void gicd_set_isenabler(uintptr_t base, unsigned int id)
269{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100270 unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100271
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100272 gicd_write_isenabler(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100273}
274
275void gicd_set_icenabler(uintptr_t base, unsigned int id)
276{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100277 unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100278
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100279 gicd_write_icenabler(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100280}
281
282void gicd_set_ispendr(uintptr_t base, unsigned int id)
283{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100284 unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100285
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100286 gicd_write_ispendr(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100287}
288
289void gicd_set_icpendr(uintptr_t base, unsigned int id)
290{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100291 unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100292
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100293 gicd_write_icpendr(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100294}
295
Jeenu Viswambharan24e70292017-09-22 08:32:09 +0100296unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
297{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100298 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
Jeenu Viswambharan24e70292017-09-22 08:32:09 +0100299 unsigned int reg_val = gicd_read_isactiver(base, id);
300
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100301 return (reg_val >> bit_num) & 0x1U;
Jeenu Viswambharan24e70292017-09-22 08:32:09 +0100302}
303
Achin Gupta92712a52015-09-03 14:18:02 +0100304void gicd_set_isactiver(uintptr_t base, unsigned int id)
305{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100306 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100307
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100308 gicd_write_isactiver(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100309}
310
311void gicd_set_icactiver(uintptr_t base, unsigned int id)
312{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100313 unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
Achin Gupta92712a52015-09-03 14:18:02 +0100314
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100315 gicd_write_icactiver(base, id, (1U << bit_num));
Achin Gupta92712a52015-09-03 14:18:02 +0100316}
Soby Mathew421259e2016-01-15 14:20:57 +0000317
318void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
319{
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100320 uint8_t val = pri & GIC_PRI_MASK;
321
322 mmio_write_8(base + GICD_IPRIORITYR + id, val);
Soby Mathew421259e2016-01-15 14:20:57 +0000323}
Jeenu Viswambharan4684bce2017-09-22 08:32:09 +0100324
325void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
326{
Jeenu Viswambharanb6982c02018-03-22 08:57:52 +0000327 /* Interrupt configuration is a 2-bit field */
Antonio Nino Diazca994e72018-08-21 10:02:33 +0100328 unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
Jeenu Viswambharanb6982c02018-03-22 08:57:52 +0000329 unsigned int bit_shift = bit_num << 1;
330
Jeenu Viswambharan4684bce2017-09-22 08:32:09 +0100331 uint32_t reg_val = gicd_read_icfgr(base, id);
332
333 /* Clear the field, and insert required configuration */
Jeenu Viswambharanb6982c02018-03-22 08:57:52 +0000334 reg_val &= ~(GIC_CFG_MASK << bit_shift);
335 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
Jeenu Viswambharan4684bce2017-09-22 08:32:09 +0100336
337 gicd_write_icfgr(base, id, reg_val);
338}