gicv3.h 15.1 KB
Newer Older
1
/*
Roberto Vargas's avatar
Roberto Vargas committed
2
 * Copyright (c) 2015-2018, 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
9
10
11
12
13
 */

#ifndef __GICV3_H__
#define __GICV3_H__

/*******************************************************************************
 * GICv3 miscellaneous definitions
 ******************************************************************************/
/* Interrupt group definitions */
14
15
16
#define INTR_GROUP1S		0
#define INTR_GROUP0		1
#define INTR_GROUP1NS		2
17
18
19
20
21
22
23
24

/* Interrupt IDs reported by the HPPIR and IAR registers */
#define PENDING_G1S_INTID	1020
#define PENDING_G1NS_INTID	1021

/* Constant to categorize LPI interrupt */
#define MIN_LPI_ID		8192

25
26
27
/* GICv3 can only target up to 16 PEs with SGI */
#define GICV3_MAX_SGI_TARGETS	16

28
29
30
31
32
33
34
35
36
/*******************************************************************************
 * GICv3 specific Distributor interface register offsets and constants.
 ******************************************************************************/
#define GICD_STATUSR		0x10
#define GICD_SETSPI_NSR		0x40
#define GICD_CLRSPI_NSR		0x48
#define GICD_SETSPI_SR		0x50
#define GICD_CLRSPI_SR		0x50
#define GICD_IGRPMODR		0xd00
37
38
39
40
41
/*
 * GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt id and
 * n >= 32, making the effective offset as 0x6100.
 */
#define GICD_IROUTER		0x6000
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#define GICD_PIDR2_GICV3	0xffe8

#define IGRPMODR_SHIFT		5

/* GICD_CTLR bit definitions */
#define CTLR_ENABLE_G1NS_SHIFT		1
#define CTLR_ENABLE_G1S_SHIFT		2
#define CTLR_ARE_S_SHIFT		4
#define CTLR_ARE_NS_SHIFT		5
#define CTLR_DS_SHIFT			6
#define CTLR_E1NWF_SHIFT		7
#define GICD_CTLR_RWP_SHIFT		31

#define CTLR_ENABLE_G1NS_MASK		0x1
#define CTLR_ENABLE_G1S_MASK		0x1
#define CTLR_ARE_S_MASK			0x1
#define CTLR_ARE_NS_MASK		0x1
#define CTLR_DS_MASK			0x1
#define CTLR_E1NWF_MASK			0x1
#define GICD_CTLR_RWP_MASK		0x1

#define CTLR_ENABLE_G1NS_BIT		(1 << CTLR_ENABLE_G1NS_SHIFT)
#define CTLR_ENABLE_G1S_BIT		(1 << CTLR_ENABLE_G1S_SHIFT)
#define CTLR_ARE_S_BIT			(1 << CTLR_ARE_S_SHIFT)
#define CTLR_ARE_NS_BIT			(1 << CTLR_ARE_NS_SHIFT)
#define CTLR_DS_BIT			(1 << CTLR_DS_SHIFT)
#define CTLR_E1NWF_BIT			(1 << CTLR_E1NWF_SHIFT)
#define GICD_CTLR_RWP_BIT		(1 << GICD_CTLR_RWP_SHIFT)

/* GICD_IROUTER shifts and masks */
72
#define IROUTER_SHIFT		0
73
74
75
#define IROUTER_IRM_SHIFT	31
#define IROUTER_IRM_MASK	0x1

76
77
78
#define GICV3_IRM_PE		0
#define GICV3_IRM_ANY		1

79
80
#define NUM_OF_DIST_REGS	30

81
82
83
84
85
86
87
88
/*******************************************************************************
 * GICv3 Re-distributor interface registers & constants
 ******************************************************************************/
