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