gic_common.c 9.4 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
3
 *
dp-arm's avatar
dp-arm committed
4
 * SPDX-License-Identifier: BSD-3-Clause
5
6
 */

7
8
#pragma message __FILE__ " is deprecated, use gicv2.mk instead"

9
#include <assert.h>
10
11
12
13

#include <drivers/arm/gic_common.h>
#include <lib/mmio.h>

14
#include "gic_common_private.h"
15
16
17
18
19
20
21
22
23
24

/*******************************************************************************
 * GIC Distributor interface accessors for reading entire registers
 ******************************************************************************/
/*
 * Accessor to read the GIC Distributor IGROUPR corresponding to the interrupt
 * `id`, 32 interrupt ids at a time.
 */
unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
25
26
	unsigned int n = id >> IGROUPR_SHIFT;

27
28
29
30
31
32
33
34
35
	return mmio_read_32(base + GICD_IGROUPR + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ISENABLER corresponding to the
 * interrupt `id`, 32 interrupt ids at a time.
 */
unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
36
37
	unsigned int n = id >> ISENABLER_SHIFT;

38
39
40
41
42
43
44
45
46
	return mmio_read_32(base + GICD_ISENABLER + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ICENABLER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
47
48
	unsigned int n = id >> ICENABLER_SHIFT;

49
50
51
52
53
54
55
56
57
	return mmio_read_32(base + GICD_ICENABLER + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ISPENDR corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
58
59
	unsigned int n = id >> ISPENDR_SHIFT;

60
61
62
63
64
65
66
67
68
	return mmio_read_32(base + GICD_ISPENDR + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ICPENDR corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
69
70
	unsigned int n = id >> ICPENDR_SHIFT;

71
72
73
74
75
76
77
78
79
	return mmio_read_32(base + GICD_ICPENDR + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ISACTIVER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
80
81
	unsigned int n = id >> ISACTIVER_SHIFT;

82
83
84
85
86
87
88
89
90
	return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ICACTIVER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
91
92
	unsigned int n = id >> ICACTIVER_SHIFT;

93
94
95
96
97
98
99
100
101
	return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
}

/*
 * Accessor to read the GIC Distributor IPRIORITYR corresponding to the
 * interrupt `id`, 4 interrupt IDs at a time.
 */
unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
102
103
	unsigned int n = id >> IPRIORITYR_SHIFT;

104
105
106
107
108
109
110
111
112
	return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
}

/*
 * Accessor to read the GIC Distributor ICGFR corresponding to the
 * interrupt `id`, 16 interrupt IDs at a time.
 */
unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
113
114
	unsigned int n = id >> ICFGR_SHIFT;

115
116
117
118
119
120
121
122
123
	return mmio_read_32(base + GICD_ICFGR + (n << 2));
}

/*
 * Accessor to read the GIC Distributor NSACR corresponding to the
 * interrupt `id`, 16 interrupt IDs at a time.
 */
unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
124
125
	unsigned int n = id >> NSACR_SHIFT;

126
127
128
129
130
131
132
133
134
135
136
137
	return mmio_read_32(base + GICD_NSACR + (n << 2));
}

/*******************************************************************************
 * GIC Distributor interface accessors for writing entire registers
 ******************************************************************************/
/*
 * Accessor to write the GIC Distributor IGROUPR corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
138
139
	unsigned int n = id >> IGROUPR_SHIFT;

140
141
142
143
144
145
146
147
148
	mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ISENABLER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
149
150
	unsigned int n = id >> ISENABLER_SHIFT;

151
152
153
154
155
156
157
158
159
	mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ICENABLER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
160
161
	unsigned int n = id >> ICENABLER_SHIFT;

162
163
164
165
166
167
168
169
170
	mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ISPENDR corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
171
172
	unsigned int n = id >> ISPENDR_SHIFT;

173
174
175
176
177
178
179
180
181
	mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ICPENDR corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
182
183
	unsigned int n = id >> ICPENDR_SHIFT;

184
185
186
187
188
189
190
191
192
	mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ISACTIVER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
193
194
	unsigned int n = id >> ISACTIVER_SHIFT;

195
196
197
198
199
200
201
202
203
	mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ICACTIVER corresponding to the
 * interrupt `id`, 32 interrupt IDs at a time.
 */
void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
204
205
	unsigned int n = id >> ICACTIVER_SHIFT;

206
207
208
209
210
211
212
213
214
	mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor IPRIORITYR corresponding to the
 * interrupt `id`, 4 interrupt IDs at a time.
 */
void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
215
216
	unsigned int n = id >> IPRIORITYR_SHIFT;

217
218
219
220
221
222
223
224
225
	mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor ICFGR corresponding to the
 * interrupt `id`, 16 interrupt IDs at a time.
 */
void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
226
227
	unsigned int n = id >> ICFGR_SHIFT;

228
229
230
231
232
233
234
235
236
	mmio_write_32(base + GICD_ICFGR + (n << 2), val);
}

