2 * Copyright (c) 2015 The FreeBSD Foundation
5 * This software was developed by Semihalf under
6 * the sponsorship of the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/module.h>
43 #include <sys/cpuset.h>
45 #include <sys/mutex.h>
50 #include <machine/bus.h>
51 #include <machine/cpu.h>
52 #include <machine/intr.h>
56 #include "gic_v3_reg.h"
57 #include "gic_v3_var.h"
59 /* Device and PIC methods */
60 static void gic_v3_dispatch(device_t, struct trapframe *);
61 static void gic_v3_eoi(device_t, u_int);
62 static void gic_v3_mask_irq(device_t, u_int);
63 static void gic_v3_unmask_irq(device_t, u_int);
65 static device_method_t gic_v3_methods[] = {
66 /* Device interface */
67 DEVMETHOD(device_detach, gic_v3_detach),
70 DEVMETHOD(pic_dispatch, gic_v3_dispatch),
71 DEVMETHOD(pic_eoi, gic_v3_eoi),
72 DEVMETHOD(pic_mask, gic_v3_mask_irq),
73 DEVMETHOD(pic_unmask, gic_v3_unmask_irq),
79 DEFINE_CLASS_0(gic_v3, gic_v3_driver, gic_v3_methods,
80 sizeof(struct gic_v3_softc));
83 * Driver-specific definitions.
85 MALLOC_DEFINE(M_GIC_V3, "GICv3", GIC_V3_DEVSTR);
88 * Helper functions and definitions.
90 /* Destination registers, either Distributor or Re-Distributor */
96 /* Helper routines starting with gic_v3_ */
97 static int gic_v3_dist_init(struct gic_v3_softc *);
98 static int gic_v3_redist_find(struct gic_v3_softc *);
99 static int gic_v3_redist_init(struct gic_v3_softc *);
100 static int gic_v3_cpu_init(struct gic_v3_softc *);
101 static void gic_v3_wait_for_rwp(struct gic_v3_softc *, enum gic_v3_xdist);
103 /* A sequence of init functions for primary (boot) CPU */
104 typedef int (*gic_v3_initseq_t) (struct gic_v3_softc *);
105 /* Primary CPU initialization sequence */
106 static gic_v3_initseq_t gic_v3_primary_init[] = {
117 gic_v3_attach(device_t dev)
119 struct gic_v3_softc *sc;
120 gic_v3_initseq_t *init_func;
126 sc = device_get_softc(dev);
127 sc->gic_registered = FALSE;
131 /* Initialize mutex */
132 mtx_init(&sc->gic_mtx, "GICv3 lock", NULL, MTX_SPIN);
135 * Allocate array of struct resource.
136 * One entry for Distributor and all remaining for Re-Distributor.
138 sc->gic_res = malloc(
139 sizeof(sc->gic_res) * (sc->gic_redists.nregions + 1),
142 /* Now allocate corresponding resources */
143 for (i = 0, rid = 0; i < (sc->gic_redists.nregions + 1); i++, rid++) {
144 sc->gic_res[rid] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
146 if (sc->gic_res[rid] == NULL)
151 * Distributor interface
153 sc->gic_dist = sc->gic_res[0];
156 * Re-Dristributor interface
158 /* Allocate space under region descriptions */
159 sc->gic_redists.regions = malloc(
160 sizeof(*sc->gic_redists.regions) * sc->gic_redists.nregions,
163 /* Fill-up bus_space information for each region. */
164 for (i = 0, rid = 1; i < sc->gic_redists.nregions; i++, rid++)
165 sc->gic_redists.regions[i] = sc->gic_res[rid];
167 /* Get the number of supported SPI interrupts */
168 typer = gic_d_read(sc, 4, GICD_TYPER);
169 sc->gic_nirqs = GICD_TYPER_I_NUM(typer);
170 if (sc->gic_nirqs > GIC_I_NUM_MAX)
171 sc->gic_nirqs = GIC_I_NUM_MAX;
173 /* Get the number of supported interrupt identifier bits */
174 sc->gic_idbits = GICD_TYPER_IDBITS(typer);
177 device_printf(dev, "SPIs: %u, IDs: %u\n",
178 sc->gic_nirqs, (1 << sc->gic_idbits) - 1);
181 /* Train init sequence for boot CPU */
182 for (init_func = gic_v3_primary_init; *init_func != NULL; init_func++) {
183 err = (*init_func)(sc);
189 * Now register PIC to the interrupts handling layer.
191 arm_register_root_pic(dev, sc->gic_nirqs);
192 sc->gic_registered = TRUE;
198 gic_v3_detach(device_t dev)
200 struct gic_v3_softc *sc;
204 sc = device_get_softc(dev);
206 if (device_is_attached(dev)) {
208 * XXX: We should probably deregister PIC
210 if (sc->gic_registered)
211 panic("Trying to detach registered PIC");
213 for (rid = 0; rid < (sc->gic_redists.nregions + 1); rid++)
214 bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->gic_res[rid]);
216 for (i = 0; i < MAXCPU; i++)
217 free(sc->gic_redists.pcpu[i], M_GIC_V3);
219 free(sc->gic_res, M_GIC_V3);
220 free(sc->gic_redists.regions, M_GIC_V3);
229 gic_v3_dispatch(device_t dev, struct trapframe *frame)
234 if (CPU_MATCH_ERRATA_CAVIUM_THUNDER_1_1) {
236 * Hardware: Cavium ThunderX
237 * Chip revision: Pass 1.0 (early version)
238 * Pass 1.1 (production)
239 * ERRATUM: 22978, 23154
242 "nop;nop;nop;nop;nop;nop;nop;nop; \n"
243 "mrs %0, ICC_IAR1_EL1 \n"
244 "nop;nop;nop;nop; \n"
246 : "=&r" (active_irq));
248 active_irq = gic_icc_read(IAR1);
251 if (__predict_false(active_irq == ICC_IAR1_EL1_SPUR))
254 if (__predict_true((active_irq >= GIC_FIRST_PPI &&
255 active_irq <= GIC_LAST_SPI) || active_irq >= GIC_FIRST_LPI)) {
256 arm_dispatch_intr(active_irq, frame);
260 if (active_irq <= GIC_LAST_SGI) {
262 * TODO: Implement proper SGI handling.
263 * Mask it if such is received for some reason.
266 "Received unsupported interrupt type: SGI\n");
267 PIC_MASK(dev, active_irq);
273 gic_v3_eoi(device_t dev, u_int irq)
276 gic_icc_write(EOIR1, (uint64_t)irq);
280 gic_v3_mask_irq(device_t dev, u_int irq)
282 struct gic_v3_softc *sc;
284 sc = device_get_softc(dev);
286 if (irq >= GIC_FIRST_PPI && irq <= GIC_LAST_PPI) { /* PPIs in corresponding Re-Distributor */
288 GICR_SGI_BASE_SIZE + GICD_ICENABLER(irq), GICD_I_MASK(irq));
289 gic_v3_wait_for_rwp(sc, REDIST);
290 } else if (irq >= GIC_FIRST_SPI && irq <= GIC_LAST_SPI) { /* SPIs in distributor */
291 gic_r_write(sc, 4, GICD_ICENABLER(irq), GICD_I_MASK(irq));
292 gic_v3_wait_for_rwp(sc, DIST);
293 } else if (irq >= GIC_FIRST_LPI) { /* LPIs */
294 lpi_mask_irq(dev, irq);
296 panic("%s: Unsupported IRQ number %u", __func__, irq);
300 gic_v3_unmask_irq(device_t dev, u_int irq)
302 struct gic_v3_softc *sc;
304 sc = device_get_softc(dev);
306 if (irq >= GIC_FIRST_PPI && irq <= GIC_LAST_PPI) { /* PPIs in corresponding Re-Distributor */
308 GICR_SGI_BASE_SIZE + GICD_ISENABLER(irq), GICD_I_MASK(irq));
309 gic_v3_wait_for_rwp(sc, REDIST);
310 } else if (irq >= GIC_FIRST_SPI && irq <= GIC_LAST_SPI) { /* SPIs in distributor */
311 gic_d_write(sc, 4, GICD_ISENABLER(irq), GICD_I_MASK(irq));
312 gic_v3_wait_for_rwp(sc, DIST);
313 } else if (irq >= GIC_FIRST_LPI) { /* LPIs */
314 lpi_unmask_irq(dev, irq);
316 panic("%s: Unsupported IRQ number %u", __func__, irq);
323 gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_v3_xdist xdist)
325 struct resource *res;
327 size_t us_left = 1000000;
329 cpuid = PCPU_GET(cpuid);
336 res = sc->gic_redists.pcpu[cpuid];
339 KASSERT(0, ("%s: Attempt to wait for unknown RWP", __func__));
343 while ((bus_read_4(res, GICD_CTLR) & GICD_CTLR_RWP) != 0) {
346 panic("GICD Register write pending for too long");
352 gic_v3_cpu_priority(uint64_t mask)
355 /* Set prority mask */
356 gic_icc_write(PMR, mask & ICC_PMR_EL1_PRIO_MASK);
360 gic_v3_cpu_enable_sre(struct gic_v3_softc *sc)
365 cpuid = PCPU_GET(cpuid);
367 * Set the SRE bit to enable access to GIC CPU interface
368 * via system registers.
370 sre = READ_SPECIALREG(icc_sre_el1);
371 sre |= ICC_SRE_EL1_SRE;
372 WRITE_SPECIALREG(icc_sre_el1, sre);
375 * Now ensure that the bit is set.
377 sre = READ_SPECIALREG(icc_sre_el1);
378 if ((sre & ICC_SRE_EL1_SRE) == 0) {
379 /* We are done. This was disabled in EL2 */
380 device_printf(sc->dev, "ERROR: CPU%u cannot enable CPU interface "
381 "via system registers\n", cpuid);
383 } else if (bootverbose) {
384 device_printf(sc->dev,
385 "CPU%u enabled CPU interface via system registers\n",
393 gic_v3_cpu_init(struct gic_v3_softc *sc)
397 /* Enable access to CPU interface via system registers */
398 err = gic_v3_cpu_enable_sre(sc);
401 /* Priority mask to minimum - accept all interrupts */
402 gic_v3_cpu_priority(GIC_PRIORITY_MIN);
403 /* Disable EOI mode */
404 gic_icc_clear(CTLR, ICC_CTLR_EL1_EOIMODE);
405 /* Enable group 1 (insecure) interrups */
406 gic_icc_set(IGRPEN1, ICC_IGRPEN0_EL1_EN);
413 gic_v3_dist_init(struct gic_v3_softc *sc)
419 * 1. Disable the Distributor
421 gic_d_write(sc, 4, GICD_CTLR, 0);
422 gic_v3_wait_for_rwp(sc, DIST);
425 * 2. Configure the Distributor
427 /* Set all global interrupts to be level triggered, active low. */
428 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_ICFGRn)
429 gic_d_write(sc, 4, GICD_ICFGR(i), 0x00000000);
431 /* Set priority to all shared interrupts */
432 for (i = GIC_FIRST_SPI;
433 i < sc->gic_nirqs; i += GICD_I_PER_IPRIORITYn) {
434 /* Set highest priority */
435 gic_d_write(sc, 4, GICD_IPRIORITYR(i), GIC_PRIORITY_MAX);
439 * Disable all interrupts. Leave PPI and SGIs as they are enabled in
440 * Re-Distributor registers.
442 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_ISENABLERn)
443 gic_d_write(sc, 4, GICD_ICENABLER(i), 0xFFFFFFFF);
445 gic_v3_wait_for_rwp(sc, DIST);
448 * 3. Enable Distributor
450 /* Enable Distributor with ARE, Group 1 */
451 gic_d_write(sc, 4, GICD_CTLR, GICD_CTLR_ARE_NS | GICD_CTLR_G1A |
455 * 4. Route all interrupts to boot CPU.
457 aff = CPU_AFFINITY(PCPU_GET(cpuid));
458 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i++)
459 gic_d_write(sc, 4, GICD_IROUTER(i), aff);
466 gic_v3_redist_find(struct gic_v3_softc *sc)
468 struct resource r_res;
469 bus_space_handle_t r_bsh;
476 cpuid = PCPU_GET(cpuid);
478 /* Allocate struct resource for this CPU's Re-Distributor registers */
479 sc->gic_redists.pcpu[cpuid] =
480 malloc(sizeof(*sc->gic_redists.pcpu[0]), M_GIC_V3, M_WAITOK);
482 aff = CPU_AFFINITY(cpuid);
483 /* Affinity in format for comparison with typer */
484 aff = (CPU_AFF3(aff) << 24) | (CPU_AFF2(aff) << 16) |
485 (CPU_AFF1(aff) << 8) | CPU_AFF0(aff);
488 device_printf(sc->dev,
489 "Start searching for Re-Distributor\n");
491 /* Iterate through Re-Distributor regions */
492 for (i = 0; i < sc->gic_redists.nregions; i++) {
493 /* Take a copy of the region's resource */
494 r_res = *sc->gic_redists.regions[i];
495 r_bsh = rman_get_bushandle(&r_res);
497 pidr2 = bus_read_4(&r_res, GICR_PIDR2);
498 switch (pidr2 & GICR_PIDR2_ARCH_MASK) {
499 case GICR_PIDR2_ARCH_GICv3: /* fall through */
500 case GICR_PIDR2_ARCH_GICv4:
503 device_printf(sc->dev,
504 "No Re-Distributor found for CPU%u\n", cpuid);
505 free(sc->gic_redists.pcpu[cpuid], M_GIC_V3);
510 typer = bus_read_8(&r_res, GICR_TYPER);
511 if ((typer >> GICR_TYPER_AFF_SHIFT) == aff) {
512 KASSERT(sc->gic_redists.pcpu[cpuid] != NULL,
513 ("Invalid pointer to per-CPU redistributor"));
514 /* Copy res contents to its final destination */
515 *sc->gic_redists.pcpu[cpuid] = r_res;
517 device_printf(sc->dev,
518 "CPU%u Re-Distributor has been found\n",
524 r_bsh += (GICR_RD_BASE_SIZE + GICR_SGI_BASE_SIZE);
525 if ((typer & GICR_TYPER_VLPIS) != 0) {
527 (GICR_VLPI_BASE_SIZE + GICR_RESERVED_SIZE);
530 rman_set_bushandle(&r_res, r_bsh);
531 } while ((typer & GICR_TYPER_LAST) == 0);
534 free(sc->gic_redists.pcpu[cpuid], M_GIC_V3);
535 device_printf(sc->dev, "No Re-Distributor found for CPU%u\n", cpuid);
540 gic_v3_redist_wake(struct gic_v3_softc *sc)
543 size_t us_left = 1000000;
545 waker = gic_r_read(sc, 4, GICR_WAKER);
546 /* Wake up Re-Distributor for this CPU */
547 waker &= ~GICR_WAKER_PS;
548 gic_r_write(sc, 4, GICR_WAKER, waker);
550 * When clearing ProcessorSleep bit it is required to wait for
551 * ChildrenAsleep to become zero following the processor power-on.
553 while ((gic_r_read(sc, 4, GICR_WAKER) & GICR_WAKER_CA) != 0) {
555 if (us_left-- == 0) {
556 panic("Could not wake Re-Distributor for CPU%u",
562 device_printf(sc->dev, "CPU%u Re-Distributor woke up\n",
570 gic_v3_redist_init(struct gic_v3_softc *sc)
575 err = gic_v3_redist_find(sc);
579 err = gic_v3_redist_wake(sc);
584 gic_r_write(sc, 4, GICR_SGI_BASE_SIZE + GICR_ICENABLER0,
585 GICR_I_ENABLER_PPI_MASK);
587 gic_r_write(sc, 4, GICR_SGI_BASE_SIZE + GICR_ISENABLER0,
588 GICR_I_ENABLER_SGI_MASK);
590 /* Set priority for SGIs and PPIs */
591 for (i = 0; i <= GIC_LAST_PPI; i += GICR_I_PER_IPRIORITYn) {
592 gic_r_write(sc, 4, GICR_SGI_BASE_SIZE + GICD_IPRIORITYR(i),
596 gic_v3_wait_for_rwp(sc, REDIST);