blob: 2f3f7f8dca8289f2ffdfd0ab4ab01da7531544f3 [file] [log] [blame]
Alexei Fedorovcaa18022020-07-14 10:47:25 +01001/*
2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
8
9#include <drivers/arm/gic_common.h>
10#include <lib/mmio.h>
Nithin Ga80ea272024-04-23 12:41:00 +053011#include <lib/utils_def.h>
Alexei Fedorovcaa18022020-07-14 10:47:25 +010012
13#include "../common/gic_common_private.h"
14
15/*******************************************************************************
16 * GIC Distributor interface accessors for reading entire registers
17 ******************************************************************************/
18/*
19 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
20 * `id`, 32 interrupt ids at a time.
21 */
22unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
23{
24 unsigned int n = id >> IGROUPR_SHIFT;
25
26 return mmio_read_32(base + GICD_IGROUPR + (n << 2));
27}
28
29/*
30 * Accessor to read the GIC Distributor ISENABLER corresponding to the
31 * interrupt `id`, 32 interrupt ids at a time.
32 */
33unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
34{
35 unsigned int n = id >> ISENABLER_SHIFT;
36
37 return mmio_read_32(base + GICD_ISENABLER + (n << 2));
38}
39
40/*
41 * Accessor to read the GIC Distributor ICENABLER corresponding to the
42 * interrupt `id`, 32 interrupt IDs at a time.
43 */
44unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
45{
46 unsigned int n = id >> ICENABLER_SHIFT;
47
48 return mmio_read_32(base + GICD_ICENABLER + (n << 2));
49}
50
51/*
52 * Accessor to read the GIC Distributor ISPENDR corresponding to the
53 * interrupt `id`, 32 interrupt IDs at a time.
54 */
55unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
56{
57 unsigned int n = id >> ISPENDR_SHIFT;
58
59 return mmio_read_32(base + GICD_ISPENDR + (n << 2));
60}
61
62/*
63 * Accessor to read the GIC Distributor ICPENDR corresponding to the
64 * interrupt `id`, 32 interrupt IDs at a time.
65 */
66unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
67{
68 unsigned int n = id >> ICPENDR_SHIFT;
69
70 return mmio_read_32(base + GICD_ICPENDR + (n << 2));
71}
72
73/*
74 * Accessor to read the GIC Distributor ISACTIVER corresponding to the
75 * interrupt `id`, 32 interrupt IDs at a time.
76 */
77unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
78{
79 unsigned int n = id >> ISACTIVER_SHIFT;
80
81 return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
82}
83
84/*
85 * Accessor to read the GIC Distributor ICACTIVER corresponding to the
86 * interrupt `id`, 32 interrupt IDs at a time.
87 */
88unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
89{
90 unsigned int n = id >> ICACTIVER_SHIFT;
91
92 return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
93}
94
95/*
96 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
97 * interrupt `id`, 4 interrupt IDs at a time.
98 */
99unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
100{
101 unsigned int n = id >> IPRIORITYR_SHIFT;
102
103 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
104}
105
106/*
107 * Accessor to read the GIC Distributor ICGFR corresponding to the
108 * interrupt `id`, 16 interrupt IDs at a time.
109 */
110unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
111{
112 unsigned int n = id >> ICFGR_SHIFT;
113
114 return mmio_read_32(base + GICD_ICFGR + (n << 2));
115}
116
117/*
118 * Accessor to read the GIC Distributor NSACR corresponding to the
119 * interrupt `id`, 16 interrupt IDs at a time.
120 */
121unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
122{
123 unsigned int n = id >> NSACR_SHIFT;
124
125 return mmio_read_32(base + GICD_NSACR + (n << 2));
126}
127
128/*******************************************************************************
129 * GIC Distributor interface accessors for writing entire registers
130 ******************************************************************************/
131/*
132 * Accessor to write the GIC Distributor IGROUPR corresponding to the
133 * interrupt `id`, 32 interrupt IDs at a time.
134 */
135void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
136{
137 unsigned int n = id >> IGROUPR_SHIFT;
138
139 mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
140}
141
142/*
143 * Accessor to write the GIC Distributor ISENABLER corresponding to the
144 * interrupt `id`, 32 interrupt IDs at a time.
145 */
146void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
147{
148 unsigned int n = id >> ISENABLER_SHIFT;
149
150 mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
151}
152
153/*
154 * Accessor to write the GIC Distributor ICENABLER corresponding to the
155 * interrupt `id`, 32 interrupt IDs at a time.
156 */
157void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
158{
159 unsigned int n = id >> ICENABLER_SHIFT;
160
161 mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
162}
163
164/*
165 * Accessor to write the GIC Distributor ISPENDR corresponding to the
166 * interrupt `id`, 32 interrupt IDs at a time.
167 */
168void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
169{
170 unsigned int n = id >> ISPENDR_SHIFT;
171
172 mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
173}
174
175/*
176 * Accessor to write the GIC Distributor ICPENDR corresponding to the
177 * interrupt `id`, 32 interrupt IDs at a time.
178 */
179void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
180{
181 unsigned int n = id >> ICPENDR_SHIFT;
182
183 mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
184}
185
186/*
187 * Accessor to write the GIC Distributor ISACTIVER corresponding to the
188 * interrupt `id`, 32 interrupt IDs at a time.
189 */
190void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
191{
192 unsigned int n = id >> ISACTIVER_SHIFT;
193
194 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
195}
196
197/*
198 * Accessor to write the GIC Distributor ICACTIVER corresponding to the
199 * interrupt `id`, 32 interrupt IDs at a time.
200 */
201void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
202{
203 unsigned int n = id >> ICACTIVER_SHIFT;
204
205 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
206}
207
208/*
209 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
210 * interrupt `id`, 4 interrupt IDs at a time.
211 */
212void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
213{
214 unsigned int n = id >> IPRIORITYR_SHIFT;
215
216 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
217}
218
219/*
220 * Accessor to write the GIC Distributor ICFGR corresponding to the
221 * interrupt `id`, 16 interrupt IDs at a time.
222 */
223void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
224{
225 unsigned int n = id >> ICFGR_SHIFT;
226
227 mmio_write_32(base + GICD_ICFGR + (n << 2), val);
228}
229
230/*
231 * Accessor to write the GIC Distributor NSACR corresponding to the
232 * interrupt `id`, 16 interrupt IDs at a time.
233 */
234void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
235{
236 unsigned int n = id >> NSACR_SHIFT;
237
238 mmio_write_32(base + GICD_NSACR + (n << 2), val);
239}
240
241/*******************************************************************************
242 * GIC Distributor functions for accessing the GIC registers
243 * corresponding to a single interrupt ID. These functions use bitwise
244 * operations or appropriate register accesses to modify or return
245 * the bit-field corresponding the single interrupt ID.
246 ******************************************************************************/
247unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
248{
249 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
250 unsigned int reg_val = gicd_read_igroupr(base, id);
251
252 return (reg_val >> bit_num) & 0x1U;
253}
254
255void gicd_set_igroupr(uintptr_t base, unsigned int id)
256{
257 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
258 unsigned int reg_val = gicd_read_igroupr(base, id);
259
Nithin Ga80ea272024-04-23 12:41:00 +0530260 gicd_write_igroupr(base, id, reg_val | BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100261}
262
263void gicd_clr_igroupr(uintptr_t base, unsigned int id)
264{
265 unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
266 unsigned int reg_val = gicd_read_igroupr(base, id);
267
Nithin Ga80ea272024-04-23 12:41:00 +0530268 gicd_write_igroupr(base, id, reg_val & ~BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100269}
270
271void gicd_set_isenabler(uintptr_t base, unsigned int id)
272{
273 unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
274
Nithin Ga80ea272024-04-23 12:41:00 +0530275 gicd_write_isenabler(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100276}
277
278void gicd_set_icenabler(uintptr_t base, unsigned int id)
279{
280 unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
281
Nithin Ga80ea272024-04-23 12:41:00 +0530282 gicd_write_icenabler(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100283}
284
285void gicd_set_ispendr(uintptr_t base, unsigned int id)
286{
287 unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
288
Nithin Ga80ea272024-04-23 12:41:00 +0530289 gicd_write_ispendr(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100290}
291
292void gicd_set_icpendr(uintptr_t base, unsigned int id)
293{
294 unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
295
Nithin Ga80ea272024-04-23 12:41:00 +0530296 gicd_write_icpendr(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100297}
298
299unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
300{
301 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
302 unsigned int reg_val = gicd_read_isactiver(base, id);
303
304 return (reg_val >> bit_num) & 0x1U;
305}
306
307void gicd_set_isactiver(uintptr_t base, unsigned int id)
308{
309 unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
310
Nithin Ga80ea272024-04-23 12:41:00 +0530311 gicd_write_isactiver(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100312}
313
314void gicd_set_icactiver(uintptr_t base, unsigned int id)
315{
316 unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
317
Nithin Ga80ea272024-04-23 12:41:00 +0530318 gicd_write_icactiver(base, id, BIT_32(bit_num));
Alexei Fedorovcaa18022020-07-14 10:47:25 +0100319}
320
321void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
322{
323 uint8_t val = pri & GIC_PRI_MASK;
324
325 mmio_write_8(base + GICD_IPRIORITYR + id, val);
326}
327
328void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
329{
330 /* Interrupt configuration is a 2-bit field */
331 unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
332 unsigned int bit_shift = bit_num << 1;
333
334 uint32_t reg_val = gicd_read_icfgr(base, id);
335
336 /* Clear the field, and insert required configuration */
337 reg_val &= ~(GIC_CFG_MASK << bit_shift);
338 reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
339
340 gicd_write_icfgr(base, id, reg_val);
341}