Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Jan 2019 22:05:42 +0000 (UTC)
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r342975 - in head/sys/powerpc: include powermac powernv powerpc ps3 pseries
Message-ID:  <201901122205.x0CM5gig001242@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhibbits
Date: Sat Jan 12 22:05:42 2019
New Revision: 342975
URL: https://svnweb.freebsd.org/changeset/base/342975

Log:
  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.

Modified:
  head/sys/powerpc/include/openpicvar.h
  head/sys/powerpc/powermac/cpcht.c
  head/sys/powerpc/powermac/hrowpic.c
  head/sys/powerpc/powernv/opal_pci.c
  head/sys/powerpc/powerpc/intr_machdep.c
  head/sys/powerpc/powerpc/openpic.c
  head/sys/powerpc/powerpc/pic_if.m
  head/sys/powerpc/ps3/ps3pic.c
  head/sys/powerpc/pseries/xics.c

Modified: head/sys/powerpc/include/openpicvar.h
==============================================================================
--- head/sys/powerpc/include/openpicvar.h	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/include/openpicvar.h	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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);

Modified: head/sys/powerpc/powermac/cpcht.c
==============================================================================
--- head/sys/powerpc/powermac/cpcht.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powermac/cpcht.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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 int
 }
 
 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 ve
 		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);
 }

Modified: head/sys/powerpc/powermac/hrowpic.c
==============================================================================
--- head/sys/powerpc/powermac/hrowpic.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powermac/hrowpic.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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;
 

Modified: head/sys/powerpc/powernv/opal_pci.c
==============================================================================
--- head/sys/powerpc/powernv/opal_pci.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powernv/opal_pci.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -93,8 +93,8 @@ static int opalpci_route_interrupt(device_t bus, devic
 /*
  * 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,
 }
 
 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

Modified: head/sys/powerpc/powerpc/intr_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/intr_machdep.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powerpc/intr_machdep.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -96,6 +96,7 @@ static MALLOC_DEFINE(M_INTR, "intr", "interrupt handle
 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
 				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 *
 	 * 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 @@ stray:
 		}
 	}
 	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);
 }

Modified: head/sys/powerpc/powerpc/openpic.c
==============================================================================
--- head/sys/powerpc/powerpc/openpic.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powerpc/openpic.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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;

Modified: head/sys/powerpc/powerpc/pic_if.m
==============================================================================
--- head/sys/powerpc/powerpc/pic_if.m	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/powerpc/pic_if.m	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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;
 };
 

Modified: head/sys/powerpc/ps3/ps3pic.c
==============================================================================
--- head/sys/powerpc/ps3/ps3pic.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/ps3/ps3pic.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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;

Modified: head/sys/powerpc/pseries/xics.c
==============================================================================
--- head/sys/powerpc/pseries/xics.c	Sat Jan 12 21:29:54 2019	(r342974)
+++ head/sys/powerpc/pseries/xics.c	Sat Jan 12 22:05:42 2019	(r342975)
@@ -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,16 +334,8 @@ xicp_bind(device_t dev, u_int irq, cpuset_t cpumask)
 	}
 	
 	cpu = pcpu_find(cpu)->pc_hwref;
+	iv->cpu = cpu;
 
-	/* 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"));
-
 	if (rtas_exists())
 		error = rtas_call_method(sc->ibm_set_xive, 3, 1, irq, cpu,
 		    XICP_PRIORITY, &status);
@@ -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
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201901122205.x0CM5gig001242>