blob: 1b028b6e867b2c2738a77fcf86a63d495be1870b [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
2 * Copyright (c) 2018, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __GIC_V3_H__
8#define __GIC_V3_H__
9
10/***************************************************************************
11 * Defines and prototypes specific to GIC v3.
12 *************************************************************************/
13
14/* GICD register offsets */
15#define GICD_IROUTER 0x6000
16
17/* GICD_CTLR bit definitions */
18#define GICD_CTLR_ENABLE_GRP1A (1 << 1)
19#define GICD_CTLR_ARE_NS_SHIFT 4
20#define GICD_CTLR_ARE_NS_MASK 0x1
21
22/* GICR_TYPER bit definitions */
23#define TYPER_AFF_VAL_SHIFT 32
24#define TYPER_PROC_NUM_SHIFT 8
25#define TYPER_LAST_SHIFT 4
26
27#define TYPER_AFF_VAL_MASK 0xffffffff
28#define TYPER_PROC_NUM_MASK 0xffff
29#define TYPER_LAST_MASK 0x1
30
31#define TYPER_LAST_BIT (1 << TYPER_LAST_SHIFT)
32
33/* GICD_IROUTER shifts and masks */
34#define IROUTER_IRM_SHIFT 31
35#define IROUTER_IRM_MASK 0x1
36
37/*******************************************************************************
38 * GICv3 Re-distributor interface registers & constants
39 ******************************************************************************/
40#define GICR_PCPUBASE_SHIFT 0x11
41#define GICR_SGIBASE_OFFSET (1 << 0x10) /* 64 KB */
42#define GICR_CTLR 0x0
43#define GICR_TYPER 0x08
44#define GICR_WAKER 0x14
45#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + 0x80)
46#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + 0x100)
47#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + 0x180)
48#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + 0x200)
49#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + 0x280)
50#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + 0x400)
51#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + 0xc00)
52#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + 0xc04)
53#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + 0xd00)
54
55/*******************************************************************************
56 * GICv3 CPU interface registers & constants
57 ******************************************************************************/
58/* ICC_SRE bit definitions*/
59#define ICC_SRE_EN_BIT (1 << 3)
60#define ICC_SRE_DIB_BIT (1 << 2)
61#define ICC_SRE_DFB_BIT (1 << 1)
62#define ICC_SRE_SRE_BIT (1 << 0)
63
64/* ICC_IAR1_EL1 bit definitions */
65#define IAR1_EL1_INTID_SHIFT 0
66#define IAR1_EL1_INTID_MASK 0xffffff
67
68/* ICC_SGI1R bit definitions */
69#define SGI1R_TARGET_LIST_MASK 0xffff
70#define SGI1R_TARGET_LIST_SHIFT 0x0
71#define SGI1R_AFF_MASK 0xff
72#define SGI1R_AFF1_SHIFT 16ULL
73#define SGI1R_AFF2_SHIFT 32ULL
74#ifndef AARCH32
75#define SGI1R_AFF3_SHIFT 48ULL
76#endif
77#define SGI1R_INTID_MASK 0xf
78#define SGI1R_INTID_SHIFT 24
79#define SGI1R_IRM_MASK 0x1
80#define SGI1R_IRM_SHIFT 0x40
81
82/* ICC_IGRPEN1_EL1 bit definitions */
83#define IGRPEN1_EL1_ENABLE_SHIFT 0
84#define IGRPEN1_EL1_ENABLE_BIT (1 << IGRPEN1_EL1_ENABLE_SHIFT)
85
86/* The highest affinity 0 that can be a SGI target*/
87#define SGI_TARGET_MAX_AFF0 16
88
89#ifndef ASSEMBLY
90
91/*******************************************************************************
92 * Helper GICv3 macros
93 ******************************************************************************/
94#define gicv3_acknowledge_interrupt() read_icc_iar1_el1() &\
95 IAR1_EL1_INTID_MASK
96#define gicv3_end_of_interrupt(id) write_icc_eoir1_el1(id)
97
98#define is_sre_enabled() \
99 (IS_IN_EL2() ? (read_icc_sre_el2() & ICC_SRE_SRE_BIT) :\
100 (read_icc_sre_el1() & ICC_SRE_SRE_BIT))
101
102/******************************************************************************
103 * GICv3 public driver API
104 *****************************************************************************/
105 /*
106 * Initialize the GICv3 driver. The base addresses of GIC Re-distributor
107 * interface `gicr_base` and the Distributor interface `gicd_base` must
108 * be provided as arguments.
109 */
110void gicv3_init(uintptr_t gicr_base, uintptr_t gicd_base);
111
112/*
113 * Setup the GIC Distributor interface.
114 */
115void gicv3_setup_distif(void);
116
117/*
118 * Probe the Re-distributor base corresponding to this core.
119 * This function is required to be invoked on successful boot of a core.
120 * The base address will be stored internally by the driver and will be
121 * used when accessing the Re-distributor interface.
122 */
123void gicv3_probe_redistif_addr(void);
124
125/*
126 * Set the bit corresponding to `interrupt_id` in the ICPENDR register
127 * at either Distributor or Re-distributor depending on the interrupt.
128 */
129void gicv3_set_icpendr(unsigned int interrupt_id);
130
131/*
132 * Get the bit corresponding to `interrupt_id` in the ISPENDR register
133 * at either Distributor or Re-distributor depending on the interrupt.
134 */
135unsigned int gicv3_get_ispendr(unsigned int interrupt_id);
136
137/*
138 * Set the bit corresponding to `interrupt_id` in the ICENABLER register
139 * at either Distributor or Re-distributor depending on the interrupt.
140 */
141void gicv3_set_icenabler(unsigned int interrupt_id);
142
143/*
144 * Get the bit corresponding to `interrupt_id` in the ISENABLER register
145 * at either Distributor or Re-distributor depending on the interrupt.
146 */
147unsigned int gicv3_get_isenabler(unsigned int interrupt_id);
148
149/*
150 * Set the bit corresponding to `interrupt_id` in the ISENABLER register
151 * at either Distributor or Re-distributor depending on the interrupt.
152 */
153void gicv3_set_isenabler(unsigned int interrupt_id);
154
155/*
156 * Set the `route` corresponding to `interrupt_id` in the IROUTER register
157 * at Distributor.
158 */
159void gicv3_set_intr_route(unsigned int interrupt_id, unsigned int core_pos);
160
161/*
162 * Send SGI with ID `sgi_id` to core with index `core_pos`.
163 */
164void gicv3_send_sgi(unsigned int sgi_id, unsigned int core_pos);
165
166/*
167 * Get the priority of the interrupt `interrupt_id`.
168 */
169unsigned int gicv3_get_ipriorityr(unsigned int interrupt_id);
170
171/*
172 * Set the priority of the interrupt `interrupt_id` to `priority`.
173 */
174void gicv3_set_ipriorityr(unsigned int interrupt_id, unsigned int priority);
175
176/*
177 * Restore the GICv3 SGI and PPI context after powering up the
178 * GIC Re-distributor.
179 */
180void gicv3_restore_sgi_ppi_context(void);
181
182/*
183 * Save the GICv3 SGI and PPI context prior to powering down the
184 * GIC Re-distributor.
185 */
186void gicv3_save_sgi_ppi_context(void);
187
188/*
189 * Restore the GICv3 CPU interface after powering up the CPU interface.
190 */
191void gicv3_restore_cpuif_context(void);
192
193/*
194 * Save the GICv3 CPU interface prior to powering down the CPU interface.
195 */
196void gicv3_save_cpuif_context(void);
197
198/*
199 * Disable the GIC CPU interface.
200 */
201void gicv3_disable_cpuif(void);
202
203/*
204 * Setup the GIC CPU interface.
205 */
206void gicv3_setup_cpuif(void);
207
208/*
209 * Enable the GIC CPU interface.
210 */
211void gicv3_enable_cpuif(void);
212
213
214#endif /*__ASSEMBLY__*/
215#endif /* __GIC_V3_H__ */