Line data Source code
1 1 : /*
2 : * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Driver for ARM Generic Interrupt Controller
10 : *
11 : * The Generic Interrupt Controller (GIC) is the default interrupt controller
12 : * for the ARM A and R profile cores. This driver is used by the ARM arch
13 : * implementation to handle interrupts.
14 : */
15 :
16 : #ifndef ZEPHYR_INCLUDE_DRIVERS_GIC_H_
17 : #define ZEPHYR_INCLUDE_DRIVERS_GIC_H_
18 :
19 : /*
20 : * GIC Register Interface Base Addresses
21 : */
22 :
23 0 : #define GIC_DIST_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0)
24 0 : #define GIC_CPU_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1)
25 :
26 : /*
27 : * GIC Distributor Interface
28 : */
29 :
30 : /*
31 : * 0x000 Distributor Control Register
32 : * v1 ICDDCR
33 : * v2/v3 GICD_CTLR
34 : */
35 0 : #define GICD_CTLR (GIC_DIST_BASE + 0x0)
36 :
37 : /*
38 : * 0x004 Interrupt Controller Type Register
39 : * v1 ICDICTR
40 : * v2/v3 GICD_TYPER
41 : */
42 0 : #define GICD_TYPER (GIC_DIST_BASE + 0x4)
43 :
44 : /*
45 : * 0x008 Distributor Implementer Identification Register
46 : * v1 ICDIIDR
47 : * v2/v3 GICD_IIDR
48 : */
49 0 : #define GICD_IIDR (GIC_DIST_BASE + 0x8)
50 :
51 : /*
52 : * 0x080 Interrupt Group Registers
53 : * v1 ICDISRn
54 : * v2/v3 GICD_IGROUPRn
55 : */
56 0 : #define GICD_IGROUPRn (GIC_DIST_BASE + 0x80)
57 :
58 : /*
59 : * 0x100 Interrupt Set-Enable Registers
60 : * v1 ICDISERn
61 : * v2/v3 GICD_ISENABLERn
62 : */
63 0 : #define GICD_ISENABLERn (GIC_DIST_BASE + 0x100)
64 :
65 : /*
66 : * 0x180 Interrupt Clear-Enable Registers
67 : * v1 ICDICERn
68 : * v2/v3 GICD_ICENABLERn
69 : */
70 0 : #define GICD_ICENABLERn (GIC_DIST_BASE + 0x180)
71 :
72 : /*
73 : * 0x200 Interrupt Set-Pending Registers
74 : * v1 ICDISPRn
75 : * v2/v3 GICD_ISPENDRn
76 : */
77 0 : #define GICD_ISPENDRn (GIC_DIST_BASE + 0x200)
78 :
79 : /*
80 : * 0x280 Interrupt Clear-Pending Registers
81 : * v1 ICDICPRn
82 : * v2/v3 GICD_ICPENDRn
83 : */
84 0 : #define GICD_ICPENDRn (GIC_DIST_BASE + 0x280)
85 :
86 : /*
87 : * 0x300 Interrupt Set-Active Registers
88 : * v1 ICDABRn
89 : * v2/v3 GICD_ISACTIVERn
90 : */
91 0 : #define GICD_ISACTIVERn (GIC_DIST_BASE + 0x300)
92 :
93 : #if CONFIG_GIC_VER >= 2
94 : /*
95 : * 0x380 Interrupt Clear-Active Registers
96 : * v2/v3 GICD_ICACTIVERn
97 : */
98 : #define GICD_ICACTIVERn (GIC_DIST_BASE + 0x380)
99 : #endif
100 :
101 : /*
102 : * 0x400 Interrupt Priority Registers
103 : * v1 ICDIPRn
104 : * v2/v3 GICD_IPRIORITYRn
105 : */
106 0 : #define GICD_IPRIORITYRn (GIC_DIST_BASE + 0x400)
107 :
108 : /*
109 : * 0x800 Interrupt Processor Targets Registers
110 : * v1 ICDIPTRn
111 : * v2/v3 GICD_ITARGETSRn
112 : */
113 0 : #define GICD_ITARGETSRn (GIC_DIST_BASE + 0x800)
114 :
115 : /*
116 : * 0xC00 Interrupt Configuration Registers
117 : * v1 ICDICRn
118 : * v2/v3 GICD_ICFGRn
119 : */
120 0 : #define GICD_ICFGRn (GIC_DIST_BASE + 0xc00)
121 :
122 : /*
123 : * 0xF00 Software Generated Interrupt Register
124 : * v1 ICDSGIR
125 : * v2/v3 GICD_SGIR
126 : */
127 0 : #define GICD_SGIR (GIC_DIST_BASE + 0xf00)
128 :
129 : /*
130 : * GIC CPU Interface
131 : */
132 :
133 : #if CONFIG_GIC_VER <= 2
134 :
135 : /*
136 : * 0x0000 CPU Interface Control Register
137 : * v1 ICCICR
138 : * v2/v3 GICC_CTLR
139 : */
140 0 : #define GICC_CTLR (GIC_CPU_BASE + 0x0)
141 :
142 : /*
143 : * 0x0004 Interrupt Priority Mask Register
144 : * v1 ICCPMR
145 : * v2/v3 GICC_PMR
146 : */
147 0 : #define GICC_PMR (GIC_CPU_BASE + 0x4)
148 :
149 : /*
150 : * 0x0008 Binary Point Register
151 : * v1 ICCBPR
152 : * v2/v3 GICC_BPR
153 : */
154 0 : #define GICC_BPR (GIC_CPU_BASE + 0x8)
155 :
156 : /*
157 : * 0x000C Interrupt Acknowledge Register
158 : * v1 ICCIAR
159 : * v2/v3 GICC_IAR
160 : */
161 0 : #define GICC_IAR (GIC_CPU_BASE + 0xc)
162 :
163 : /*
164 : * 0x0010 End of Interrupt Register
165 : * v1 ICCEOIR
166 : * v2/v3 GICC_EOIR
167 : */
168 0 : #define GICC_EOIR (GIC_CPU_BASE + 0x10)
169 :
170 :
171 : /*
172 : * Helper Constants
173 : */
174 :
175 : /* GICC_CTLR */
176 0 : #define GICC_CTLR_ENABLEGRP0 BIT(0)
177 0 : #define GICC_CTLR_ENABLEGRP1 BIT(1)
178 :
179 0 : #define GICC_CTLR_ENABLE_MASK (GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1)
180 :
181 : #if defined(CONFIG_GIC_V2)
182 :
183 : #define GICC_CTLR_FIQBYPDISGRP0 BIT(5)
184 : #define GICC_CTLR_IRQBYPDISGRP0 BIT(6)
185 : #define GICC_CTLR_FIQBYPDISGRP1 BIT(7)
186 : #define GICC_CTLR_IRQBYPDISGRP1 BIT(8)
187 :
188 : #define GICC_CTLR_BYPASS_MASK (GICC_CTLR_FIQBYPDISGRP0 | \
189 : GICC_CTLR_IRQBYPDISGRP1 | \
190 : GICC_CTLR_FIQBYPDISGRP1 | \
191 : GICC_CTLR_IRQBYPDISGRP1)
192 :
193 : #endif /* CONFIG_GIC_V2 */
194 :
195 : /* GICD_SGIR */
196 0 : #define GICD_SGIR_TGTFILT(x) ((x) << 24)
197 0 : #define GICD_SGIR_TGTFILT_CPULIST GICD_SGIR_TGTFILT(0b00)
198 0 : #define GICD_SGIR_TGTFILT_ALLBUTREQ GICD_SGIR_TGTFILT(0b01)
199 0 : #define GICD_SGIR_TGTFILT_REQONLY GICD_SGIR_TGTFILT(0b10)
200 :
201 0 : #define GICD_SGIR_CPULIST(x) ((x) << 16)
202 0 : #define GICD_SGIR_CPULIST_CPU(n) GICD_SGIR_CPULIST(BIT(n))
203 0 : #define GICD_SGIR_CPULIST_MASK 0xff
204 :
205 0 : #define GICD_SGIR_NSATT BIT(15)
206 :
207 0 : #define GICD_SGIR_SGIINTID(x) (x)
208 :
209 : #endif /* CONFIG_GIC_VER <= 2 */
210 :
211 :
212 : /* GICD_ICFGR */
213 0 : #define GICD_ICFGR_MASK BIT_MASK(2)
214 0 : #define GICD_ICFGR_TYPE BIT(1)
215 :
216 : /* GICD_TYPER.ITLinesNumber 0:4 */
217 0 : #define GICD_TYPER_ITLINESNUM_MASK 0x1f
218 :
219 : /* GICD_TYPER.IDbits */
220 0 : #define GICD_TYPER_IDBITS(typer) ((((typer) >> 19) & 0x1f) + 1)
221 :
222 : /*
223 : * Common Helper Constants
224 : */
225 0 : #define GIC_SGI_INT_BASE 0
226 0 : #define GIC_PPI_INT_BASE 16
227 :
228 0 : #define GIC_IS_SGI(intid) (((intid) >= GIC_SGI_INT_BASE) && \
229 : ((intid) < GIC_PPI_INT_BASE))
230 :
231 :
232 0 : #define GIC_SPI_INT_BASE 32
233 :
234 0 : #define GIC_SPI_MAX_INTID 1019
235 :
236 0 : #define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && \
237 : ((intid) <= GIC_SPI_MAX_INTID))
238 :
239 0 : #define GIC_NUM_INTR_PER_REG 32
240 :
241 0 : #define GIC_NUM_CFG_PER_REG 16
242 :
243 0 : #define GIC_NUM_PRI_PER_REG 4
244 :
245 : /* GIC idle priority : value '0xff' will allow all interrupts */
246 0 : #define GIC_IDLE_PRIO 0xff
247 :
248 : /* Priority levels 0:255 */
249 0 : #define GIC_PRI_MASK 0xff
250 :
251 : /*
252 : * '0xa0'is used to initialize each interrupt default priority.
253 : * This is an arbitrary value in current context.
254 : * Any value '0x80' to '0xff' will work for both NS and S state.
255 : * The values of individual interrupt and default has to be chosen
256 : * carefully if PMR and BPR based nesting and preemption has to be done.
257 : */
258 0 : #define GIC_INT_DEF_PRI_X4 0xa0a0a0a0
259 :
260 : /* GIC special interrupt id */
261 0 : #define GIC_INTID_SPURIOUS 1023
262 :
263 : /* Fixme: update from platform specific define or dt */
264 0 : #define GIC_NUM_CPU_IF CONFIG_MP_MAX_NUM_CPUS
265 :
266 : #ifndef _ASMLANGUAGE
267 :
268 : #include <zephyr/types.h>
269 : #include <zephyr/device.h>
270 :
271 : /*
272 : * GIC Driver Interface Functions
273 : */
274 :
275 : /**
276 : * @brief Enable interrupt
277 : *
278 : * @param irq interrupt ID
279 : */
280 1 : void arm_gic_irq_enable(unsigned int irq);
281 :
282 : /**
283 : * @brief Disable interrupt
284 : *
285 : * @param irq interrupt ID
286 : */
287 1 : void arm_gic_irq_disable(unsigned int irq);
288 :
289 : /**
290 : * @brief Check if an interrupt is enabled
291 : *
292 : * @param irq interrupt ID
293 : * @return Returns true if interrupt is enabled, false otherwise
294 : */
295 1 : bool arm_gic_irq_is_enabled(unsigned int irq);
296 :
297 : /**
298 : * @brief Check if an interrupt is pending
299 : *
300 : * @param irq interrupt ID
301 : * @return Returns true if interrupt is pending, false otherwise
302 : */
303 1 : bool arm_gic_irq_is_pending(unsigned int irq);
304 :
305 : /**
306 : * @brief Set interrupt as pending
307 : *
308 : * @param irq interrupt ID
309 : */
310 1 : void arm_gic_irq_set_pending(unsigned int irq);
311 :
312 : /**
313 : * @brief Clear the pending irq
314 : *
315 : * @param irq interrupt ID
316 : */
317 1 : void arm_gic_irq_clear_pending(unsigned int irq);
318 :
319 : /**
320 : * @brief Set interrupt priority
321 : *
322 : * @param irq interrupt ID
323 : * @param prio interrupt priority
324 : * @param flags interrupt flags
325 : */
326 1 : void arm_gic_irq_set_priority(
327 : unsigned int irq, unsigned int prio, unsigned int flags);
328 :
329 : /**
330 : * @brief Get active interrupt ID
331 : *
332 : * @return Returns the ID of an active interrupt
333 : */
334 1 : unsigned int arm_gic_get_active(void);
335 :
336 : /**
337 : * @brief Signal end-of-interrupt
338 : *
339 : * @param irq interrupt ID
340 : */
341 1 : void arm_gic_eoi(unsigned int irq);
342 :
343 : #ifdef CONFIG_SMP
344 : /**
345 : * @brief Initialize GIC of secondary cores
346 : */
347 1 : void arm_gic_secondary_init(void);
348 : #endif
349 :
350 : /**
351 : * @brief raise SGI to target cores
352 : *
353 : * @param sgi_id SGI ID 0 to 15
354 : * @param target_aff target affinity in mpidr form.
355 : * Aff level 1 2 3 will be extracted by api.
356 : * @param target_list bitmask of target cores
357 : */
358 1 : void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
359 : uint16_t target_list);
360 :
361 : #endif /* !_ASMLANGUAGE */
362 :
363 : #endif /* ZEPHYR_INCLUDE_DRIVERS_GIC_H_ */
|