Remove teh non-INTRNG code from the ARM GIC interrupt controller driver.

We don't build for the non-INTRNG case and it was makeing the code harder
to read.
This commit is contained in:
Andrew Turner 2018-07-30 10:55:02 +00:00
parent 4ad5b7a0ac
commit 011dc75d9c
3 changed files with 0 additions and 378 deletions

View File

@ -53,9 +53,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/smp.h>
#ifdef INTRNG
#include <sys/sched.h>
#endif
#include <vm/vm.h>
#include <vm/pmap.h>
@ -77,10 +75,8 @@ __FBSDID("$FreeBSD$");
#include <arm/arm/gic.h>
#include <arm/arm/gic_common.h>
#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

View File

@ -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);

View File

@ -54,12 +54,10 @@ __FBSDID("$FreeBSD$");
#include <arm/arm/gic.h>
#include <arm/arm/gic_common.h>
#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