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 : * 0x1000 Interrupt Group Registers for Extended SPI Range
60 : * v3.1 GICD_IGROUPRnE
61 : */
62 0 : #define GICD_IGROUPRnE (GIC_DIST_BASE + 0x1000)
63 :
64 : /*
65 : * 0x100 Interrupt Set-Enable Registers
66 : * v1 ICDISERn
67 : * v2/v3 GICD_ISENABLERn
68 : */
69 0 : #define GICD_ISENABLERn (GIC_DIST_BASE + 0x100)
70 :
71 : /*
72 : * 0x1200 Interrupt Set-Enable Registers for Extended SPI Range
73 : * v3.1 GICD_ISENABLERnE
74 : */
75 0 : #define GICD_ISENABLERnE (GIC_DIST_BASE + 0x1200)
76 :
77 : /*
78 : * 0x180 Interrupt Clear-Enable Registers
79 : * v1 ICDICERn
80 : * v2/v3 GICD_ICENABLERn
81 : */
82 0 : #define GICD_ICENABLERn (GIC_DIST_BASE + 0x180)
83 :
84 : /*
85 : * 0x1400 Interrupt Clear-Enable Registers for Extended SPI Range
86 : * v3.1 GICD_ICENABLERnE
87 : */
88 0 : #define GICD_ICENABLERnE (GIC_DIST_BASE + 0x1400)
89 :
90 : /*
91 : * 0x200 Interrupt Set-Pending Registers
92 : * v1 ICDISPRn
93 : * v2/v3 GICD_ISPENDRn
94 : */
95 0 : #define GICD_ISPENDRn (GIC_DIST_BASE + 0x200)
96 :
97 : /*
98 : * 1600 Interrupt Set-Pending Registers for Extended SPI Range
99 : * v3.1 GICD_ISPENDRnE
100 : */
101 0 : #define GICD_ISPENDRnE (GIC_DIST_BASE + 0x1600)
102 :
103 : /*
104 : * 0x280 Interrupt Clear-Pending Registers
105 : * v1 ICDICPRn
106 : * v2/v3 GICD_ICPENDRn
107 : */
108 0 : #define GICD_ICPENDRn (GIC_DIST_BASE + 0x280)
109 :
110 : /*
111 : * 0x1800 Interrupt Clear-Pending Registers for Extended SPI Range
112 : * v3.1 GICD_ICPENDRnE
113 : */
114 0 : #define GICD_ICPENDRnE (GIC_DIST_BASE + 0x1800)
115 :
116 : /*
117 : * 0x300 Interrupt Set-Active Registers
118 : * v1 ICDABRn
119 : * v2/v3 GICD_ISACTIVERn
120 : */
121 0 : #define GICD_ISACTIVERn (GIC_DIST_BASE + 0x300)
122 :
123 : /*
124 : * 0x1A00 Interrupt Set-Active Registers for Extended SPI Range
125 : * v3.1 GICD_ISACTIVERnE
126 : */
127 0 : #define GICD_ISACTIVERnE (GIC_DIST_BASE + 0x1A00)
128 :
129 : #if CONFIG_GIC_VER >= 2
130 : /*
131 : * 0x380 Interrupt Clear-Active Registers
132 : * v2/v3 GICD_ICACTIVERn
133 : */
134 : #define GICD_ICACTIVERn (GIC_DIST_BASE + 0x380)
135 :
136 : /*
137 : * 0x1C00 Interrupt Clear-Active Registers for Extended SPI Range
138 : * v3.1 GICD_ICACTIVERnE
139 : */
140 : #define GICD_ICACTIVERnE (GIC_DIST_BASE + 0x1C00)
141 : #endif
142 :
143 : /*
144 : * 0x400 Interrupt Priority Registers
145 : * v1 ICDIPRn
146 : * v2/v3 GICD_IPRIORITYRn
147 : */
148 0 : #define GICD_IPRIORITYRn (GIC_DIST_BASE + 0x400)
149 :
150 : /*
151 : * 0x2000 Interrupt Priority Registers for Extended SPI Range
152 : * v3.1 GICD_IPRIORITYRnE
153 : */
154 0 : #define GICD_IPRIORITYRnE (GIC_DIST_BASE + 0x2000)
155 :
156 : /*
157 : * 0x800 Interrupt Processor Targets Registers
158 : * v1 ICDIPTRn
159 : * v2/v3 GICD_ITARGETSRn
160 : */
161 0 : #define GICD_ITARGETSRn (GIC_DIST_BASE + 0x800)
162 :
163 : /*
164 : * 0xC00 Interrupt Configuration Registers
165 : * v1 ICDICRn
166 : * v2/v3 GICD_ICFGRn
167 : */
168 0 : #define GICD_ICFGRn (GIC_DIST_BASE + 0xc00)
169 :
170 : /*
171 : * 0x3000 Interrupt Configuration Registers for Extended SPI Range
172 : * v3.1 GICD_ICFGRnE
173 : */
174 0 : #define GICD_ICFGRnE (GIC_DIST_BASE + 0x3000)
175 :
176 : /*
177 : * 0xF00 Software Generated Interrupt Register
178 : * v1 ICDSGIR
179 : * v2/v3 GICD_SGIR
180 : */
181 0 : #define GICD_SGIR (GIC_DIST_BASE + 0xf00)
182 :
183 : /*
184 : * GIC CPU Interface
185 : */
186 :
187 : #if CONFIG_GIC_VER <= 2
188 :
189 : /*
190 : * 0x0000 CPU Interface Control Register
191 : * v1 ICCICR
192 : * v2/v3 GICC_CTLR
193 : */
194 0 : #define GICC_CTLR (GIC_CPU_BASE + 0x0)
195 :
196 : /*
197 : * 0x0004 Interrupt Priority Mask Register
198 : * v1 ICCPMR
199 : * v2/v3 GICC_PMR
200 : */
201 0 : #define GICC_PMR (GIC_CPU_BASE + 0x4)
202 :
203 : /*
204 : * 0x0008 Binary Point Register
205 : * v1 ICCBPR
206 : * v2/v3 GICC_BPR
207 : */
208 0 : #define GICC_BPR (GIC_CPU_BASE + 0x8)
209 :
210 : /*
211 : * 0x000C Interrupt Acknowledge Register
212 : * v1 ICCIAR
213 : * v2/v3 GICC_IAR
214 : */
215 0 : #define GICC_IAR (GIC_CPU_BASE + 0xc)
216 :
217 : /*
218 : * 0x0010 End of Interrupt Register
219 : * v1 ICCEOIR
220 : * v2/v3 GICC_EOIR
221 : */
222 0 : #define GICC_EOIR (GIC_CPU_BASE + 0x10)
223 :
224 : /*
225 : * Helper Constants
226 : */
227 :
228 : /* GICC_CTLR */
229 0 : #define GICC_CTLR_ENABLEGRP0 BIT(0)
230 0 : #define GICC_CTLR_ENABLEGRP1 BIT(1)
231 :
232 0 : #define GICC_CTLR_ENABLE_MASK (GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1)
233 :
234 : #if defined(CONFIG_GIC_V2)
235 :
236 : #define GICC_CTLR_FIQBYPDISGRP0 BIT(5)
237 : #define GICC_CTLR_IRQBYPDISGRP0 BIT(6)
238 : #define GICC_CTLR_FIQBYPDISGRP1 BIT(7)
239 : #define GICC_CTLR_IRQBYPDISGRP1 BIT(8)
240 :
241 : #define GICC_CTLR_BYPASS_MASK \
242 : (GICC_CTLR_FIQBYPDISGRP0 | GICC_CTLR_IRQBYPDISGRP1 | GICC_CTLR_FIQBYPDISGRP1 | \
243 : GICC_CTLR_IRQBYPDISGRP1)
244 :
245 : #endif /* CONFIG_GIC_V2 */
246 :
247 : /* GICD_SGIR */
248 0 : #define GICD_SGIR_TGTFILT(x) ((x) << 24)
249 0 : #define GICD_SGIR_TGTFILT_CPULIST GICD_SGIR_TGTFILT(0b00)
250 0 : #define GICD_SGIR_TGTFILT_ALLBUTREQ GICD_SGIR_TGTFILT(0b01)
251 0 : #define GICD_SGIR_TGTFILT_REQONLY GICD_SGIR_TGTFILT(0b10)
252 :
253 0 : #define GICD_SGIR_CPULIST(x) ((x) << 16)
254 0 : #define GICD_SGIR_CPULIST_CPU(n) GICD_SGIR_CPULIST(BIT(n))
255 0 : #define GICD_SGIR_CPULIST_MASK 0xff
256 :
257 0 : #define GICD_SGIR_NSATT BIT(15)
258 :
259 0 : #define GICD_SGIR_SGIINTID(x) (x)
260 :
261 : #endif /* CONFIG_GIC_VER <= 2 */
262 :
263 : /* GICD_ICFGR */
264 0 : #define GICD_ICFGR_MASK BIT_MASK(2)
265 0 : #define GICD_ICFGR_TYPE BIT(1)
266 :
267 : /* GICD_TYPER.ITLinesNumber 0:4 */
268 0 : #define GICD_TYPER_ITLINESNUM_MASK 0x1f
269 :
270 : /* GICD_TYPER.ESPI [8] */
271 0 : #define GICD_TYPER_ESPI_MASK BIT(8)
272 :
273 : /* GICD_TYPER.IDbits */
274 0 : #define GICD_TYPER_IDBITS(typer) ((((typer) >> 19) & 0x1f) + 1)
275 :
276 : /*
277 : * Common Helper Constants
278 : */
279 0 : #define GIC_SGI_INT_BASE 0
280 0 : #define GIC_PPI_INT_BASE 16
281 :
282 0 : #define GIC_IS_SGI(intid) (((intid) >= GIC_SGI_INT_BASE) && ((intid) < GIC_PPI_INT_BASE))
283 :
284 0 : #define GIC_SPI_INT_BASE 32
285 :
286 0 : #define GIC_SPI_MAX_INTID 1019
287 :
288 0 : #define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && ((intid) <= GIC_SPI_MAX_INTID))
289 :
290 0 : #define GIC_NUM_INTR_PER_REG 32
291 :
292 0 : #define GIC_NUM_CFG_PER_REG 16
293 :
294 0 : #define GIC_NUM_PRI_PER_REG 4
295 :
296 : /* GIC idle priority : value '0xff' will allow all interrupts */
297 0 : #define GIC_IDLE_PRIO 0xff
298 :
299 : /* Priority levels 0:255 */
300 0 : #define GIC_PRI_MASK 0xff
301 :
302 : /*
303 : * '0xa0'is used to initialize each interrupt default priority.
304 : * This is an arbitrary value in current context.
305 : * Any value '0x80' to '0xff' will work for both NS and S state.
306 : * The values of individual interrupt and default has to be chosen
307 : * carefully if PMR and BPR based nesting and preemption has to be done.
308 : */
309 0 : #define GIC_INT_DEF_PRI_X4 0xa0a0a0a0
310 :
311 : /* GIC special interrupt id */
312 0 : #define GIC_INTID_SPURIOUS 1023
313 :
314 : /* Fixme: update from platform specific define or dt */
315 0 : #define GIC_NUM_CPU_IF CONFIG_MP_MAX_NUM_CPUS
316 :
317 : #ifndef _ASMLANGUAGE
318 :
319 : #include <zephyr/types.h>
320 : #include <zephyr/device.h>
321 :
322 : /*
323 : * GIC Driver Interface Functions
324 : */
325 :
326 : /**
327 : * @brief Enable interrupt
328 : *
329 : * @param irq interrupt ID
330 : */
331 1 : void arm_gic_irq_enable(unsigned int irq);
332 :
333 : /**
334 : * @brief Disable interrupt
335 : *
336 : * @param irq interrupt ID
337 : */
338 1 : void arm_gic_irq_disable(unsigned int irq);
339 :
340 : /**
341 : * @brief Check if an interrupt is enabled
342 : *
343 : * @param irq interrupt ID
344 : * @return Returns true if interrupt is enabled, false otherwise
345 : */
346 1 : bool arm_gic_irq_is_enabled(unsigned int irq);
347 :
348 : /**
349 : * @brief Check if an interrupt is pending
350 : *
351 : * @param irq interrupt ID
352 : * @return Returns true if interrupt is pending, false otherwise
353 : */
354 1 : bool arm_gic_irq_is_pending(unsigned int irq);
355 :
356 : /**
357 : * @brief Set interrupt as pending
358 : *
359 : * @param irq interrupt ID
360 : */
361 1 : void arm_gic_irq_set_pending(unsigned int irq);
362 :
363 : /**
364 : * @brief Clear the pending irq
365 : *
366 : * @param irq interrupt ID
367 : */
368 1 : void arm_gic_irq_clear_pending(unsigned int irq);
369 :
370 : /**
371 : * @brief Set interrupt priority
372 : *
373 : * @param irq interrupt ID
374 : * @param prio interrupt priority
375 : * @param flags interrupt flags
376 : */
377 1 : void arm_gic_irq_set_priority(unsigned int irq, unsigned int prio, unsigned int flags);
378 :
379 : /**
380 : * @brief Get active interrupt ID
381 : *
382 : * @return Returns the ID of an active interrupt
383 : */
384 1 : unsigned int arm_gic_get_active(void);
385 :
386 : /**
387 : * @brief Signal end-of-interrupt
388 : *
389 : * @param irq interrupt ID
390 : */
391 1 : void arm_gic_eoi(unsigned int irq);
392 :
393 : #ifdef CONFIG_SMP
394 : /**
395 : * @brief Initialize GIC of secondary cores
396 : */
397 1 : void arm_gic_secondary_init(void);
398 : #endif
399 :
400 : /**
401 : * @brief raise SGI to target cores
402 : *
403 : * @param sgi_id SGI ID 0 to 15
404 : * @param target_aff target affinity in mpidr form.
405 : * Aff level 1 2 3 will be extracted by api.
406 : * @param target_list bitmask of target cores
407 : */
408 1 : void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff, uint16_t target_list);
409 :
410 : #endif /* !_ASMLANGUAGE */
411 :
412 : #endif /* ZEPHYR_INCLUDE_DRIVERS_GIC_H_ */
|