xref: /freebsd/sys/arm/arm/gic.c (revision a0ee8cc6)
1 /*-
2  * Copyright (c) 2011 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * Developed by Damjan Marion <damjan.marion@gmail.com>
6  *
7  * Based on OMAP4 GIC code by Ben Gray
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the company nor the name of the author may be used to
18  *    endorse or promote products derived from this software without specific
19  *    prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 #include "opt_platform.h"
38 
39 #include "opt_platform.h"
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/bus.h>
44 #include <sys/kernel.h>
45 #include <sys/ktr.h>
46 #include <sys/module.h>
47 #include <sys/malloc.h>
48 #include <sys/rman.h>
49 #include <sys/pcpu.h>
50 #include <sys/proc.h>
51 #include <sys/cpuset.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/smp.h>
55 #ifdef ARM_INTRNG
56 #include <sys/sched.h>
57 #endif
58 #include <machine/bus.h>
59 #include <machine/intr.h>
60 #include <machine/smp.h>
61 
62 #include <dev/fdt/fdt_common.h>
63 #include <dev/ofw/openfirm.h>
64 #include <dev/ofw/ofw_bus.h>
65 #include <dev/ofw/ofw_bus_subr.h>
66 
67 #ifdef ARM_INTRNG
68 #include "pic_if.h"
69 #endif
70 
71 #define GIC_DEBUG_SPURIOUS
72 
73 /* We are using GICv2 register naming */
74 
75 /* Distributor Registers */
76 #define GICD_CTLR		0x000			/* v1 ICDDCR */
77 #define GICD_TYPER		0x004			/* v1 ICDICTR */
78 #define GICD_IIDR		0x008			/* v1 ICDIIDR */
79 #define GICD_IGROUPR(n)		(0x0080 + ((n) * 4))	/* v1 ICDISER */
80 #define GICD_ISENABLER(n)	(0x0100 + ((n) * 4))	/* v1 ICDISER */
81 #define GICD_ICENABLER(n)	(0x0180 + ((n) * 4))	/* v1 ICDICER */
82 #define GICD_ISPENDR(n)		(0x0200 + ((n) * 4))	/* v1 ICDISPR */
83 #define GICD_ICPENDR(n)		(0x0280 + ((n) * 4))	/* v1 ICDICPR */
84 #define GICD_ICACTIVER(n)	(0x0380 + ((n) * 4))	/* v1 ICDABR */
85 #define GICD_IPRIORITYR(n)	(0x0400 + ((n) * 4))	/* v1 ICDIPR */
86 #define GICD_ITARGETSR(n)	(0x0800 + ((n) * 4))	/* v1 ICDIPTR */
87 #define GICD_ICFGR(n)		(0x0C00 + ((n) * 4))	/* v1 ICDICFR */
88 #define GICD_SGIR(n)		(0x0F00 + ((n) * 4))	/* v1 ICDSGIR */
89 
90 /* CPU Registers */
91 #define GICC_CTLR		0x0000			/* v1 ICCICR */
92 #define GICC_PMR		0x0004			/* v1 ICCPMR */
93 #define GICC_BPR		0x0008			/* v1 ICCBPR */
94 #define GICC_IAR		0x000C			/* v1 ICCIAR */
95 #define GICC_EOIR		0x0010			/* v1 ICCEOIR */
96 #define GICC_RPR		0x0014			/* v1 ICCRPR */
97 #define GICC_HPPIR		0x0018			/* v1 ICCHPIR */
98 #define GICC_ABPR		0x001C			/* v1 ICCABPR */
99 #define GICC_IIDR		0x00FC			/* v1 ICCIIDR*/
100 
101 #define	GIC_FIRST_SGI		 0	/* Irqs 0-15 are SGIs/IPIs. */
102 #define	GIC_LAST_SGI		15
103 #define	GIC_FIRST_PPI		16	/* Irqs 16-31 are private (per */
104 #define	GIC_LAST_PPI		31	/* core) peripheral interrupts. */
105 #define	GIC_FIRST_SPI		32	/* Irqs 32+ are shared peripherals. */
106 
107 /* First bit is a polarity bit (0 - low, 1 - high) */
108 #define GICD_ICFGR_POL_LOW	(0 << 0)
109 #define GICD_ICFGR_POL_HIGH	(1 << 0)
110 #define GICD_ICFGR_POL_MASK	0x1
111 /* Second bit is a trigger bit (0 - level, 1 - edge) */
112 #define GICD_ICFGR_TRIG_LVL	(0 << 1)
113 #define GICD_ICFGR_TRIG_EDGE	(1 << 1)
114 #define GICD_ICFGR_TRIG_MASK	0x2
115 
116 #ifndef	GIC_DEFAULT_ICFGR_INIT
117 #define	GIC_DEFAULT_ICFGR_INIT	0x00000000
118 #endif
119 
120 #ifdef ARM_INTRNG
121 static u_int gic_irq_cpu;
122 static int arm_gic_intr(void *);
123 static int arm_gic_bind(device_t dev, struct intr_irqsrc *isrc);
124 #endif
125 
126 struct arm_gic_softc {
127 	device_t		gic_dev;
128 #ifdef ARM_INTRNG
129 	void *			gic_intrhand;
130 	struct intr_irqsrc **	gic_irqs;
131 #endif
132 	struct resource *	gic_res[3];
133 	bus_space_tag_t		gic_c_bst;
134 	bus_space_tag_t		gic_d_bst;
135 	bus_space_handle_t	gic_c_bsh;
136 	bus_space_handle_t	gic_d_bsh;
137 	uint8_t			ver;
138 	struct mtx		mutex;
139 	uint32_t		nirqs;
140 #ifdef GIC_DEBUG_SPURIOUS
141 	uint32_t		last_irq[MAXCPU];
142 #endif
143 };
144 
145 static struct resource_spec arm_gic_spec[] = {
146 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE },	/* Distributor registers */
147 	{ SYS_RES_MEMORY,	1,	RF_ACTIVE },	/* CPU Interrupt Intf. registers */
148 #ifdef ARM_INTRNG
149 	{ SYS_RES_IRQ,	  0, RF_ACTIVE | RF_OPTIONAL }, /* Parent interrupt */
150 #endif
151 	{ -1, 0 }
152 };
153 
154 static struct arm_gic_softc *gic_sc = NULL;
155 
156 #define	gic_c_read_4(_sc, _reg)		\
157     bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg))
158 #define	gic_c_write_4(_sc, _reg, _val)		\
159     bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val))
160 #define	gic_d_read_4(_sc, _reg)		\
161     bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg))
162 #define	gic_d_write_1(_sc, _reg, _val)		\
163     bus_space_write_1((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
164 #define	gic_d_write_4(_sc, _reg, _val)		\
165     bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
166 
167 #ifndef ARM_INTRNG
168 static int gic_config_irq(int irq, enum intr_trigger trig,
169     enum intr_polarity pol);
170 static void gic_post_filter(void *);
171 #endif
172 
173 static struct ofw_compat_data compat_data[] = {
174 	{"arm,gic",		true},	/* Non-standard, used in FreeBSD dts. */
175 	{"arm,gic-400",		true},
176 	{"arm,cortex-a15-gic",	true},
177 	{"arm,cortex-a9-gic",	true},
178 	{"arm,cortex-a7-gic",	true},
179 	{"arm,arm11mp-gic",	true},
180 	{"brcm,brahma-b15-gic",	true},
181 	{NULL,			false}
182 };
183 
184 static int
185 arm_gic_probe(device_t dev)
186 {
187 
188 	if (!ofw_bus_status_okay(dev))
189 		return (ENXIO);
190 
191 	if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data)
192 		return (ENXIO);
193 	device_set_desc(dev, "ARM Generic Interrupt Controller");
194 	return (BUS_PROBE_DEFAULT);
195 }
196 
197 #ifdef ARM_INTRNG
198 static inline void
199 gic_irq_unmask(struct arm_gic_softc *sc, u_int irq)
200 {
201 
202 	gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
203 }
204 
205 static inline void
206 gic_irq_mask(struct arm_gic_softc *sc, u_int irq)
207 {
208 
209 	gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
210 }
211 #endif
212 
213 #ifdef SMP
214 #ifdef ARM_INTRNG
215 static void
216 arm_gic_init_secondary(device_t dev)
217 {
218 	struct arm_gic_softc *sc = device_get_softc(dev);
219 	struct intr_irqsrc *isrc;
220 	u_int irq;
221 
222 	for (irq = 0; irq < sc->nirqs; irq += 4)
223 		gic_d_write_4(sc, GICD_IPRIORITYR(irq >> 2), 0);
224 
225 	/* Set all the interrupts to be in Group 0 (secure) */
226 	for (irq = 0; irq < sc->nirqs; irq += 32) {
227 		gic_d_write_4(sc, GICD_IGROUPR(irq >> 5), 0);
228 	}
229 
230 	/* Enable CPU interface */
231 	gic_c_write_4(sc, GICC_CTLR, 1);
232 
233 	/* Set priority mask register. */
234 	gic_c_write_4(sc, GICC_PMR, 0xff);
235 
236 	/* Enable interrupt distribution */
237 	gic_d_write_4(sc, GICD_CTLR, 0x01);
238 
239 	/* Unmask attached SGI interrupts. */
240 	for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++) {
241 		isrc = sc->gic_irqs[irq];
242 		if (isrc != NULL && isrc->isrc_handlers != 0) {
243 			CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
244 			gic_irq_unmask(sc, irq);
245 		}
246 	}
247 
248 	/* Unmask attached PPI interrupts. */
249 	for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++) {
250 		isrc = sc->gic_irqs[irq];
251 		if (isrc == NULL || isrc->isrc_handlers == 0)
252 			continue;
253 		if (isrc->isrc_flags & INTR_ISRCF_BOUND) {
254 			if (CPU_ISSET(PCPU_GET(cpuid), &isrc->isrc_cpu))
255 				gic_irq_unmask(sc, irq);
256 		} else {
257 			CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
258 			gic_irq_unmask(sc, irq);
259 		}
260 	}
261 }
262 #else
263 static void
264 arm_gic_init_secondary(device_t dev)
265 {
266 	struct arm_gic_softc *sc = device_get_softc(dev);
267 	int i;
268 
269 	for (i = 0; i < sc->nirqs; i += 4)
270 		gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
271 
272 	/* Set all the interrupts to be in Group 0 (secure) */
273 	for (i = 0; i < sc->nirqs; i += 32) {
274 		gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
275 	}
276 
277 	/* Enable CPU interface */
278 	gic_c_write_4(sc, GICC_CTLR, 1);
279 
280 	/* Set priority mask register. */
281 	gic_c_write_4(sc, GICC_PMR, 0xff);
282 
283 	/* Enable interrupt distribution */
284 	gic_d_write_4(sc, GICD_CTLR, 0x01);
285 
286 	/*
287 	 * Activate the timer interrupts: virtual, secure, and non-secure.
288 	 */
289 	gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
290 	gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
291 	gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
292 }
293 #endif /* ARM_INTRNG */
294 #endif /* SMP */
295 
296 #ifndef ARM_INTRNG
297 int
298 gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
299     int *trig, int *pol)
300 {
301 	static u_int num_intr_cells;
302 	static phandle_t self;
303 	struct ofw_compat_data *ocd;
304 
305 	if (self == 0) {
306 		for (ocd = compat_data; ocd->ocd_str != NULL; ocd++) {
307 			if (fdt_is_compatible(iparent, ocd->ocd_str)) {
308 				self = iparent;
309 				break;
310 			}
311 		}
312 	}
313 	if (self != iparent)
314 		return (ENXIO);
315 
316 	if (num_intr_cells == 0) {
317 		if (OF_searchencprop(OF_node_from_xref(iparent),
318 		    "#interrupt-cells", &num_intr_cells,
319 		    sizeof(num_intr_cells)) == -1) {
320 			num_intr_cells = 1;
321 		}
322 	}
323 
324 	if (num_intr_cells == 1) {
325 		*interrupt = fdt32_to_cpu(intr[0]);
326 		*trig = INTR_TRIGGER_CONFORM;
327 		*pol = INTR_POLARITY_CONFORM;
328 	} else {
329 		if (fdt32_to_cpu(intr[0]) == 0)
330 			*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI;
331 		else
332 			*interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI;
333 		/*
334 		 * In intr[2], bits[3:0] are trigger type and level flags.
335 		 *   1 = low-to-high edge triggered
336 		 *   2 = high-to-low edge triggered
337 		 *   4 = active high level-sensitive
338 		 *   8 = active low level-sensitive
339 		 * The hardware only supports active-high-level or rising-edge.
340 		 */
341 		if (fdt32_to_cpu(intr[2]) & 0x0a) {
342 			printf("unsupported trigger/polarity configuration "
343 			    "0x%02x\n", fdt32_to_cpu(intr[2]) & 0x0f);
344 		}
345 		*pol  = INTR_POLARITY_CONFORM;
346 		if (fdt32_to_cpu(intr[2]) & 0x03)
347 			*trig = INTR_TRIGGER_EDGE;
348 		else
349 			*trig = INTR_TRIGGER_LEVEL;
350 	}
351 	return (0);
352 }
353 #endif
354 
355 #ifdef ARM_INTRNG
356 static inline intptr_t
357 gic_xref(device_t dev)
358 {
359 #ifdef FDT
360 	return (OF_xref_from_node(ofw_bus_get_node(dev)));
361 #else
362 	return (0);
363 #endif
364 }
365 #endif
366 
367 static int
368 arm_gic_attach(device_t dev)
369 {
370 	struct		arm_gic_softc *sc;
371 	int		i;
372 	uint32_t	icciidr;
373 #ifdef ARM_INTRNG
374 	phandle_t	pxref;
375 	intptr_t	xref = gic_xref(dev);
376 #endif
377 
378 	if (gic_sc)
379 		return (ENXIO);
380 
381 	sc = device_get_softc(dev);
382 
383 	if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
384 		device_printf(dev, "could not allocate resources\n");
385 		return (ENXIO);
386 	}
387 
388 	sc->gic_dev = dev;
389 	gic_sc = sc;
390 
391 	/* Initialize mutex */
392 	mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
393 
394 	/* Distributor Interface */
395 	sc->gic_d_bst = rman_get_bustag(sc->gic_res[0]);
396 	sc->gic_d_bsh = rman_get_bushandle(sc->gic_res[0]);
397 
398 	/* CPU Interface */
399 	sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
400 	sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
401 
402 	/* Disable interrupt forwarding to the CPU interface */
403 	gic_d_write_4(sc, GICD_CTLR, 0x00);
404 
405 	/* Get the number of interrupts */
406 	sc->nirqs = gic_d_read_4(sc, GICD_TYPER);
407 	sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1);
408 
409 #ifdef ARM_INTRNG
410 	sc->gic_irqs = malloc(sc->nirqs * sizeof (*sc->gic_irqs), M_DEVBUF,
411 	    M_WAITOK | M_ZERO);
412 #else
413 	/* Set up function pointers */
414 	arm_post_filter = gic_post_filter;
415 	arm_config_irq = gic_config_irq;
416 #endif
417 
418 	icciidr = gic_c_read_4(sc, GICC_IIDR);
419 	device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
420 			icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf,
421 			(icciidr & 0xfff), sc->nirqs);
422 
423 	/* Set all global interrupts to be level triggered, active low. */
424 	for (i = 32; i < sc->nirqs; i += 16) {
425 		gic_d_write_4(sc, GICD_ICFGR(i >> 4), GIC_DEFAULT_ICFGR_INIT);
426 	}
427 
428 	/* Disable all interrupts. */
429 	for (i = 32; i < sc->nirqs; i += 32) {
430 		gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
431 	}
432 
433 	for (i = 0; i < sc->nirqs; i += 4) {
434 		gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
435 		gic_d_write_4(sc, GICD_ITARGETSR(i >> 2),
436 		    1 << 0 | 1 << 8 | 1 << 16 | 1 << 24);
437 	}
438 
439 	/* Set all the interrupts to be in Group 0 (secure) */
440 	for (i = 0; i < sc->nirqs; i += 32) {
441 		gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
442 	}
443 
444 	/* Enable CPU interface */
445 	gic_c_write_4(sc, GICC_CTLR, 1);
446 
447 	/* Set priority mask register. */
448 	gic_c_write_4(sc, GICC_PMR, 0xff);
449 
450 	/* Enable interrupt distribution */
451 	gic_d_write_4(sc, GICD_CTLR, 0x01);
452 #ifndef ARM_INTRNG
453 	return (0);
454 #else
455 	/*
456 	 * Now, when everything is initialized, it's right time to
457 	 * register interrupt controller to interrupt framefork.
458 	 */
459 	if (intr_pic_register(dev, xref) != 0) {
460 		device_printf(dev, "could not register PIC\n");
461 		goto cleanup;
462 	}
463 
464 	/*
465 	 * Controller is root if:
466 	 * - doesn't have interrupt parent
467 	 * - his interrupt parent is this controller
468 	 */
469 	pxref = ofw_bus_find_iparent(ofw_bus_get_node(dev));
470 	if (pxref == 0 || xref == pxref) {
471 		if (intr_pic_claim_root(dev, xref, arm_gic_intr, sc,
472 		    GIC_LAST_SGI - GIC_FIRST_SGI + 1) != 0) {
473 			device_printf(dev, "could not set PIC as a root\n");
474 			intr_pic_unregister(dev, xref);
475 			goto cleanup;
476 		}
477 	} else {
478 		if (sc->gic_res[2] == NULL) {
479 			device_printf(dev,
480 			    "not root PIC must have defined interrupt\n");
481 			intr_pic_unregister(dev, xref);
482 			goto cleanup;
483 		}
484 		if (bus_setup_intr(dev, sc->gic_res[2], INTR_TYPE_CLK,
485 		    arm_gic_intr, NULL, sc, &sc->gic_intrhand)) {
486 			device_printf(dev, "could not setup irq handler\n");
487 			intr_pic_unregister(dev, xref);
488 			goto cleanup;
489 		}
490 	}
491 
492 	OF_device_register_xref(xref, dev);
493 	return (0);
494 
495 cleanup:
496 	/*
497 	 * XXX - not implemented arm_gic_detach() should be called !
498 	 */
499 	if (sc->gic_irqs != NULL)
500 		free(sc->gic_irqs, M_DEVBUF);
501 	bus_release_resources(dev, arm_gic_spec, sc->gic_res);
502 	return(ENXIO);
503 #endif
504 }
505 
506 #ifdef ARM_INTRNG
507 static int
508 arm_gic_intr(void *arg)
509 {
510 	struct arm_gic_softc *sc = arg;
511 	struct intr_irqsrc *isrc;
512 	uint32_t irq_active_reg, irq;
513 	struct trapframe *tf;
514 
515 	irq_active_reg = gic_c_read_4(sc, GICC_IAR);
516 	irq = irq_active_reg & 0x3FF;
517 
518 	/*
519 	 * 1. We do EOI here because recent read value from active interrupt
520 	 *    register must be used for it. Another approach is to save this
521 	 *    value into associated interrupt source.
522 	 * 2. EOI must be done on same CPU where interrupt has fired. Thus
523 	 *    we must ensure that interrupted thread does not migrate to
524 	 *    another CPU.
525 	 * 3. EOI cannot be delayed by any preemption which could happen on
526 	 *    critical_exit() used in MI intr code, when interrupt thread is
527 	 *    scheduled. See next point.
528 	 * 4. IPI_RENDEZVOUS assumes that no preemption is permitted during
529 	 *    an action and any use of critical_exit() could break this
530 	 *    assumption. See comments within smp_rendezvous_action().
531 	 * 5. We always return FILTER_HANDLED as this is an interrupt
532 	 *    controller dispatch function. Otherwise, in cascaded interrupt
533 	 *    case, the whole interrupt subtree would be masked.
534 	 */
535 
536 	if (irq >= sc->nirqs) {
537 #ifdef GIC_DEBUG_SPURIOUS
538 		device_printf(sc->gic_dev,
539 		    "Spurious interrupt detected: last irq: %d on CPU%d\n",
540 		    sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid));
541 #endif
542 		return (FILTER_HANDLED);
543 	}
544 
545 	tf = curthread->td_intr_frame;
546 dispatch_irq:
547 	isrc = sc->gic_irqs[irq];
548 	if (isrc == NULL) {
549 		device_printf(sc->gic_dev, "Stray interrupt %u detected\n", irq);
550 		gic_irq_mask(sc, irq);
551 		gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
552 		goto next_irq;
553 	}
554 
555 	/*
556 	 * Note that GIC_FIRST_SGI is zero and is not used in 'if' statement
557 	 * as compiler complains that comparing u_int >= 0 is always true.
558 	 */
559 	if (irq <= GIC_LAST_SGI) {
560 #ifdef SMP
561 		/* Call EOI for all IPI before dispatch. */
562 		gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
563 		intr_ipi_dispatch(isrc, tf);
564 		goto next_irq;
565 #else
566 		device_printf(sc->gic_dev, "SGI %u on UP system detected\n",
567 		    irq - GIC_FIRST_SGI);
568 		gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
569 		goto next_irq;
570 #endif
571 	}
572 
573 #ifdef GIC_DEBUG_SPURIOUS
574 	sc->last_irq[PCPU_GET(cpuid)] = irq;
575 #endif
576 	if (isrc->isrc_trig == INTR_TRIGGER_EDGE)
577 		gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
578 
579 	intr_irq_dispatch(isrc, tf);
580 
581 next_irq:
582 	arm_irq_memory_barrier(irq);
583 	irq_active_reg = gic_c_read_4(sc, GICC_IAR);
584 	irq = irq_active_reg & 0x3FF;
585 	if (irq < sc->nirqs)
586 		goto dispatch_irq;
587 
588 	return (FILTER_HANDLED);
589 }
590 
591 static int
592 gic_attach_isrc(struct arm_gic_softc *sc, struct intr_irqsrc *isrc, u_int irq)
593 {
594 	const char *name;
595 
596 	/*
597 	 * 1. The link between ISRC and controller must be set atomically.
598 	 * 2. Just do things only once in rare case when consumers
599 	 *    of shared interrupt came here at the same moment.
600 	 */
601 	mtx_lock_spin(&sc->mutex);
602 	if (sc->gic_irqs[irq] != NULL) {
603 		mtx_unlock_spin(&sc->mutex);
604 		return (sc->gic_irqs[irq] == isrc ? 0 : EEXIST);
605 	}
606 	sc->gic_irqs[irq] = isrc;
607 	isrc->isrc_data = irq;
608 	mtx_unlock_spin(&sc->mutex);
609 
610 	name = device_get_nameunit(sc->gic_dev);
611 	if (irq <= GIC_LAST_SGI)
612 		intr_irq_set_name(isrc, "%s,i%u", name, irq - GIC_FIRST_SGI);
613 	else if (irq <= GIC_LAST_PPI)
614 		intr_irq_set_name(isrc, "%s,p%u", name, irq - GIC_FIRST_PPI);
615 	else
616 		intr_irq_set_name(isrc, "%s,s%u", name, irq - GIC_FIRST_SPI);
617 	return (0);
618 }
619 
620 static int
621 gic_detach_isrc(struct arm_gic_softc *sc, struct intr_irqsrc *isrc, u_int irq)
622 {
623 
624 	mtx_lock_spin(&sc->mutex);
625 	if (sc->gic_irqs[irq] != isrc) {
626 		mtx_unlock_spin(&sc->mutex);
627 		return (sc->gic_irqs[irq] == NULL ? 0 : EINVAL);
628 	}
629 	sc->gic_irqs[irq] = NULL;
630 	isrc->isrc_data = 0;
631 	mtx_unlock_spin(&sc->mutex);
632 
633 	intr_irq_set_name(isrc, "");
634 	return (0);
635 }
636 
637 static void
638 gic_config(struct arm_gic_softc *sc, u_int irq, enum intr_trigger trig,
639     enum intr_polarity pol)
640 {
641 	uint32_t reg;
642 	uint32_t mask;
643 
644 	if (irq < GIC_FIRST_SPI)
645 		return;
646 
647 	mtx_lock_spin(&sc->mutex);
648 
649 	reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
650 	mask = (reg >> 2*(irq % 16)) & 0x3;
651 
652 	if (pol == INTR_POLARITY_LOW) {
653 		mask &= ~GICD_ICFGR_POL_MASK;
654 		mask |= GICD_ICFGR_POL_LOW;
655 	} else if (pol == INTR_POLARITY_HIGH) {
656 		mask &= ~GICD_ICFGR_POL_MASK;
657 		mask |= GICD_ICFGR_POL_HIGH;
658 	}
659 
660 	if (trig == INTR_TRIGGER_LEVEL) {
661 		mask &= ~GICD_ICFGR_TRIG_MASK;
662 		mask |= GICD_ICFGR_TRIG_LVL;
663 	} else if (trig == INTR_TRIGGER_EDGE) {
664 		mask &= ~GICD_ICFGR_TRIG_MASK;
665 		mask |= GICD_ICFGR_TRIG_EDGE;
666 	}
667 
668 	/* Set mask */
669 	reg = reg & ~(0x3 << 2*(irq % 16));
670 	reg = reg | (mask << 2*(irq % 16));
671 	gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
672 
673 	mtx_unlock_spin(&sc->mutex);
674 }
675 
676 static int
677 gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus)
678 {
679 	uint32_t cpu, end, mask;
680 
681 	end = min(mp_ncpus, 8);
682 	for (cpu = end; cpu < MAXCPU; cpu++)
683 		if (CPU_ISSET(cpu, cpus))
684 			return (EINVAL);
685 
686 	for (mask = 0, cpu = 0; cpu < end; cpu++)
687 		if (CPU_ISSET(cpu, cpus))
688 			mask |= 1 << cpu;
689 
690 	gic_d_write_1(sc, GICD_ITARGETSR(0) + irq, mask);
691 	return (0);
692 }
693 
694 static int
695 gic_irq_from_nspc(struct arm_gic_softc *sc, u_int type, u_int num, u_int *irqp)
696 {
697 
698 	switch (type) {
699 	case INTR_IRQ_NSPC_PLAIN:
700 		*irqp = num;
701 		return (*irqp < sc->nirqs ? 0 : EINVAL);
702 
703 	case INTR_IRQ_NSPC_IRQ:
704 		*irqp = num + GIC_FIRST_PPI;
705 		return (*irqp < sc->nirqs ? 0 : EINVAL);
706 
707 	case INTR_IRQ_NSPC_IPI:
708 		*irqp = num + GIC_FIRST_SGI;
709 		return (*irqp < GIC_LAST_SGI ? 0 : EINVAL);
710 
711 	default:
712 		return (EINVAL);
713 	}
714 }
715 
716 static int
717 gic_map_nspc(struct arm_gic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp)
718 {
719 	int error;
720 
721 	error = gic_irq_from_nspc(sc, isrc->isrc_nspc_type, isrc->isrc_nspc_num,
722 	    irqp);
723 	if (error != 0)
724 		return (error);
725 	return (gic_attach_isrc(sc, isrc, *irqp));
726 }
727 
728 #ifdef FDT
729 static int
730 gic_map_fdt(struct arm_gic_softc *sc, struct intr_irqsrc *isrc, u_int *irqp)
731 {
732 	u_int irq, tripol;
733 	enum intr_trigger trig;
734 	enum intr_polarity pol;
735 	int error;
736 
737 	if (isrc->isrc_ncells == 1) {
738 		irq = isrc->isrc_cells[0];
739 		pol = INTR_POLARITY_CONFORM;
740 		trig = INTR_TRIGGER_CONFORM;
741 	} else if (isrc->isrc_ncells == 3) {
742 		if (isrc->isrc_cells[0] == 0)
743 			irq = isrc->isrc_cells[1] + GIC_FIRST_SPI;
744 		else
745 			irq = isrc->isrc_cells[1] + GIC_FIRST_PPI;
746 
747 		/*
748 		 * In intr[2], bits[3:0] are trigger type and level flags.
749 		 *   1 = low-to-high edge triggered
750 		 *   2 = high-to-low edge triggered
751 		 *   4 = active high level-sensitive
752 		 *   8 = active low level-sensitive
753 		 * The hardware only supports active-high-level or rising-edge.
754 		 */
755 		tripol = isrc->isrc_cells[2];
756 		if (tripol & 0x0a) {
757 			device_printf(sc->gic_dev,
758 			   "unsupported trigger/polarity configuration "
759 			   "0x%02x\n",  tripol & 0x0f);
760 		}
761 		pol = INTR_POLARITY_CONFORM;
762 		if (tripol & 0x03)
763 			trig = INTR_TRIGGER_EDGE;
764 		else
765 			trig = INTR_TRIGGER_LEVEL;
766 	} else
767 		return (EINVAL);
768 
769 	if (irq >= sc->nirqs)
770 		return (EINVAL);
771 
772 	error = gic_attach_isrc(sc, isrc, irq);
773 	if (error != 0)
774 		return (error);
775 
776 	isrc->isrc_nspc_type = INTR_IRQ_NSPC_PLAIN;
777 	isrc->isrc_nspc_num = irq;
778 	isrc->isrc_trig = trig;
779 	isrc->isrc_pol = pol;
780 
781 	*irqp = irq;
782 	return (0);
783 }
784 #endif
785 
786 static int
787 arm_gic_register(device_t dev, struct intr_irqsrc *isrc, boolean_t *is_percpu)
788 {
789 	struct arm_gic_softc *sc = device_get_softc(dev);
790 	u_int irq;
791 	int error;
792 
793 	if (isrc->isrc_type == INTR_ISRCT_NAMESPACE)
794 		error = gic_map_nspc(sc, isrc, &irq);
795 #ifdef FDT
796 	else if (isrc->isrc_type == INTR_ISRCT_FDT)
797 		error = gic_map_fdt(sc, isrc, &irq);
798 #endif
799 	else
800 		return (EINVAL);
801 
802 	if (error == 0)
803 		*is_percpu = irq < GIC_FIRST_SPI ? TRUE : FALSE;
804 	return (error);
805 }
806 
807 static void
808 arm_gic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
809 {
810 	struct arm_gic_softc *sc = device_get_softc(dev);
811 	u_int irq = isrc->isrc_data;
812 
813 	if (isrc->isrc_trig == INTR_TRIGGER_CONFORM)
814 		isrc->isrc_trig = INTR_TRIGGER_LEVEL;
815 
816 	/*
817 	 * XXX - In case that per CPU interrupt is going to be enabled in time
818 	 *       when SMP is already started, we need some IPI call which
819 	 *       enables it on others CPUs. Further, it's more complicated as
820 	 *       pic_enable_source() and pic_disable_source() should act on
821 	 *       per CPU basis only. Thus, it should be solved here somehow.
822 	 */
823 	if (isrc->isrc_flags & INTR_ISRCF_PERCPU)
824 		CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
825 
826 	gic_config(sc, irq, isrc->isrc_trig, isrc->isrc_pol);
827 	arm_gic_bind(dev, isrc);
828 }
829 
830 static void
831 arm_gic_enable_source(device_t dev, struct intr_irqsrc *isrc)
832 {
833 	struct arm_gic_softc *sc = device_get_softc(dev);
834 	u_int irq = isrc->isrc_data;
835 
836 	arm_irq_memory_barrier(irq);
837 	gic_irq_unmask(sc, irq);
838 }
839 
840 static void
841 arm_gic_disable_source(device_t dev, struct intr_irqsrc *isrc)
842 {
843 	struct arm_gic_softc *sc = device_get_softc(dev);
844 	u_int irq = isrc->isrc_data;
845 
846 	gic_irq_mask(sc, irq);
847 }
848 
849 static int
850 arm_gic_unregister(device_t dev, struct intr_irqsrc *isrc)
851 {
852 	struct arm_gic_softc *sc = device_get_softc(dev);
853 	u_int irq = isrc->isrc_data;
854 
855 	return (gic_detach_isrc(sc, isrc, irq));
856 }
857 
858 static void
859 arm_gic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
860 {
861 	struct arm_gic_softc *sc = device_get_softc(dev);
862 
863 	arm_gic_disable_source(dev, isrc);
864 	gic_c_write_4(sc, GICC_EOIR, isrc->isrc_data);
865 }
866 
867 static void
868 arm_gic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
869 {
870 
871 	arm_irq_memory_barrier(0);
872 	arm_gic_enable_source(dev, isrc);
873 }
874 
875 static void
876 arm_gic_post_filter(device_t dev, struct intr_irqsrc *isrc)
877 {
878 	struct arm_gic_softc *sc = device_get_softc(dev);
879 
880         /* EOI for edge-triggered done earlier. */
881 	if (isrc->isrc_trig == INTR_TRIGGER_EDGE)
882 		return;
883 
884 	arm_irq_memory_barrier(0);
885 	gic_c_write_4(sc, GICC_EOIR, isrc->isrc_data);
886 }
887 
888 static int
889 arm_gic_bind(device_t dev, struct intr_irqsrc *isrc)
890 {
891 	struct arm_gic_softc *sc = device_get_softc(dev);
892 	uint32_t irq = isrc->isrc_data;
893 
894 	if (irq < GIC_FIRST_SPI)
895 		return (EINVAL);
896 
897 	if (CPU_EMPTY(&isrc->isrc_cpu)) {
898 		gic_irq_cpu = intr_irq_next_cpu(gic_irq_cpu, &all_cpus);
899 		CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu);
900 	}
901 	return (gic_bind(sc, irq, &isrc->isrc_cpu));
902 }
903 
904 #ifdef SMP
905 static void
906 arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus)
907 {
908 	struct arm_gic_softc *sc = device_get_softc(dev);
909 	uint32_t irq, val = 0, i;
910 
911 	irq = isrc->isrc_data;
912 
913 	for (i = 0; i < MAXCPU; i++)
914 		if (CPU_ISSET(i, &cpus))
915 			val |= 1 << (16 + i);
916 
917 	gic_d_write_4(sc, GICD_SGIR(0), val | irq);
918 }
919 #endif
920 #else
921 static int
922 arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq)
923 {
924 	uint32_t active_irq;
925 
926 	active_irq = gic_c_read_4(sc, GICC_IAR);
927 
928 	/*
929 	 * Immediatly EOIR the SGIs, because doing so requires the other
930 	 * bits (ie CPU number), not just the IRQ number, and we do not
931 	 * have this information later.
932 	 */
933 	if ((active_irq & 0x3ff) <= GIC_LAST_SGI)
934 		gic_c_write_4(sc, GICC_EOIR, active_irq);
935 	active_irq &= 0x3FF;
936 
937 	if (active_irq == 0x3FF) {
938 		if (last_irq == -1)
939 			device_printf(sc->gic_dev,
940 			    "Spurious interrupt detected\n");
941 		return -1;
942 	}
943 
944 	return active_irq;
945 }
946 
947 static int
948 arm_gic_config(device_t dev, int irq, enum intr_trigger trig,
949     enum intr_polarity pol)
950 {
951 	struct arm_gic_softc *sc = device_get_softc(dev);
952 	uint32_t reg;
953 	uint32_t mask;
954 
955 	/* Function is public-accessible, so validate input arguments */
956 	if ((irq < 0) || (irq >= sc->nirqs))
957 		goto invalid_args;
958 	if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) &&
959 	    (trig != INTR_TRIGGER_CONFORM))
960 		goto invalid_args;
961 	if ((pol != INTR_POLARITY_HIGH) && (pol != INTR_POLARITY_LOW) &&
962 	    (pol != INTR_POLARITY_CONFORM))
963 		goto invalid_args;
964 
965 	mtx_lock_spin(&sc->mutex);
966 
967 	reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
968 	mask = (reg >> 2*(irq % 16)) & 0x3;
969 
970 	if (pol == INTR_POLARITY_LOW) {
971 		mask &= ~GICD_ICFGR_POL_MASK;
972 		mask |= GICD_ICFGR_POL_LOW;
973 	} else if (pol == INTR_POLARITY_HIGH) {
974 		mask &= ~GICD_ICFGR_POL_MASK;
975 		mask |= GICD_ICFGR_POL_HIGH;
976 	}
977 
978 	if (trig == INTR_TRIGGER_LEVEL) {
979 		mask &= ~GICD_ICFGR_TRIG_MASK;
980 		mask |= GICD_ICFGR_TRIG_LVL;
981 	} else if (trig == INTR_TRIGGER_EDGE) {
982 		mask &= ~GICD_ICFGR_TRIG_MASK;
983 		mask |= GICD_ICFGR_TRIG_EDGE;
984 	}
985 
986 	/* Set mask */
987 	reg = reg & ~(0x3 << 2*(irq % 16));
988 	reg = reg | (mask << 2*(irq % 16));
989 	gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
990 
991 	mtx_unlock_spin(&sc->mutex);
992 
993 	return (0);
994 
995 invalid_args:
996 	device_printf(dev, "gic_config_irg, invalid parameters\n");
997 	return (EINVAL);
998 }
999 
1000 
1001 static void
1002 arm_gic_mask(device_t dev, int irq)
1003 {
1004 	struct arm_gic_softc *sc = device_get_softc(dev);
1005 
1006 	gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
1007 	gic_c_write_4(sc, GICC_EOIR, irq); /* XXX - not allowed */
1008 }
1009 
1010 static void
1011 arm_gic_unmask(device_t dev, int irq)
1012 {
1013 	struct arm_gic_softc *sc = device_get_softc(dev);
1014 
1015 	if (irq > GIC_LAST_SGI)
1016 		arm_irq_memory_barrier(irq);
1017 
1018 	gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
1019 }
1020 
1021 #ifdef SMP
1022 static void
1023 arm_gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi)
1024 {
1025 	struct arm_gic_softc *sc = device_get_softc(dev);
1026 	uint32_t val = 0, i;
1027 
1028 	for (i = 0; i < MAXCPU; i++)
1029 		if (CPU_ISSET(i, &cpus))
1030 			val |= 1 << (16 + i);
1031 
1032 	gic_d_write_4(sc, GICD_SGIR(0), val | ipi);
1033 }
1034 
1035 static int
1036 arm_gic_ipi_read(device_t dev, int i)
1037 {
1038 
1039 	if (i != -1) {
1040 		/*
1041 		 * The intr code will automagically give the frame pointer
1042 		 * if the interrupt argument is 0.
1043 		 */
1044 		if ((unsigned int)i > 16)
1045 			return (0);
1046 		return (i);
1047 	}
1048 
1049 	return (0x3ff);
1050 }
1051 
1052 static void
1053 arm_gic_ipi_clear(device_t dev, int ipi)
1054 {
1055 	/* no-op */
1056 }
1057 #endif
1058 
1059 static void
1060 gic_post_filter(void *arg)
1061 {
1062 	struct arm_gic_softc *sc = gic_sc;
1063 	uintptr_t irq = (uintptr_t) arg;
1064 
1065 	if (irq > GIC_LAST_SGI)
1066 		arm_irq_memory_barrier(irq);
1067 	gic_c_write_4(sc, GICC_EOIR, irq);
1068 }
1069 
1070 static int
1071 gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol)
1072 {
1073 
1074 	return (arm_gic_config(gic_sc->gic_dev, irq, trig, pol));
1075 }
1076 
1077 void
1078 arm_mask_irq(uintptr_t nb)
1079 {
1080 
1081 	arm_gic_mask(gic_sc->gic_dev, nb);
1082 }
1083 
1084 void
1085 arm_unmask_irq(uintptr_t nb)
1086 {
1087 
1088 	arm_gic_unmask(gic_sc->gic_dev, nb);
1089 }
1090 
1091 int
1092 arm_get_next_irq(int last_irq)
1093 {
1094 
1095 	return (arm_gic_next_irq(gic_sc, last_irq));
1096 }
1097 
1098 #ifdef SMP
1099 void
1100 intr_pic_init_secondary(void)
1101 {
1102 
1103 	arm_gic_init_secondary(gic_sc->gic_dev);
1104 }
1105 
1106 void
1107 pic_ipi_send(cpuset_t cpus, u_int ipi)
1108 {
1109 
1110 	arm_gic_ipi_send(gic_sc->gic_dev, cpus, ipi);
1111 }
1112 
1113 int
1114 pic_ipi_read(int i)
1115 {
1116 
1117 	return (arm_gic_ipi_read(gic_sc->gic_dev, i));
1118 }
1119 
1120 void
1121 pic_ipi_clear(int ipi)
1122 {
1123 
1124 	arm_gic_ipi_clear(gic_sc->gic_dev, ipi);
1125 }
1126 #endif
1127 #endif /* ARM_INTRNG */
1128 
1129 static device_method_t arm_gic_methods[] = {
1130 	/* Device interface */
1131 	DEVMETHOD(device_probe,		arm_gic_probe),
1132 	DEVMETHOD(device_attach,	arm_gic_attach),
1133 #ifdef ARM_INTRNG
1134 	/* Interrupt controller interface */
1135 	DEVMETHOD(pic_disable_source,	arm_gic_disable_source),
1136 	DEVMETHOD(pic_enable_intr,	arm_gic_enable_intr),
1137 	DEVMETHOD(pic_enable_source,	arm_gic_enable_source),
1138 	DEVMETHOD(pic_post_filter,	arm_gic_post_filter),
1139 	DEVMETHOD(pic_post_ithread,	arm_gic_post_ithread),
1140 	DEVMETHOD(pic_pre_ithread,	arm_gic_pre_ithread),
1141 	DEVMETHOD(pic_register,		arm_gic_register),
1142 	DEVMETHOD(pic_unregister,	arm_gic_unregister),
1143 #ifdef SMP
1144 	DEVMETHOD(pic_bind,		arm_gic_bind),
1145 	DEVMETHOD(pic_init_secondary,	arm_gic_init_secondary),
1146 	DEVMETHOD(pic_ipi_send,		arm_gic_ipi_send),
1147 #endif
1148 #endif
1149 	{ 0, 0 }
1150 };
1151 
1152 static driver_t arm_gic_driver = {
1153 	"gic",
1154 	arm_gic_methods,
1155 	sizeof(struct arm_gic_softc),
1156 };
1157 
1158 static devclass_t arm_gic_devclass;
1159 
1160 EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
1161     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
1162 EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
1163     BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
1164