Subject: ibm4xx interrupts
To: None <port-powerpc@netbsd.org>
From: Jachym Holecek <freza@dspfpga.com>
List: port-powerpc
Date: 06/27/2006 01:55:23
Hello,

the diff below converts ibm4xx to:

  * generic soft interrupts
  * evcnt interrupt counters (cpu_info evcnts used where applicable)
  * more flexible interrupt code layout, so that slighly different
    intr controllers, like Xilinx XINTC, may be supported easily

Included are changes needed to compile all affected evbppc kernels.
The change was successfully tested on a Walnut (thanks simonb@).

Unless there are objections/problems, I'd like to commit in a few days.
It would also be good to hear how this works on !Walnut boards.

Thanks,
	-- Jachym

Index: arch/powerpc/ibm4xx/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/clock.c,v
retrieving revision 1.16
diff -d -p -u -r1.16 clock.c
--- arch/powerpc/ibm4xx/clock.c	5 May 2006 18:04:42 -0000	1.16
+++ arch/powerpc/ibm4xx/clock.c	26 Jun 2006 23:39:00 -0000
@@ -72,10 +72,8 @@ void stat_intr(struct clockframe *);	/* 
 void
 stat_intr(struct clockframe *frame)
 {
-	extern u_long intrcnt[];
-
 	mtspr(SPR_TSR, TSR_FIS);	/* Clear TSR[FIS] */
-	intrcnt[CNT_STATCLOCK]++;
+	curcpu()->ci_ev_statclock.ev_count++;
   	statclock(frame);
 }
 
@@ -85,7 +83,7 @@ decr_intr(struct clockframe *frame)
 	int pri;
 	long tbtick, xticks;
 	int nticks;
-	extern u_long intrcnt[];
+
 	/*
 	 * Check whether we are initialized.
 	 */
@@ -100,11 +98,11 @@ decr_intr(struct clockframe *frame)
 		xticks -= ticks_per_intr;
 	lasttb2 = tbtick - xticks;
 
-	intrcnt[CNT_CLOCK]++;
+	curcpu()->ci_ev_clock.ev_count++;
 	pri = splclock();
-	if (pri & SPL_CLOCK) {
+	if (pri & mask_clock) {
 		tickspending += nticks;
-		ticksmissed+= nticks;
+		ticksmissed += nticks;
 	} else {
 		nticks += tickspending;
 		tickspending = 0;
@@ -124,7 +122,7 @@ decr_intr(struct clockframe *frame)
 		 * Do standard timer interrupt stuff.
 		 * Do softclock stuff only on the last iteration.
 		 */
-		frame->pri = pri | SINT_CLOCK;
+		frame->pri = pri | mask_clock;
 		while (--nticks > 0)
 			hardclock(frame);
 		frame->pri = pri;
@@ -136,12 +134,19 @@ decr_intr(struct clockframe *frame)
 void
 cpu_initclocks(void)
 {
+	/* Initialized in powerpc/ibm4xx/cpu.c */
+	evcnt_attach_static(&curcpu()->ci_ev_clock);
+	evcnt_attach_static(&curcpu()->ci_ev_statclock);
 
 	ticks_per_intr = ticks_per_sec / hz;
 	stathz = profhz = ticks_per_sec / (1 << PERIOD_POWER);
-	printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz, ticks_per_intr);
+
+	printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz,
+	    ticks_per_intr);
+
 	lasttb2 = lasttb = mftbl();
 	mtspr(SPR_PIT, ticks_per_intr);
+
 	/* Enable PIT & FIT(2^17c = 0.655ms) interrupts and auto-reload */
 	mtspr(SPR_TCR, TCR_PIE | TCR_ARE | TCR_FIE | TCR_PERIOD);
 }
Index: arch/powerpc/ibm4xx/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/cpu.c,v
retrieving revision 1.23
diff -d -p -u -r1.23 cpu.c
--- arch/powerpc/ibm4xx/cpu.c	5 May 2006 18:04:42 -0000	1.23
+++ arch/powerpc/ibm4xx/cpu.c	26 Jun 2006 23:39:00 -0000
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.23
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
+#include <sys/evcnt.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -75,7 +76,21 @@ CFATTACH_DECL(cpu, sizeof(struct device)
 
 int ncpus;
 
-struct cpu_info cpu_info[1];
+struct cpu_info cpu_info[1] = {
+	{
+		/* XXX add more ci_ev_* as we teach 4xx about them */
+		.ci_ev_clock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+		    NULL, "cpu0", "clock"),
+		.ci_ev_statclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+		    NULL, "cpu0", "stat clock"),
+		.ci_ev_softclock = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+		    NULL, "cpu0", "soft clock"),
+		.ci_ev_softnet = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+		    NULL, "cpu0", "soft net"),
+		.ci_ev_softserial = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,
+		    NULL, "cpu0", "soft serial"),
+	}
+};
 
 char cpu_model[80];
 
Index: arch/powerpc/ibm4xx/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/intr.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 intr.c
--- arch/powerpc/ibm4xx/intr.c	13 Jun 2006 18:24:37 -0000	1.11
+++ arch/powerpc/ibm4xx/intr.c	26 Jun 2006 23:39:01 -0000
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.c,v 1.11 2006/06/13 18:24:37 freza Exp $	*/
+/*	$NetBSD: intr.c,v 1.10 2005/12/24 22:45:36 perry Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -36,20 +36,49 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.11 2006/06/13 18:24:37 freza Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.10 2005/12/24 22:45:36 perry Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
+#include <sys/evcnt.h>
 
 #include <uvm/uvm_extern.h>
 
-#include <machine/cpu.h>
 #include <machine/intr.h>
 #include <machine/psl.h>
 
+#include <powerpc/cpu.h>
 #include <powerpc/spr.h>
+#include <powerpc/softintr.h>
 
+
+/*
+ * Number of interrupts (hard + soft), irq number legality test,
+ * mapping of irq number to mask and a way to pick irq number
+ * off a mask of active intrs.
+ */
+#define	ICU_LEN			32
+#define	LEGAL_IRQ(x)		((x) >= 0 && (x) < ICU_LEN)
+
+#define	IRQ_TO_MASK(irq) 	(0x80000000UL >> (irq))
+#define IRQ_OF_MASK(mask) 	cntlzw(mask)
+
+/*
+ * Assign these to unused (reserved) interrupt bits.
+ *
+ * For 405GP (and 403CGX?) interrupt bits 0-18 and 25-31 are used
+ * by hardware.  This leaves us bits 19-24 for software.
+ */
+#define	IRQ_SOFTNET	19
+#define	IRQ_SOFTCLOCK	20
+#define	IRQ_SOFTSERIAL	21
+#define	IRQ_CLOCK       22
+#define	IRQ_STATCLOCK	23
+
+/*
+ * Platform specific code may override any of the above.
+ */
 #ifdef PPC_IBM403
 #include <powerpc/ibm4xx/dcr403cgx.h>
 #define INTR_STATUS	DCR_EXISR
