diff --git a/sys/powerpc/include/openpicvar.h b/sys/powerpc/include/openpicvar.h index b675b01210e5..36b2c93342fa 100644 --- a/sys/powerpc/include/openpicvar.h +++ b/sys/powerpc/include/openpicvar.h @@ -75,14 +75,14 @@ int openpic_common_attach(device_t, uint32_t); /* * PIC interface. */ -void openpic_bind(device_t dev, u_int irq, cpuset_t cpumask); +void openpic_bind(device_t dev, u_int irq, cpuset_t cpumask, void **); void openpic_config(device_t, u_int, enum intr_trigger, enum intr_polarity); void openpic_dispatch(device_t, struct trapframe *); -void openpic_enable(device_t, u_int, u_int); -void openpic_eoi(device_t, u_int); +void openpic_enable(device_t, u_int, u_int, void **); +void openpic_eoi(device_t, u_int, void *); void openpic_ipi(device_t, u_int); -void openpic_mask(device_t, u_int); -void openpic_unmask(device_t, u_int); +void openpic_mask(device_t, u_int, void *); +void openpic_unmask(device_t, u_int, void *); int openpic_suspend(device_t dev); int openpic_resume(device_t dev); diff --git a/sys/powerpc/powermac/cpcht.c b/sys/powerpc/powermac/cpcht.c index 8905e89bc4cb..ca3e4281d26a 100644 --- a/sys/powerpc/powermac/cpcht.c +++ b/sys/powerpc/powermac/cpcht.c @@ -512,9 +512,10 @@ static int openpic_cpcht_probe(device_t); static int openpic_cpcht_attach(device_t); static void openpic_cpcht_config(device_t, u_int irq, enum intr_trigger trig, enum intr_polarity pol); -static void openpic_cpcht_enable(device_t, u_int irq, u_int vector); -static void openpic_cpcht_unmask(device_t, u_int irq); -static void openpic_cpcht_eoi(device_t, u_int irq); +static void openpic_cpcht_enable(device_t, u_int irq, u_int vector, + void **priv); +static void openpic_cpcht_unmask(device_t, u_int irq, void *priv); +static void openpic_cpcht_eoi(device_t, u_int irq, void *priv); static device_method_t openpic_cpcht_methods[] = { /* Device interface */ @@ -649,12 +650,12 @@ openpic_cpcht_config(device_t dev, u_int irq, enum intr_trigger trig, } static void -openpic_cpcht_enable(device_t dev, u_int irq, u_int vec) +openpic_cpcht_enable(device_t dev, u_int irq, u_int vec, void **priv) { struct openpic_cpcht_softc *sc; uint32_t ht_irq; - openpic_enable(dev, irq, vec); + openpic_enable(dev, irq, vec, priv); sc = device_get_softc(dev); @@ -674,16 +675,16 @@ openpic_cpcht_enable(device_t dev, u_int irq, u_int vec) mtx_unlock_spin(&sc->sc_ht_mtx); } - openpic_cpcht_eoi(dev, irq); + openpic_cpcht_eoi(dev, irq, *priv); } static void -openpic_cpcht_unmask(device_t dev, u_int irq) +openpic_cpcht_unmask(device_t dev, u_int irq, void *priv) { struct openpic_cpcht_softc *sc; uint32_t ht_irq; - openpic_unmask(dev, irq); + openpic_unmask(dev, irq, priv); sc = device_get_softc(dev); @@ -703,11 +704,11 @@ openpic_cpcht_unmask(device_t dev, u_int irq) mtx_unlock_spin(&sc->sc_ht_mtx); } - openpic_cpcht_eoi(dev, irq); + openpic_cpcht_eoi(dev, irq, priv); } static void -openpic_cpcht_eoi(device_t dev, u_int irq) +openpic_cpcht_eoi(device_t dev, u_int irq, void *priv) { struct openpic_cpcht_softc *sc; uint32_t off, mask; @@ -737,5 +738,5 @@ openpic_cpcht_eoi(device_t dev, u_int irq) } } - openpic_eoi(dev, irq); + openpic_eoi(dev, irq, priv); } diff --git a/sys/powerpc/powermac/hrowpic.c b/sys/powerpc/powermac/hrowpic.c index 1df23b982e82..6206304a59b8 100644 --- a/sys/powerpc/powermac/hrowpic.c +++ b/sys/powerpc/powermac/hrowpic.c @@ -66,11 +66,11 @@ static int hrowpic_probe(device_t); static int hrowpic_attach(device_t); static void hrowpic_dispatch(device_t, struct trapframe *); -static void hrowpic_enable(device_t, u_int, u_int); -static void hrowpic_eoi(device_t, u_int); +static void hrowpic_enable(device_t, u_int, u_int, void **); +static void hrowpic_eoi(device_t, u_int, void *); static void hrowpic_ipi(device_t, u_int); -static void hrowpic_mask(device_t, u_int); -static void hrowpic_unmask(device_t, u_int); +static void hrowpic_mask(device_t, u_int, void *); +static void hrowpic_unmask(device_t, u_int, void *); static device_method_t hrowpic_methods[] = { /* Device interface */ @@ -237,7 +237,7 @@ hrowpic_dispatch(device_t dev, struct trapframe *tf) } static void -hrowpic_enable(device_t dev, u_int irq, u_int vector) +hrowpic_enable(device_t dev, u_int irq, u_int vector, void **priv __unused) { struct hrowpic_softc *sc; @@ -247,7 +247,7 @@ hrowpic_enable(device_t dev, u_int irq, u_int vector) } static void -hrowpic_eoi(device_t dev, u_int irq) +hrowpic_eoi(device_t dev, u_int irq, void *priv __unused) { struct hrowpic_softc *sc; int bank; @@ -264,7 +264,7 @@ hrowpic_ipi(device_t dev, u_int irq) } static void -hrowpic_mask(device_t dev, u_int irq) +hrowpic_mask(device_t dev, u_int irq, void *priv __unused) { struct hrowpic_softc *sc; @@ -273,7 +273,7 @@ hrowpic_mask(device_t dev, u_int irq) } static void -hrowpic_unmask(device_t dev, u_int irq) +hrowpic_unmask(device_t dev, u_int irq, void *priv __unused) { struct hrowpic_softc *sc; diff --git a/sys/powerpc/powernv/opal_pci.c b/sys/powerpc/powernv/opal_pci.c index 3ae68716bb7e..50ee3904dc76 100644 --- a/sys/powerpc/powernv/opal_pci.c +++ b/sys/powerpc/powernv/opal_pci.c @@ -93,8 +93,8 @@ static int opalpci_route_interrupt(device_t bus, device_t dev, int pin); /* * MSI PIC interface. */ -static void opalpic_pic_enable(device_t dev, u_int irq, u_int vector); -static void opalpic_pic_eoi(device_t dev, u_int irq); +static void opalpic_pic_enable(device_t dev, u_int irq, u_int vector, void **); +static void opalpic_pic_eoi(device_t dev, u_int irq, void *); /* Bus interface */ static bus_dma_tag_t opalpci_get_dma_tag(device_t dev, device_t child); @@ -675,22 +675,22 @@ opalpci_map_msi(device_t dev, device_t child, int irq, uint64_t *addr, } static void -opalpic_pic_enable(device_t dev, u_int irq, u_int vector) +opalpic_pic_enable(device_t dev, u_int irq, u_int vector, void **priv) { struct opalpci_softc *sc = device_get_softc(dev); - PIC_ENABLE(root_pic, irq, vector); - opal_call(OPAL_PCI_MSI_EOI, sc->phb_id, irq); + PIC_ENABLE(root_pic, irq, vector, priv); + opal_call(OPAL_PCI_MSI_EOI, sc->phb_id, irq, priv); } -static void opalpic_pic_eoi(device_t dev, u_int irq) +static void opalpic_pic_eoi(device_t dev, u_int irq, void *priv) { struct opalpci_softc *sc; sc = device_get_softc(dev); opal_call(OPAL_PCI_MSI_EOI, sc->phb_id, irq); - PIC_EOI(root_pic, irq); + PIC_EOI(root_pic, irq, priv); } static bus_dma_tag_t diff --git a/sys/powerpc/powerpc/intr_machdep.c b/sys/powerpc/powerpc/intr_machdep.c index 4d56a8ac9324..851b4265a168 100644 --- a/sys/powerpc/powerpc/intr_machdep.c +++ b/sys/powerpc/powerpc/intr_machdep.c @@ -96,6 +96,7 @@ static MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data"); struct powerpc_intr { struct intr_event *event; long *cntp; + void *priv; /* PIC-private data */ u_int irq; device_t pic; u_int intline; @@ -158,7 +159,7 @@ smp_intr_init(void *dummy __unused) for (vector = 0; vector < nvectors; vector++) { i = powerpc_intrs[vector]; if (i != NULL && i->event != NULL && i->pic == root_pic) - PIC_BIND(i->pic, i->intline, i->cpu); + PIC_BIND(i->pic, i->intline, i->cpu, &i->priv); } } SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); @@ -281,7 +282,7 @@ powerpc_intr_eoi(void *arg) { struct powerpc_intr *i = arg; - PIC_EOI(i->pic, i->intline); + PIC_EOI(i->pic, i->intline, i->priv); } static void @@ -289,8 +290,8 @@ powerpc_intr_pre_ithread(void *arg) { struct powerpc_intr *i = arg; - PIC_MASK(i->pic, i->intline); - PIC_EOI(i->pic, i->intline); + PIC_MASK(i->pic, i->intline, i->priv); + PIC_EOI(i->pic, i->intline, i->priv); } static void @@ -298,7 +299,7 @@ powerpc_intr_post_ithread(void *arg) { struct powerpc_intr *i = arg; - PIC_UNMASK(i->pic, i->intline); + PIC_UNMASK(i->pic, i->intline, i->priv); } static int @@ -313,7 +314,7 @@ powerpc_assign_intr_cpu(void *arg, int cpu) CPU_SETOF(cpu, &i->cpu); if (!cold && i->pic != NULL && i->pic == root_pic) - PIC_BIND(i->pic, i->intline, i->cpu); + PIC_BIND(i->pic, i->intline, i->cpu, &i->priv); return (0); #else @@ -465,7 +466,7 @@ powerpc_enable_intr(void) PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); if (i->event != NULL) - PIC_ENABLE(i->pic, i->intline, vector); + PIC_ENABLE(i->pic, i->intline, vector, &i->priv); } return (0); @@ -512,10 +513,11 @@ powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter, PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); if (i->pic == root_pic) - PIC_BIND(i->pic, i->intline, i->cpu); + PIC_BIND(i->pic, i->intline, i->cpu, &i->priv); if (enable) - PIC_ENABLE(i->pic, i->intline, i->vector); + PIC_ENABLE(i->pic, i->intline, i->vector, + &i->priv); } } return (error); @@ -602,7 +604,7 @@ powerpc_dispatch_intr(u_int vector, struct trapframe *tf) * This prevents races in IPI handling. */ if (i->ipi) - PIC_EOI(i->pic, i->intline); + PIC_EOI(i->pic, i->intline, i->priv); if (intr_event_handle(ie, tf) != 0) { goto stray; @@ -619,7 +621,7 @@ powerpc_dispatch_intr(u_int vector, struct trapframe *tf) } } if (i != NULL) - PIC_MASK(i->pic, i->intline); + PIC_MASK(i->pic, i->intline, i->priv); } void @@ -631,7 +633,7 @@ powerpc_intr_mask(u_int irq) if (i == NULL || i->pic == NULL) return; - PIC_MASK(i->pic, i->intline); + PIC_MASK(i->pic, i->intline, i->priv); } void @@ -643,5 +645,5 @@ powerpc_intr_unmask(u_int irq) if (i == NULL || i->pic == NULL) return; - PIC_UNMASK(i->pic, i->intline); + PIC_UNMASK(i->pic, i->intline, i->priv); } diff --git a/sys/powerpc/powerpc/openpic.c b/sys/powerpc/powerpc/openpic.c index 4bf7f1e9612f..6941c70ef704 100644 --- a/sys/powerpc/powerpc/openpic.c +++ b/sys/powerpc/powerpc/openpic.c @@ -233,7 +233,7 @@ openpic_common_attach(device_t dev, uint32_t node) */ void -openpic_bind(device_t dev, u_int irq, cpuset_t cpumask) +openpic_bind(device_t dev, u_int irq, cpuset_t cpumask, void **priv __unused) { struct openpic_softc *sc; @@ -302,7 +302,7 @@ openpic_dispatch(device_t dev, struct trapframe *tf) } void -openpic_enable(device_t dev, u_int irq, u_int vector) +openpic_enable(device_t dev, u_int irq, u_int vector, void **priv __unused) { struct openpic_softc *sc; uint32_t x; @@ -322,7 +322,7 @@ openpic_enable(device_t dev, u_int irq, u_int vector) } void -openpic_eoi(device_t dev, u_int irq __unused) +openpic_eoi(device_t dev, u_int irq __unused, void *priv __unused) { struct openpic_softc *sc; u_int cpuid; @@ -348,7 +348,7 @@ openpic_ipi(device_t dev, u_int cpu) } void -openpic_mask(device_t dev, u_int irq) +openpic_mask(device_t dev, u_int irq, void *priv __unused) { struct openpic_softc *sc; uint32_t x; @@ -366,7 +366,7 @@ openpic_mask(device_t dev, u_int irq) } void -openpic_unmask(device_t dev, u_int irq) +openpic_unmask(device_t dev, u_int irq, void *priv __unused) { struct openpic_softc *sc; uint32_t x; diff --git a/sys/powerpc/powerpc/pic_if.m b/sys/powerpc/powerpc/pic_if.m index f42c31a0692c..edbbc3376a7a 100644 --- a/sys/powerpc/powerpc/pic_if.m +++ b/sys/powerpc/powerpc/pic_if.m @@ -48,6 +48,7 @@ METHOD void bind { device_t dev; u_int irq; cpuset_t cpumask; + void **priv; }; METHOD void translate_code { @@ -74,11 +75,13 @@ METHOD void enable { device_t dev; u_int irq; u_int vector; + void **priv; }; METHOD void eoi { device_t dev; u_int irq; + void *priv; }; METHOD void ipi { @@ -89,10 +92,12 @@ METHOD void ipi { METHOD void mask { device_t dev; u_int irq; + void *priv; }; METHOD void unmask { device_t dev; u_int irq; + void *priv; }; diff --git a/sys/powerpc/ps3/ps3pic.c b/sys/powerpc/ps3/ps3pic.c index 3ae8c326ee85..423c137fb7f3 100644 --- a/sys/powerpc/ps3/ps3pic.c +++ b/sys/powerpc/ps3/ps3pic.c @@ -51,11 +51,11 @@ static int ps3pic_probe(device_t); static int ps3pic_attach(device_t); static void ps3pic_dispatch(device_t, struct trapframe *); -static void ps3pic_enable(device_t, u_int, u_int); -static void ps3pic_eoi(device_t, u_int); +static void ps3pic_enable(device_t, u_int, u_int, void **); +static void ps3pic_eoi(device_t, u_int, void *); static void ps3pic_ipi(device_t, u_int); -static void ps3pic_mask(device_t, u_int); -static void ps3pic_unmask(device_t, u_int); +static void ps3pic_mask(device_t, u_int, void *); +static void ps3pic_unmask(device_t, u_int, void *); struct ps3pic_softc { volatile uint64_t *bitmap_thread0; @@ -183,18 +183,18 @@ ps3pic_dispatch(device_t dev, struct trapframe *tf) } static void -ps3pic_enable(device_t dev, u_int irq, u_int vector) +ps3pic_enable(device_t dev, u_int irq, u_int vector, void **priv) { struct ps3pic_softc *sc; sc = device_get_softc(dev); sc->sc_vector[irq] = vector; - ps3pic_unmask(dev, irq); + ps3pic_unmask(dev, irq, priv); } static void -ps3pic_eoi(device_t dev, u_int irq) +ps3pic_eoi(device_t dev, u_int irq, void *priv) { uint64_t ppe; int thread; @@ -215,7 +215,7 @@ ps3pic_ipi(device_t dev, u_int cpu) } static void -ps3pic_mask(device_t dev, u_int irq) +ps3pic_mask(device_t dev, u_int irq, void *priv) { struct ps3pic_softc *sc; uint64_t ppe; @@ -235,7 +235,7 @@ ps3pic_mask(device_t dev, u_int irq) } static void -ps3pic_unmask(device_t dev, u_int irq) +ps3pic_unmask(device_t dev, u_int irq, void *priv) { struct ps3pic_softc *sc; uint64_t ppe; diff --git a/sys/powerpc/pseries/xics.c b/sys/powerpc/pseries/xics.c index 9a760d590652..6c1c551b40ce 100644 --- a/sys/powerpc/pseries/xics.c +++ b/sys/powerpc/pseries/xics.c @@ -69,13 +69,13 @@ static int xicp_attach(device_t); static int xics_probe(device_t); static int xics_attach(device_t); -static void xicp_bind(device_t dev, u_int irq, cpuset_t cpumask); +static void xicp_bind(device_t dev, u_int irq, cpuset_t cpumask, void **priv); static void xicp_dispatch(device_t, struct trapframe *); -static void xicp_enable(device_t, u_int, u_int); -static void xicp_eoi(device_t, u_int); +static void xicp_enable(device_t, u_int, u_int, void **priv); +static void xicp_eoi(device_t, u_int, void *priv); static void xicp_ipi(device_t, u_int); -static void xicp_mask(device_t, u_int); -static void xicp_unmask(device_t, u_int); +static void xicp_mask(device_t, u_int, void *priv); +static void xicp_unmask(device_t, u_int, void *priv); #ifdef POWERNV void xicp_smp_cpu_startup(void); @@ -106,6 +106,12 @@ static device_method_t xics_methods[] = { DEVMETHOD_END }; +struct xicp_intvec { + int irq; + int vector; + int cpu; +}; + struct xicp_softc { struct mtx sc_mtx; struct resource *mem[MAXCPU]; @@ -118,11 +124,7 @@ struct xicp_softc { int ibm_set_xive; /* XXX: inefficient -- hash table? tree? */ - struct { - int irq; - int vector; - int cpu; - } intvecs[256]; + struct xicp_intvec intvecs[256]; int nintvecs; bool xics_emu; }; @@ -297,9 +299,10 @@ xics_attach(device_t dev) */ static void -xicp_bind(device_t dev, u_int irq, cpuset_t cpumask) +xicp_bind(device_t dev, u_int irq, cpuset_t cpumask, void **priv) { struct xicp_softc *sc = device_get_softc(dev); + struct xicp_intvec *iv; cell_t status, cpu; int ncpus, i, error; @@ -307,6 +310,11 @@ xicp_bind(device_t dev, u_int irq, cpuset_t cpumask) if (irq == MAX_XICP_IRQS) return; + if (*priv == NULL) + *priv = &sc->intvecs[sc->nintvecs++]; + + iv = *priv; + /* * This doesn't appear to actually support affinity groups, so pick a * random CPU. @@ -326,15 +334,7 @@ xicp_bind(device_t dev, u_int irq, cpuset_t cpumask) } cpu = pcpu_find(cpu)->pc_hwref; - - /* XXX: super inefficient */ - for (i = 0; i < sc->nintvecs; i++) { - if (sc->intvecs[i].irq == irq) { - sc->intvecs[i].cpu = cpu; - break; - } - } - KASSERT(i < sc->nintvecs, ("Binding non-configured interrupt")); + iv->cpu = cpu; if (rtas_exists()) error = rtas_call_method(sc->ibm_set_xive, 3, 1, irq, cpu, @@ -412,26 +412,30 @@ xicp_dispatch(device_t dev, struct trapframe *tf) } static void -xicp_enable(device_t dev, u_int irq, u_int vector) +xicp_enable(device_t dev, u_int irq, u_int vector, void **priv) { struct xicp_softc *sc; + struct xicp_intvec *intr; cell_t status, cpu; sc = device_get_softc(dev); - KASSERT(sc->nintvecs + 1 < nitems(sc->intvecs), - ("Too many XICP interrupts")); - /* Bind to this CPU to start: distrib. ID is last entry in gserver# */ cpu = PCPU_GET(hwref); - mtx_lock(&sc->sc_mtx); - sc->intvecs[sc->nintvecs].irq = irq; - sc->intvecs[sc->nintvecs].vector = vector; - sc->intvecs[sc->nintvecs].cpu = cpu; + if (*priv == NULL) { + KASSERT(sc->nintvecs + 1 < nitems(sc->intvecs), + ("Too many XICP interrupts")); + mtx_lock(&sc->sc_mtx); + *priv = &sc->intvecs[sc->nintvecs++]; + mtx_unlock(&sc->sc_mtx); + } + intr = *priv; + + intr->irq = irq; + intr->vector = vector; + intr->cpu = cpu; mb(); - sc->nintvecs++; - mtx_unlock(&sc->sc_mtx); /* IPIs are also enabled */ if (irq == MAX_XICP_IRQS) @@ -440,7 +444,7 @@ xicp_enable(device_t dev, u_int irq, u_int vector) if (rtas_exists()) { rtas_call_method(sc->ibm_set_xive, 3, 1, irq, cpu, XICP_PRIORITY, &status); - xicp_unmask(dev, irq); + xicp_unmask(dev, irq, intr); #ifdef POWERNV } else { status = opal_call(OPAL_SET_XIVE, irq, cpu << 2, XICP_PRIORITY); @@ -454,7 +458,7 @@ xicp_enable(device_t dev, u_int irq, u_int vector) } static void -xicp_eoi(device_t dev, u_int irq) +xicp_eoi(device_t dev, u_int irq, void *priv) { #ifdef POWERNV struct xicp_softc *sc; @@ -500,7 +504,7 @@ xicp_ipi(device_t dev, u_int cpu) } static void -xicp_mask(device_t dev, u_int irq) +xicp_mask(device_t dev, u_int irq, void *priv) { struct xicp_softc *sc = device_get_softc(dev); cell_t status; @@ -512,21 +516,16 @@ xicp_mask(device_t dev, u_int irq) rtas_call_method(sc->ibm_int_off, 1, 1, irq, &status); #ifdef POWERNV } else { - int i; + struct xicp_intvec *ivec = priv; - for (i = 0; i < sc->nintvecs; i++) { - if (sc->intvecs[i].irq == irq) { - break; - } - } - KASSERT(i < sc->nintvecs, ("Masking unconfigured interrupt")); - opal_call(OPAL_SET_XIVE, irq, sc->intvecs[i].cpu << 2, 0xff); + KASSERT(ivec != NULL, ("Masking unconfigured interrupt")); + opal_call(OPAL_SET_XIVE, irq, ivec->cpu << 2, 0xff); #endif } } static void -xicp_unmask(device_t dev, u_int irq) +xicp_unmask(device_t dev, u_int irq, void *priv) { struct xicp_softc *sc = device_get_softc(dev); cell_t status; @@ -538,16 +537,10 @@ xicp_unmask(device_t dev, u_int irq) rtas_call_method(sc->ibm_int_on, 1, 1, irq, &status); #ifdef POWERNV } else { - int i; + struct xicp_intvec *ivec = priv; - for (i = 0; i < sc->nintvecs; i++) { - if (sc->intvecs[i].irq == irq) { - break; - } - } - KASSERT(i < sc->nintvecs, ("Unmasking unconfigured interrupt")); - opal_call(OPAL_SET_XIVE, irq, sc->intvecs[i].cpu << 2, - XICP_PRIORITY); + KASSERT(ivec != NULL, ("Unmasking unconfigured interrupt")); + opal_call(OPAL_SET_XIVE, irq, ivec->cpu << 2, XICP_PRIORITY); #endif } }