1 /*
2  * Copyright (c) 2018 Marvell
3  * Copyright (c) 2018 Lexmark International, Inc.
4  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
5  * Copyright 2024 NXP
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  */
9 
10 /*
11  * NOTE: This driver implements the GICv1 and GICv2 interfaces.
12  */
13 
14 #include <zephyr/device.h>
15 #include <zephyr/arch/cpu.h>
16 #include <zephyr/devicetree.h>
17 #include <zephyr/sw_isr_table.h>
18 #include <zephyr/dt-bindings/interrupt-controller/arm-gic.h>
19 #include <zephyr/drivers/interrupt_controller/gic.h>
20 #include <zephyr/sys/barrier.h>
21 
22 #if defined(CONFIG_GIC_V1)
23 #define DT_DRV_COMPAT arm_gic_v1
24 #elif defined(CONFIG_GIC_V2)
25 #define DT_DRV_COMPAT arm_gic_v2
26 #else
27 #error "Unknown GIC controller compatible for this configuration"
28 #endif
29 
30 static const uint64_t cpu_mpid_list[] = {
31 	DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,))
32 };
33 
34 BUILD_ASSERT(ARRAY_SIZE(cpu_mpid_list) >= CONFIG_MP_MAX_NUM_CPUS,
35 		"The count of CPU Cores nodes in dts is less than CONFIG_MP_MAX_NUM_CPUS\n");
36 
arm_gic_irq_enable(unsigned int irq)37 void arm_gic_irq_enable(unsigned int irq)
38 {
39 	int int_grp, int_off;
40 
41 	int_grp = irq / 32;
42 	int_off = irq % 32;
43 
44 	sys_write32((1 << int_off), (GICD_ISENABLERn + int_grp * 4));
45 }
46 
arm_gic_irq_disable(unsigned int irq)47 void arm_gic_irq_disable(unsigned int irq)
48 {
49 	int int_grp, int_off;
50 
51 	int_grp = irq / 32;
52 	int_off = irq % 32;
53 
54 	sys_write32((1 << int_off), (GICD_ICENABLERn + int_grp * 4));
55 }
56 
arm_gic_irq_is_enabled(unsigned int irq)57 bool arm_gic_irq_is_enabled(unsigned int irq)
58 {
59 	int int_grp, int_off;
60 	unsigned int enabler;
61 
62 	int_grp = irq / 32;
63 	int_off = irq % 32;
64 
65 	enabler = sys_read32(GICD_ISENABLERn + int_grp * 4);
66 
67 	return (enabler & (1 << int_off)) != 0;
68 }
69 
arm_gic_irq_is_pending(unsigned int irq)70 bool arm_gic_irq_is_pending(unsigned int irq)
71 {
72 	int int_grp, int_off;
73 	unsigned int enabler;
74 
75 	int_grp = irq / 32;
76 	int_off = irq % 32;
77 
78 	enabler = sys_read32(GICD_ISPENDRn + int_grp * 4);
79 
80 	return (enabler & (1 << int_off)) != 0;
81 }
82 
arm_gic_irq_set_pending(unsigned int irq)83 void arm_gic_irq_set_pending(unsigned int irq)
84 {
85 	int int_grp, int_off;
86 
87 	int_grp = irq / 32;
88 	int_off = irq % 32;
89 
90 	sys_write32((1 << int_off), (GICD_ISPENDRn + int_grp * 4));
91 }
92 
arm_gic_irq_clear_pending(unsigned int irq)93 void arm_gic_irq_clear_pending(unsigned int irq)
94 {
95 	int int_grp, int_off;
96 
97 	int_grp = irq / 32;
98 	int_off = irq % 32;
99 
100 	sys_write32((1 << int_off), (GICD_ICPENDRn + int_grp * 4));
101 }
102 
arm_gic_irq_set_priority(unsigned int irq,unsigned int prio,uint32_t flags)103 void arm_gic_irq_set_priority(
104 	unsigned int irq, unsigned int prio, uint32_t flags)
105 {
106 	int int_grp, int_off;
107 	uint32_t val;
108 
109 	/* Set priority */
110 	sys_write8(prio & 0xff, GICD_IPRIORITYRn + irq);
111 
112 	/* Set interrupt type */
113 	int_grp = (irq / 16) * 4;
114 	int_off = (irq % 16) * 2;
115 
116 	/* GICD_ICFGR0 is read-only; SGIs are always edge-triggered */
117 	if (int_grp != 0) {
118 		val = sys_read32(GICD_ICFGRn + int_grp);
119 		val &= ~(GICD_ICFGR_MASK << int_off);
120 		if (flags & IRQ_TYPE_EDGE) {
121 			val |= (GICD_ICFGR_TYPE << int_off);
122 		}
123 
124 		sys_write32(val, GICD_ICFGRn + int_grp);
125 	}
126 }
127 
arm_gic_get_active(void)128 unsigned int arm_gic_get_active(void)
129 {
130 	unsigned int irq;
131 
132 	/*
133 	 * "ARM Generic Interrupt Controller Architecture version 2.0" states that
134 	 * [4.4.5 End of Interrupt Register, GICC_EOIR)]:
135 	 * """
136 	 * For compatibility with possible extensions to the GIC architecture
137 	 * specification, ARM recommends that software preserves the entire register
138 	 * value read from the GICC_IAR when it acknowledges the interrupt, and uses
139 	 * that entire value for its corresponding write to the GICC_EOIR.
140 	 * """
141 	 * Because of that, we read the entire value here, to be later written back to GICC_EOIR
142 	 */
143 	irq = sys_read32(GICC_IAR);
144 	return irq;
145 }
146 
arm_gic_eoi(unsigned int irq)147 void arm_gic_eoi(unsigned int irq)
148 {
149 	/*
150 	 * Ensure the write to peripheral registers are *complete* before the write
151 	 * to GIC_EOIR.
152 	 *
153 	 * Note: The completion guarantee depends on various factors of system design
154 	 * and the barrier is the best core can do by which execution of further
155 	 * instructions waits till the barrier is alive.
156 	 */
157 	barrier_dsync_fence_full();
158 
159 	/* set to inactive */
160 	sys_write32(irq, GICC_EOIR);
161 }
162 
gic_raise_sgi(unsigned int sgi_id,uint64_t target_aff,uint16_t target_list)163 void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
164 		uint16_t target_list)
165 {
166 	uint32_t sgi_val;
167 
168 	ARG_UNUSED(target_aff);
169 
170 	sgi_val = GICD_SGIR_TGTFILT_CPULIST |
171 		GICD_SGIR_CPULIST(target_list & GICD_SGIR_CPULIST_MASK) |
172 		sgi_id;
173 
174 	barrier_dsync_fence_full();
175 	sys_write32(sgi_val, GICD_SGIR);
176 	barrier_isync_fence_full();
177 }
178 
gic_dist_init(void)179 static void gic_dist_init(void)
180 {
181 	unsigned int gic_irqs, i;
182 	uint8_t cpu_mask = 0;
183 	uint32_t reg_val;
184 
185 	gic_irqs = sys_read32(GICD_TYPER) & 0x1f;
186 	gic_irqs = (gic_irqs + 1) * 32;
187 	if (gic_irqs > 1020) {
188 		gic_irqs = 1020;
189 	}
190 
191 	/*
192 	 * Disable the forwarding of pending interrupts
193 	 * from the Distributor to the CPU interfaces
194 	 */
195 	sys_write32(0, GICD_CTLR);
196 
197 	/*
198 	 * Enable all global interrupts distributing to CPUs listed
199 	 * in dts with the count of arch_num_cpus().
200 	 */
201 	unsigned int num_cpus = arch_num_cpus();
202 
203 	for (i = 0; i < num_cpus; i++) {
204 		cpu_mask |= BIT(cpu_mpid_list[i]);
205 	}
206 	reg_val = cpu_mask | (cpu_mask << 8) | (cpu_mask << 16)
207 		| (cpu_mask << 24);
208 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 4) {
209 		sys_write32(reg_val, GICD_ITARGETSRn + i);
210 	}
211 
212 	/*
213 	 * Set all global interrupts to be level triggered, active low.
214 	 */
215 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 16) {
216 		sys_write32(0, GICD_ICFGRn + i / 4);
217 	}
218 
219 	/*  Set priority on all global interrupts.   */
220 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 4) {
221 		sys_write32(0, GICD_IPRIORITYRn + i);
222 	}
223 
224 	/* Set all interrupts to group 0 */
225 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 32) {
226 		sys_write32(0, GICD_IGROUPRn + i / 8);
227 	}
228 
229 	/*
230 	 * Disable all interrupts.  Leave the PPI and SGIs alone
231 	 * as these enables are banked registers.
232 	 */
233 	for (i = GIC_SPI_INT_BASE; i < gic_irqs; i += 32) {
234 #ifndef CONFIG_GIC_V1
235 		sys_write32(0xffffffff, GICD_ICACTIVERn + i / 8);
236 #endif
237 		sys_write32(0xffffffff, GICD_ICENABLERn + i / 8);
238 	}
239 
240 	/*
241 	 * Enable the forwarding of pending interrupts
242 	 * from the Distributor to the CPU interfaces
243 	 */
244 	sys_write32(1, GICD_CTLR);
245 }
246 
gic_cpu_init(void)247 static void gic_cpu_init(void)
248 {
249 	int i;
250 	uint32_t val;
251 
252 	/*
253 	 * Deal with the banked PPI and SGI interrupts - disable all
254 	 * PPI interrupts, ensure all SGI interrupts are enabled.
255 	 */
256 #ifndef CONFIG_GIC_V1
257 	sys_write32(0xffffffff, GICD_ICACTIVERn);
258 #endif
259 	sys_write32(0xffff0000, GICD_ICENABLERn);
260 	sys_write32(0x0000ffff, GICD_ISENABLERn);
261 
262 	/*
263 	 * Set priority on PPI and SGI interrupts
264 	 */
265 	for (i = 0; i < 32; i += 4) {
266 		sys_write32(0xa0a0a0a0, GICD_IPRIORITYRn + i);
267 	}
268 
269 	sys_write32(0xf0, GICC_PMR);
270 
271 	/*
272 	 * Enable interrupts and signal them using the IRQ signal.
273 	 */
274 	val = sys_read32(GICC_CTLR);
275 #ifndef CONFIG_GIC_V1
276 	val &= ~GICC_CTLR_BYPASS_MASK;
277 #endif
278 	val |= GICC_CTLR_ENABLE_MASK;
279 	sys_write32(val, GICC_CTLR);
280 }
281 
282 #define GIC_PARENT_IRQ 0
283 #define GIC_PARENT_IRQ_PRI 0
284 #define GIC_PARENT_IRQ_FLAGS 0
285 
286 /**
287  * @brief Initialize the GIC device driver
288  */
arm_gic_init(const struct device * dev)289 int arm_gic_init(const struct device *dev)
290 {
291 	/* Init of Distributor interface registers */
292 	gic_dist_init();
293 
294 	/* Init CPU interface registers */
295 	gic_cpu_init();
296 
297 	return 0;
298 }
299 
300 DEVICE_DT_INST_DEFINE(0, arm_gic_init, NULL, NULL, NULL,
301 		      PRE_KERNEL_1, CONFIG_INTC_INIT_PRIORITY, NULL);
302 
303 #ifdef CONFIG_SMP
arm_gic_secondary_init(void)304 void arm_gic_secondary_init(void)
305 {
306 	/* Init CPU interface registers for each secondary core */
307 	gic_cpu_init();
308 }
309 #endif
310