/*
 * Accessor to write the GIC Distributor NSACR corresponding to the
 * interrupt `id`, 16 interrupt IDs at a time.
 */
void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
237
238
	unsigned int n = id >> NSACR_SHIFT;

239
240
241
242
	mmio_write_32(base + GICD_NSACR + (n << 2), val);
}

/*******************************************************************************
243
244
245
246
 * GIC Distributor functions for accessing the GIC registers
 * corresponding to a single interrupt ID. These functions use bitwise
 * operations or appropriate register accesses to modify or return
 * the bit-field corresponding the single interrupt ID.
247
248
249
 ******************************************************************************/
unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
250
	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
251
252
	unsigned int reg_val = gicd_read_igroupr(base, id);

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
253
	return (reg_val >> bit_num) & 0x1U;
254
255
256
257
}

void gicd_set_igroupr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
258
	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
259
260
	unsigned int reg_val = gicd_read_igroupr(base, id);

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
261
	gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
262
263
264
265
}

void gicd_clr_igroupr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
266
	unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
267
268
	unsigned int reg_val = gicd_read_igroupr(base, id);

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
269
	gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
270
271
272
273
}

void gicd_set_isenabler(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
274
	unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
275

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
276
	gicd_write_isenabler(base, id, (1U << bit_num));
277
278
279
280
}

void gicd_set_icenabler(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
281
	unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
282

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
283
	gicd_write_icenabler(base, id, (1U << bit_num));
284
285
286
287
}

void gicd_set_ispendr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
288
	unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
289

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
290
	gicd_write_ispendr(base, id, (1U << bit_num));
291
292
293
294
}

void gicd_set_icpendr(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
295
	unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
296

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
297
	gicd_write_icpendr(base, id, (1U << bit_num));
298
299
}

300
301
unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
302
	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
303
304
	unsigned int reg_val = gicd_read_isactiver(base, id);

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
305
	return (reg_val >> bit_num) & 0x1U;
306
307
}

308
309
void gicd_set_isactiver(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
310
	unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
311

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
312
	gicd_write_isactiver(base, id, (1U << bit_num));
313
314
315
316
}

void gicd_set_icactiver(uintptr_t base, unsigned int id)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
317
	unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
318

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
319
	gicd_write_icactiver(base, id, (1U << bit_num));
320
}
321
322
323

void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
{
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
324
325
326
	uint8_t val = pri & GIC_PRI_MASK;

	mmio_write_8(base + GICD_IPRIORITYR + id, val);
327
}
328
329
330

void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
{
331
	/* Interrupt configuration is a 2-bit field */
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
332
	unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
333
334
	unsigned int bit_shift = bit_num << 1;

335
336
337
	uint32_t reg_val = gicd_read_icfgr(base, id);

	/* Clear the field, and insert required configuration */
338
339
	reg_val &= ~(GIC_CFG_MASK << bit_shift);
	reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift);
340
341
342

	gicd_write_icfgr(base, id, reg_val);
}