#define GICR_PCPUBASE_SHIFT	0x11
#define GICR_SGIBASE_OFFSET	(1 << 0x10)	/* 64 KB */
#define GICR_CTLR		0x0
#define GICR_TYPER		0x08
#define GICR_WAKER		0x14
89
90
#define GICR_PROPBASER		0x70
#define GICR_PENDBASER		0x78
91
92
93
#define GICR_IGROUPR0		(GICR_SGIBASE_OFFSET + 0x80)
#define GICR_ISENABLER0		(GICR_SGIBASE_OFFSET + 0x100)
#define GICR_ICENABLER0		(GICR_SGIBASE_OFFSET + 0x180)
94
95
96
97
#define GICR_ISPENDR0		(GICR_SGIBASE_OFFSET + 0x200)
#define GICR_ICPENDR0		(GICR_SGIBASE_OFFSET + 0x280)
#define GICR_ISACTIVER0		(GICR_SGIBASE_OFFSET + 0x300)
#define GICR_ICACTIVER0		(GICR_SGIBASE_OFFSET + 0x380)
98
99
100
101
#define GICR_IPRIORITYR		(GICR_SGIBASE_OFFSET + 0x400)
#define GICR_ICFGR0		(GICR_SGIBASE_OFFSET + 0xc00)
#define GICR_ICFGR1		(GICR_SGIBASE_OFFSET + 0xc04)
#define GICR_IGRPMODR0		(GICR_SGIBASE_OFFSET + 0xd00)
102
#define GICR_NSACR		(GICR_SGIBASE_OFFSET + 0xe00)
103
104

/* GICR_CTLR bit definitions */
105
106
107
#define GICR_CTLR_UWP_SHIFT	31
#define GICR_CTLR_UWP_MASK	0x1
#define GICR_CTLR_UWP_BIT	(1U << GICR_CTLR_UWP_SHIFT)
108
109
#define GICR_CTLR_RWP_SHIFT	3
#define GICR_CTLR_RWP_MASK	0x1
110
111
#define GICR_CTLR_RWP_BIT	(1U << GICR_CTLR_RWP_SHIFT)
#define GICR_CTLR_EN_LPIS_BIT	(1U << 0)
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

/* GICR_WAKER bit definitions */
#define WAKER_CA_SHIFT		2
#define WAKER_PS_SHIFT		1

#define WAKER_CA_MASK		0x1
#define WAKER_PS_MASK		0x1

#define WAKER_CA_BIT		(1 << WAKER_CA_SHIFT)
#define WAKER_PS_BIT		(1 << WAKER_PS_SHIFT)

/* GICR_TYPER bit definitions */
#define TYPER_AFF_VAL_SHIFT	32
#define TYPER_PROC_NUM_SHIFT	8
#define TYPER_LAST_SHIFT	4

#define TYPER_AFF_VAL_MASK	0xffffffff
#define TYPER_PROC_NUM_MASK	0xffff
#define TYPER_LAST_MASK		0x1

#define TYPER_LAST_BIT		(1 << TYPER_LAST_SHIFT)

134
135
#define NUM_OF_REDIST_REGS	30

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*******************************************************************************
 * GICv3 CPU interface registers & constants
 ******************************************************************************/
/* ICC_SRE bit definitions*/
#define ICC_SRE_EN_BIT		(1 << 3)
#define ICC_SRE_DIB_BIT		(1 << 2)
#define ICC_SRE_DFB_BIT		(1 << 1)
#define ICC_SRE_SRE_BIT		(1 << 0)

/* ICC_IGRPEN1_EL3 bit definitions */
#define IGRPEN1_EL3_ENABLE_G1NS_SHIFT	0
#define IGRPEN1_EL3_ENABLE_G1S_SHIFT	1

#define IGRPEN1_EL3_ENABLE_G1NS_BIT	(1 << IGRPEN1_EL3_ENABLE_G1NS_SHIFT)
#define IGRPEN1_EL3_ENABLE_G1S_BIT	(1 << IGRPEN1_EL3_ENABLE_G1S_SHIFT)

/* ICC_IGRPEN0_EL1 bit definitions */
#define IGRPEN1_EL1_ENABLE_G0_SHIFT	0
#define IGRPEN1_EL1_ENABLE_G0_BIT	(1 << IGRPEN1_EL1_ENABLE_G0_SHIFT)

