diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 324f7deb91b9..0b6d90be053e 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -53,9 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef INTRNG #include -#endif #include #include @@ -77,10 +75,8 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef INTRNG #include "pic_if.h" #include "msi_if.h" -#endif /* We are using GICv2 register naming */ @@ -107,7 +103,6 @@ __FBSDID("$FreeBSD$"); #define GIC_DEFAULT_ICFGR_INIT 0x00000000 #endif -#ifdef INTRNG struct gic_irqsrc { struct intr_irqsrc gi_isrc; uint32_t gi_irq; @@ -130,26 +125,11 @@ static u_int sgi_first_unused = GIC_FIRST_SGI; #endif #define GIC_INTR_ISRC(sc, irq) (&sc->gic_irqs[irq].gi_isrc) -#else /* !INTRNG */ -static struct ofw_compat_data compat_data[] = { - {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */ - {"arm,gic-400", true}, - {"arm,cortex-a15-gic", true}, - {"arm,cortex-a9-gic", true}, - {"arm,cortex-a7-gic", true}, - {"arm,arm11mp-gic", true}, - {"brcm,brahma-b15-gic", true}, - {"qcom,msm-qgic2", true}, - {NULL, false} -}; -#endif static struct resource_spec arm_gic_spec[] = { { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Distributor registers */ { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* CPU Interrupt Intf. registers */ -#ifdef INTRNG { SYS_RES_IRQ, 0, RF_ACTIVE | RF_OPTIONAL }, /* Parent interrupt */ -#endif { -1, 0 } }; @@ -176,13 +156,6 @@ static struct arm_gic_softc *gic_sc = NULL; #define gic_d_write_4(_sc, _reg, _val) \ bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val)) -#ifndef INTRNG -static int gic_config_irq(int irq, enum intr_trigger trig, - enum intr_polarity pol); -static void gic_post_filter(void *); -#endif - -#ifdef INTRNG static inline void gic_irq_unmask(struct arm_gic_softc *sc, u_int irq) { @@ -196,7 +169,6 @@ gic_irq_mask(struct arm_gic_softc *sc, u_int irq) gic_d_write_4(sc, GICD_ICENABLER(irq), GICD_I_MASK(irq)); } -#endif static uint8_t gic_cpu_mask(struct arm_gic_softc *sc) @@ -222,7 +194,6 @@ gic_cpu_mask(struct arm_gic_softc *sc) } #ifdef SMP -#ifdef INTRNG static void arm_gic_init_secondary(device_t dev) { @@ -260,105 +231,8 @@ arm_gic_init_secondary(device_t dev) if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu)) gic_irq_unmask(sc, irq); } -#else -static void -arm_gic_init_secondary(device_t dev) -{ - struct arm_gic_softc *sc = device_get_softc(dev); - int i; - - /* Set the mask so we can find this CPU to send it IPIs */ - arm_gic_map[PCPU_GET(cpuid)] = gic_cpu_mask(sc); - - for (i = 0; i < sc->nirqs; i += 4) - gic_d_write_4(sc, GICD_IPRIORITYR(i), 0); - - /* Set all the interrupts to be in Group 0 (secure) */ - for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { - gic_d_write_4(sc, GICD_IGROUPR(i), 0); - } - - /* Enable CPU interface */ - gic_c_write_4(sc, GICC_CTLR, 1); - - /* Set priority mask register. */ - gic_c_write_4(sc, GICC_PMR, 0xff); - - /* Enable interrupt distribution */ - gic_d_write_4(sc, GICD_CTLR, 0x01); - - /* - * Activate the timer interrupts: virtual, secure, and non-secure. - */ - gic_d_write_4(sc, GICD_ISENABLER(27), GICD_I_MASK(27)); - gic_d_write_4(sc, GICD_ISENABLER(29), GICD_I_MASK(29)); - gic_d_write_4(sc, GICD_ISENABLER(30), GICD_I_MASK(30)); -} -#endif /* INTRNG */ #endif /* SMP */ -#ifndef INTRNG -int -gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt, - int *trig, int *pol) -{ - static u_int num_intr_cells; - static phandle_t self; - struct ofw_compat_data *ocd; - - if (self == 0) { - for (ocd = compat_data; ocd->ocd_str != NULL; ocd++) { - if (ofw_bus_node_is_compatible(iparent, ocd->ocd_str)) { - self = iparent; - break; - } - } - } - if (self != iparent) - return (ENXIO); - - if (num_intr_cells == 0) { - if (OF_searchencprop(OF_node_from_xref(iparent), - "#interrupt-cells", &num_intr_cells, - sizeof(num_intr_cells)) == -1) { - num_intr_cells = 1; - } - } - - if (num_intr_cells == 1) { - *interrupt = fdt32_to_cpu(intr[0]); - *trig = INTR_TRIGGER_CONFORM; - *pol = INTR_POLARITY_CONFORM; - } else { - if (fdt32_to_cpu(intr[0]) == 0) - *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_SPI; - else - *interrupt = fdt32_to_cpu(intr[1]) + GIC_FIRST_PPI; - /* - * In intr[2], bits[3:0] are trigger type and level flags. - * 1 = low-to-high edge triggered - * 2 = high-to-low edge triggered - * 4 = active high level-sensitive - * 8 = active low level-sensitive - * The hardware only supports active-high-level or rising-edge - * for SPIs - */ - if (*interrupt >= GIC_FIRST_SPI && - fdt32_to_cpu(intr[2]) & 0x0a) { - printf("unsupported trigger/polarity configuration " - "0x%02x\n", fdt32_to_cpu(intr[2]) & 0x0f); - } - *pol = INTR_POLARITY_CONFORM; - if (fdt32_to_cpu(intr[2]) & 0x03) - *trig = INTR_TRIGGER_EDGE; - else - *trig = INTR_TRIGGER_LEVEL; - } - return (0); -} -#endif - -#ifdef INTRNG static int arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num) { @@ -425,7 +299,6 @@ arm_gic_reserve_msi_range(device_t dev, u_int start, u_int count) sc->gic_irqs[start + i].gi_flags |= GI_FLAG_MSI; } } -#endif int arm_gic_attach(device_t dev) @@ -465,27 +338,17 @@ arm_gic_attach(device_t dev) sc->typer = gic_d_read_4(sc, GICD_TYPER); nirqs = GICD_TYPER_I_NUM(sc->typer); -#ifdef INTRNG if (arm_gic_register_isrcs(sc, nirqs)) { device_printf(dev, "could not register irqs\n"); goto cleanup; } -#else - sc->nirqs = nirqs; - - /* Set up function pointers */ - arm_post_filter = gic_post_filter; - arm_config_irq = gic_config_irq; -#endif icciidr = gic_c_read_4(sc, GICC_IIDR); device_printf(dev, "pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n", GICD_IIDR_PROD(icciidr), GICD_IIDR_VAR(icciidr), GICD_IIDR_REV(icciidr), GICD_IIDR_IMPL(icciidr), sc->nirqs); -#ifdef INTRNG sc->gic_iidr = icciidr; -#endif /* Set all global interrupts to be level triggered, active low. */ for (i = 32; i < sc->nirqs; i += 16) { @@ -527,17 +390,14 @@ arm_gic_attach(device_t dev) gic_d_write_4(sc, GICD_CTLR, 0x01); return (0); -#ifdef INTRNG cleanup: arm_gic_detach(dev); return(ENXIO); -#endif } int arm_gic_detach(device_t dev) { -#ifdef INTRNG struct arm_gic_softc *sc; sc = device_get_softc(dev); @@ -546,12 +406,10 @@ arm_gic_detach(device_t dev) free(sc->gic_irqs, M_DEVBUF); bus_release_resources(dev, arm_gic_spec, sc->gic_res); -#endif return (0); } -#ifdef INTRNG static int arm_gic_print_child(device_t bus, device_t child) { @@ -1145,217 +1003,8 @@ arm_gic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc **isrcp) return (0); } #endif -#else -static int -arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq) -{ - uint32_t active_irq; - - active_irq = gic_c_read_4(sc, GICC_IAR); - - /* - * Immediately EOIR the SGIs, because doing so requires the other - * bits (ie CPU number), not just the IRQ number, and we do not - * have this information later. - */ - if ((active_irq & 0x3ff) <= GIC_LAST_SGI) - gic_c_write_4(sc, GICC_EOIR, active_irq); - active_irq &= 0x3FF; - - if (active_irq == 0x3FF) { - if (last_irq == -1) - device_printf(sc->gic_dev, - "Spurious interrupt detected\n"); - return -1; - } - - return active_irq; -} - -static int -arm_gic_config(device_t dev, int irq, enum intr_trigger trig, - enum intr_polarity pol) -{ - struct arm_gic_softc *sc = device_get_softc(dev); - uint32_t reg; - uint32_t mask; - - /* Function is public-accessible, so validate input arguments */ - if ((irq < 0) || (irq >= sc->nirqs)) - goto invalid_args; - if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) && - (trig != INTR_TRIGGER_CONFORM)) - goto invalid_args; - if ((pol != INTR_POLARITY_HIGH) && (pol != INTR_POLARITY_LOW) && - (pol != INTR_POLARITY_CONFORM)) - goto invalid_args; - - mtx_lock_spin(&sc->mutex); - - reg = gic_d_read_4(sc, GICD_ICFGR(irq)); - mask = (reg >> 2*(irq % 16)) & 0x3; - - if (pol == INTR_POLARITY_LOW) { - mask &= ~GICD_ICFGR_POL_MASK; - mask |= GICD_ICFGR_POL_LOW; - } else if (pol == INTR_POLARITY_HIGH) { - mask &= ~GICD_ICFGR_POL_MASK; - mask |= GICD_ICFGR_POL_HIGH; - } - - if (trig == INTR_TRIGGER_LEVEL) { - mask &= ~GICD_ICFGR_TRIG_MASK; - mask |= GICD_ICFGR_TRIG_LVL; - } else if (trig == INTR_TRIGGER_EDGE) { - mask &= ~GICD_ICFGR_TRIG_MASK; - mask |= GICD_ICFGR_TRIG_EDGE; - } - - /* Set mask */ - reg = reg & ~(0x3 << 2*(irq % 16)); - reg = reg | (mask << 2*(irq % 16)); - gic_d_write_4(sc, GICD_ICFGR(irq), reg); - - mtx_unlock_spin(&sc->mutex); - - return (0); - -invalid_args: - device_printf(dev, "gic_config_irg, invalid parameters\n"); - return (EINVAL); -} - - -static void -arm_gic_mask(device_t dev, int irq) -{ - struct arm_gic_softc *sc = device_get_softc(dev); - - gic_d_write_4(sc, GICD_ICENABLER(irq), (1UL << (irq & 0x1F))); - gic_c_write_4(sc, GICC_EOIR, irq); /* XXX - not allowed */ -} - -static void -arm_gic_unmask(device_t dev, int irq) -{ - struct arm_gic_softc *sc = device_get_softc(dev); - - if (irq > GIC_LAST_SGI) - arm_irq_memory_barrier(irq); - - gic_d_write_4(sc, GICD_ISENABLER(irq), (1UL << (irq & 0x1F))); -} - -#ifdef SMP -static void -arm_gic_ipi_send(device_t dev, cpuset_t cpus, u_int ipi) -{ - struct arm_gic_softc *sc = device_get_softc(dev); - uint32_t val = 0, i; - - for (i = 0; i < MAXCPU; i++) - if (CPU_ISSET(i, &cpus)) - val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT; - - gic_d_write_4(sc, GICD_SGIR, val | ipi); -} - -static int -arm_gic_ipi_read(device_t dev, int i) -{ - - if (i != -1) { - /* - * The intr code will automagically give the frame pointer - * if the interrupt argument is 0. - */ - if ((unsigned int)i > 16) - return (0); - return (i); - } - - return (0x3ff); -} - -static void -arm_gic_ipi_clear(device_t dev, int ipi) -{ - /* no-op */ -} -#endif - -static void -gic_post_filter(void *arg) -{ - struct arm_gic_softc *sc = gic_sc; - uintptr_t irq = (uintptr_t) arg; - - if (irq > GIC_LAST_SGI) - arm_irq_memory_barrier(irq); - gic_c_write_4(sc, GICC_EOIR, irq); -} - -static int -gic_config_irq(int irq, enum intr_trigger trig, enum intr_polarity pol) -{ - - return (arm_gic_config(gic_sc->gic_dev, irq, trig, pol)); -} - -void -arm_mask_irq(uintptr_t nb) -{ - - arm_gic_mask(gic_sc->gic_dev, nb); -} - -void -arm_unmask_irq(uintptr_t nb) -{ - - arm_gic_unmask(gic_sc->gic_dev, nb); -} - -int -arm_get_next_irq(int last_irq) -{ - - return (arm_gic_next_irq(gic_sc, last_irq)); -} - -#ifdef SMP -void -intr_pic_init_secondary(void) -{ - - arm_gic_init_secondary(gic_sc->gic_dev); -} - -void -pic_ipi_send(cpuset_t cpus, u_int ipi) -{ - - arm_gic_ipi_send(gic_sc->gic_dev, cpus, ipi); -} - -int -pic_ipi_read(int i) -{ - - return (arm_gic_ipi_read(gic_sc->gic_dev, i)); -} - -void -pic_ipi_clear(int ipi) -{ - - arm_gic_ipi_clear(gic_sc->gic_dev, ipi); -} -#endif -#endif /* INTRNG */ static device_method_t arm_gic_methods[] = { -#ifdef INTRNG /* Bus interface */ DEVMETHOD(bus_print_child, arm_gic_print_child), DEVMETHOD(bus_add_child, bus_generic_add_child), @@ -1378,7 +1027,6 @@ static device_method_t arm_gic_methods[] = { DEVMETHOD(pic_init_secondary, arm_gic_init_secondary), DEVMETHOD(pic_ipi_send, arm_gic_ipi_send), DEVMETHOD(pic_ipi_setup, arm_gic_ipi_setup), -#endif #endif { 0, 0 } }; @@ -1386,7 +1034,6 @@ static device_method_t arm_gic_methods[] = { DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods, sizeof(struct arm_gic_softc)); -#ifdef INTRNG /* * GICv2m support -- the GICv2 MSI/MSI-X controller. */ @@ -1611,4 +1258,3 @@ static device_method_t arm_gicv2m_methods[] = { DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods, sizeof(struct arm_gicv2m_softc)); -#endif diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h index 5352408c7f9c..3df226c2819a 100644 --- a/sys/arm/arm/gic.h +++ b/sys/arm/arm/gic.h @@ -39,20 +39,16 @@ #ifndef _ARM_GIC_H_ #define _ARM_GIC_H_ -#ifdef INTRNG struct arm_gic_range { uint64_t bus; uint64_t host; uint64_t size; }; -#endif struct arm_gic_softc { device_t gic_dev; -#ifdef INTRNG void * gic_intrhand; struct gic_irqsrc * gic_irqs; -#endif struct resource * gic_res[3]; bus_space_tag_t gic_c_bst; bus_space_tag_t gic_d_bst; @@ -64,18 +60,15 @@ struct arm_gic_softc { uint32_t typer; uint32_t last_irq[MAXCPU]; -#ifdef INTRNG uint32_t gic_iidr; u_int gic_bus; int nranges; struct arm_gic_range * ranges; -#endif }; DECLARE_CLASS(arm_gic_driver); -#ifdef INTRNG struct arm_gicv2m_softc { struct resource *sc_mem; struct mtx sc_mutex; @@ -86,7 +79,6 @@ struct arm_gicv2m_softc { }; DECLARE_CLASS(arm_gicv2m_driver); -#endif int arm_gic_attach(device_t); int arm_gic_detach(device_t); diff --git a/sys/arm/arm/gic_fdt.c b/sys/arm/arm/gic_fdt.c index cae5307d8bd7..bf43339d65bd 100644 --- a/sys/arm/arm/gic_fdt.c +++ b/sys/arm/arm/gic_fdt.c @@ -54,12 +54,10 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef INTRNG struct arm_gic_devinfo { struct ofw_bus_devinfo obdinfo; struct resource_list rl; }; -#endif struct arm_gic_fdt_softc { struct arm_gic_softc base; @@ -70,10 +68,8 @@ struct arm_gic_fdt_softc { static device_probe_t gic_fdt_probe; static device_attach_t gic_fdt_attach; static ofw_bus_get_devinfo_t gic_ofw_get_devinfo; -#ifdef INTRNG static bus_get_resource_list_t gic_fdt_get_resource_list; static bool arm_gic_add_children(device_t); -#endif static struct ofw_compat_data compat_data[] = { {"arm,gic", true}, /* Non-standard, used in FreeBSD dts. */ @@ -92,7 +88,6 @@ static device_method_t gic_fdt_methods[] = { DEVMETHOD(device_probe, gic_fdt_probe), DEVMETHOD(device_attach, gic_fdt_attach), -#ifdef INTRNG /* Bus interface */ DEVMETHOD(bus_get_resource_list,gic_fdt_get_resource_list), @@ -103,7 +98,6 @@ static device_method_t gic_fdt_methods[] = { DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name), DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node), DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type), -#endif DEVMETHOD_END, }; @@ -134,22 +128,17 @@ gic_fdt_probe(device_t dev) static int gic_fdt_attach(device_t dev) { -#ifdef INTRNG struct arm_gic_fdt_softc *sc = device_get_softc(dev); phandle_t pxref; intptr_t xref; -#endif int err; -#ifdef INTRNG sc->base.gic_bus = GIC_BUS_FDT; -#endif err = arm_gic_attach(dev); if (err != 0) return (err); -#ifdef INTRNG xref = OF_xref_from_node(ofw_bus_get_node(dev)); /* @@ -196,18 +185,14 @@ gic_fdt_attach(device_t dev) bus_generic_probe(dev); return (bus_generic_attach(dev)); } -#endif return (0); -#ifdef INTRNG cleanup: arm_gic_detach(dev); return(ENXIO); -#endif } -#ifdef INTRNG static struct resource_list * gic_fdt_get_resource_list(device_t bus, device_t child) { @@ -376,4 +361,3 @@ static devclass_t arm_gicv2m_fdt_devclass; EARLY_DRIVER_MODULE(gicv2m, gic, arm_gicv2m_fdt_driver, arm_gicv2m_fdt_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); -#endif