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