@@ -62,27 +91,75 @@ __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.1
 #define INTR_ENABLE	DCR_UIC0_ER
 #endif
 
+#define	MASK_SOFTNET	IRQ_TO_MASK(IRQ_SOFTNET)
+#define	MASK_SOFTCLOCK	IRQ_TO_MASK(IRQ_SOFTCLOCK)
+#define	MASK_SOFTSERIAL	IRQ_TO_MASK(IRQ_SOFTSERIAL)
+#define	MASK_CLOCK	(IRQ_TO_MASK(IRQ_CLOCK) | IRQ_TO_MASK(IRQ_STATCLOCK))
+#define	MASK_SOFTINTR	(MASK_SOFTCLOCK|MASK_SOFTNET|MASK_SOFTSERIAL)
+#define MASK_HARDINTR 	~(MASK_SOFTINTR|MASK_CLOCK)
+
 static inline void disable_irq(int irq);
 static inline void enable_irq(int irq);
 static void intr_calculatemasks(void);
+static void do_pending_int(void);
 static const char *intr_typename(int);
 
-static int fakeintr(void *);
 
+/*
+ * Interrupt handler chains.  intr_establish() inserts a handler into
+ * the list.  The handler is called with its (single) argument.
+ */
+struct intrhand {
+	int			(*ih_fun)(void *);
+	void			*ih_arg;
+	struct	intrhand 	*ih_next;
+	int 			ih_level;
+};
 
-volatile int cpl, ipending;
-u_long imask[NIPL];
+struct intrsrc {
+	struct evcnt 		is_evcnt;
+	struct intrhand 	*is_head;
+	u_int 			is_mask;
+	int			is_level; 	/* spls bitmask */
+	int 			is_type; 	/* sensitivity */
+};
 
-static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
-static struct intrhand *intrhand[ICU_LEN];
 
+volatile u_int 			imask[NIPL];
+const int 			mask_clock = MASK_CLOCK;
 
-static int
-fakeintr(void *arg)
-{
+static struct intrsrc 		intrs[ICU_LEN] = {
+#define DEFINTR(name) 		\
+	{ EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "uic", name), NULL, 0, 0 }
 
-	return 0;
-}
+	DEFINTR("pin0"), 	DEFINTR("pin1"), 	DEFINTR("pin2"),
+	DEFINTR("pin3"), 	DEFINTR("pin4"), 	DEFINTR("pin5"),
+	DEFINTR("pin6"), 	DEFINTR("pin7"), 	DEFINTR("pin8"),
+	DEFINTR("pin9"), 	DEFINTR("pin10"), 	DEFINTR("pin11"),
+	DEFINTR("pin12"), 	DEFINTR("pin13"), 	DEFINTR("pin14"),
+	DEFINTR("pin15"), 	DEFINTR("pin16"), 	DEFINTR("pin17"),
+	DEFINTR("pin18"),
+
+	/* Reserved intrs, accounted in cpu_info */
+	DEFINTR(NULL), 		/* unused "pin19", softnet */
+	DEFINTR(NULL), 		/* unused "pin20", softclock */
+	DEFINTR(NULL), 		/* unused "pin21", softserial */
+	DEFINTR(NULL), 		/* unused "pin22", PIT hardclock */
+	DEFINTR(NULL), 		/* unused "pin23", FIT statclock */
+
+	DEFINTR("pin24"), 	DEFINTR("pin25"), 	DEFINTR("pin26"),
+	DEFINTR("pin27"), 	DEFINTR("pin28"), 	DEFINTR("pin29"),
+	DEFINTR("pin30"), 	DEFINTR("pin31")
+
+#undef DEFINTR
+};
+
+
+/* Write External Enable Immediate */
+#define wrteei(en) 		__asm volatile ("wrteei %0" : : "K"(en))
+
+/* Enforce In Order Execution Of I/O */
+#define eieio() 		__asm volatile ("eieio")
 
 /*
  * Set up interrupt mapping array.
@@ -90,7 +167,33 @@ fakeintr(void *arg)
 void
 intr_init(void)
 {
+	struct cpu_info 	*ci = curcpu();
+	int 			i;
 
+	for (i = 0; i < ICU_LEN; i++)
+		switch (i) {
+		case IRQ_SOFTNET:
+		case IRQ_SOFTCLOCK:
+		case IRQ_SOFTSERIAL:
+		case IRQ_CLOCK:
+		case IRQ_STATCLOCK:
+			continue;
+		default:
+			evcnt_attach_static(&intrs[i].is_evcnt);
+		}
+
+	/* Initialized in powerpc/ibm4xx/cpu.c */
+	evcnt_attach_static(&ci->ci_ev_softclock);
+	evcnt_attach_static(&ci->ci_ev_softnet);
+	evcnt_attach_static(&ci->ci_ev_softserial);
+
+	softintr__init();
+
+	mtdcr(INTR_ENABLE, 0x00000000); 	/* mask all */
+	mtdcr(INTR_ACK, 0xffffffff); 		/* acknowledge all */
+#ifdef INTR_MASTER
+	mtdcr(INTR_MASTER, 0xffffffff); 	/* enable controller */
+#endif
 }
 
 /*
@@ -99,48 +202,52 @@ intr_init(void)
 void
 ext_intr(void)
 {
-	int i, bits_to_clear;
-	int r_imen, msr;
-	int pcpl;
-	struct intrhand *ih;
-	u_long int_state;
+	struct cpu_info 	*ci = curcpu();
+	struct intrhand 	*ih;
+	int 			i, bits_to_clear;
+	int 			r_imen, msr;
+	int 			pcpl;
+	u_long 			int_state;
 
-	pcpl = cpl;
-	__asm volatile ("mfmsr %0" : "=r"(msr));
+	pcpl = ci->ci_cpl;
+	msr = mfmsr();
 
 	int_state = mfdcr(INTR_STATUS);	/* Read non-masked interrupt status */
 	bits_to_clear = int_state;
 
 	while (int_state) {
-		i = cntlzw(int_state);
-		int_state &= ~IRQ_TO_MASK(i);
+		i = IRQ_OF_MASK(int_state);
 
 		r_imen = IRQ_TO_MASK(i);
+		int_state &= ~r_imen;
 
 		if ((pcpl & r_imen) != 0) {
-			ipending |= r_imen;	/* Masked! Mark this as pending */
+			/* Masked! Mark as pending */
+			ci->ci_ipending |= r_imen;
 			disable_irq(i);
  		} else {
-			splraise(intrmask[i]);
-			__asm volatile ("mtmsr %0" :: "r"(msr | PSL_EE));
+			splraise(intrs[i].is_mask);
+			wrteei(1);
+
 			KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-			ih = intrhand[i];
+			ih = intrs[i].is_head;
 			while (ih) {
 				(*ih->ih_fun)(ih->ih_arg);
 				ih = ih->ih_next;
 			}
 			KERNEL_UNLOCK();
-			__asm volatile ("mtmsr %0" :: "r"(msr));
-			cpl = pcpl;
+
+			mtmsr(msr);
+			ci->ci_cpl = pcpl;
 			uvmexp.intrs++;
-			intrcnt[i]++;
+			intrs[i].is_evcnt.ev_count++;
 		}
 	}
 	mtdcr(INTR_ACK, bits_to_clear);	/* Acknowledge all pending interrupts */
 
