]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/gic.c
Update ThunderX PCIe driver to fit new DTS layout
[FreeBSD/FreeBSD.git] / sys / arm64 / arm64 / gic.c
1 /*-
2  * Copyright (c) 2011 The FreeBSD Foundation
3  * Copyright (c) 2014 Andrew Turner
4  * All rights reserved.
5  *
6  * Developed by Damjan Marion <damjan.marion@gmail.com>
7  *
8  * Based on OMAP4 GIC code by Ben Gray
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. The name of the company nor the name of the author may be used to
19  *    endorse or promote products derived from this software without specific
20  *    prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/bus.h>
41 #include <sys/kernel.h>
42 #include <sys/ktr.h>
43 #include <sys/module.h>
44 #include <sys/rman.h>
45 #include <sys/pcpu.h>
46 #include <sys/proc.h>
47 #include <sys/cpuset.h>
48 #include <sys/lock.h>
49 #include <sys/mutex.h>
50
51 #include <machine/bus.h>
52 #include <machine/intr.h>
53 #include <machine/smp.h>
54
55 #include <vm/vm.h>
56 #include <vm/pmap.h>
57
58 #include <arm64/arm64/gic.h>
59
60 #include "pic_if.h"
61
62 /* We are using GICv2 register naming */
63
64 /* Distributor Registers */
65 #define GICD_CTLR               0x000                   /* v1 ICDDCR */
66 #define GICD_TYPER              0x004                   /* v1 ICDICTR */
67 #define GICD_IIDR               0x008                   /* v1 ICDIIDR */
68 #define GICD_IGROUPR(n)         (0x0080 + ((n) * 4))    /* v1 ICDISER */
69 #define GICD_ISENABLER(n)       (0x0100 + ((n) * 4))    /* v1 ICDISER */
70 #define GICD_ICENABLER(n)       (0x0180 + ((n) * 4))    /* v1 ICDICER */
71 #define GICD_ISPENDR(n)         (0x0200 + ((n) * 4))    /* v1 ICDISPR */
72 #define GICD_ICPENDR(n)         (0x0280 + ((n) * 4))    /* v1 ICDICPR */
73 #define GICD_ICACTIVER(n)       (0x0380 + ((n) * 4))    /* v1 ICDABR */
74 #define GICD_IPRIORITYR(n)      (0x0400 + ((n) * 4))    /* v1 ICDIPR */
75 #define GICD_ITARGETSR(n)       (0x0800 + ((n) * 4))    /* v1 ICDIPTR */
76 #define GICD_ICFGR(n)           (0x0C00 + ((n) * 4))    /* v1 ICDICFR */
77 #define GICD_SGIR(n)            (0x0F00 + ((n) * 4))    /* v1 ICDSGIR */
78
79 /* CPU Registers */
80 #define GICC_CTLR               0x0000                  /* v1 ICCICR */
81 #define GICC_PMR                0x0004                  /* v1 ICCPMR */
82 #define GICC_BPR                0x0008                  /* v1 ICCBPR */
83 #define GICC_IAR                0x000C                  /* v1 ICCIAR */
84 #define GICC_EOIR               0x0010                  /* v1 ICCEOIR */
85 #define GICC_RPR                0x0014                  /* v1 ICCRPR */
86 #define GICC_HPPIR              0x0018                  /* v1 ICCHPIR */
87 #define GICC_ABPR               0x001C                  /* v1 ICCABPR */
88 #define GICC_IIDR               0x00FC                  /* v1 ICCIIDR*/
89
90 #define GIC_FIRST_IPI            0      /* Irqs 0-15 are SGIs/IPIs. */
91 #define GIC_LAST_IPI            15
92 #define GIC_FIRST_PPI           16      /* Irqs 16-31 are private (per */
93 #define GIC_LAST_PPI            31      /* core) peripheral interrupts. */
94 #define GIC_FIRST_SPI           32      /* Irqs 32+ are shared peripherals. */
95
96 /* First bit is a polarity bit (0 - low, 1 - high) */
97 #define GICD_ICFGR_POL_LOW      (0 << 0)
98 #define GICD_ICFGR_POL_HIGH     (1 << 0)
99 #define GICD_ICFGR_POL_MASK     0x1
100 /* Second bit is a trigger bit (0 - level, 1 - edge) */
101 #define GICD_ICFGR_TRIG_LVL     (0 << 1)
102 #define GICD_ICFGR_TRIG_EDGE    (1 << 1)
103 #define GICD_ICFGR_TRIG_MASK    0x2
104
105 static struct resource_spec arm_gic_spec[] = {
106         { SYS_RES_MEMORY,       0,      RF_ACTIVE },    /* Distributor registers */
107         { SYS_RES_MEMORY,       1,      RF_ACTIVE },    /* CPU Interrupt Intf. registers */
108         { -1, 0 }
109 };
110
111 static struct arm_gic_softc *arm_gic_sc = NULL;
112
113 #define gic_c_read_4(_sc, _reg)         \
114     bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg))
115 #define gic_c_write_4(_sc, _reg, _val)          \
116     bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val))
117 #define gic_d_read_4(_sc, _reg)         \
118     bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg))
119 #define gic_d_write_4(_sc, _reg, _val)          \
120     bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
121
122 static pic_dispatch_t gic_dispatch;
123 static pic_eoi_t gic_eoi;
124 static pic_mask_t gic_mask_irq;
125 static pic_unmask_t gic_unmask_irq;
126
127 #ifdef SMP
128 static void
129 gic_init_secondary(device_t dev)
130 {
131         struct arm_gic_softc *sc = device_get_softc(dev);
132         int i;
133
134         for (i = 0; i < sc->nirqs; i += 4)
135                 gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
136
137         /* Set all the interrupts to be in Group 0 (secure) */
138         for (i = 0; i < sc->nirqs; i += 32) {
139                 gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
140         }
141
142         /* Enable CPU interface */
143         gic_c_write_4(sc, GICC_CTLR, 1);
144
145         /* Set priority mask register. */
146         gic_c_write_4(sc, GICC_PMR, 0xff);
147
148         /* Enable interrupt distribution */
149         gic_d_write_4(sc, GICD_CTLR, 0x01);
150
151         /*
152          * Activate the timer interrupts: virtual, secure, and non-secure.
153          */
154         gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
155         gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
156         gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
157 }
158 #endif
159
160 int
161 arm_gic_attach(device_t dev)
162 {
163         struct          arm_gic_softc *sc;
164         int             i;
165         uint32_t        icciidr;
166
167         if (arm_gic_sc)
168                 return (ENXIO);
169
170         sc = device_get_softc(dev);
171
172         if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
173                 device_printf(dev, "could not allocate resources\n");
174                 return (ENXIO);
175         }
176
177         sc->gic_dev = dev;
178         arm_gic_sc = sc;
179
180         /* Initialize mutex */
181         mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
182
183         /* Distributor Interface */
184         sc->gic_d_bst = rman_get_bustag(sc->gic_res[0]);
185         sc->gic_d_bsh = rman_get_bushandle(sc->gic_res[0]);
186
187         /* CPU Interface */
188         sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
189         sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
190
191         /* Disable interrupt forwarding to the CPU interface */
192         gic_d_write_4(sc, GICD_CTLR, 0x00);
193
194         /* Get the number of interrupts */
195         sc->nirqs = gic_d_read_4(sc, GICD_TYPER);
196         sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1);
197
198         arm_register_root_pic(dev, sc->nirqs);
199
200         icciidr = gic_c_read_4(sc, GICC_IIDR);
201         device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n",
202                         icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf,
203                         (icciidr & 0xfff), sc->nirqs);
204
205         /* Set all global interrupts to be level triggered, active low. */
206         for (i = 32; i < sc->nirqs; i += 16) {
207                 gic_d_write_4(sc, GICD_ICFGR(i >> 4), 0x00000000);
208         }
209
210         /* Disable all interrupts. */
211         for (i = 32; i < sc->nirqs; i += 32) {
212                 gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
213         }
214
215         for (i = 0; i < sc->nirqs; i += 4) {
216                 gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
217                 gic_d_write_4(sc, GICD_ITARGETSR(i >> 2),
218                     1 << 0 | 1 << 8 | 1 << 16 | 1 << 24);
219         }
220
221         /* Set all the interrupts to be in Group 0 (secure) */
222         for (i = 0; i < sc->nirqs; i += 32) {
223                 gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
224         }
225
226         /* Enable CPU interface */
227         gic_c_write_4(sc, GICC_CTLR, 1);
228
229         /* Set priority mask register. */
230         gic_c_write_4(sc, GICC_PMR, 0xff);
231
232         /* Enable interrupt distribution */
233         gic_d_write_4(sc, GICD_CTLR, 0x01);
234
235         return (0);
236 }
237
238 static void gic_dispatch(device_t dev, struct trapframe *frame)
239 {
240         struct arm_gic_softc *sc = device_get_softc(dev);
241         uint32_t active_irq;
242         int first = 1;
243
244         while (1) {
245                 active_irq = gic_c_read_4(sc, GICC_IAR);
246
247                 /*
248                  * Immediatly EOIR the SGIs, because doing so requires the other
249                  * bits (ie CPU number), not just the IRQ number, and we do not
250                  * have this information later.
251                  */
252
253                 if ((active_irq & 0x3ff) <= GIC_LAST_IPI)
254                         gic_c_write_4(sc, GICC_EOIR, active_irq);
255                 active_irq &= 0x3FF;
256
257                 if (active_irq == 0x3FF) {
258                         if (first)
259                                 printf("Spurious interrupt detected\n");
260                         return;
261                 }
262
263                 arm_dispatch_intr(active_irq, frame);
264                 first = 0;
265         }
266 }
267
268 static void
269 gic_eoi(device_t dev, u_int irq)
270 {
271         struct arm_gic_softc *sc = device_get_softc(dev);
272
273         gic_c_write_4(sc, GICC_EOIR, irq);
274 }
275
276 void
277 gic_mask_irq(device_t dev, u_int irq)
278 {
279         struct arm_gic_softc *sc = device_get_softc(dev);
280
281         gic_d_write_4(sc, GICD_ICENABLER(irq >> 5), (1UL << (irq & 0x1F)));
282         gic_c_write_4(sc, GICC_EOIR, irq);
283 }
284
285 void
286 gic_unmask_irq(device_t dev, u_int irq)
287 {
288         struct arm_gic_softc *sc = device_get_softc(dev);
289
290         gic_d_write_4(sc, GICD_ISENABLER(irq >> 5), (1UL << (irq & 0x1F)));
291 }
292
293 #ifdef SMP
294 static void
295 gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi)
296 {
297         struct arm_gic_softc *sc = device_get_softc(dev);
298         uint32_t val = 0, i;
299
300         for (i = 0; i < MAXCPU; i++)
301                 if (CPU_ISSET(i, &cpus))
302                         val |= 1 << (16 + i);
303
304         gic_d_write_4(sc, GICD_SGIR(0), val | ipi);
305 }
306
307 static int
308 arm_gic_ipi_read(device_t dev, int i)
309 {
310
311         if (i != -1) {
312                 /*
313                  * The intr code will automagically give the frame pointer
314                  * if the interrupt argument is 0.
315                  */
316                 if ((unsigned int)i > 16)
317                         return (0);
318                 return (i);
319         }
320
321         return (0x3ff);
322 }
323
324 static void
325 arm_gic_ipi_clear(device_t dev, int ipi)
326 {
327         /* no-op */
328 }
329 #endif
330
331 static device_method_t arm_gic_methods[] = {
332         /* Device interface */
333         DEVMETHOD(device_attach,        arm_gic_attach),
334
335         /* pic_if */
336         DEVMETHOD(pic_dispatch,         gic_dispatch),
337         DEVMETHOD(pic_eoi,              gic_eoi),
338         DEVMETHOD(pic_mask,             gic_mask_irq),
339         DEVMETHOD(pic_unmask,           gic_unmask_irq),
340
341 #ifdef SMP
342         DEVMETHOD(pic_init_secondary,   gic_init_secondary),
343         DEVMETHOD(pic_ipi_send,         gic_ipi_send),
344 #endif
345
346         { 0, 0 }
347 };
348
349 DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods,
350     sizeof(struct arm_gic_softc));
351
352 #define GICV2M_MSI_TYPER        0x008
353 #define  MSI_TYPER_SPI_BASE(x)  (((x) >> 16) & 0x3ff)
354 #define  MSI_TYPER_SPI_COUNT(x) (((x) >> 0) & 0x3ff)
355 #define GICv2M_MSI_SETSPI_NS    0x040
356 #define GICV2M_MSI_IIDR         0xFCC
357
358 struct gicv2m_softc {
359         struct resource *sc_mem;
360         struct mtx      sc_mutex;
361         u_int           sc_spi_start;
362         u_int           sc_spi_count;
363         u_int           sc_spi_offset;
364 };
365
366 static int
367 gicv2m_probe(device_t dev)
368 {
369
370         device_set_desc(dev, "ARM Generic Interrupt Controller MSI/MSIX");
371         return (BUS_PROBE_DEFAULT);
372 }
373
374 static int
375 gicv2m_attach(device_t dev)
376 {
377         struct gicv2m_softc *sc;
378         uint32_t typer;
379         int rid;
380
381         sc = device_get_softc(dev);
382
383         rid = 0;
384         sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
385         if (sc->sc_mem == NULL) {
386                 device_printf(dev, "Unable to allocate resources\n");
387                 return (ENXIO);
388         }
389
390         typer = bus_read_4(sc->sc_mem, GICV2M_MSI_TYPER);
391         sc->sc_spi_start = MSI_TYPER_SPI_BASE(typer);
392         sc->sc_spi_count = MSI_TYPER_SPI_COUNT(typer);
393
394         device_printf(dev, "using spi %u to %u\n", sc->sc_spi_start,
395             sc->sc_spi_start + sc->sc_spi_count - 1);
396
397         mtx_init(&sc->sc_mutex, "GICv2m lock", "", MTX_DEF);
398
399         arm_register_msi_pic(dev);
400
401         return (0);
402 }
403
404 static int
405 gicv2m_alloc_msix(device_t dev, device_t pci_dev, int *pirq)
406 {
407         struct arm_gic_softc *psc;
408         struct gicv2m_softc *sc;
409         uint32_t reg;
410         int irq;
411
412         psc = device_get_softc(device_get_parent(dev));
413         sc = device_get_softc(dev);
414
415         mtx_lock(&sc->sc_mutex);
416         /* Find an unused interrupt */
417         KASSERT(sc->sc_spi_offset < sc->sc_spi_count, ("No free SPIs"));
418
419         irq = sc->sc_spi_start + sc->sc_spi_offset;
420         sc->sc_spi_offset++;
421
422         /* Interrupts need to be edge triggered, set this */
423         reg = gic_d_read_4(psc, GICD_ICFGR(irq >> 4));
424         reg |= (GICD_ICFGR_TRIG_EDGE | GICD_ICFGR_POL_HIGH) <<
425             ((irq & 0xf) * 2);
426         gic_d_write_4(psc, GICD_ICFGR(irq >> 4), reg);
427
428         *pirq = irq;
429         mtx_unlock(&sc->sc_mutex);
430
431         return (0);
432 }
433
434 static int
435 gicv2m_alloc_msi(device_t dev, device_t pci_dev, int count, int *irqs)
436 {
437         struct arm_gic_softc *psc;
438         struct gicv2m_softc *sc;
439         uint32_t reg;
440         int i, irq;
441
442         psc = device_get_softc(device_get_parent(dev));
443         sc = device_get_softc(dev);
444
445         mtx_lock(&sc->sc_mutex);
446         KASSERT(sc->sc_spi_offset + count <= sc->sc_spi_count,
447             ("No free SPIs for %d MSI interrupts", count));
448
449         /* Find an unused interrupt */
450         for (i = 0; i < count; i++) {
451                 irq = sc->sc_spi_start + sc->sc_spi_offset;
452                 sc->sc_spi_offset++;
453
454                 /* Interrupts need to be edge triggered, set this */
455                 reg = gic_d_read_4(psc, GICD_ICFGR(irq >> 4));
456                 reg |= (GICD_ICFGR_TRIG_EDGE | GICD_ICFGR_POL_HIGH) <<
457                     ((irq & 0xf) * 2);
458                 gic_d_write_4(psc, GICD_ICFGR(irq >> 4), reg);
459
460                 irqs[i] = irq;
461         }
462         mtx_unlock(&sc->sc_mutex);
463
464         return (0);
465 }
466
467 static int
468 gicv2m_map_msi(device_t dev, device_t pci_dev, int irq, uint64_t *addr,
469     uint32_t *data)
470 {
471         struct gicv2m_softc *sc = device_get_softc(dev);
472
473         *addr = vtophys(rman_get_virtual(sc->sc_mem)) + 0x40;
474         *data = irq;
475
476         return (0);
477 }
478
479 static device_method_t arm_gicv2m_methods[] = {
480         /* Device interface */
481         DEVMETHOD(device_probe,         gicv2m_probe),
482         DEVMETHOD(device_attach,        gicv2m_attach),
483
484         /* MSI/MSI-X */
485         DEVMETHOD(pic_alloc_msix,       gicv2m_alloc_msix),
486         DEVMETHOD(pic_alloc_msi,        gicv2m_alloc_msi),
487         DEVMETHOD(pic_map_msi,          gicv2m_map_msi),
488
489         { 0, 0 }
490 };
491
492 static devclass_t arm_gicv2m_devclass;
493
494 DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods,
495     sizeof(struct gicv2m_softc));
496 EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_driver, arm_gicv2m_devclass,
497     0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);