blob: cfa0d23e76141999aa910f9dc6c54c915c8b7531 [file] [log] [blame]
Achin Gupta92712a52015-09-03 14:18:02 +01001/*
Soby Mathew421259e2016-01-15 14:20:57 +00002 * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
Achin Gupta92712a52015-09-03 14:18:02 +01003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <assert.h>
32#include <gic_common.h>
33#include <mmio.h>
Soby Mathew50f6fe42016-02-01 17:59:22 +000034#include "gic_common_private.h"
Achin Gupta92712a52015-09-03 14:18:02 +010035
36/*******************************************************************************
37 * GIC Distributor interface accessors for reading entire registers
38 ******************************************************************************/
39/*
40 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
41 * `id`, 32 interrupt ids at a time.
42 */
43unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
44{
45 unsigned n = id >> IGROUPR_SHIFT;
46 return mmio_read_32(base + GICD_IGROUPR + (n << 2));
47}
48
49/*
50 * Accessor to read the GIC Distributor ISENABLER corresponding to the
51 * interrupt `id`, 32 interrupt ids at a time.
52 */
53unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
54{
55 unsigned n = id >> ISENABLER_SHIFT;
56 return mmio_read_32(base + GICD_ISENABLER + (n << 2));
57}
58
59/*
60 * Accessor to read the GIC Distributor ICENABLER corresponding to the
61 * interrupt `id`, 32 interrupt IDs at a time.
62 */
63unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
64{
65 unsigned n = id >> ICENABLER_SHIFT;
66 return mmio_read_32(base + GICD_ICENABLER + (n << 2));
67}
68
69/*
70 * Accessor to read the GIC Distributor ISPENDR corresponding to the
71 * interrupt `id`, 32 interrupt IDs at a time.
72 */
73unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
74{
75 unsigned n = id >> ISPENDR_SHIFT;
76 return mmio_read_32(base + GICD_ISPENDR + (n << 2));
77}
78
79/*
80 * Accessor to read the GIC Distributor ICPENDR corresponding to the
81 * interrupt `id`, 32 interrupt IDs at a time.
82 */
83unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
84{
85 unsigned n = id >> ICPENDR_SHIFT;
86 return mmio_read_32(base + GICD_ICPENDR + (n << 2));
87}
88
89/*
90 * Accessor to read the GIC Distributor ISACTIVER corresponding to the
91 * interrupt `id`, 32 interrupt IDs at a time.
92 */
93unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
94{
95 unsigned n = id >> ISACTIVER_SHIFT;
96 return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
97}
98
99/*
100 * Accessor to read the GIC Distributor ICACTIVER corresponding to the
101 * interrupt `id`, 32 interrupt IDs at a time.
102 */
103unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
104{
105 unsigned n = id >> ICACTIVER_SHIFT;
106 return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
107}
108
109/*
110 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
111 * interrupt `id`, 4 interrupt IDs at a time.
112 */
113unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
114{
115 unsigned n = id >> IPRIORITYR_SHIFT;
116 return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
117}
118
119/*
120 * Accessor to read the GIC Distributor ICGFR corresponding to the
121 * interrupt `id`, 16 interrupt IDs at a time.
122 */
123unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
124{
125 unsigned n = id >> ICFGR_SHIFT;
126 return mmio_read_32(base + GICD_ICFGR + (n << 2));
127}
128
129/*
130 * Accessor to read the GIC Distributor NSACR corresponding to the
131 * interrupt `id`, 16 interrupt IDs at a time.
132 */
133unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
134{
135 unsigned n = id >> NSACR_SHIFT;
136 return mmio_read_32(base + GICD_NSACR + (n << 2));
137}
138
139/*******************************************************************************
140 * GIC Distributor interface accessors for writing entire registers
141 ******************************************************************************/
142/*
143 * Accessor to write the GIC Distributor IGROUPR corresponding to the
144 * interrupt `id`, 32 interrupt IDs at a time.
145 */
146void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
147{
148 unsigned n = id >> IGROUPR_SHIFT;
149 mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
150}
151
152/*
153 * Accessor to write the GIC Distributor ISENABLER corresponding to the
154 * interrupt `id`, 32 interrupt IDs at a time.
155 */
156void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
157{
158 unsigned n = id >> ISENABLER_SHIFT;
159 mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
160}
161
162/*
163 * Accessor to write the GIC Distributor ICENABLER corresponding to the
164 * interrupt `id`, 32 interrupt IDs at a time.
165 */
166void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
167{
168 unsigned n = id >> ICENABLER_SHIFT;
169 mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
170}
171
172/*
173 * Accessor to write the GIC Distributor ISPENDR corresponding to the
174 * interrupt `id`, 32 interrupt IDs at a time.
175 */
176void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
177{
178 unsigned n = id >> ISPENDR_SHIFT;
179 mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
180}
181
182/*
183 * Accessor to write the GIC Distributor ICPENDR corresponding to the
184 * interrupt `id`, 32 interrupt IDs at a time.
185 */
186void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
187{
188 unsigned n = id >> ICPENDR_SHIFT;
189 mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
190}
191
192/*
193 * Accessor to write the GIC Distributor ISACTIVER corresponding to the
194 * interrupt `id`, 32 interrupt IDs at a time.
195 */
196void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
197{
198 unsigned n = id >> ISACTIVER_SHIFT;
199 mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
200}
201
202/*
203 * Accessor to write the GIC Distributor ICACTIVER corresponding to the
204 * interrupt `id`, 32 interrupt IDs at a time.
205 */
206void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
207{
208 unsigned n = id >> ICACTIVER_SHIFT;
209 mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
210}
211
212/*
213 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
214 * interrupt `id`, 4 interrupt IDs at a time.
215 */
216void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
217{
218 unsigned n = id >> IPRIORITYR_SHIFT;
219 mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
220}
221
222/*
223 * Accessor to write the GIC Distributor ICFGR corresponding to the
224 * interrupt `id`, 16 interrupt IDs at a time.
225 */
226void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
227{
228 unsigned n = id >> ICFGR_SHIFT;
229 mmio_write_32(base + GICD_ICFGR + (n << 2), val);
230}
231
232/*
233 * Accessor to write the GIC Distributor NSACR corresponding to the
234 * interrupt `id`, 16 interrupt IDs at a time.
235 */
236void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
237{
238 unsigned n = id >> NSACR_SHIFT;
239 mmio_write_32(base + GICD_NSACR + (n << 2), val);
240}
241
242/*******************************************************************************
Soby Mathew50f6fe42016-02-01 17:59:22 +0000243 * GIC Distributor functions for accessing the GIC registers
244 * corresponding to a single interrupt ID. These functions use bitwise
245 * operations or appropriate register accesses to modify or return
246 * the bit-field corresponding the single interrupt ID.
Achin Gupta92712a52015-09-03 14:18:02 +0100247 ******************************************************************************/
248unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
249{
250 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
251 unsigned int reg_val = gicd_read_igroupr(base, id);
252
253 return (reg_val >> bit_num) & 0x1;
254}
255
256void gicd_set_igroupr(uintptr_t base, unsigned int id)
257{
258 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
259 unsigned int reg_val = gicd_read_igroupr(base, id);
260
261 gicd_write_igroupr(base, id, reg_val | (1 << bit_num));
262}
263
264void gicd_clr_igroupr(uintptr_t base, unsigned int id)
265{
266 unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
267 unsigned int reg_val = gicd_read_igroupr(base, id);
268
269 gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num));
270}
271
272void gicd_set_isenabler(uintptr_t base, unsigned int id)
273{
274 unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1);
275
276 gicd_write_isenabler(base, id, (1 << bit_num));
277}
278
279void gicd_set_icenabler(uintptr_t base, unsigned int id)
280{
281 unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
282
283 gicd_write_icenabler(base, id, (1 << bit_num));
284}
285
286void gicd_set_ispendr(uintptr_t base, unsigned int id)
287{
288 unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1);
289
290 gicd_write_ispendr(base, id, (1 << bit_num));
291}
292
293void gicd_set_icpendr(uintptr_t base, unsigned int id)
294{
295 unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1);
296
297 gicd_write_icpendr(base, id, (1 << bit_num));
298}
299
300void gicd_set_isactiver(uintptr_t base, unsigned int id)
301{
302 unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
303
304 gicd_write_isactiver(base, id, (1 << bit_num));
305}
306
307void gicd_set_icactiver(uintptr_t base, unsigned int id)
308{
309 unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1);
310
311 gicd_write_icactiver(base, id, (1 << bit_num));
312}
Soby Mathew421259e2016-01-15 14:20:57 +0000313
314void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
315{
316 mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK);
317}