svn commit: r205726 - in head/sys/ia64: ia64 include

Marcel Moolenaar marcel at FreeBSD.org
Sat Mar 27 05:40:51 UTC 2010


Author: marcel
Date: Sat Mar 27 05:40:50 2010
New Revision: 205726
URL: http://svn.freebsd.org/changeset/base/205726

Log:
  Implement interrupt to CPU binding. Assign interrupts to CPUs in a
  round-robin fashion, starting with the highest priority interrupt
  on the highest-numbered CPU and cycling downwards.

Modified:
  head/sys/ia64/ia64/autoconf.c
  head/sys/ia64/ia64/interrupt.c
  head/sys/ia64/ia64/mp_machdep.c
  head/sys/ia64/ia64/nexus.c
  head/sys/ia64/ia64/sapic.c
  head/sys/ia64/include/intr.h

Modified: head/sys/ia64/ia64/autoconf.c
==============================================================================
--- head/sys/ia64/ia64/autoconf.c	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/ia64/autoconf.c	Sat Mar 27 05:40:50 2010	(r205726)
@@ -93,7 +93,7 @@ configure_final(void *dummy)
 
 	cninit_finish();
 
-	ia64_finalize_intr();
+	ia64_enable_intr();
 
 	cold = 0;
 }

Modified: head/sys/ia64/ia64/interrupt.c
==============================================================================
--- head/sys/ia64/ia64/interrupt.c	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/ia64/interrupt.c	Sat Mar 27 05:40:50 2010	(r205726)
@@ -122,7 +122,7 @@ ia64_xiv_reserve(u_int xiv, enum ia64_xi
 		return (EBUSY);
 	ia64_xiv[xiv] = what;
 	ia64_handler[xiv] = (ih == NULL) ? ia64_ih_invalid: ih;
-	if (1 || bootverbose)
+	if (bootverbose)
 		printf("XIV %u: use=%u, IH=%p\n", xiv, what, ih);
 	return (0);
 }
@@ -139,7 +139,7 @@ ia64_xiv_alloc(u_int prio, enum ia64_xiv
 
 	xiv0 = IA64_NXIVS - (hwprio + 1) * 16;
 
-	KASSERT(xiv0 > IA64_MIN_XIV, ("%s: min XIV", __func__));
+	KASSERT(xiv0 >= IA64_MIN_XIV, ("%s: min XIV", __func__));
 	KASSERT(xiv0 < IA64_NXIVS, ("%s: max XIV", __func__));
 
 	xiv = xiv0;
@@ -281,10 +281,24 @@ ia64_teardown_intr(void *cookie)
 }
 
 void
-ia64_finalize_intr(void)
+ia64_bind_intr(void)
 {
+	struct ia64_intr *i;
+	struct pcpu *pc;
+	u_int xiv;
+	int cpu;
 
-	ia64_enable_intr();
+	cpu = MAXCPU;
+	for (xiv = IA64_NXIVS - 1; xiv >= IA64_MIN_XIV; xiv--) {
+		if (ia64_xiv[xiv] != IA64_XIV_IRQ)
+			continue;
+		i = ia64_intrs[xiv];
+		do {
+			cpu = (cpu == 0) ? MAXCPU - 1 : cpu - 1;
+			pc = cpuid_to_pcpu[cpu];
+		} while (pc == NULL || !pc->pc_md.awake);
+		sapic_bind_intr(i->irq, pc);
+	}
 }
 
 /*

Modified: head/sys/ia64/ia64/mp_machdep.c
==============================================================================
--- head/sys/ia64/ia64/mp_machdep.c	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/ia64/mp_machdep.c	Sat Mar 27 05:40:50 2010	(r205726)
@@ -382,6 +382,12 @@ cpu_mp_unleash(void *dummy)
 
 	smp_active = 1;
 	smp_started = 1;
+
+	/*
+	 * Now that all CPUs are up and running, bind interrupts to each of
+	 * them.
+	 */
+	ia64_bind_intr();
 }
 
 /*

Modified: head/sys/ia64/ia64/nexus.c
==============================================================================
--- head/sys/ia64/ia64/nexus.c	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/ia64/nexus.c	Sat Mar 27 05:40:50 2010	(r205726)
@@ -50,6 +50,7 @@
 #include <machine/bus.h>
 #include <sys/rman.h>
 #include <sys/interrupt.h>
+#include <sys/pcpu.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
@@ -101,6 +102,7 @@ static	int nexus_set_resource(device_t, 
 static	int nexus_get_resource(device_t, device_t, int, int, u_long *,
 			       u_long *);
 static void nexus_delete_resource(device_t, device_t, int, int);
+static int nexus_bind_intr(device_t, device_t, struct resource *, int);
 static	int nexus_config_intr(device_t, int, enum intr_trigger,
 			      enum intr_polarity);
 
@@ -129,6 +131,7 @@ static device_method_t nexus_methods[] =
 	DEVMETHOD(bus_set_resource,	nexus_set_resource),
 	DEVMETHOD(bus_get_resource,	nexus_get_resource),
 	DEVMETHOD(bus_delete_resource,	nexus_delete_resource),
+	DEVMETHOD(bus_bind_intr,	nexus_bind_intr),
 	DEVMETHOD(bus_config_intr,	nexus_config_intr),
 
 	/* Clock interface */
