powerpc: Add opaque 'private data' to interrupt vectors
The XICS and XIVE need extra data beyond irq and vector. Rather than performing a separate search, it's better for the general interrupt facility to hold a private pointer, since the search already must be done anyway at that level.
This commit is contained in:
parent
5d031e332f
commit
56505ec016
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=342975
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user