/* ICC_HPPIR0_EL1 bit definitions */
#define HPPIR0_EL1_INTID_SHIFT		0
#define HPPIR0_EL1_INTID_MASK		0xffffff

/* ICC_HPPIR1_EL1 bit definitions */
#define HPPIR1_EL1_INTID_SHIFT		0
#define HPPIR1_EL1_INTID_MASK		0xffffff

/* ICC_IAR0_EL1 bit definitions */
#define IAR0_EL1_INTID_SHIFT		0
#define IAR0_EL1_INTID_MASK		0xffffff

/* ICC_IAR1_EL1 bit definitions */
#define IAR1_EL1_INTID_SHIFT		0
#define IAR1_EL1_INTID_MASK		0xffffff

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/* ICC SGI macros */
#define SGIR_TGT_MASK			0xffff
#define SGIR_AFF1_SHIFT			16
#define SGIR_INTID_SHIFT		24
#define SGIR_INTID_MASK			0xf
#define SGIR_AFF2_SHIFT			32
#define SGIR_IRM_SHIFT			40
#define SGIR_IRM_MASK			0x1
#define SGIR_AFF3_SHIFT			48
#define SGIR_AFF_MASK			0xf

#define SGIR_IRM_TO_AFF			0

#define GICV3_SGIR_VALUE(aff3, aff2, aff1, intid, irm, tgt) \
	((((uint64_t) (aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \
	 (((uint64_t) (irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \
	 (((uint64_t) (aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \
	 (((intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \
	 (((aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
	 ((tgt) & SGIR_TGT_MASK))

193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*****************************************************************************
 * GICv3 ITS registers and constants
 *****************************************************************************/

#define GITS_CTLR			0x0
#define GITS_IIDR			0x4
#define GITS_TYPER			0x8
#define GITS_CBASER			0x80
#define GITS_CWRITER			0x88
#define GITS_CREADR			0x90
#define GITS_BASER			0x100

/* GITS_CTLR bit definitions */
#define GITS_CTLR_ENABLED_BIT		1
#define GITS_CTLR_QUIESCENT_SHIFT	31
#define GITS_CTLR_QUIESCENT_BIT		(1U << GITS_CTLR_QUIESCENT_SHIFT)

210
211
#ifndef __ASSEMBLY__

212
#include <gic_common.h>
213
#include <interrupt_props.h>
214
#include <stdint.h>
215
#include <types.h>
216
#include <utils_def.h>
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

#define gicv3_is_intr_id_special_identifier(id)	\
	(((id) >= PENDING_G1S_INTID) && ((id) <= GIC_SPURIOUS_INTERRUPT))

/*******************************************************************************
 * Helper GICv3 macros for SEL1
 ******************************************************************************/
#define gicv3_acknowledge_interrupt_sel1()	read_icc_iar1_el1() &\
							IAR1_EL1_INTID_MASK
#define gicv3_get_pending_interrupt_id_sel1()	read_icc_hppir1_el1() &\
							HPPIR1_EL1_INTID_MASK
#define gicv3_end_of_interrupt_sel1(id)		write_icc_eoir1_el1(id)


/*******************************************************************************
 * Helper GICv3 macros for EL3
 ******************************************************************************/
#define gicv3_acknowledge_interrupt()		read_icc_iar0_el1() &\
							IAR0_EL1_INTID_MASK
#define gicv3_end_of_interrupt(id)		write_icc_eoir0_el1(id)

238
239
240
241
242
243
244
245
246
247
/*
 * This macro returns the total number of GICD registers corresponding to
 * the name.
 */
#define GICD_NUM_REGS(reg_name)	\
	DIV_ROUND_UP_2EVAL(TOTAL_SPI_INTR_NUM, (1 << reg_name ## _SHIFT))

#define GICR_NUM_REGS(reg_name)	\
	DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT))

248
249
250
/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
#define INT_ID_MASK	0xffffff

251
252
253
254
255
/*******************************************************************************
 * This structure describes some of the implementation defined attributes of the
 * GICv3 IP. It is used by the platform port to specify these attributes in order
 * to initialise the GICV3 driver. The attributes are described below.
 *
256
257
258
259
260
261
262
263
264
 * The 'gicd_base' field contains the base address of the Distributor interface
 * programmer's view.
 *
 * The 'gicr_base' field contains the base address of the Re-distributor
 * interface programmer's view.
 *
 * The 'g0_interrupt_array' field is a pointer to an array in which each entry
 * corresponds to an ID of a Group 0 interrupt. This field is ignored when
 * 'interrupt_props' field is used. This field is deprecated.
265
 *
266
267
268
 * The 'g0_interrupt_num' field contains the number of entries in the
 * 'g0_interrupt_array'. This field is ignored when 'interrupt_props' field is
 * used. This field is deprecated.
269
 *
270
271
272
 * The 'g1s_interrupt_array' field is a pointer to an array in which each entry
 * corresponds to an ID of a Group 1 interrupt. This field is ignored when
 * 'interrupt_props' field is used. This field is deprecated.
273
 *
274
275
276
277
 * The 'g1s_interrupt_num' field contains the number of entries in the
 * 'g1s_interrupt_array'. This field must be 0 if 'interrupt_props' field is
 * used. This field is ignored when 'interrupt_props' field is used. This field
 * is deprecated.
278
 *
279
280
281
 * The 'interrupt_props' field is a pointer to an array that enumerates secure
 * interrupts and their properties. If this field is not NULL, both
 * 'g0_interrupt_array' and 'g1s_interrupt_array' fields are ignored.
282
 *
283
284
285
 * The 'interrupt_props_num' field contains the number of entries in the
 * 'interrupt_props' array. If this field is non-zero, both 'g0_interrupt_num'
 * and 'g1s_interrupt_num' are ignored.
286
 *
287
288
289
 * The 'rdistif_num' field contains the number of Redistributor interfaces the
 * GIC implements. This is equal to the number of CPUs or CPU interfaces
 * instantiated in the GIC.
290
 *
291
292
293
294
 * The 'rdistif_base_addrs' field is a pointer to an array that has an entry for
 * storing the base address of the Redistributor interface frame of each CPU in
 * the system. The size of the array = 'rdistif_num'. The base addresses are
 * detected during driver initialisation.
295
 *
296
297
298
299
300
301
302
303
304
305
 * The 'mpidr_to_core_pos' field is a pointer to a hash function which the
 * driver will use to convert an MPIDR value to a linear core index. This index
 * will be used for accessing the 'rdistif_base_addrs' array. This is an
 * optional field. A GICv3 implementation maps each MPIDR to a linear core index
 * as well. This mapping can be found by reading the "Affinity Value" and
 * "Processor Number" fields in the GICR_TYPER. It is IMP. DEF. if the
 * "Processor Numbers" are suitable to index into an array to access core
 * specific information. If this not the case, the platform port must provide a
 * hash function. Otherwise, the "Processor Number" field will be used to access
 * the array elements.
306
 ******************************************************************************/
307
typedef unsigned int (*mpidr_hash_fn)(u_register_t mpidr);
308
309
310
311

typedef struct gicv3_driver_data {
	uintptr_t gicd_base;
	uintptr_t gicr_base;
312
#if !ERROR_DEPRECATED
313
314
315
316
	unsigned int g0_interrupt_num __deprecated;
	unsigned int g1s_interrupt_num __deprecated;
	const unsigned int *g0_interrupt_array __deprecated;
	const unsigned int *g1s_interrupt_array __deprecated;
317
318
319
#endif
	const interrupt_prop_t *interrupt_props;
	unsigned int interrupt_props_num;
320
321
322
323
324
	unsigned int rdistif_num;
	uintptr_t *rdistif_base_addrs;
	mpidr_hash_fn mpidr_to_core_pos;
} gicv3_driver_data_t;

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
typedef struct gicv3_redist_ctx {
	/* 64 bits registers */
	uint64_t gicr_propbaser;
	uint64_t gicr_pendbaser;

	/* 32 bits registers */
	uint32_t gicr_ctlr;
	uint32_t gicr_igroupr0;
	uint32_t gicr_isenabler0;
	uint32_t gicr_ispendr0;
	uint32_t gicr_isactiver0;
	uint32_t gicr_ipriorityr[GICR_NUM_REGS(IPRIORITYR)];
	uint32_t gicr_icfgr0;
	uint32_t gicr_icfgr1;
	uint32_t gicr_igrpmodr0;
	uint32_t gicr_nsacr;
} gicv3_redist_ctx_t;

typedef struct gicv3_dist_ctx {
	/* 64 bits registers */
	uint64_t gicd_irouter[TOTAL_SPI_INTR_NUM];

	/* 32 bits registers */
	uint32_t gicd_ctlr;
	uint32_t gicd_igroupr[GICD_NUM_REGS(IGROUPR)];
	uint32_t gicd_isenabler[GICD_NUM_REGS(ISENABLER)];
	uint32_t gicd_ispendr[GICD_NUM_REGS(ISPENDR)];
	uint32_t gicd_isactiver[GICD_NUM_REGS(ISACTIVER)];
	uint32_t gicd_ipriorityr[GICD_NUM_REGS(IPRIORITYR)];
	uint32_t gicd_icfgr[GICD_NUM_REGS(ICFGR)];
	uint32_t gicd_igrpmodr[GICD_NUM_REGS(IGRPMODR)];
	uint32_t gicd_nsacr[GICD_NUM_REGS(NSACR)];
} gicv3_dist_ctx_t;

359
360
361
362
363
364
365
366
367
368
typedef struct gicv3_its_ctx {
	/* 64 bits registers */
	uint64_t gits_cbaser;
	uint64_t gits_cwriter;
	uint64_t gits_baser[8];

	/* 32 bits registers */
	uint32_t gits_ctlr;
} gicv3_its_ctx_t;

369
370
371
372
373
374
/*******************************************************************************
 * GICv3 EL3 driver API
 ******************************************************************************/
void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data);
void gicv3_distif_init(void);
void gicv3_rdistif_init(unsigned int proc_num);
375
376
void gicv3_rdistif_on(unsigned int proc_num);
void gicv3_rdistif_off(unsigned int proc_num);
377
378
379
380
381
382
void gicv3_cpuif_enable(unsigned int proc_num);
void gicv3_cpuif_disable(unsigned int proc_num);
unsigned int gicv3_get_pending_interrupt_type(void);
unsigned int gicv3_get_pending_interrupt_id(void);
unsigned int gicv3_get_interrupt_type(unsigned int id,
					  unsigned int proc_num);
383
384
385
386
387
388
389
390
391
392
393
394
void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx);
void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx);
/*
 * gicv3_distif_post_restore and gicv3_distif_pre_save must be implemented if
 * gicv3_distif_save and gicv3_rdistif_init_restore are used. If no
 * implementation-defined sequence is needed at these steps, an empty function
 * can be provided.
 */
void gicv3_distif_post_restore(unsigned int proc_num);
void gicv3_distif_pre_save(unsigned int proc_num);
void gicv3_rdistif_init_restore(unsigned int proc_num, const gicv3_redist_ctx_t * const rdist_ctx);
void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_ctx);
395
396
void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx);
void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx);
397

398
unsigned int gicv3_get_running_priority(void);
399
unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num);
400
401
void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num);
void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num);
402
403
void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
		unsigned int priority);
404
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
Roberto Vargas's avatar
Roberto Vargas committed
405
		unsigned int type);
406
void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target);
407
408
void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
		u_register_t mpidr);
409
410
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num);
411
unsigned int gicv3_set_pmr(unsigned int mask);
412

413
414
#endif /* __ASSEMBLY__ */
#endif /* __GICV3_H__ */