@@ -462,6 +465,17 @@ nexus_config_intr(device_t dev, int irq,
 }
 
 static int
+nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
+{
+	struct pcpu *pc;
+
+	pc = cpuid_to_pcpu[cpu];
+	if (pc == NULL)
+		return (EINVAL);
+	return (sapic_bind_intr(rman_get_start(irq), pc));
+}
+
+static int
 nexus_gettime(device_t dev, struct timespec *ts)
 {
 	struct clocktime ct;

Modified: head/sys/ia64/ia64/sapic.c
==============================================================================
--- head/sys/ia64/ia64/sapic.c	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/ia64/sapic.c	Sat Mar 27 05:40:50 2010	(r205726)
@@ -35,6 +35,7 @@
 #include <sys/bus.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/pcpu.h>
 #include <sys/sysctl.h>
 
 #include <machine/intr.h>
@@ -172,6 +173,26 @@ sapic_lookup(u_int irq, u_int *vecp)
 
 
 int
+sapic_bind_intr(u_int irq, struct pcpu *pc)
+{
+	struct sapic_rte rte;
+	struct sapic *sa;
+
+	sa = sapic_lookup(irq, NULL);
+	if (sa == NULL)
+		return (EINVAL);
+
+	mtx_lock_spin(&sa->sa_mtx);
+	sapic_read_rte(sa, irq - sa->sa_base, &rte);
+	rte.rte_destination_id = (pc->pc_md.lid >> 24) & 255;
+	rte.rte_destination_eid = (pc->pc_md.lid >> 16) & 255;
+	rte.rte_delivery_mode = SAPIC_DELMODE_FIXED;
+	sapic_write_rte(sa, irq - sa->sa_base, &rte);
+	mtx_unlock_spin(&sa->sa_mtx);
+	return (0);
+}
+
+int
 sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol)
 {
 	struct sapic_rte rte;

Modified: head/sys/ia64/include/intr.h
==============================================================================
--- head/sys/ia64/include/intr.h	Sat Mar 27 04:39:59 2010	(r205725)
+++ head/sys/ia64/include/intr.h	Sat Mar 27 05:40:50 2010	(r205726)
@@ -35,6 +35,7 @@
 
 #define	IA64_MAX_HWPRIO		14
 
+struct pcpu;
 struct sapic;
 struct thread;
 struct trapframe;
@@ -65,7 +66,7 @@ typedef u_int (ia64_ihtype)(struct threa
 
 extern struct ia64_pib *ia64_pib;
 
-void	ia64_finalize_intr(void);
+void	ia64_bind_intr(void);
 void	ia64_handle_intr(struct trapframe *);
 int	ia64_setup_intr(const char *, int, driver_filter_t, driver_intr_t,
 	    void *, enum intr_type, void **);
@@ -76,6 +77,7 @@ u_int	ia64_xiv_alloc(u_int, enum ia64_xi
 int	ia64_xiv_free(u_int, enum ia64_xiv_use);
 int	ia64_xiv_reserve(u_int, enum ia64_xiv_use, ia64_ihtype);
 
+int	sapic_bind_intr(u_int, struct pcpu *);
 int	sapic_config_intr(u_int, enum intr_trigger, enum intr_polarity);
 struct sapic *sapic_create(u_int, u_int, uint64_t);
 int	sapic_enable(struct sapic *, u_int, u_int);


More information about the svn-src-head mailing list