]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/gic.c
Rework printouts and logging level in ENA driver
[FreeBSD/FreeBSD.git] / sys / arm / arm / gic.c
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 <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/bus.h>
42 #include <sys/kernel.h>
43 #include <sys/ktr.h>
44 #include <sys/module.h>
45 #include <sys/malloc.h>
46 #include <sys/rman.h>
47 #include <sys/pcpu.h>
48 #include <sys/proc.h>
49 #include <sys/cpuset.h>
50 #include <sys/lock.h>
51 #include <sys/mutex.h>
52 #include <sys/smp.h>
53 #ifdef INTRNG
54 #include <sys/sched.h>
55 #endif
56
57 #include <vm/vm.h>
58 #include <vm/pmap.h>
59
60 #include <machine/bus.h>
61 #include <machine/intr.h>
62 #include <machine/smp.h>
63
64 #ifdef FDT
65 #include <dev/fdt/fdt_intr.h>
66 #include <dev/ofw/ofw_bus_subr.h>
67 #endif
68
69 #include <arm/arm/gic.h>
70 #include <arm/arm/gic_common.h>
71
72 #ifdef INTRNG
73 #include "pic_if.h"
74 #include "msi_if.h"
75 #endif
76
77 /* We are using GICv2 register naming */
78
79 /* Distributor Registers */
80
81 /* CPU Registers */
82 #define GICC_CTLR               0x0000                  /* v1 ICCICR */
83 #define GICC_PMR                0x0004                  /* v1 ICCPMR */
84 #define GICC_BPR                0x0008                  /* v1 ICCBPR */
85 #define GICC_IAR                0x000C                  /* v1 ICCIAR */
86 #define GICC_EOIR               0x0010                  /* v1 ICCEOIR */
87 #define GICC_RPR                0x0014                  /* v1 ICCRPR */
88 #define GICC_HPPIR              0x0018                  /* v1 ICCHPIR */
89 #define GICC_ABPR               0x001C                  /* v1 ICCABPR */
90 #define GICC_IIDR               0x00FC                  /* v1 ICCIIDR*/
91
92 /* TYPER Registers */
93 #define GICD_TYPER_SECURITYEXT  0x400
94 #define GIC_SUPPORT_SECEXT(_sc) \
95     ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT)
96
97
98 #ifndef GIC_DEFAULT_ICFGR_INIT
99 #define GIC_DEFAULT_ICFGR_INIT  0x00000000
100 #endif
101
102 #ifdef INTRNG
103 struct gic_irqsrc {
104         struct intr_irqsrc      gi_isrc;
105         uint32_t                gi_irq;
106         enum intr_polarity      gi_pol;
107         enum intr_trigger       gi_trig;
108 #define GI_FLAG_EARLY_EOI       (1 << 0)
109 #define GI_FLAG_MSI             (1 << 1) /* This interrupt source should only */
110                                          /* be used for MSI/MSI-X interrupts */
111 #define GI_FLAG_MSI_USED        (1 << 2) /* This irq is already allocated */
112                                          /* for a MSI/MSI-X interrupt */
113         u_int                   gi_flags;
114 };
115
116 static u_int gic_irq_cpu;
117 static int arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc);
118
119 #ifdef SMP
120 static u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1];
121 static u_int sgi_first_unused = GIC_FIRST_SGI;
122 #endif
123
124 #define GIC_INTR_ISRC(sc, irq)  (&sc->gic_irqs[irq].gi_isrc)
125 #else /* !INTRNG */
126 static struct ofw_compat_data compat_data[] = {
127         {"arm,gic",             true},  /* Non-standard, used in FreeBSD dts. */
128         {"arm,gic-400",         true},
129         {"arm,cortex-a15-gic",  true},
130         {"arm,cortex-a9-gic",   true},
131         {"arm,cortex-a7-gic",   true},
132         {"arm,arm11mp-gic",     true},
133         {"brcm,brahma-b15-gic", true},
134         {"qcom,msm-qgic2",      true},
135         {NULL,                  false}
136 };
137 #endif
138
139 static struct resource_spec arm_gic_spec[] = {
140         { SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Distributor registers */
141         { SYS_RES_MEMORY,       1,      RF_ACTIVE },    /* CPU Interrupt Intf. registers */
142 #ifdef INTRNG
143         { SYS_RES_IRQ,    0, RF_ACTIVE | RF_OPTIONAL }, /* Parent interrupt */
144 #endif
145         { -1, 0 }
146 };
147
148
149 #if defined(__arm__) && defined(INVARIANTS)
150 static int gic_debug_spurious = 1;
151 #else
152 static int gic_debug_spurious = 0;
153 #endif
154 TUNABLE_INT("hw.gic.debug_spurious", &gic_debug_spurious);
155
156 static u_int arm_gic_map[MAXCPU];
157
158 static struct arm_gic_softc *gic_sc = NULL;
159
160 #define gic_c_read_4(_sc, _reg)         \
161     bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg))
162 #define gic_c_write_4(_sc, _reg, _val)          \
163     bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val))
164 #define gic_d_read_4(_sc, _reg)         \
165     bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg))
166 #define gic_d_write_1(_sc, _reg, _val)          \
167     bus_space_write_1((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
168 #define gic_d_write_4(_sc, _reg, _val)          \
169     bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
170
171 #ifndef INTRNG
172 static int gic_config_irq(int irq, enum intr_trigger trig,
173     enum intr_polarity pol);
174 static void gic_post_filter(void *);
175 #endif
176
177 #ifdef INTRNG
178 static inline void
179 gic_irq_unmask(struct arm_gic_softc *sc, u_int irq)
180 {
181
182         gic_d_write_4(sc, GICD_ISENABLER(irq), GICD_I_MASK(irq));
183 }
184
185 static inline void
186 gic_irq_mask(struct arm_gic_softc *sc, u_int irq)
187 {
188
189         gic_d_write_4(sc, GICD_ICENABLER(irq), GICD_I_MASK(irq));
190 }
191 #endif
192
193 static uint8_t
194 gic_cpu_mask(struct arm_gic_softc *sc)
195 {
196         uint32_t mask;
197         int i;
198
199         /* Read the current cpuid mask by reading ITARGETSR{0..7} */
200         for (i = 0; i < 8; i++) {
201                 mask = gic_d_read_4(sc, GICD_ITARGETSR(4 * i));
202                 if (mask != 0)
203                         break;
204         }
205         /* No mask found, assume we are on CPU interface 0 */
206         if (mask == 0)
207                 return (1);
208
209         /* Collect the mask in the lower byte */
210         mask |= mask >> 16;
211         mask |= mask >> 8;
212
213         return (mask);
214 }
215
216 #ifdef SMP
217 #ifdef INTRNG
218 static void
219 arm_gic_init_secondary(device_t dev)
220 {
221         struct arm_gic_softc *sc = device_get_softc(dev);
222         u_int irq, cpu;
223
224         /* Set the mask so we can find this CPU to send it IPIs */
225         cpu = PCPU_GET(cpuid);
226         arm_gic_map[cpu] = gic_cpu_mask(sc);
227
228         for (irq = 0; irq < sc->nirqs; irq += 4)
229                 gic_d_write_4(sc, GICD_IPRIORITYR(irq), 0);
230
231         /* Set all the interrupts to be in Group 0 (secure) */
232         for (irq = 0; GIC_SUPPORT_SECEXT(sc) && irq < sc->nirqs; irq += 32) {
233                 gic_d_write_4(sc, GICD_IGROUPR(irq), 0);
234         }
235
236         /* Enable CPU interface */
237         gic_c_write_4(sc, GICC_CTLR, 1);
238
239         /* Set priority mask register. */
240         gic_c_write_4(sc, GICC_PMR, 0xff);
241
242         /* Enable interrupt distribution */
243         gic_d_write_4(sc, GICD_CTLR, 0x01);
244
245         /* Unmask attached SGI interrupts. */
246         for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++)
247                 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
248                         gic_irq_unmask(sc, irq);
249
250         /* Unmask attached PPI interrupts. */
251         for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++)
252                 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu))
253                         gic_irq_unmask(sc, irq);
254 }
255 #else
256 static void
257 arm_gic_init_secondary(device_t dev)
258 {
259         struct arm_gic_softc *sc = device_get_softc(dev);
260         int i;
261
262         /* Set the mask so we can find this CPU to send it IPIs */
263         arm_gic_map[PCPU_GET(cpuid)] = gic_cpu_mask(sc);
264
265         for (i = 0; i < sc->nirqs; i += 4)
266                 gic_d_write_4(sc, GICD_IPRIORITYR(i), 0);
267
268         /* Set all the interrupts to be in Group 0 (secure) */
269         for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
270                 gic_d_write_4(sc, GICD_IGROUPR(i), 0);
271         }
272
273         /* Enable CPU interface */
274         gic_c_write_4(sc, GICC_CTLR, 1);
275
276         /* Set priority mask register. */
277         gic_c_write_4(sc, GICC_PMR, 0xff);
278
279         /* Enable interrupt distribution */
280         gic_d_write_4(sc, GICD_CTLR, 0x01);
281
282         /*
283          * Activate the timer interrupts: virtual, secure, and non-secure.
284          */
285         gic_d_write_4(sc, GICD_ISENABLER(27), GICD_I_MASK(27));
286         gic_d_write_4(sc, GICD_ISENABLER(29), GICD_I_MASK(29));
287         gic_d_write_4(sc, GICD_ISENABLER(30), GICD_I_MASK(30));
288 }
289 #endif /* INTRNG */
290 #endif /* SMP */
291
292 #ifndef INTRNG
293 int
294 gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
295     int *trig, int *pol)
296 {
297         static u_int num_intr_cells;
298         static phandle_t self;
299         struct ofw_compat_data *ocd;
300
301         if (self == 0) {
302                 for (ocd = compat_data; ocd->ocd_str != NULL; ocd++) {
303                         if (ofw_bus_node_is_compatible(iparent, ocd->ocd_str)) {
304                                 self = iparent;
305                                 break;
306                         }
307                 }
308         }
309         if (self != iparent)
310                 return (ENXIO);
311
312         if (num_intr_cells == 0) {
313                 if (OF_searchencprop(OF_node_from_xref(iparent),
314                     "#interrupt-cells", &num_intr_cells,
315                     sizeof(num_intr_cells)) == -1) {
316                         num_intr_cells = 1;
317                 }
318         }
319
320         if (num_intr_cells == 1) {
321                 *interrupt = fdt32_to_cpu(intr[0]);
322                 *trig = INTR_TRIGGER_CONFORM;
323                 *pol = INTR_POLARITY_CONFORM;
324         } else {
325                 if (fdt32_to_cpu(intr[0]) == 0)
326                         *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI;
327                 else
328                         *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI;
329                 /*
330                  * In intr[2], bits[3:0] are trigger type and level flags.
331                  *   1 = low-to-high edge triggered
332                  *   2 = high-to-low edge triggered
333                  *   4 = active high level-sensitive
334                  *   8 = active low level-sensitive
335                  * The hardware only supports active-high-level or rising-edge
336                  * for SPIs
337                  */
338                 if (*interrupt >= GIC_FIRST_SPI &&
339                     fdt32_to_cpu(intr[2]) & 0x0a) {
340                         printf("unsupported trigger/polarity configuration "
341                             "0x%02x\n", fdt32_to_cpu(intr[2]) & 0x0f);
342                 }
343                 *pol  = INTR_POLARITY_CONFORM;
344                 if (fdt32_to_cpu(intr[2]) & 0x03)
345                         *trig = INTR_TRIGGER_EDGE;
346                 else
347                         *trig = INTR_TRIGGER_LEVEL;
348         }
349         return (0);
350 }
351 #endif
352
353 #ifdef INTRNG
354 static int
355 arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num)
356 {
357         int error;
358         uint32_t irq;
359         struct gic_irqsrc *irqs;
360         struct intr_irqsrc *isrc;
361         const char *name;
362
363         irqs = malloc(num * sizeof(struct gic_irqsrc), M_DEVBUF,
364             M_WAITOK | M_ZERO);
365
366         name = device_get_nameunit(sc->gic_dev);
367         for (irq = 0; irq < num; irq++) {
368                 irqs[irq].gi_irq = irq;
369                 irqs[irq].gi_pol = INTR_POLARITY_CONFORM;
370                 irqs[irq].gi_trig = INTR_TRIGGER_CONFORM;
371
372                 isrc = &irqs[irq].gi_isrc;
373                 if (irq <= GIC_LAST_SGI) {
374                         error = intr_isrc_register(isrc, sc->gic_dev,
375                             INTR_ISRCF_IPI, "%s,i%u", name, irq - GIC_FIRST_SGI);
376                 } else if (irq <= GIC_LAST_PPI) {
377                         error = intr_isrc_register(isrc, sc->gic_dev,
378                             INTR_ISRCF_PPI, "%s,p%u", name, irq - GIC_FIRST_PPI);
379                 } else {
380                         error = intr_isrc_register(isrc, sc->gic_dev, 0,
381                             "%s,s%u", name, irq - GIC_FIRST_SPI);
382                 }
383                 if (error != 0) {
384                         /* XXX call intr_isrc_deregister() */
385                         free(irqs, M_DEVBUF);
386                         return (error);
387                 }
388         }
389         sc->gic_irqs = irqs;
390         sc->nirqs = num;
391         return (0);
392 }
393
394 static void
395 arm_gic_reserve_msi_range(device_t dev, u_int start, u_int count)
396 {
397         struct arm_gic_softc *sc;
398         int i;
399
400         sc = device_get_softc(dev);
401
402         KASSERT((start + count) < sc->nirqs,
403             ("%s: Trying to allocate too many MSI IRQs: %d + %d > %d", __func__,
404             start, count, sc->nirqs));
405         for (i = 0; i < count; i++) {
406                 KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0,
407                     ("%s: MSI interrupt %d already has a handler", __func__,
408                     count + i));
409                 KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM,
410                     ("%s: MSI interrupt %d already has a polarity", __func__,
411                     count + i));
412                 KASSERT(sc->gic_irqs[start + i].gi_trig == INTR_TRIGGER_CONFORM,
413                     ("%s: MSI interrupt %d already has a trigger", __func__,
414                     count + i));
415                 sc->gic_irqs[start + i].gi_pol = INTR_POLARITY_HIGH;
416                 sc->gic_irqs[start + i].gi_trig = INTR_TRIGGER_EDGE;
417                 sc->gic_irqs[start + i].gi_flags |= GI_FLAG_MSI;
418         }
419 }
420 #endif
421
422 int
423 arm_gic_attach(device_t dev)
424 {
425         struct          arm_gic_softc *sc;
426         int             i;
427         uint32_t        icciidr, mask, nirqs;
428
429         if (gic_sc)
430                 return (ENXIO);
431
432         sc = device_get_softc(dev);
433
434         if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
435                 device_printf(dev, "could not allocate resources\n");
436                 return (ENXIO);
437         }
438
439         sc->gic_dev = dev;
440         gic_sc = sc;
441
442         /* Initialize mutex */
443         mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
444
445         /* Distributor Interface */
446         sc->gic_d_bst = rman_get_bustag(sc->gic_res[0]);
447         sc->gic_d_bsh = rman_get_bushandle(sc->gic_res[0]);
448
449         /* CPU Interface */
450         sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
451         sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
452
453         /* Disable interrupt forwarding to the CPU interface */
454         gic_d_write_4(sc, GICD_CTLR, 0x00);
455
456         /* Get the number of interrupts */
457         sc->typer = gic_d_read_4(sc, GICD_TYPER);
458         nirqs = GICD_TYPER_I_NUM(sc->typer);
459
460 #ifdef INTRNG
461         if (arm_gic_register_isrcs(sc, nirqs)) {
462                 device_printf(dev, "could not register irqs\n");
463                 goto cleanup;
464         }
465 #else
466         sc->nirqs = nirqs;
467
468         /* Set up function pointers */
469         arm_post_filter = gic_post_filter;
470         arm_config_irq = gic_config_irq;
471 #endif
472
473         icciidr = gic_c_read_4(sc, GICC_IIDR);
474         device_printf(dev,
475             "pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
476             GICD_IIDR_PROD(icciidr), GICD_IIDR_VAR(icciidr),
477             GICD_IIDR_REV(icciidr), GICD_IIDR_IMPL(icciidr), sc->nirqs);
478 #ifdef INTRNG
479         sc->gic_iidr = icciidr;
480 #endif
481
482         /* Set all global interrupts to be level triggered, active low. */
483         for (i = 32; i < sc->nirqs; i += 16) {
484                 gic_d_write_4(sc, GICD_ICFGR(i), GIC_DEFAULT_ICFGR_INIT);
485         }
486
487         /* Disable all interrupts. */
488         for (i = 32; i < sc->nirqs; i += 32) {
489                 gic_d_write_4(sc, GICD_ICENABLER(i), 0xFFFFFFFF);
490         }
491
492         /* Find the current cpu mask */
493         mask = gic_cpu_mask(sc);
494         /* Set the mask so we can find this CPU to send it IPIs */
495         arm_gic_map[PCPU_GET(cpuid)] = mask;
496         /* Set all four targets to this cpu */
497         mask |= mask << 8;
498         mask |= mask << 16;
499
500         for (i = 0; i < sc->nirqs; i += 4) {
501                 gic_d_write_4(sc, GICD_IPRIORITYR(i), 0);
502                 if (i > 32) {
503                         gic_d_write_4(sc, GICD_ITARGETSR(i), mask);
504                 }
505         }
506
507         /* Set all the interrupts to be in Group 0 (secure) */
508         for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) {
509                 gic_d_write_4(sc, GICD_IGROUPR(i), 0);
510         }
511
512         /* Enable CPU interface */
513         gic_c_write_4(sc, GICC_CTLR, 1);
514
515         /* Set priority mask register. */
516         gic_c_write_4(sc, GICC_PMR, 0xff);
517
518         /* Enable interrupt distribution */
519         gic_d_write_4(sc, GICD_CTLR, 0x01);
520         return (0);
521
522 #ifdef INTRNG
523 cleanup:
524         arm_gic_detach(dev);
525         return(ENXIO);
526 #endif
527 }
528
529 int
530 arm_gic_detach(device_t dev)
531 {
532 #ifdef INTRNG
533         struct arm_gic_softc *sc;
534
535         sc = device_get_softc(dev);
536
537         if (sc->gic_irqs != NULL)
538                 free(sc->gic_irqs, M_DEVBUF);
539
540         bus_release_resources(dev, arm_gic_spec, sc->gic_res);
541 #endif
542
543         return (0);
544 }
545
546 #ifdef INTRNG
547 static int
548 arm_gic_print_child(device_t bus, device_t child)
549 {
550         struct resource_list *rl;
551         int rv;
552
553         rv = bus_print_child_header(bus, child);
554
555         rl = BUS_GET_RESOURCE_LIST(bus, child);
556         if (rl != NULL) {
557                 rv += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
558                     "%#jx");
559                 rv += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd");
560         }
561
562         rv += bus_print_child_footer(bus, child);
563
564         return (rv);
565 }
566
567 static struct resource *
568 arm_gic_alloc_resource(device_t bus, device_t child, int type, int *rid,
569     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
570 {
571         struct arm_gic_softc *sc;
572         struct resource_list_entry *rle;
573         struct resource_list *rl;
574         int j;
575
576         KASSERT(type == SYS_RES_MEMORY, ("Invalid resoure type %x", type));
577
578         sc = device_get_softc(bus);
579
580         /*
581          * Request for the default allocation with a given rid: use resource
582          * list stored in the local device info.
583          */
584         if (RMAN_IS_DEFAULT_RANGE(start, end)) {
585                 rl = BUS_GET_RESOURCE_LIST(bus, child);
586
587                 if (type == SYS_RES_IOPORT)
588                         type = SYS_RES_MEMORY;
589
590                 rle = resource_list_find(rl, type, *rid);
591                 if (rle == NULL) {
592                         if (bootverbose)
593                                 device_printf(bus, "no default resources for "
594                                     "rid = %d, type = %d\n", *rid, type);
595                         return (NULL);
596                 }
597                 start = rle->start;
598                 end = rle->end;
599                 count = rle->count;
600         }
601
602         /* Remap through ranges property */
603         for (j = 0; j < sc->nranges; j++) {
604                 if (start >= sc->ranges[j].bus && end <
605                     sc->ranges[j].bus + sc->ranges[j].size) {
606                         start -= sc->ranges[j].bus;
607                         start += sc->ranges[j].host;
608                         end -= sc->ranges[j].bus;
609                         end += sc->ranges[j].host;
610                         break;
611                 }
612         }
613         if (j == sc->nranges && sc->nranges != 0) {
614                 if (bootverbose)
615                         device_printf(bus, "Could not map resource "
616                             "%#jx-%#jx\n", (uintmax_t)start, (uintmax_t)end);
617
618                 return (NULL);
619         }
620
621         return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
622             count, flags));
623 }
624
625 static int
626 arm_gic_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
627 {
628         struct arm_gic_softc *sc;
629
630         sc = device_get_softc(dev);
631
632         switch(which) {
633         case GIC_IVAR_HW_REV:
634                 KASSERT(GICD_IIDR_VAR(sc->gic_iidr) < 3 &&
635                     GICD_IIDR_VAR(sc->gic_iidr) != 0,
636                     ("arm_gic_read_ivar: Unknown IIDR revision %u (%.08x)",
637                      GICD_IIDR_VAR(sc->gic_iidr), sc->gic_iidr));
638                 *result = GICD_IIDR_VAR(sc->gic_iidr);
639                 return (0);
640         case GIC_IVAR_BUS:
641                 KASSERT(sc->gic_bus != GIC_BUS_UNKNOWN,
642                     ("arm_gic_read_ivar: Unknown bus type"));
643                 KASSERT(sc->gic_bus <= GIC_BUS_MAX,
644                     ("arm_gic_read_ivar: Invalid bus type %u", sc->gic_bus));
645                 *result = sc->gic_bus;
646                 return (0);
647         }
648
649         return (ENOENT);
650 }
651
652 int
653 arm_gic_intr(void *arg)
654 {
655         struct arm_gic_softc *sc = arg;
656         struct gic_irqsrc *gi;
657         uint32_t irq_active_reg, irq;
658         struct trapframe *tf;
659
660         irq_active_reg = gic_c_read_4(sc, GICC_IAR);
661         irq = irq_active_reg & 0x3FF;
662
663         /*
664          * 1. We do EOI here because recent read value from active interrupt
665          *    register must be used for it. Another approach is to save this
666          *    value into associated interrupt source.
667          * 2. EOI must be done on same CPU where interrupt has fired. Thus
668          *    we must ensure that interrupted thread does not migrate to
669          *    another CPU.
670          * 3. EOI cannot be delayed by any preemption which could happen on
671          *    critical_exit() used in MI intr code, when interrupt thread is
672          *    scheduled. See next point.
673          * 4. IPI_RENDEZVOUS assumes that no preemption is permitted during
674          *    an action and any use of critical_exit() could break this
675          *    assumption. See comments within smp_rendezvous_action().
676          * 5. We always return FILTER_HANDLED as this is an interrupt
677          *    controller dispatch function. Otherwise, in cascaded interrupt
678          *    case, the whole interrupt subtree would be masked.
679          */
680
681         if (irq >= sc->nirqs) {
682                 if (gic_debug_spurious)
683                         device_printf(sc->gic_dev,
684                             "Spurious interrupt detected: last irq: %d on CPU%d\n",
685                             sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid));
686                 return (FILTER_HANDLED);
687         }
688
689         tf = curthread->td_intr_frame;
690 dispatch_irq:
691         gi = sc->gic_irqs + irq;
692         /*
693          * Note that GIC_FIRST_SGI is zero and is not used in 'if' statement
694          * as compiler complains that comparing u_int >= 0 is always true.
695          */
696         if (irq <= GIC_LAST_SGI) {
697 #ifdef SMP
698                 /* Call EOI for all IPI before dispatch. */
699                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
700                 intr_ipi_dispatch(sgi_to_ipi[gi->gi_irq], tf);
701                 goto next_irq;
702 #else
703                 device_printf(sc->gic_dev, "SGI %u on UP system detected\n",
704                     irq - GIC_FIRST_SGI);
705                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
706                 goto next_irq;
707 #endif
708         }
709
710         if (gic_debug_spurious)
711                 sc->last_irq[PCPU_GET(cpuid)] = irq;
712         if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI)
713                 gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
714
715         if (intr_isrc_dispatch(&gi->gi_isrc, tf) != 0) {
716                 gic_irq_mask(sc, irq);
717                 if ((gi->gi_flags & GI_FLAG_EARLY_EOI) != GI_FLAG_EARLY_EOI)
718                         gic_c_write_4(sc, GICC_EOIR, irq_active_reg);
719                 device_printf(sc->gic_dev, "Stray irq %u disabled\n", irq);
720         }
721
722 next_irq:
723         arm_irq_memory_barrier(irq);
724         irq_active_reg = gic_c_read_4(sc, GICC_IAR);
725         irq = irq_active_reg & 0x3FF;
726         if (irq < sc->nirqs)
727                 goto dispatch_irq;
728
729         return (FILTER_HANDLED);
730 }
731
732 static void
733 gic_config(struct arm_gic_softc *sc, u_int irq, enum intr_trigger trig,
734     enum intr_polarity pol)
735 {
736         uint32_t reg;
737         uint32_t mask;
738
739         if (irq < GIC_FIRST_SPI)
740                 return;
741
742         mtx_lock_spin(&sc->mutex);
743
744         reg = gic_d_read_4(sc, GICD_ICFGR(irq));
745         mask = (reg >> 2*(irq % 16)) & 0x3;
746
747         if (pol == INTR_POLARITY_LOW) {
748                 mask &= ~GICD_ICFGR_POL_MASK;
749                 mask |= GICD_ICFGR_POL_LOW;
750         } else if (pol == INTR_POLARITY_HIGH) {
751                 mask &= ~GICD_ICFGR_POL_MASK;
752                 mask |= GICD_ICFGR_POL_HIGH;
753         }
754
755         if (trig == INTR_TRIGGER_LEVEL) {
756                 mask &= ~GICD_ICFGR_TRIG_MASK;
757                 mask |= GICD_ICFGR_TRIG_LVL;
758         } else if (trig == INTR_TRIGGER_EDGE) {
759                 mask &= ~GICD_ICFGR_TRIG_MASK;
760                 mask |= GICD_ICFGR_TRIG_EDGE;
761         }
762
763         /* Set mask */
764         reg = reg & ~(0x3 << 2*(irq % 16));
765         reg = reg | (mask << 2*(irq % 16));
766         gic_d_write_4(sc, GICD_ICFGR(irq), reg);
767
768         mtx_unlock_spin(&sc->mutex);
769 }
770
771 static int
772 gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus)
773 {
774         uint32_t cpu, end, mask;
775
776         end = min(mp_ncpus, 8);
777         for (cpu = end; cpu < MAXCPU; cpu++)
778                 if (CPU_ISSET(cpu, cpus))
779                         return (EINVAL);
780
781         for (mask = 0, cpu = 0; cpu < end; cpu++)
782                 if (CPU_ISSET(cpu, cpus))
783                         mask |= arm_gic_map[cpu];
784
785         gic_d_write_1(sc, GICD_ITARGETSR(0) + irq, mask);
786         return (0);
787 }
788
789 #ifdef FDT
790 static int
791 gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
792     enum intr_polarity *polp, enum intr_trigger *trigp)
793 {
794
795         if (ncells == 1) {
796                 *irqp = cells[0];
797                 *polp = INTR_POLARITY_CONFORM;
798                 *trigp = INTR_TRIGGER_CONFORM;
799                 return (0);
800         }
801         if (ncells == 3) {
802                 u_int irq, tripol;
803
804                 /*
805                  * The 1st cell is the interrupt type:
806                  *      0 = SPI
807                  *      1 = PPI
808                  * The 2nd cell contains the interrupt number:
809                  *      [0 - 987] for SPI
810                  *      [0 -  15] for PPI
811                  * The 3rd cell is the flags, encoded as follows:
812                  *   bits[3:0] trigger type and level flags
813                  *      1 = low-to-high edge triggered
814                  *      2 = high-to-low edge triggered
815                  *      4 = active high level-sensitive
816                  *      8 = active low level-sensitive
817                  *   bits[15:8] PPI interrupt cpu mask
818                  *      Each bit corresponds to each of the 8 possible cpus
819                  *      attached to the GIC.  A bit set to '1' indicated
820                  *      the interrupt is wired to that CPU.
821                  */
822                 switch (cells[0]) {
823                 case 0:
824                         irq = GIC_FIRST_SPI + cells[1];
825                         /* SPI irq is checked later. */
826                         break;
827                 case 1:
828                         irq = GIC_FIRST_PPI + cells[1];
829                         if (irq > GIC_LAST_PPI) {
830                                 device_printf(dev, "unsupported PPI interrupt "
831                                     "number %u\n", cells[1]);
832                                 return (EINVAL);
833                         }
834                         break;
835                 default:
836                         device_printf(dev, "unsupported interrupt type "
837                             "configuration %u\n", cells[0]);
838                         return (EINVAL);
839                 }
840
841                 tripol = cells[2] & 0xff;
842                 if (tripol & 0xf0 || (tripol & FDT_INTR_LOW_MASK &&
843                     cells[0] == 0))
844                         device_printf(dev, "unsupported trigger/polarity "
845                             "configuration 0x%02x\n", tripol);
846
847                 *irqp = irq;
848                 *polp = INTR_POLARITY_CONFORM;
849                 *trigp = tripol & FDT_INTR_EDGE_MASK ?
850                     INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL;
851                 return (0);
852         }
853         return (EINVAL);
854 }
855 #endif
856
857 static int
858 gic_map_msi(device_t dev, struct intr_map_data_msi *msi_data, u_int *irqp,
859     enum intr_polarity *polp, enum intr_trigger *trigp)
860 {
861         struct gic_irqsrc *gi;
862
863         /* Map a non-GICv2m MSI */
864         gi = (struct gic_irqsrc *)msi_data->isrc;
865         if (gi == NULL)
866                 return (ENXIO);
867
868         *irqp = gi->gi_irq;
869
870         /* MSI/MSI-X interrupts are always edge triggered with high polarity */
871         *polp = INTR_POLARITY_HIGH;
872         *trigp = INTR_TRIGGER_EDGE;
873
874         return (0);
875 }
876
877 static int
878 gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
879     enum intr_polarity *polp, enum intr_trigger *trigp)
880 {
881         u_int irq;
882         enum intr_polarity pol;
883         enum intr_trigger trig;
884         struct arm_gic_softc *sc;
885         struct intr_map_data_msi *dam;
886 #ifdef FDT
887         struct intr_map_data_fdt *daf;
888 #endif
889
890         sc = device_get_softc(dev);
891         switch (data->type) {
892 #ifdef FDT
893         case INTR_MAP_DATA_FDT:
894                 daf = (struct intr_map_data_fdt *)data;
895                 if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
896                     &trig) != 0)
897                         return (EINVAL);
898                 KASSERT(irq >= sc->nirqs ||
899                     (sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) == 0,
900                     ("%s: Attempting to map a MSI interrupt from FDT",
901                     __func__));
902                 break;
903 #endif
904         case INTR_MAP_DATA_MSI:
905                 /* Non-GICv2m MSI */
906                 dam = (struct intr_map_data_msi *)data;
907                 if (gic_map_msi(dev, dam, &irq, &pol, &trig) != 0)
908                         return (EINVAL);
909                 break;
910         default:
911                 return (ENOTSUP);
912         }
913
914         if (irq >= sc->nirqs)
915                 return (EINVAL);
916         if (pol != INTR_POLARITY_CONFORM && pol != INTR_POLARITY_LOW &&
917             pol != INTR_POLARITY_HIGH)
918                 return (EINVAL);
919         if (trig != INTR_TRIGGER_CONFORM && trig != INTR_TRIGGER_EDGE &&
920             trig != INTR_TRIGGER_LEVEL)
921                 return (EINVAL);
922
923         *irqp = irq;
924         if (polp != NULL)
925                 *polp = pol;
926         if (trigp != NULL)
927                 *trigp = trig;
928         return (0);
929 }
930
931 static int
932 arm_gic_map_intr(device_t dev, struct intr_map_data *data,
933     struct intr_irqsrc **isrcp)
934 {
935         int error;
936         u_int irq;
937         struct arm_gic_softc *sc;
938
939         error = gic_map_intr(dev, data, &irq, NULL, NULL);
940         if (error == 0) {
941                 sc = device_get_softc(dev);
942                 *isrcp = GIC_INTR_ISRC(sc, irq);
943         }
944         return (error);
945 }
946
947 static int
948 arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
949     struct resource *res, struct intr_map_data *data)
950 {
951         struct arm_gic_softc *sc = device_get_softc(dev);
952         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
953         enum intr_trigger trig;
954         enum intr_polarity pol;
955
956         if ((gi->gi_flags & GI_FLAG_MSI) == GI_FLAG_MSI) {
957                 /* GICv2m MSI */
958                 pol = gi->gi_pol;
959                 trig = gi->gi_trig;
960                 KASSERT(pol == INTR_POLARITY_HIGH,
961                     ("%s: MSI interrupts must be active-high", __func__));
962                 KASSERT(trig == INTR_TRIGGER_EDGE,
963                     ("%s: MSI interrupts must be edge triggered", __func__));
964         } else if (data != NULL) {
965                 u_int irq;
966
967                 /* Get config for resource. */
968                 if (gic_map_intr(dev, data, &irq, &pol, &trig) ||
969                     gi->gi_irq != irq)
970                         return (EINVAL);
971         } else {
972                 pol = INTR_POLARITY_CONFORM;
973                 trig = INTR_TRIGGER_CONFORM;
974         }
975
976         /* Compare config if this is not first setup. */
977         if (isrc->isrc_handlers != 0) {
978                 if ((pol != INTR_POLARITY_CONFORM && pol != gi->gi_pol) ||
979                     (trig != INTR_TRIGGER_CONFORM && trig != gi->gi_trig))
980                         return (EINVAL);
981                 else
982                         return (0);
983         }
984
985         /* For MSI/MSI-X we should have already configured these */
986         if ((gi->gi_flags & GI_FLAG_MSI) == 0) {
987                 if (pol == INTR_POLARITY_CONFORM)
988                         pol = INTR_POLARITY_LOW;        /* just pick some */
989                 if (trig == INTR_TRIGGER_CONFORM)
990                         trig = INTR_TRIGGER_EDGE;       /* just pick some */
991
992                 gi->gi_pol = pol;
993                 gi->gi_trig = trig;
994
995                 /* Edge triggered interrupts need an early EOI sent */
996                 if (gi->gi_trig == INTR_TRIGGER_EDGE)
997                         gi->gi_flags |= GI_FLAG_EARLY_EOI;
998         }
999
1000         /*
1001          * XXX - In case that per CPU interrupt is going to be enabled in time
1002          *       when SMP is already started, we need some IPI call which
1003          *       enables it on others CPUs. Further, it's more complicated as
1004          *       pic_enable_source() and pic_disable_source() should act on
1005          *       per CPU basis only. Thus, it should be solved here somehow.
1006          */
1007         if (isrc->isrc_flags & INTR_ISRCF_PPI)
1008                 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
1009
1010         gic_config(sc, gi->gi_irq, gi->gi_trig, gi->gi_pol);
1011         arm_gic_bind_intr(dev, isrc);
1012         return (0);
1013 }
1014
1015 static int
1016 arm_gic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
1017     struct resource *res, struct intr_map_data *data)
1018 {
1019         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1020
1021         if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) {
1022                 gi->gi_pol = INTR_POLARITY_CONFORM;
1023                 gi->gi_trig = INTR_TRIGGER_CONFORM;
1024         }
1025         return (0);
1026 }
1027
1028 static void
1029 arm_gic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
1030 {
1031         struct arm_gic_softc *sc = device_get_softc(dev);
1032         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1033
1034         arm_irq_memory_barrier(gi->gi_irq);
1035         gic_irq_unmask(sc, gi->gi_irq);
1036 }
1037
1038 static void
1039 arm_gic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
1040 {
1041         struct arm_gic_softc *sc = device_get_softc(dev);
1042         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1043
1044         gic_irq_mask(sc, gi->gi_irq);
1045 }
1046
1047 static void
1048 arm_gic_pre_ithread(device_t dev, struct intr_irqsrc *isrc)
1049 {
1050         struct arm_gic_softc *sc = device_get_softc(dev);
1051         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1052
1053         arm_gic_disable_intr(dev, isrc);
1054         gic_c_write_4(sc, GICC_EOIR, gi->gi_irq);
1055 }
1056
1057 static void
1058 arm_gic_post_ithread(device_t dev, struct intr_irqsrc *isrc)
1059 {
1060
1061         arm_irq_memory_barrier(0);
1062         arm_gic_enable_intr(dev, isrc);
1063 }
1064
1065 static void
1066 arm_gic_post_filter(device_t dev, struct intr_irqsrc *isrc)
1067 {
1068         struct arm_gic_softc *sc = device_get_softc(dev);
1069         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1070
1071         /* EOI for edge-triggered done earlier. */
1072         if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI)
1073                 return;
1074
1075         arm_irq_memory_barrier(0);
1076         gic_c_write_4(sc, GICC_EOIR, gi->gi_irq);
1077 }
1078
1079 static int
1080 arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc)
1081 {
1082         struct arm_gic_softc *sc = device_get_softc(dev);
1083         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1084
1085         if (gi->gi_irq < GIC_FIRST_SPI)
1086                 return (EINVAL);
1087
1088         if (CPU_EMPTY(&isrc->isrc_cpu)) {
1089                 gic_irq_cpu = intr_irq_next_cpu(gic_irq_cpu, &all_cpus);
1090                 CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu);
1091         }
1092         return (gic_bind(sc, gi->gi_irq, &isrc->isrc_cpu));
1093 }
1094
1095 #ifdef SMP
1096 static void
1097 arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus,
1098     u_int ipi)
1099 {
1100         struct arm_gic_softc *sc = device_get_softc(dev);
1101         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1102         uint32_t val = 0, i;
1103
1104         for (i = 0; i < MAXCPU; i++)
1105                 if (CPU_ISSET(i, &cpus))
1106                         val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
1107
1108         gic_d_write_4(sc, GICD_SGIR, val | gi->gi_irq);
1109 }
1110
1111 static int
1112 arm_gic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc **isrcp)
1113 {
1114         struct intr_irqsrc *isrc;
1115         struct arm_gic_softc *sc = device_get_softc(dev);
1116
1117         if (sgi_first_unused > GIC_LAST_SGI)
1118                 return (ENOSPC);
1119
1120         isrc = GIC_INTR_ISRC(sc, sgi_first_unused);
1121         sgi_to_ipi[sgi_first_unused++] = ipi;
1122
1123         CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
1124
1125         *isrcp = isrc;
1126         return (0);
1127 }
1128 #endif
1129 #else
1130 static int
1131 arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq)
1132 {
1133         uint32_t active_irq;
1134
1135         active_irq = gic_c_read_4(sc, GICC_IAR);
1136
1137         /*
1138          * Immediately EOIR the SGIs, because doing so requires the other
1139          * bits (ie CPU number), not just the IRQ number, and we do not
1140          * have this information later.
1141          */
1142         if ((active_irq & 0x3ff) <= GIC_LAST_SGI)
1143                 gic_c_write_4(sc, GICC_EOIR, active_irq);
1144         active_irq &= 0x3FF;
1145
1146         if (active_irq == 0x3FF) {
1147                 if (last_irq == -1)
1148                         device_printf(sc->gic_dev,
1149                             "Spurious interrupt detected\n");
1150                 return -1;
1151         }
1152
1153         return active_irq;
1154 }
1155
1156 static int
1157 arm_gic_config(device_t dev, int irq, enum intr_trigger trig,
1158     enum intr_polarity pol)
1159 {
1160         struct arm_gic_softc *sc = device_get_softc(dev);
1161         uint32_t reg;
1162         uint32_t mask;
1163
1164         /* Function is public-accessible, so validate input arguments */
1165         if ((irq < 0) || (irq >= sc->nirqs))
1166                 goto invalid_args;
1167         if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) &&
1168             (trig != INTR_TRIGGER_CONFORM))
1169                 goto invalid_args;
1170         if ((pol != INTR_POLARITY_HIGH) && (pol != INTR_POLARITY_LOW) &&
1171             (pol != INTR_POLARITY_CONFORM))
1172                 goto invalid_args;
1173
1174         mtx_lock_spin(&sc->mutex);
1175
1176         reg = gic_d_read_4(sc, GICD_ICFGR(irq));
1177         mask = (reg >> 2*(irq % 16)) & 0x3;
1178
1179         if (pol == INTR_POLARITY_LOW) {
1180                 mask &= ~GICD_ICFGR_POL_MASK;
1181                 mask |= GICD_ICFGR_POL_LOW;
1182         } else if (pol == INTR_POLARITY_HIGH) {
1183                 mask &= ~GICD_ICFGR_POL_MASK;
1184                 mask |= GICD_ICFGR_POL_HIGH;
1185         }
1186
1187         if (trig == INTR_TRIGGER_LEVEL) {
1188                 mask &= ~GICD_ICFGR_TRIG_MASK;
1189                 mask |= GICD_ICFGR_TRIG_LVL;
1190         } else if (trig == INTR_TRIGGER_EDGE) {
1191                 mask &= ~GICD_ICFGR_TRIG_MASK;
1192                 mask |= GICD_ICFGR_TRIG_EDGE;
1193         }
1194
1195         /* Set mask */
1196         reg = reg & ~(0x3 << 2*(irq % 16));
1197         reg = reg | (mask << 2*(irq % 16));
1198         gic_d_write_4(sc, GICD_ICFGR(irq), reg);
1199
1200         mtx_unlock_spin(&sc->mutex);
1201
1202         return (0);
1203
1204 invalid_args:
1205         device_printf(dev, "gic_config_irg, invalid parameters\n");
1206         return (EINVAL);
1207 }
1208
1209
1210 static void
1211 arm_gic_mask(device_t dev, int irq)
1212 {
1213         struct arm_gic_softc *sc = device_get_softc(dev);
1214
1215         gic_d_write_4(sc, GICD_ICENABLER(irq), (1UL << (irq & 0x1F)));
1216         gic_c_write_4(sc, GICC_EOIR, irq); /* XXX - not allowed */
1217 }
1218
1219 static void
1220 arm_gic_unmask(device_t dev, int irq)
1221 {
1222         struct arm_gic_softc *sc = device_get_softc(dev);
1223
1224         if (irq > GIC_LAST_SGI)
1225                 arm_irq_memory_barrier(irq);
1226
1227         gic_d_write_4(sc, GICD_ISENABLER(irq), (1UL << (irq & 0x1F)));
1228 }
1229
1230 #ifdef SMP
1231 static void
1232 arm_gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi)
1233 {
1234         struct arm_gic_softc *sc = device_get_softc(dev);
1235         uint32_t val = 0, i;
1236
1237         for (i = 0; i < MAXCPU; i++)
1238                 if (CPU_ISSET(i, &cpus))
1239                         val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
1240
1241         gic_d_write_4(sc, GICD_SGIR, val | ipi);
1242 }
1243
1244 static int
1245 arm_gic_ipi_read(device_t dev, int i)
1246 {
1247
1248         if (i != -1) {
1249                 /*
1250                  * The intr code will automagically give the frame pointer
1251                  * if the interrupt argument is 0.
1252                  */
1253                 if ((unsigned int)i > 16)
1254                         return (0);
1255                 return (i);
1256         }
1257
1258         return (0x3ff);
1259 }
1260
1261 static void
1262 arm_gic_ipi_clear(device_t dev, int ipi)
1263 {
1264         /* no-op */
1265 }
1266 #endif
1267
1268 static void
1269 gic_post_filter(void *arg)
1270 {
1271         struct arm_gic_softc *sc = gic_sc;
1272         uintptr_t irq = (uintptr_t) arg;
1273
1274         if (irq > GIC_LAST_SGI)
1275                 arm_irq_memory_barrier(irq);
1276         gic_c_write_4(sc, GICC_EOIR, irq);
1277 }
1278
1279 static int
1280 gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol)
1281 {
1282
1283         return (arm_gic_config(gic_sc->gic_dev, irq, trig, pol));
1284 }
1285
1286 void
1287 arm_mask_irq(uintptr_t nb)
1288 {
1289
1290         arm_gic_mask(gic_sc->gic_dev, nb);
1291 }
1292
1293 void
1294 arm_unmask_irq(uintptr_t nb)
1295 {
1296
1297         arm_gic_unmask(gic_sc->gic_dev, nb);
1298 }
1299
1300 int
1301 arm_get_next_irq(int last_irq)
1302 {
1303
1304         return (arm_gic_next_irq(gic_sc, last_irq));
1305 }
1306
1307 #ifdef SMP
1308 void
1309 intr_pic_init_secondary(void)
1310 {
1311
1312         arm_gic_init_secondary(gic_sc->gic_dev);
1313 }
1314
1315 void
1316 pic_ipi_send(cpuset_t cpus, u_int ipi)
1317 {
1318
1319         arm_gic_ipi_send(gic_sc->gic_dev, cpus, ipi);
1320 }
1321
1322 int
1323 pic_ipi_read(int i)
1324 {
1325
1326         return (arm_gic_ipi_read(gic_sc->gic_dev, i));
1327 }
1328
1329 void
1330 pic_ipi_clear(int ipi)
1331 {
1332
1333         arm_gic_ipi_clear(gic_sc->gic_dev, ipi);
1334 }
1335 #endif
1336 #endif /* INTRNG */
1337
1338 static device_method_t arm_gic_methods[] = {
1339 #ifdef INTRNG
1340         /* Bus interface */
1341         DEVMETHOD(bus_print_child,      arm_gic_print_child),
1342         DEVMETHOD(bus_add_child,        bus_generic_add_child),
1343         DEVMETHOD(bus_alloc_resource,   arm_gic_alloc_resource),
1344         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
1345         DEVMETHOD(bus_activate_resource,bus_generic_activate_resource),
1346         DEVMETHOD(bus_read_ivar,        arm_gic_read_ivar),
1347
1348         /* Interrupt controller interface */
1349         DEVMETHOD(pic_disable_intr,     arm_gic_disable_intr),
1350         DEVMETHOD(pic_enable_intr,      arm_gic_enable_intr),
1351         DEVMETHOD(pic_map_intr,         arm_gic_map_intr),
1352         DEVMETHOD(pic_setup_intr,       arm_gic_setup_intr),
1353         DEVMETHOD(pic_teardown_intr,    arm_gic_teardown_intr),
1354         DEVMETHOD(pic_post_filter,      arm_gic_post_filter),
1355         DEVMETHOD(pic_post_ithread,     arm_gic_post_ithread),
1356         DEVMETHOD(pic_pre_ithread,      arm_gic_pre_ithread),
1357 #ifdef SMP
1358         DEVMETHOD(pic_bind_intr,        arm_gic_bind_intr),
1359         DEVMETHOD(pic_init_secondary,   arm_gic_init_secondary),
1360         DEVMETHOD(pic_ipi_send,         arm_gic_ipi_send),
1361         DEVMETHOD(pic_ipi_setup,        arm_gic_ipi_setup),
1362 #endif
1363 #endif
1364         { 0, 0 }
1365 };
1366
1367 DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
1368     sizeof(struct arm_gic_softc));
1369
1370 #ifdef INTRNG
1371 /*
1372  * GICv2m support -- the GICv2 MSI/MSI-X controller.
1373  */
1374
1375 #define GICV2M_MSI_TYPER        0x008
1376 #define  MSI_TYPER_SPI_BASE(x)  (((x) >> 16) & 0x3ff)
1377 #define  MSI_TYPER_SPI_COUNT(x) (((x) >> 0) & 0x3ff)
1378 #define GICv2M_MSI_SETSPI_NS    0x040
1379 #define GICV2M_MSI_IIDR         0xFCC
1380
1381 int
1382 arm_gicv2m_attach(device_t dev)
1383 {
1384         struct arm_gicv2m_softc *sc;
1385         struct arm_gic_softc *psc;
1386         uint32_t typer;
1387         int rid;
1388
1389         psc = device_get_softc(device_get_parent(dev));
1390         sc = device_get_softc(dev);
1391
1392         rid = 0;
1393         sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
1394             RF_ACTIVE);
1395         if (sc->sc_mem == NULL) {
1396                 device_printf(dev, "Unable to allocate resources\n");
1397                 return (ENXIO);
1398         }
1399
1400         typer = bus_read_4(sc->sc_mem, GICV2M_MSI_TYPER);
1401         sc->sc_spi_start = MSI_TYPER_SPI_BASE(typer);
1402         sc->sc_spi_count = MSI_TYPER_SPI_COUNT(typer);
1403         sc->sc_spi_end = sc->sc_spi_start + sc->sc_spi_count;
1404
1405         /* Reserve these interrupts for MSI/MSI-X use */
1406         arm_gic_reserve_msi_range(device_get_parent(dev), sc->sc_spi_start,
1407             sc->sc_spi_count);
1408
1409         mtx_init(&sc->sc_mutex, "GICv2m lock", "", MTX_DEF);
1410
1411         intr_msi_register(dev, sc->sc_xref);
1412
1413         if (bootverbose)
1414                 device_printf(dev, "using spi %u to %u\n", sc->sc_spi_start,
1415                     sc->sc_spi_start + sc->sc_spi_count - 1);
1416
1417         return (0);
1418 }
1419
1420 static int
1421 arm_gicv2m_alloc_msi(device_t dev, device_t child, int count, int maxcount,
1422     device_t *pic, struct intr_irqsrc **srcs)
1423 {
1424         struct arm_gic_softc *psc;
1425         struct arm_gicv2m_softc *sc;
1426         int i, irq, end_irq;
1427         bool found;
1428
1429         KASSERT(powerof2(count), ("%s: bad count", __func__));
1430         KASSERT(powerof2(maxcount), ("%s: bad maxcount", __func__));
1431
1432         psc = device_get_softc(device_get_parent(dev));
1433         sc = device_get_softc(dev);
1434
1435         mtx_lock(&sc->sc_mutex);
1436
1437         found = false;
1438         for (irq = sc->sc_spi_start; irq < sc->sc_spi_end; irq++) {
1439                 /* Start on an aligned interrupt */
1440                 if ((irq & (maxcount - 1)) != 0)
1441                         continue;
1442
1443                 /* Assume we found a valid range until shown otherwise */
1444                 found = true;
1445
1446                 /* Check this range is valid */
1447                 for (end_irq = irq; end_irq != irq + count; end_irq++) {
1448                         /* No free interrupts */
1449                         if (end_irq == sc->sc_spi_end) {
1450                                 found = false;
1451                                 break;
1452                         }
1453
1454                         KASSERT((psc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI)!= 0,
1455                             ("%s: Non-MSI interrupt found", __func__));
1456
1457                         /* This is already used */
1458                         if ((psc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI_USED) ==
1459                             GI_FLAG_MSI_USED) {
1460                                 found = false;
1461                                 break;
1462                         }
1463                 }
1464                 if (found)
1465                         break;
1466         }
1467
1468         /* Not enough interrupts were found */
1469         if (!found || irq == sc->sc_spi_end) {
1470                 mtx_unlock(&sc->sc_mutex);
1471                 return (ENXIO);
1472         }
1473
1474         for (i = 0; i < count; i++) {
1475                 /* Mark the interrupt as used */
1476                 psc->gic_irqs[irq + i].gi_flags |= GI_FLAG_MSI_USED;
1477
1478         }
1479         mtx_unlock(&sc->sc_mutex);
1480
1481         for (i = 0; i < count; i++)
1482                 srcs[i] = (struct intr_irqsrc *)&psc->gic_irqs[irq + i];
1483         *pic = device_get_parent(dev);
1484
1485         return (0);
1486 }
1487
1488 static int
1489 arm_gicv2m_release_msi(device_t dev, device_t child, int count,
1490     struct intr_irqsrc **isrc)
1491 {
1492         struct arm_gicv2m_softc *sc;
1493         struct gic_irqsrc *gi;
1494         int i;
1495
1496         sc = device_get_softc(dev);
1497
1498         mtx_lock(&sc->sc_mutex);
1499         for (i = 0; i < count; i++) {
1500                 gi = (struct gic_irqsrc *)isrc[i];
1501
1502                 KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
1503                     ("%s: Trying to release an unused MSI-X interrupt",
1504                     __func__));
1505
1506                 gi->gi_flags &= ~GI_FLAG_MSI_USED;
1507         }
1508         mtx_unlock(&sc->sc_mutex);
1509
1510         return (0);
1511 }
1512
1513 static int
1514 arm_gicv2m_alloc_msix(device_t dev, device_t child, device_t *pic,
1515     struct intr_irqsrc **isrcp)
1516 {
1517         struct arm_gicv2m_softc *sc;
1518         struct arm_gic_softc *psc;
1519         int irq;
1520
1521         psc = device_get_softc(device_get_parent(dev));
1522         sc = device_get_softc(dev);
1523
1524         mtx_lock(&sc->sc_mutex);
1525         /* Find an unused interrupt */
1526         for (irq = sc->sc_spi_start; irq < sc->sc_spi_end; irq++) {
1527                 KASSERT((psc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) != 0,
1528                     ("%s: Non-MSI interrupt found", __func__));
1529                 if ((psc->gic_irqs[irq].gi_flags & GI_FLAG_MSI_USED) == 0)
1530                         break;
1531         }
1532         /* No free interrupt was found */
1533         if (irq == sc->sc_spi_end) {
1534                 mtx_unlock(&sc->sc_mutex);
1535                 return (ENXIO);
1536         }
1537
1538         /* Mark the interrupt as used */
1539         psc->gic_irqs[irq].gi_flags |= GI_FLAG_MSI_USED;
1540         mtx_unlock(&sc->sc_mutex);
1541
1542         *isrcp = (struct intr_irqsrc *)&psc->gic_irqs[irq];
1543         *pic = device_get_parent(dev);
1544
1545         return (0);
1546 }
1547
1548 static int
1549 arm_gicv2m_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc)
1550 {
1551         struct arm_gicv2m_softc *sc;
1552         struct gic_irqsrc *gi;
1553
1554         sc = device_get_softc(dev);
1555         gi = (struct gic_irqsrc *)isrc;
1556
1557         KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
1558             ("%s: Trying to release an unused MSI-X interrupt", __func__));
1559
1560         mtx_lock(&sc->sc_mutex);
1561         gi->gi_flags &= ~GI_FLAG_MSI_USED;
1562         mtx_unlock(&sc->sc_mutex);
1563
1564         return (0);
1565 }
1566
1567 static int
1568 arm_gicv2m_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc,
1569     uint64_t *addr, uint32_t *data)
1570 {
1571         struct arm_gicv2m_softc *sc = device_get_softc(dev);
1572         struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
1573
1574         *addr = vtophys(rman_get_virtual(sc->sc_mem)) + GICv2M_MSI_SETSPI_NS;
1575         *data = gi->gi_irq;
1576
1577         return (0);
1578 }
1579
1580 static device_method_t arm_gicv2m_methods[] = {
1581         /* Device interface */
1582         DEVMETHOD(device_attach,        arm_gicv2m_attach),
1583
1584         /* MSI/MSI-X */
1585         DEVMETHOD(msi_alloc_msi,        arm_gicv2m_alloc_msi),
1586         DEVMETHOD(msi_release_msi,      arm_gicv2m_release_msi),
1587         DEVMETHOD(msi_alloc_msix,       arm_gicv2m_alloc_msix),
1588         DEVMETHOD(msi_release_msix,     arm_gicv2m_release_msix),
1589         DEVMETHOD(msi_map_msi,          arm_gicv2m_map_msi),
1590
1591         /* End */
1592         DEVMETHOD_END
1593 };
1594
1595 DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods,
1596     sizeof(struct arm_gicv2m_softc));
1597 #endif