-	__asm volatile ("mtmsr %0" :: "r"(msr | PSL_EE));
+	wrteei(1);
 	splx(pcpl);
-	__asm volatile ("mtmsr %0" :: "r"(msr));
+	mtmsr(msr);
 }
 
 static inline void
@@ -195,60 +302,61 @@ intr_typename(int type)
  * Register an interrupt handler.
  */
 void *
-intr_establish(int irq, int type, int level, int (*ih_fun)(void *), void *ih_arg)
+intr_establish(int irq, int type, int level, int (*ih_fun)(void *),
+    void *ih_arg)
 {
-	struct intrhand **p, *q, *ih;
-	static struct intrhand fakehand = { fakeintr };
+	struct intrhand 	*ih;
+	int 			s;
 
-	/* no point in sleeping unless someone can free memory. */
+	if (! LEGAL_IRQ(irq))
+		panic("intr_establish: bogus irq %d", irq);
+
+	if (type == IST_NONE)
+		panic("intr_establish: bogus type %d for irq %d", type, irq);
+
+	/* No point in sleeping unless someone can free memory. */
 	ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
 	if (ih == NULL)
 		panic("intr_establish: can't malloc handler info");
 
-	if (!LEGAL_IRQ(irq) || type == IST_NONE)
-		panic("intr_establish: bogus irq or type");
+	switch (intrs[irq].is_type) {
+	case IST_NONE:
+		intrs[irq].is_type = type;
+		break;
 
-	switch (intrtype[irq]) {
 	case IST_EDGE:
 	case IST_LEVEL:
-		if (type == intrtype[irq])
+		if (type == intrs[irq].is_type)
 			break;
+		/* FALLTHROUGH */
+
 	case IST_PULSE:
 		if (type != IST_NONE)
 			panic("intr_establish: can't share %s with %s",
-			    intr_typename(intrtype[irq]),
+			    intr_typename(intrs[irq].is_type),
 			    intr_typename(type));
 		break;
 	}
 
 	/*
-	 * Figure out where to put the handler.
-	 * This is O(N^2), but we want to preserve the order, and N is
-	 * generally small.
-	 */
-	for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
-		;
-
-	/*
-	 * Actually install a fake handler momentarily, since we might be doing
-	 * this with interrupts enabled and don't want the real routine called
-	 * until masking is set up.
+	 * We're not on critical paths, so just block intrs for a while.
 	 */
-	fakehand.ih_level = level;
-	*p = &fakehand;
-
+	s = splhigh();
 	intr_calculatemasks();
 
 	/*
-	 * Poke the real handler in now.
+	 * Poke the real handler in now. We deliberately don't preserve order,
+	 * the user is not allowed to make any assumptions about it anyway.
 	 */
 	ih->ih_fun = ih_fun;
 	ih->ih_arg = ih_arg;
-	ih->ih_count = 0;
-	ih->ih_next = NULL;
 	ih->ih_level = level;
-	ih->ih_irq = irq;
-	*p = ih;
+	ih->ih_next = intrs[irq].is_head;
+	intrs[irq].is_head = ih;
+
+	eieio();
+	splx(s);
+
 #ifdef IRQ_DEBUG
 	printf("***** intr_establish: irq%d h=%p arg=%p\n",irq, ih_fun, ih_arg);
 #endif
@@ -261,29 +369,28 @@ intr_establish(int irq, int type, int le
 void
 intr_disestablish(void *arg)
 {
-	struct intrhand *ih = arg;
-	int irq = ih->ih_irq;
-	struct intrhand **p, *q;
-
-	if (!LEGAL_IRQ(irq))
-		panic("intr_disestablish: bogus irq");
+	struct intrhand 	*ih = arg;
+	struct intrhand 	**p;
+	int 			i, s;
 
-	/*
-	 * Remove the handler from the chain.
-	 * This is O(n^2), too.
-	 */
-	for (p = &intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
-		;
-	if (q)
-		*p = q->ih_next;
-	else
+	/* Lookup the handler. This is expensive, but not run often. */
+	for (i = 0; i < ICU_LEN; i++)
+		for (p = &intrs[i].is_head; *p != NULL; p = &(*p)->ih_next)
+			if (*p == ih)
+				goto out;
+ out:
+	if (i == ICU_LEN)
 		panic("intr_disestablish: handler not registered");
-	free((void *)ih, M_DEVBUF);
 
+	*p = ih->ih_next;
+	free(ih, M_DEVBUF);
+
+	s = splhigh();
 	intr_calculatemasks();
+	splx(s);
 
-	if (intrhand[irq] == NULL)
-		intrtype[irq] = IST_NONE;
+	if (intrs[i].is_head == NULL)
+		intrs[i].is_type = IST_NONE;
 }
 
 /*
@@ -301,32 +408,32 @@ intr_calculatemasks(void)
 	/* First, figure out which levels each IRQ uses. */
 	for (irq = 0; irq < ICU_LEN; irq++) {
 		register int levels = 0;
-		for (q = intrhand[irq]; q; q = q->ih_next)
+		for (q = intrs[irq].is_head; q; q = q->ih_next)
 			levels |= 1 << q->ih_level;
-		intrlevel[irq] = levels;
+		intrs[irq].is_level = levels;
 	}
 
 	/* Then figure out which IRQs use each level. */
 	for (level = 0; level < NIPL; level++) {
 		register int irqs = 0;
 		for (irq = 0; irq < ICU_LEN; irq++)
-			if (intrlevel[irq] & (1 << level))
+			if (intrs[irq].is_level & (1 << level))
 				irqs |= IRQ_TO_MASK(irq);
-		imask[level] = irqs | SINT_MASK;
+		imask[level] = irqs | MASK_SOFTINTR;
 	}
 
 	/*
 	 * IPL_CLOCK should mask clock interrupt even if interrupt handler
 	 * is not registered.
 	 */
-	imask[IPL_CLOCK] |= SPL_CLOCK;
+	imask[IPL_CLOCK] |= MASK_CLOCK;
 
 	/*
 	 * Initialize the soft interrupt masks to block themselves.
 	 */
-	imask[IPL_SOFTCLOCK] = SINT_CLOCK;
-	imask[IPL_SOFTNET] = SINT_NET;
-	imask[IPL_SOFTSERIAL] = SINT_SERIAL;
+	imask[IPL_SOFTCLOCK] = MASK_SOFTCLOCK;
+	imask[IPL_SOFTNET] = MASK_SOFTNET;
+	imask[IPL_SOFTSERIAL] = MASK_SOFTSERIAL;
 
 	/*
 	 * IPL_NONE is used for hardware interrupts that are never blocked,
@@ -373,95 +480,170 @@ intr_calculatemasks(void)
 	/* And eventually calculate the complete masks. */
 	for (irq = 0; irq < ICU_LEN; irq++) {
 		register int irqs = IRQ_TO_MASK(irq);
-		for (q = intrhand[irq]; q; q = q->ih_next)
+		for (q = intrs[irq].is_head; q; q = q->ih_next)
 			irqs |= imask[q->ih_level];
-		intrmask[irq] = irqs;
+		intrs[irq].is_mask = irqs;
 	}
 
 	for (irq = 0; irq < ICU_LEN; irq++)
-		if (intrhand[irq])
+		if (intrs[irq].is_head != NULL)
 			enable_irq(irq);
 		else
 			disable_irq(irq);
 }
 
-void
+static void
 do_pending_int(void)
 {
-	struct intrhand *ih;
-	int irq;
-	int pcpl;
-	int hwpend;
-	int emsr, dmsr;
-	static int processing;
+	struct cpu_info 	*ci = curcpu();
+	struct intrhand 	*ih;
+	int 			irq;
+	int 			pcpl;
+	int 			hwpend;
+	int 			emsr;
 
-	if (processing)
+	if (ci->ci_iactive)
 		return;
 
-	processing = 1;
-	__asm volatile("mfmsr %0" : "=r"(emsr));
-	dmsr = emsr & ~PSL_EE;
-	__asm volatile("mtmsr %0" :: "r"(dmsr));
+	ci->ci_iactive = 1;
+	emsr = mfmsr();
+	wrteei(0);
 
-	pcpl = cpl;		/* Turn off all */
+	pcpl = ci->ci_cpl;	/* Turn off all */
   again:
-	while ((hwpend = ipending & ~pcpl & HWINT_MASK)) {
-		irq = cntlzw(hwpend);
+	while ((hwpend = ci->ci_ipending & ~pcpl & MASK_HARDINTR) != 0) {
+		irq = IRQ_OF_MASK(hwpend);
 		enable_irq(irq);
 
-		ipending &= ~IRQ_TO_MASK(irq);
+		ci->ci_ipending &= ~IRQ_TO_MASK(irq);
+
+		splraise(intrs[irq].is_mask);
+		mtmsr(emsr);
 
-		splraise(intrmask[irq]);
-		__asm volatile("mtmsr %0" :: "r"(emsr));
 		KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-		ih = intrhand[irq];
+		ih = intrs[irq].is_head;
 		while(ih) {
 			(*ih->ih_fun)(ih->ih_arg);
 			ih = ih->ih_next;
 		}
 		KERNEL_UNLOCK();
-		__asm volatile("mtmsr %0" :: "r"(dmsr));
-		cpl = pcpl;
-		intrcnt[irq]++;
+
+		wrteei(0);
+		ci->ci_cpl = pcpl;
+		intrs[irq].is_evcnt.ev_count++;
 	}
 
-	if ((ipending & ~pcpl) & SINT_SERIAL) {
-		ipending &= ~SINT_SERIAL;
+	if ((ci->ci_ipending & ~pcpl) & MASK_SOFTSERIAL) {
+		ci->ci_ipending &= ~MASK_SOFTSERIAL;
 		splsoftserial();
-		__asm volatile("mtmsr %0" :: "r"(emsr));
+		mtmsr(emsr);
+
 		KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-		softserial();
+		softintr__run(IPL_SOFTSERIAL);
 		KERNEL_UNLOCK();
-		__asm volatile("mtmsr %0" :: "r"(dmsr));
-		cpl = pcpl;
-		intrcnt[CNT_SINT_SERIAL]++;
+
+		wrteei(0);
+		ci->ci_cpl = pcpl;
+		ci->ci_ev_softserial.ev_count++;
 		goto again;
 	}
-	if ((ipending & ~pcpl) & SINT_NET) {
-		ipending &= ~SINT_NET;
+	if ((ci->ci_ipending & ~pcpl) & MASK_SOFTNET) {
+		ci->ci_ipending &= ~MASK_SOFTNET;
 		splsoftnet();
-		__asm volatile("mtmsr %0" :: "r"(emsr));
+		mtmsr(emsr);
+
 		KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-		softnet();
+		softintr__run(IPL_SOFTNET);
 		KERNEL_UNLOCK();
-		__asm volatile("mtmsr %0" :: "r"(dmsr));
-		cpl = pcpl;
-		intrcnt[CNT_SINT_NET]++;
+
+		wrteei(0);
+		ci->ci_cpl = pcpl;
+		ci->ci_ev_softnet.ev_count++;
 		goto again;
 	}
-	if ((ipending & ~pcpl) & SINT_CLOCK) {
-		ipending &= ~SINT_CLOCK;
+	if ((ci->ci_ipending & ~pcpl) & MASK_SOFTCLOCK) {
+		ci->ci_ipending &= ~MASK_SOFTCLOCK;
 		splsoftclock();
-		__asm volatile("mtmsr %0" :: "r"(emsr));
+		mtmsr(emsr);
+
 		KERNEL_LOCK(LK_CANRECURSE|LK_EXCLUSIVE);
-		softclock(NULL);
+		softintr__run(IPL_SOFTCLOCK);
 		KERNEL_UNLOCK();
-		__asm volatile("mtmsr %0" :: "r"(dmsr));
-		cpl = pcpl;
-		intrcnt[CNT_SINT_CLOCK]++;
+
+		wrteei(0);
+		ci->ci_cpl = pcpl;
+		ci->ci_ev_softclock.ev_count++;
 		goto again;
 	}
-	cpl = pcpl;	/* Don't use splx... we are here already! */
-	__asm volatile("mtmsr %0" :: "r"(emsr));
-	processing = 0;
+	ci->ci_cpl = pcpl; /* Don't use splx... we are here already! */
+	mtmsr(emsr);
+	ci->ci_iactive = 0;
+}
+
+void
+softintr(int idx)
+{
+	static const int 	softmap[3] = {
+		MASK_SOFTCLOCK, MASK_SOFTNET, MASK_SOFTSERIAL
+	};
+	struct cpu_info 	*ci = curcpu();
+	int 			oldmsr;
+
+	/*
+	 * This could be implemented with lwarx/stwcx to avoid the
+	 * disable/enable... Note softintr() is only ever called
+	 * with constant 0, 1, 2 as argument, no need to check.
+	 */
+
+	oldmsr = mfmsr();
+	wrteei(0);
+
+	ci->ci_ipending |= softmap[idx];
+
+	mtmsr(oldmsr);
+}
+
+int
+splraise(int newcpl)
+{
+	struct cpu_info 	*ci = curcpu();
+	int 			oldcpl, oldmsr;
+
+	/*
+	 * We're about to block some intrs, so make sure they don't
+	 * fire while we're busy.
+	 */
+
+	oldmsr = mfmsr();
+	wrteei(0);
+
+	oldcpl = ci->ci_cpl;
+	ci->ci_cpl |= newcpl;
+
+	mtmsr(oldmsr);
+	return (oldcpl);
+}
+
+void
+splx(int newcpl)
+{
+	struct cpu_info 	*ci = curcpu();
+
+	ci->ci_cpl = newcpl;
+	if (ci->ci_ipending & ~newcpl)
+		do_pending_int();
+}
+
+int
+spllower(int newcpl)
+{
+	struct cpu_info 	*ci = curcpu();
+	int 			oldcpl;
+
+	oldcpl = ci->ci_cpl;
+	ci->ci_cpl = newcpl;
+	if (ci->ci_ipending & ~newcpl)
+		do_pending_int();
+
+	return (oldcpl);
 }
Index: arch/powerpc/ibm4xx/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/pci/pci_machdep.c,v
retrieving revision 1.4
diff -d -p -u -r1.4 pci_machdep.c
--- arch/powerpc/ibm4xx/pci/pci_machdep.c	29 Mar 2006 17:50:33 -0000	1.4
+++ arch/powerpc/ibm4xx/pci/pci_machdep.c	26 Jun 2006 23:39:02 -0000
@@ -165,8 +165,8 @@ pci_intr_string(pci_chipset_tag_t pc, pc
 {
 	static char irqstr[8];		/* 4 + 2 + NUL + sanity */
 
-	if (ih == 0 || ih >= ICU_LEN)
-		panic("pci_intr_string: bogus handle 0x%x", ih);
+	if (ih < 0 || ih > 99)
+		panic("pci_intr_string: handle %#x won't fit two digits", ih);
 
 	sprintf(irqstr, "irq %d", ih);
 	return (irqstr);
@@ -185,10 +185,6 @@ void *
 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
 		   int (*func)(void *), void *arg)
 {
-
-	if (ih == 0 || ih >= ICU_LEN)
-		panic("pci_intr_establish: bogus handle 0x%x", ih);
-
 	return intr_establish(ih, IST_LEVEL, level, func, arg);
 }
 
Index: arch/powerpc/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/cpu.h,v
retrieving revision 1.49
diff -d -p -u -r1.49 cpu.h
--- arch/powerpc/include/cpu.h	13 Jun 2006 18:24:37 -0000	1.49
+++ arch/powerpc/include/cpu.h	26 Jun 2006 23:39:03 -0000
@@ -72,9 +72,9 @@ struct cpu_info {
 	int ci_want_resched;
 	volatile u_long ci_lasttb;
 	volatile int ci_tickspending;
-	int ci_cpl;
-	int ci_iactive;
-	int ci_ipending;
+	volatile int ci_cpl;
+	volatile int ci_iactive;
+	volatile int ci_ipending;
 	int ci_intrdepth;
 	char *ci_intstk;
 #define	CPUSAVE_LEN	8
@@ -96,6 +96,7 @@ struct cpu_info {
 	void (*ci_idlespin)(void);
 	uint32_t ci_khz;
 	struct evcnt ci_ev_clock;	/* clock intrs */
+	struct evcnt ci_ev_statclock; 	/* stat clock */
 	struct evcnt ci_ev_softclock;	/* softclock intrs */
 	struct evcnt ci_ev_softnet;	/* softnet intrs */
 	struct evcnt ci_ev_softserial;	/* softserial intrs */
Index: arch/powerpc/include/ibm4xx/ibm4xx_intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/include/ibm4xx/ibm4xx_intr.h,v
retrieving revision 1.11
diff -d -p -u -r1.11 ibm4xx_intr.h
--- arch/powerpc/include/ibm4xx/ibm4xx_intr.h	31 Dec 2005 14:07:32 -0000	1.11
+++ arch/powerpc/include/ibm4xx/ibm4xx_intr.h	26 Jun 2006 23:39:03 -0000
@@ -36,8 +36,10 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _EVBPPC_INTR_H_
-#define _EVBPPC_INTR_H_
+#ifndef _IBM4XX_INTR_H_
+#define _IBM4XX_INTR_H_
+
+#include <powerpc/softintr.h>
 
 /* Interrupt priority `levels'. */
 #define	IPL_NONE	9	/* nothing */
@@ -67,134 +69,29 @@
 #ifndef _LOCORE
 
 #define	CLKF_BASEPRI(frame)	((frame)->pri == 0)
-/*
- * Interrupt handler chains.  intr_establish() inserts a handler into
- * the list.  The handler is called with its (single) argument.
- */
-struct intrhand {
-	int	(*ih_fun)(void *);
-	void	*ih_arg;
-	u_long	ih_count;
-	struct	intrhand *ih_next;
-	int	ih_level;
-	int	ih_irq;
-};
 
-void setsoftclock(void);
-void setsoftnet(void);
-
-void do_pending_int(void);
-void ext_intr(void);
-void *intr_establish(int, int, int, int (*)(void *), void *);
-void intr_disestablish(void *);
-void intr_init(void);
-
-static inline int splraise(int);
-static inline int spllower(int);
-static inline void splx(int);
-static inline void set_sint(int);
-
-extern volatile int cpl, ipending, astpending;
-extern u_long imask[];
-extern u_long intrcnt[];
-
-/*
- * Reorder protection in the following inline functions is
- * achived with the "eieio" instruction which the assembler
- * seems to detect and then doesn't move instructions past....
- */
-static inline int
-splraise(newcpl)
-	int newcpl;
-{
-	int oldcpl;
-
-	__asm volatile("sync; eieio\n");	/* don't reorder.... */
-	oldcpl = cpl;
-	cpl = oldcpl | newcpl;
-	__asm volatile("sync; eieio\n");	/* reorder protect */
-	return(oldcpl);
-}
-
-static inline void
-splx(newcpl)
-	int newcpl;
-{
-	__asm volatile("sync; eieio\n");	/* reorder protect */
-	cpl = newcpl;
-	if (ipending & ~newcpl)
-		do_pending_int();
-	__asm volatile("sync; eieio\n");	/* reorder protect */
-}
-
-static inline int
-spllower(newcpl)
-	int newcpl;
-{
-	int oldcpl;
-
-	__asm volatile("sync; eieio\n");	/* reorder protect */
-	oldcpl = cpl;
-	cpl = newcpl;
-	if (ipending & ~newcpl)
-		do_pending_int();
-	__asm volatile("sync; eieio\n");	/* reorder protect */
-	return(oldcpl);
-}
-
-/* Following code should be implemented with lwarx/stwcx to avoid
- * the disable/enable. i need to read the manual once more.... */
-static inline void
-set_sint(pending)
-	int	pending;
-{
-	int	msrsave;
-
-	__asm ("mfmsr %0" : "=r"(msrsave));
-	__asm volatile ("mtmsr %0" :: "r"(msrsave & ~PSL_EE));
-	ipending |= pending;
-	__asm volatile ("mtmsr %0" :: "r"(msrsave));
-}
-
-#define	ICU_LEN		32
-#define	LEGAL_IRQ(x)	((x) >= 0 && (x) < ICU_LEN)
-#define	IRQ_TO_MASK(x)	(0x80000000UL >> (x))
-
-/*
- * XXX 405GP specific.
- * Interrupt bits 0-18 and 25-31 are used by hardware.  This 
- * leaves us bits 19-24 for software.
- */
-#define	HWINT_MASK	~0x1fc0
-
-/* Assign these to unused (reserved) interrupt bits: */
-#define	CNT_SINT_NET	19
-#define	CNT_SINT_CLOCK	20
-#define	CNT_SINT_SERIAL	21
-#define	CNT_CLOCK       22
-#define	CNT_STATCLOCK	23
-
-#define	SINT_NET	IRQ_TO_MASK(CNT_SINT_NET)
-#define	SINT_CLOCK	IRQ_TO_MASK(CNT_SINT_CLOCK)
-#define	SINT_SERIAL	IRQ_TO_MASK(CNT_SINT_SERIAL)
-#define	SPL_CLOCK	IRQ_TO_MASK(CNT_CLOCK)
-#define	SINT_MASK	(SINT_CLOCK|SINT_NET|SINT_SERIAL)
+void 	*intr_establish(int, int, int, int (*)(void *), void *);
+void 	intr_disestablish(void *);
+void 	intr_init(void);
+void 	ext_intr(void); 			/* for machdep */
+int 	splraise(int);
+int 	spllower(int);
+void 	splx(int);
+void 	softintr(int);
 
-#define	spllowersoftclock() spllower(imask[IPL_SOFTCLOCK])
+extern volatile u_int 		imask[NIPL];
+extern const int 		mask_clock; 	/* for clock.c */
 
-#define	splraiseipl(x)	splraise(imask[x])
+#define	spllowersoftclock() 	spllower(imask[IPL_SOFTCLOCK])
+#define	splraiseipl(x)		splraise(imask[x])
 
 #include <sys/spl.h>
 
-#define	setsoftclock()	set_sint(SINT_CLOCK);
-#define	setsoftnet()	set_sint(SINT_NET);
-#define	setsoftserial()	set_sint(SINT_SERIAL);
-
-#define	spl0()		spllower(0)
+#define	setsoftclock()		softintr(0);
+#define	setsoftnet()		softintr(1);
+#define	setsoftserial()		softintr(2);
 
-void softnet(void);
-void softserial(void);
+#define	spl0()			spllower(0)
 
 #endif /* !_LOCORE */
-
-#endif /* !_EVBPPC_INTR_H_ */
+#endif /* !_IBM4XX_INTR_H_ */
Index: arch/powerpc/marvell/marvell_intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/marvell/marvell_intr.h,v
retrieving revision 1.9
diff -d -p -u -r1.9 marvell_intr.h
--- arch/powerpc/marvell/marvell_intr.h	24 Dec 2005 20:07:28 -0000	1.9
+++ arch/powerpc/marvell/marvell_intr.h	26 Jun 2006 23:39:04 -0000
@@ -463,7 +463,6 @@ struct intrhand;
 extern struct intrhand *softnet_handlers[];
 #define	schednetisr(an_isr)	softintr_schedule(softnet_handlers[(an_isr)])
 
-#define __HAVE_GENERIC_SOFT_INTERRUPTS	/* should be in <machine/types.h> */
 void *softintr_establish(int level, void (*fun)(void *), void *arg);
 void softintr_disestablish(void *cookie);
 void softintr_schedule(void *cookie);
Index: arch/evbppc/conf/files.explora
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.explora,v
retrieving revision 1.5
diff -d -p -u -r1.5 files.explora
--- arch/evbppc/conf/files.explora	11 Dec 2005 12:17:11 -0000	1.5
+++ arch/evbppc/conf/files.explora	26 Jun 2006 23:39:04 -0000
@@ -18,6 +18,7 @@ file	arch/evbppc/explora/autoconf.c
 file	arch/evbppc/explora/consinit.c
 file	arch/evbppc/explora/machdep.c
 file	arch/powerpc/ibm4xx/intr.c
+file 	arch/powerpc/powerpc/softintr.c
 file	dev/md_root.c				memory_disk_hooks
 
 # Explora local bus
Index: arch/evbppc/conf/files.obs200
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.obs200,v
retrieving revision 1.4
diff -d -p -u -r1.4 files.obs200
--- arch/evbppc/conf/files.obs200	15 May 2006 15:56:54 -0000	1.4
+++ arch/evbppc/conf/files.obs200	26 Jun 2006 23:39:04 -0000
@@ -7,6 +7,7 @@ file	arch/powerpc/ibm4xx/ibm4xx_autoconf
 file	arch/powerpc/ibm4xx/ibm40x_machdep.c
 file	arch/powerpc/ibm4xx/ibm4xx_machdep.c
 file	arch/powerpc/ibm4xx/intr.c
+file 	arch/powerpc/powerpc/softintr.c
 file	arch/evbppc/obs405/dev/century_bios.c
 file	arch/evbppc/obs405/consinit.c
 file	arch/evbppc/obs405/obs200_autoconf.c
Index: arch/evbppc/conf/files.obs405
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.obs405,v
retrieving revision 1.16
diff -d -p -u -r1.16 files.obs405
--- arch/evbppc/conf/files.obs405	15 May 2006 15:56:54 -0000	1.16
+++ arch/evbppc/conf/files.obs405	26 Jun 2006 23:39:04 -0000
@@ -6,6 +6,7 @@ file	arch/powerpc/ibm4xx/ibm4xx_autoconf
 file	arch/powerpc/ibm4xx/ibm40x_machdep.c
 file	arch/powerpc/ibm4xx/ibm4xx_machdep.c
 file	arch/powerpc/ibm4xx/intr.c
+file 	arch/powerpc/powerpc/softintr.c
 file	arch/powerpc/ibm4xx/openbios/openbios.c
 file	arch/evbppc/obs405/consinit.c
 file	arch/evbppc/obs405/obs266_autoconf.c
Index: arch/evbppc/conf/files.walnut
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/conf/files.walnut,v
retrieving revision 1.9
diff -d -p -u -r1.9 files.walnut
--- arch/evbppc/conf/files.walnut	27 Feb 2006 11:04:31 -0000	1.9
+++ arch/evbppc/conf/files.walnut	26 Jun 2006 23:39:04 -0000
@@ -6,6 +6,7 @@ file	arch/evbppc/walnut/autoconf.c
 file	arch/evbppc/walnut/consinit.c
 file	arch/evbppc/walnut/machdep.c
 file	arch/powerpc/ibm4xx/intr.c
+file 	arch/powerpc/powerpc/softintr.c
 file	arch/powerpc/ibm4xx/ibm4xx_autoconf.c
 
 # Memory Disk for install kernel
Index: arch/evbppc/explora/explora_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/explora/explora_start.S,v
retrieving revision 1.3
diff -d -p -u -r1.3 explora_start.S
--- arch/evbppc/explora/explora_start.S	11 Dec 2005 12:17:12 -0000	1.3
+++ arch/evbppc/explora/explora_start.S	26 Jun 2006 23:39:05 -0000
@@ -65,22 +65,6 @@
 GLOBAL(proc0paddr)
 	.long	0			/* proc0 p_addr */
 
-GLOBAL(intrnames)
-	.asciz	"irq0", "irq1", "irq2", "irq3"
-	.asciz	"irq4", "irq5", "irq6", "irq7"
-	.asciz	"irq8", "irq9", "irq10", "irq11"
-	.asciz	"irq12", "irq13", "irq14", "irq15"
-	.asciz	"irq16", "irq17", "irq18", "softnet"
-	.asciz	"softclock", "softserial", "clock", "statclock"
-	.asciz	"irq24", "irq25", "irq26", "irq27"
-	.asciz	"irq28", "irq29", "irq30", "irq31"
-GLOBAL(eintrnames)
-	.align	4
-GLOBAL(intrcnt)
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-GLOBAL(eintrcnt)
-
 /*
  * Initially the dram starts at 0x01000000. This is way too high.
  * We relocate dram to 0x00000000. We use the video ram at 0xf0000000
Index: arch/evbppc/explora/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/explora/machdep.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 machdep.c
--- arch/evbppc/explora/machdep.c	5 May 2006 18:04:41 -0000	1.11
+++ arch/evbppc/explora/machdep.c	26 Jun 2006 23:39:05 -0000
@@ -401,36 +401,6 @@ lcsplx(int ipl)
 }
 
 void
-softnet(void)
-{
-	int isr;
-
-	isr = netisr;
-	netisr = 0;
-
-#define DONETISR(bit, fn)		\
-	do {				\
-		if (isr & (1 << bit))	\
-		fn();			\
-	} while (0)
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
-}
-
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
-	void comsoft(void);	/* XXX from dev/ic/com.c */
-
-	comsoft();
-#endif
-}
-
-void
 cpu_reboot(int howto, char *what)
 {
 	static int syncing = 0;
Index: arch/evbppc/include/types.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/include/types.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 types.h
--- arch/evbppc/include/types.h	11 Dec 2005 12:17:12 -0000	1.3
+++ arch/evbppc/include/types.h	26 Jun 2006 23:39:07 -0000
@@ -4,3 +4,4 @@
 
 #define	__HAVE_NWSCONS
 #define	__HAVE_DEVICE_REGISTER
+#define	__HAVE_GENERIC_SOFT_INTERRUPTS
Index: arch/evbppc/obs405/obs200_locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/obs405/obs200_locore.S,v
retrieving revision 1.2
diff -d -p -u -r1.2 obs200_locore.S
--- arch/evbppc/obs405/obs200_locore.S	11 Dec 2005 12:17:12 -0000	1.2
+++ arch/evbppc/obs405/obs200_locore.S	26 Jun 2006 23:39:07 -0000
@@ -105,24 +105,6 @@
 GLOBAL(proc0paddr)
 	.long	0			/* proc0 p_addr */
 
-GLOBAL(intrnames)
-	.asciz	"clock", "irq1", "irq2", "irq3"
-	.asciz	"irq4", "irq5", "irq6", "irq7"
-	.asciz	"irq8", "irq9", "irq10", "irq11"
-	.asciz	"irq12", "irq13", "irq14", "irq15"
-	.asciz	"irq16", "irq17", "irq18", "irq19"
-	.asciz	"irq20", "irq21", "irq22", "irq23"
-	.asciz	"irq24", "irq25", "irq26", "irq27"
-	.asciz	"irq28", "softnet", "softclock", "softserial"
-	.asciz  "statclock"
-GLOBAL(eintrnames)
-	.align	4
-GLOBAL(intrcnt)
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-	.long	0
-GLOBAL(eintrcnt)
-
 /*
  * This symbol is here for the benefit of kvm_mkdb, and is supposed to
  * mark the start of kernel text.
Index: arch/evbppc/obs405/obs405_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/obs405/obs405_machdep.c,v
retrieving revision 1.2
diff -d -p -u -r1.2 obs405_machdep.c
--- arch/evbppc/obs405/obs405_machdep.c	11 Dec 2005 12:17:12 -0000	1.2
+++ arch/evbppc/obs405/obs405_machdep.c	26 Jun 2006 23:39:07 -0000
@@ -54,43 +54,3 @@ struct vm_map *mb_map = NULL;
 struct vm_map *phys_map = NULL;
 char machine[] = MACHINE;		/* from <machine/param.h> */
 char machine_arch[] = MACHINE_ARCH;	/* from <machine/param.h> */
-
-/*
- * TODO: XXX these functions are machine-dependent ??
- */
-
-/*
- * softnet:
- * Soft networking interrupts.
- */
-void
-softnet(void)
-{
-	int isr;
-
-	isr = netisr;
-	netisr = 0;
-
-#define DONETISR(bit, fn) do {		\
-	if (isr & (1 << bit))		\
-		fn();			\
-} while (0)
-
-#include <net/netisr_dispatch.h>
-#undef DONETISR
-}
-
-/*
- * softserial:
- * Soft tty interrupts.
- */
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
-	void comsoft(void);	/* XXX from dev/ic/com.c */
-
-	comsoft();
-#endif
-}
Index: arch/evbppc/walnut/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/machdep.c,v
retrieving revision 1.27
diff -d -p -u -r1.27 machdep.c
--- arch/evbppc/walnut/machdep.c	5 May 2006 18:04:41 -0000	1.27
+++ arch/evbppc/walnut/machdep.c	26 Jun 2006 23:39:07 -0000
@@ -459,42 +459,6 @@ dumpsys(void)
 }
 
 /*
- * Soft networking interrupts.
- */
-void
-softnet(void)
-{
-	int isr;
-
-	isr = netisr;
-	netisr = 0;
-
-#define DONETISR(bit, fn) do {		\
-	if (isr & (1 << bit))		\
-		fn();			\
-} while (0)
-
-#include <net/netisr_dispatch.h>
-
-#undef DONETISR
-
-}
-
-/*
- * Soft tty interrupts.
- */
-#include "com.h"
-void
-softserial(void)
-{
-#if NCOM > 0
-	void comsoft(void);	/* XXX from dev/ic/com.c */
-
-	comsoft();
-#endif
-}
-
-/*
  * Halt or reboot the machine after syncing/dumping according to howto.
  */
 void
Index: arch/evbppc/walnut/walnut_start.S
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/walnut_start.S,v
retrieving revision 1.12
diff -d -p -u -r1.12 walnut_start.S
--- arch/evbppc/walnut/walnut_start.S	11 Dec 2005 12:17:13 -0000	1.12
+++ arch/evbppc/walnut/walnut_start.S	26 Jun 2006 23:39:08 -0000
@@ -104,24 +104,6 @@
 GLOBAL(proc0paddr)
 	.long	0			/* proc0 p_addr */
 
-GLOBAL(intrnames)
-	.asciz	"clock", "irq1", "irq2", "irq3"
-	.asciz	"irq4", "irq5", "irq6", "irq7"
-	.asciz	"irq8", "irq9", "irq10", "irq11"
-	.asciz	"irq12", "irq13", "irq14", "irq15"
-	.asciz	"irq16", "irq17", "irq18", "irq19"
-	.asciz	"irq20", "irq21", "irq22", "irq23"
-	.asciz	"irq24", "irq25", "irq26", "irq27"
-	.asciz	"irq28", "softnet", "softclock", "softserial"
-	.asciz  "statclock"
-GLOBAL(eintrnames)
-	.align	4
-GLOBAL(intrcnt)
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-	.long	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-	.long	0
-GLOBAL(eintrcnt)
-
 /*
  * This symbol is here for the benefit of kvm_mkdb, and is supposed to
  * mark the start of kernel text.
Index: arch/evbppc/walnut/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/walnut/pci/pci_machdep.c,v
retrieving revision 1.6
diff -d -p -u -r1.6 pci_machdep.c
--- arch/evbppc/walnut/pci/pci_machdep.c	10 Feb 2006 20:52:57 -0000	1.6
+++ arch/evbppc/walnut/pci/pci_machdep.c	26 Jun 2006 23:39:08 -0000
@@ -205,8 +205,9 @@ pci_intr_string(pci_chipset_tag_t pc, pc
 {
 	static char irqstr[8];		/* 4 + 2 + NUL + sanity */
 
-	if (ih == 0 || ih >= ICU_LEN)
-		panic("pci_intr_string: bogus handle 0x%x", ih);
+	/* Make sure it looks sane, intr_establish does the real check. */
+	if (ih < 0 || ih > 99)
+		panic("pci_intr_string: handle %#x won't fit two digits", ih);
 
 	sprintf(irqstr, "irq %d", ih);
 	return (irqstr);
@@ -225,10 +226,6 @@ void *
 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
 		   int (*func)(void *), void *arg)
 {
-
-	if (ih == 0 || ih >= ICU_LEN)
-		panic("pci_intr_establish: bogus handle 0x%x", ih);
-
 	return intr_establish(ih, IST_LEVEL, level, func, arg);
 }