login
Header Space

 
 

MacPPC interrupt controller change testing

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <misc@...>
Date: Tuesday, May 20, 2008 - 7:26 pm

As was announced on undeadly recently, I have been back hacking on PowerPC.
One of the things noticed once SMP was working was that an occasionally seen
wdc DRQ error message occurred very frequently. This pointed out that
the interrupt controller was doing something poorly. After several attempts
to figure out what the specific problem was, I finally decided to rewrite
the driver to remove the lazy interrupt disable which was originally
implemented for the 8259 interrupt controller found on very old powerpc
systems.

This lazy disable system doesn't make a lot of sense when the interrupt
control registers are easily (quickly) accessible. Also the programming
model is much simpler when the chip is programmed as designed.

What follows is a rewrite of the powerpc interrupt controller API and
the macppc interrupt controllers to use this new api. It greatly simplifies
the interrupt controller code and makes the wdc DRQ problem go away.


This diff needs heavy testing on all macppc systems.

Currently this diff breaks with socppc interrupt controller, but that
will be resolved shortly.

Index: arch/powerpc/include/intr.h
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/include/intr.h,v
retrieving revision 1.34
diff -u -r1.34 intr.h
--- arch/powerpc/include/intr.h	14 Nov 2007 20:33:32 -0000	1.34
+++ arch/powerpc/include/intr.h	20 May 2008 23:23:49 -0000
@@ -36,14 +36,18 @@
 #define _POWERPC_INTR_H_
 
 #define	IPL_NONE	0
-#define	IPL_BIO		1
+#define	IPL_SOFT	1
+#define	IPL_SOFTCLOCK	2
+#define	IPL_SOFTNET	3
+#define	IPL_SOFTTTY	4
+#define	IPL_BIO		5
 #define	IPL_AUDIO	IPL_BIO /* XXX - was defined this val in audio_if.h */
-#define	IPL_NET		2
-#define	IPL_TTY		3
-#define	IPL_VM		4
-#define	IPL_CLOCK	5
-#define	IPL_HIGH	6
-#define	IPL_NUM		7
+#define	IPL_NET		6
+#define	IPL_TTY		7
+#define	IPL_VM		8
+#define	IPL_CLOCK	9
+#define	IPL_HIGH	10
+#define	IPL_NUM		11
 
 #define	IST_NONE	0
 #define	IST_PULSE	1
@@ -55,9 +59,9 @@
 #include <sys/evcount.h>
 #include <machine/atomic.h>
 
-#define PPC_NIRQ	66
-#define PPC_CLK_IRQ	64
-#define PPC_STAT_IRQ	65
+#define	PPC_NIRQ	66
+#define	PPC_CLK_IRQ	64
+#define	PPC_STAT_IRQ	65
 
 void setsoftclock(void);
 void clearsoftclock(void);
@@ -70,48 +74,69 @@
 int	spllower(int);
 void	splx(int);
 
+typedef int (ppc_splraise_t) (int);
+typedef int (ppc_spllower_t) (int);
+typedef void (ppc_splx_t) (int);
+
+extern struct ppc_intr_func {
+	ppc_splraise_t *raise;
+	ppc_spllower_t *lower;
+	ppc_splx_t *x;
+}ppc_intr_func;
+
+#if 0
+/* does it make sense to call directly ?? */
+#define	splraise(x)	ppc_intr.raise(x)
+#define	spllower(x)	ppc_intr.lower(x)
+#define	splx(x)		ppc_intr.x(x)
+#endif
 
-void do_pending_int(void);
+extern int ppc_smask[IPL_NUM];
+
+void ppc_smask_init(void);
+char *ppc_intr_typename(int type);
 
-extern int imask[IPL_NUM];
+void do_pending_int(void);
 
 /* SPL asserts */
 #define	splassert(wantipl)	/* nothing */
 
 #define	set_sint(p)	atomic_setbits_int(&curcpu()->ci_ipending, p)
 
+#if 0
 #define	SINT_CLOCK	0x10000000
 #define	SINT_NET	0x20000000
 #define	SINT_TTY	0x40000000
 #define	SPL_CLOCK	0x80000000
 #define	SINT_MASK	(SINT_CLOCK|SINT_NET|SINT_TTY)
+#endif
 
-#define splbio()	splraise(imask[IPL_BIO])
-#define splnet()	splraise(imask[IPL_NET])
-#define spltty()	splraise(imask[IPL_TTY])
-#define splaudio()	splraise(imask[IPL_AUDIO])
-#define splclock()	splraise(imask[IPL_CLOCK])
-#define splvm()		splraise(imask[IPL_VM])
-#define splsched()	splhigh()
-#define spllock()	splhigh()
-#define splstatclock()	splhigh()
-#define	splsoftclock()	splraise(SINT_CLOCK)
-#define	splsoftnet()	splraise(SINT_NET|SINT_CLOCK)
-#define	splsofttty()	splraise(SINT_TTY|SINT_NET|SINT_CLOCK)
-
-#define	setsoftclock()	set_sint(SINT_CLOCK);
-#define	setsoftnet()	set_sint(SINT_NET);
-#define	setsofttty()	set_sint(SINT_TTY);
+#define	splbio()	splraise(IPL_BIO)
+#define	splnet()	splraise(IPL_NET)
+#define	spltty()	splraise(IPL_TTY)
+#define	splaudio()	splraise(IPL_AUDIO)
+#define	splclock()	splraise(IPL_CLOCK)
+#define	splvm()		splraise(IPL_VM)
+#define	splsched()	splhigh()
+#define	spllock()	splhigh()
+#define	splstatclock()	splhigh()
+#define	splsoftclock()	splraise(IPL_SOFTCLOCK)
+#define	splsoftnet()	splraise(IPL_SOFTNET)
+#define	splsofttty()	splraise(IPL_SOFTTTY)
+
+#define	setsoftclock()	set_sint(SI_TO_IRQBIT(SI_SOFTCLOCK))
+#define	setsoftnet()	set_sint(SI_TO_IRQBIT(SI_SOFTNET))
+#define	setsofttty()	set_sint(SI_TO_IRQBIT(SI_SOFTTTY))
 
-#define	splhigh()	splraise(0xffffffff)
-#define	spl0()		spllower(0)
+#define	splhigh()	splraise(IPL_HIGH)
+#define	spl0()		spllower(IPL_NONE)
 
 /*
  *	Interrupt control struct used to control the ICU setup.
  */
 
 struct intrhand {
-	struct intrhand	*ih_next;
+	TAILQ_ENTRY(intrhand) ih_list;
 	int		(*ih_fun)(void *);
 	void		*ih_arg;
 	struct evcount	ih_count;
@@ -119,10 +144,33 @@
 	int		ih_irq;
 	char		*ih_what;
 };
+
+struct intrq {
+	TAILQ_HEAD(, intrhand) iq_list; /* handler list */
+	int iq_ipl;			/* IPL_ to mask while handling */ 
+	int iq_ist;			/* share type */
+};
+
 extern int ppc_configed_intr_cnt;
-#define MAX_PRECONF_INTR 16
+#define	MAX_PRECONF_INTR 16
 extern struct intrhand ppc_configed_intr[MAX_PRECONF_INTR];
 void softnet(int isr);
+
+#define	SI_TO_IRQBIT(x) (1 << ((x)+(30-SI_SOFTTTY)))
+
+#define	SI_SOFT			0	/* for IPL_SOFT */
+#define	SI_SOFTCLOCK		1	/* for IPL_SOFTCLOCK */
+#define	SI_SOFTNET		2	/* for IPL_SOFTNET */
+#define	SI_SOFTTTY		3	/* for IPL_SOFTSERIAL */
+
+#define	SI_NQUEUES		4
+
+#define SI_QUEUENAMES {		\
+	"generic",		\
+	"clock",		\
+	"net",			\
+	"serial",		\
+}
 
 #endif /* _LOCORE */
 #endif /* _POWERPC_INTR_H_ */
Index: arch/powerpc/powerpc/intr.c
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/powerpc/intr.c,v
retrieving revision 1.2
diff -u -r1.2 intr.c
--- arch/powerpc/powerpc/intr.c	14 Nov 2007 20:47:34 -0000	1.2
+++ arch/powerpc/powerpc/intr.c	20 May 2008 23:23:49 -0000
@@ -35,45 +35,121 @@
 
 #include <machine/cpu.h>
 #include <machine/intr.h>
+#include <machine/lock.h>
+
+int ppc_dflt_splraise(int);
+int ppc_dflt_spllower(int);
+void ppc_dflt_splx(int);
+
+/* provide a function for asm code to call */
+#undef splraise
+#undef spllower
+#undef splx
+
+int ppc_smask[IPL_NUM];
+
+void
+ppc_smask_init()
+{
+	int i;
+
+        for (i = IPL_NONE; i <= IPL_HIGH; i++)  {
+                ppc_smask[i] = 0;
+                if (i < IPL_SOFT)
+                        ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFT);
+                if (i < IPL_SOFTCLOCK)
+                        ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTCLOCK);
+                if (i < IPL_SOFTNET)
+                        ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTNET);
+                if (i < IPL_SOFTTTY)
+                        ppc_smask[i] |= SI_TO_IRQBIT(SI_SOFTTTY);
+#if 0
+                printf("smask[%d]: %x\n", i, ppc_smask[i])
+#endif
+        }
+}
+
 
 int
 splraise(int newcpl)
 {
+	return ppc_intr_func.raise(newcpl);
+}
+
+int
+spllower(int newcpl)
+{
+	return ppc_intr_func.lower(newcpl);
+}
+
+void
+splx(int newcpl)
+{
+	ppc_intr_func.x(newcpl);
+}
+
+int
+ppc_dflt_splraise(int newcpl)
+{
 	struct cpu_info *ci = curcpu();
 	int oldcpl;
 
-	__asm__ volatile("":::"memory");	/* reorder protect */
 	oldcpl = ci->ci_cpl;
-	ci->ci_cpl = oldcpl | newcpl;
-	__asm__ volatile("":::"memory");
+	if (newcpl < oldcpl)
+		newcpl = oldcpl;
+	ci->ci_cpl = newcpl;
 
 	return (oldcpl);
 }
 
+/*
+ * functions with 'default' behavior to use before the real
+ * interrupt controller attaches
+ */
 int
-spllower(int newcpl)
+ppc_dflt_spllower(int newcpl)
 {
 	struct cpu_info *ci = curcpu();
 	int oldcpl;
 
-	__asm__ volatile("":::"memory");	/* reorder protect */
 	oldcpl = ci->ci_cpl;
-	ci->ci_cpl = newcpl;
-	if (ci->ci_ipending & ~newcpl)
-		do_pending_int();
-	__asm__ volatile("":::"memory");
+
+	splx(newcpl);
 
 	return (oldcpl);
 }
 
 void
-splx(int newcpl)
+ppc_dflt_splx(int newcpl)
 {
 	struct cpu_info *ci = curcpu();
 
-	__asm__ volatile("":::"memory");	/* reorder protect */
 	ci->ci_cpl = newcpl;
-	if (ci->ci_ipending & ~newcpl)
+
+	if (ci->ci_ipending & ppc_smask[newcpl])
 		do_pending_int();
-	__asm__ volatile("":::"memory");
+}
+
+struct ppc_intr_func ppc_intr_func =
+{
+	ppc_dflt_splraise,
+	ppc_dflt_spllower,
+	ppc_dflt_splx
+};
+
+char *
+ppc_intr_typename(int type)
+{
+	switch (type) {
+        case IST_NONE :
+		return ("none");
+        case IST_PULSE:
+		return ("pulsed");
+        case IST_EDGE:
+		return ("edge-triggered");
+        case IST_LEVEL:
+		return ("level-triggered");
+	default:
+		return ("unknown");
+	}
 }
Index: arch/powerpc/powerpc/mutex.S
===================================================================
RCS file: /cvs/src/sys/arch/powerpc/powerpc/mutex.S,v
retrieving revision 1.3
diff -u -r1.3 mutex.S
--- arch/powerpc/powerpc/mutex.S	31 May 2007 23:50:25 -0000	1.3
+++ arch/powerpc/powerpc/mutex.S	20 May 2008 23:23:49 -0000
@@ -22,7 +22,11 @@
 #include <machine/asm.h>
 
 /* XXX */
+#ifdef USERLAND
+#define GET_CPUINFO(r)	mr r, %r4
+#else
 #define GET_CPUINFO(r)	mfsprg r,0
+#endif
 
 ENTRY(mtx_init)
 	li	%r5,0
@@ -32,44 +36,44 @@
 	blr
 
 
+/*
+ * mtx_enter(struct mutex *mtx[%r3])
+ */
 ENTRY(mtx_enter)
-	stwu	%r1,-32(%r1)			# reserve stack
+	stwu	%r1,-16(%r1)			# reserve stack
 	mflr	%r0
-	stw	%r0,36(%r1)			# save return address
+	stw	%r0,20(%r1)			# save return address
 .L_retry:
+	stw	%r3, 12(%r1)
+	lwz	%r3,MTX_WANTIPL(%r3)		# load new ipl
+	bl	_C_LABEL(splraise)
+	mr	%r7, %r3			
 	GET_CPUINFO(%r4)
-	lwz	%r5,MTX_WANTIPL(%r3)		# load new ipl
-	lis	%r6,_C_LABEL(imask)@ha		# convert into cpl
-	slwi	%r5,%r5,2
-	addi	%r5,%r5,_C_LABEL(imask)@l
-	lwzx	%r5,%r5,%r6
-	lwz	%r7,CI_CPL(%r4)			# load current cpl
-	or	%r6,%r5,%r7			# raise	cpl
-	stw	%r6,CI_CPL(%r4)			# store new cpl
+	lwz	%r3,12(%r1)
 	li	%r5,MTX_OWNER			# load offset constant
 	lwarx	%r6,%r5,%r3			# load reserve owner
 	cmpwi	0,%r6,0				# test owner == 0
 	beq+	0,.L_mutex_free			# if owner == 0 branch free
-.L_mutex_locked:
 #ifdef DIAGNOSTIC
 	cmpl	0,%r4,%r6
 	beq-	.L_mutex_selflocked
 #endif
-	stw	%r3,28(%r1)			# save mtx during lcsplx
-	la	%r4,28(%r1)
+.L_mutex_busy:
+	stw	%r3,12(%r1)			# save mtx during lcsplx
+	la	%r4,12(%r1)
 	stwcx.	%r3,0,%r4			# unreserve owner
 	mr	%r3,%r7				# move old cpl to arg0
 	bl	_C_LABEL(lcsplx)		# call splx on old cpl
-	lwz	%r3,28(%r1)
+	lwz	%r3,12(%r1)
 	b	.L_retry
 
 .L_mutex_free:
 	stwcx.	%r4,%r5,%r3			# old owner was 0 cond store
-	bne-	.L_mutex_locked			# branch if reserve cancelled
+	bne-	.L_mutex_busy			# branch if reserve cancelled
 	stw	%r7,MTX_OLDCPL(%r3)		# save old ipl
-	lwz	%r0,36(%r1)			# load return address
+	lwz	%r0,20(%r1)			# load return address
 	mtlr	%r0
-	addi	%r1,%r1,32			# restore stack
+	addi	%r1,%r1,16			# restore stack
 	blr
 
 #ifdef DIAGNOSTIC
@@ -91,14 +95,10 @@
 	beq-	.L_mutex_notlocked
 #endif
 	li	%r4,0
-	lwz	%r5,MTX_OLDCPL(%r3)
+	lwz	% r5,MTX_OLDCPL(%r3)
 	stw	%r4,MTX_OLDCPL(%r3)
 	stw	%r4,MTX_OWNER(%r3)
-	GET_CPUINFO(%r4)
 	mr	%r3,%r5
-	lwz	%r5,CI_CPL(%r4)
-	cmpl	0,%r3,%r5
-	beq	1f
 	b	_C_LABEL(lcsplx)
 1:
 	blr
Index: arch/macppc/dev/macintr.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/macintr.c,v
retrieving revision 1.33
diff -u -r1.33 macintr.c
--- arch/macppc/dev/macintr.c	29 May 2007 18:10:42 -0000	1.33
+++ arch/macppc/dev/macintr.c	20 May 2008 23:23:49 -0000
@@ -1,6 +1,7 @@
 /*	$OpenBSD: macintr.c,v 1.33 2007/05/29 18:10:42 miod Exp $	*/
 
 /*-
+ * Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
  * Copyright (c) 1995 Per Fogelstrom
  * Copyright (c) 1993, 1994 Charles M. Hannum.
  * Copyright (c) 1990 The Regents of the University of California.
@@ -58,25 +59,17 @@
 #define ICU_LEN 64
 #define LEGAL_IRQ(x) ((x >= 0) && (x < ICU_LEN))
 
-int m_intrtype[ICU_LEN], m_intrmask[ICU_LEN], m_intrlevel[ICU_LEN];
-struct intrhand *m_intrhand[ICU_LEN];
-int m_hwirq[ICU_LEN], m_virq[64];
-unsigned int imen_m = 0xffffffff;
-int m_virq_max = 0;
-
-static int fakeintr(void *);
-static char *intr_typename(int type);
-static void intr_calculatemasks(void);
-static void enable_irq(int x);
-static __inline int cntlzw(int x);
-static int mapirq(int irq);
-static int read_irq(void);
-static void mac_intr_do_pending_int(void);
+int macintr_ienable_l[IPL_NUM], macintr_ienable_h[IPL_NUM];
+int macintr_pri_share[IPL_NUM];
 
-extern u_int32_t *heathrow_FCR;
+struct intrq macintr_handler[ICU_LEN];
+
+void macintr_calc_mask(void);
+void macintr_eoi(int irq);
+int macintr_read_irq(void);
+static void macintr_do_pending_int(void);
 
-#define HWIRQ_MAX 27
-#define HWIRQ_MASK 0x0fffffff
+extern u_int32_t *heathrow_FCR;
 
 #define INT_STATE_REG0  (interrupt_reg + 0x20)
 #define INT_ENABLE_REG0 (interrupt_reg + 0x24)
@@ -95,6 +88,8 @@
 void	macintr_attach(struct device *, struct device *, void *);
 void	mac_do_pending_int(void);
 void	mac_ext_intr(void);
+void	macintr_collect_preconf_intr(void);
+void	macintr_setipl(int ipl);
 
 struct cfattach macintr_ca = {
 	sizeof(struct macintr_softc),
@@ -140,31 +135,84 @@
 intr_disestablish_t macintr_disestablish;
 extern intr_establish_t *mac_intr_establish_func;
 extern intr_disestablish_t *mac_intr_disestablish_func;
-void macintr_collect_preconf_intr(void);
+
+ppc_splraise_t macintr_splraise;
+ppc_spllower_t macintr_spllower;
+ppc_splx_t macintr_splx;
+
+
+int
+macintr_splraise(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	newcpl = macintr_pri_share[newcpl];
+	int ocpl = ci->ci_cpl;
+	if (ocpl > newcpl)
+		newcpl = ocpl;
+
+	macintr_setipl(newcpl);
+
+	return ocpl;
+}
+
+int
+macintr_spllower(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	int ocpl = ci->ci_cpl;
+
+	macintr_splx(newcpl);
+
+	return ocpl;
+}
+
+void
+macintr_splx(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	 
+	macintr_setipl(newcpl);
+	if (ci->ci_ipending & ppc_smask[newcpl])
+		macintr_do_pending_int();
+}
 
 void
 macintr_attach(struct device *parent, struct device *self, void *aux)
 {
+	struct cpu_info *ci = curcpu();
 	struct confargs *ca = aux;
 	extern intr_establish_t *intr_establish_func;
 	extern intr_disestablish_t *intr_disestablish_func;
+	struct intrq *iq;
+	int i;
 
 	interrupt_reg = (void *)mapiodev(ca->ca_baseaddr,0x100); /* XXX */
 
+	for (i = 0; i < ICU_LEN; i++) {
+		iq = &macintr_handler[i];
+		TAILQ_INIT(&iq->iq_list);
+	}
+	ppc_smask_init();
+
 	install_extint(mac_ext_intr);
-	pending_int_f = mac_intr_do_pending_int;
+	pending_int_f = macintr_do_pending_int;
 	intr_establish_func  = macintr_establish;
 	intr_disestablish_func  = macintr_disestablish;
 	mac_intr_establish_func  = macintr_establish;
 	mac_intr_disestablish_func  = macintr_disestablish;
 
+	ppc_intr_func.raise = macintr_splraise;
+	ppc_intr_func.lower = macintr_spllower;
+	ppc_intr_func.x = macintr_splx;
+
+	ci->ci_iactive = 0;
+
 	macintr_collect_preconf_intr();
 
 	mac_intr_establish(parent, 0x14, IST_LEVEL, IPL_HIGH,
 	    macintr_prog_button, (void *)0x14, "progbutton");
 
 	ppc_intr_enable(1);
-
 	printf("\n");
 }
 
@@ -209,11 +257,19 @@
 	return 1;
 }
 
-static int
-fakeintr(void *arg)
+void
+macintr_setipl(int ipl)
 {
+	struct cpu_info *ci = curcpu();
+	int s;
+	s = ppc_intr_disable();
+	ci->ci_cpl = ipl;
+	if (heathrow_FCR)
+		out32rb(INT_ENABLE_REG1,
+		    macintr_ienable_h[macintr_pri_share[ipl]]);
 
-	return 0;
+	out32rb(INT_ENABLE_REG0, macintr_ienable_l[macintr_pri_share[ipl]]);
+	ppc_intr_enable(s);
 }
 
 /*
@@ -223,19 +279,13 @@
 macintr_establish(void * lcv, int irq, int type, int level,
     int (*ih_fun)(void *), void *ih_arg, char *name)
 {
-	struct intrhand **p, *q, *ih;
-	static struct intrhand fakehand;
-
-	fakehand.ih_next = NULL;
-	fakehand.ih_fun  = fakeintr;
+	struct cpu_info *ci = curcpu();
+	struct intrq *iq;
+	struct intrhand *ih;
+	int s;
 
 #if 0
-printf("macintr_establish, hI %d L %d ", irq, type);
-printf("addr reg0 %x\n", INT_STATE_REG0);
-#endif
-	irq = mapirq(irq);
-#if 0
-printf("vI %d ", irq);
+printf("macintr_establish, hI %d L %d %s", irq, level, ppc_intr_typename(type));
 #endif
 
 	/* no point in sleeping unless someone can free memory. */
@@ -246,51 +296,40 @@
 	if (!LEGAL_IRQ(irq) || type == IST_NONE)
 		panic("intr_establish: bogus irq or type");
 
-	switch (m_intrtype[irq]) {
+	iq = &macintr_handler[irq];
+	switch (iq->iq_ist) {
 	case IST_NONE:
-		m_intrtype[irq] = type;
+		iq->iq_ist = type;
 		break;
 	case IST_EDGE:
 	case IST_LEVEL:
-		if (type == m_intrtype[irq])
+		if (type == iq->iq_ist)
 			break;
 	case IST_PULSE:
 		if (type != IST_NONE)
 			panic("intr_establish: can't share %s with %s",
-			    intr_typename(m_intrtype[irq]),
-			    intr_typename(type));
+			    ppc_intr_typename(iq->iq_ist),
+			    ppc_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 = &m_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.
-	 */
-	fakehand.ih_level = level;
-	*p = &fakehand;
-
-	intr_calculatemasks();
-
-	/*
-	 * Poke the real handler in now.
-	 */
 	ih->ih_fun = ih_fun;
 	ih->ih_arg = ih_arg;
-	ih->ih_next = NULL;
 	ih->ih_level = level;
 	ih->ih_irq = irq;
-	evcount_attach(&ih->ih_count, name, (void *)&m_hwirq[irq],
+	evcount_attach(&ih->ih_count, name, (void *)&ih->ih_irq,
 	    &evcount_intr);
-	*p = ih;
+
+	/*
+	 * Append handler to end of list
+	 */
+	s = ppc_intr_disable();
+
+	TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
+	macintr_calc_mask();
+
+	macintr_setipl(ci->ci_cpl);
+	ppc_intr_enable(s);
 
 	return (ih);
 }
@@ -301,195 +340,93 @@
 void
 macintr_disestablish(void *lcp, void *arg)
 {
+	struct cpu_info *ci = curcpu();
 	struct intrhand *ih = arg;
 	int irq = ih->ih_irq;
-	struct intrhand **p, *q;
+	int s;
+	struct intrq *iq;
 
 	if (!LEGAL_IRQ(irq))
 		panic("intr_disestablish: bogus irq");
 
 	/*
 	 * Remove the handler from the chain.
-	 * This is O(n^2), too.
 	 */
-	for (p = &m_intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
-		;
-	if (q)
-		*p = q->ih_next;
-	else
-		panic("intr_disestablish: handler not registered");
 
-	evcount_detach(&ih->ih_count);
-	free((void *)ih, M_DEVBUF);
+	iq = &macintr_handler[irq];
+	s = ppc_intr_disable();
 
-	intr_calculatemasks();
+	TAILQ_REMOVE(&iq->iq_list, ih, ih_list);
+	macintr_calc_mask();
 
-	if (m_intrhand[irq] == NULL)
-		m_intrtype[irq] = IST_NONE;
-}
+	macintr_setipl(ci->ci_cpl);
+	ppc_intr_enable(s);
 
+	evcount_detach(&ih->ih_count);
+	free((void *)ih, M_DEVBUF);
 
-static char *
-intr_typename(int type)
-{
-	switch (type) {
-        case IST_NONE :
-		return ("none");
-        case IST_PULSE:
-		return ("pulsed");
-        case IST_EDGE:
-		return ("edge-triggered");
-        case IST_LEVEL:
-		return ("level-triggered");
-	default:
-		panic("intr_typename: invalid type %d", type);
-#if 1 /* XXX */
-		return ("unknown");
-#endif
-	}
+	if (TAILQ_EMPTY(&iq->iq_list))
+		iq->iq_ist = IST_NONE;
 }
+
 /*
  * Recalculate the interrupt masks from scratch.
  * We could code special registry and deregistry versions of this function that
  * would be faster, but the code would be nastier, and we don't expect this to
  * happen very much anyway.
  */
-static void
-intr_calculatemasks()
+void
+macintr_calc_mask()
 {
-	int irq, level;
-	struct intrhand *q;
-
-	/* First, figure out which levels each IRQ uses. */
-	for (irq = 0; irq < ICU_LEN; irq++) {
-		register int levels = 0;
-		for (q = m_intrhand[irq]; q; q = q->ih_next)
-			levels |= 1 << q->ih_level;
-		m_intrlevel[irq] = levels;
-	}
+	int irq;
+	struct intrhand *ih;
+	int i;
 
-	/* Then figure out which IRQs use each level. */
-	for (level = IPL_NONE; level < IPL_NUM; level++) {
-		register int irqs = 0;
-		for (irq = 0; irq < ICU_LEN; irq++)
-			if (m_intrlevel[irq] & (1 << level))
-				irqs |= 1 << irq;
-		imask[level] = irqs | SINT_MASK;
+	for (i = IPL_NONE; i < IPL_NUM; i++) {
+		macintr_pri_share[i] = i;
 	}
 
-	/*
-	 * There are tty, network and disk drivers that use free() at interrupt
-	 * time, so vm > (tty | net | bio).
-	 *
-	 * Enforce a hierarchy that gives slow devices a better chance at not
-	 * dropping data.
-	 */
-	imask[IPL_NET] |= imask[IPL_BIO];
-	imask[IPL_TTY] |= imask[IPL_NET];
-	imask[IPL_VM] |= imask[IPL_TTY];
-	imask[IPL_CLOCK] |= imask[IPL_VM] | SPL_CLOCK;
-
-	/*
-	 * These are pseudo-levels.
-	 */
-	imask[IPL_NONE] = 0x00000000;
-	imask[IPL_HIGH] = 0xffffffff;
-
-	/* And eventually calculate the complete masks. */
 	for (irq = 0; irq < ICU_LEN; irq++) {
-		register int irqs = 1 << irq;
-		for (q = m_intrhand[irq]; q; q = q->ih_next)
-			irqs |= imask[q->ih_level];
-		m_intrmask[irq] = irqs | SINT_MASK;
-	}
-
-	/* Lastly, determine which IRQs are actually in use. */
-	{
-		register int irqs = 0;
-		for (irq = 0; irq < ICU_LEN; irq++) {
-			if (m_intrhand[irq])
-				irqs |= 1 << irq;
+		int maxipl = IPL_NONE;
+		int minipl = IPL_HIGH;
+		struct intrq *iq = &macintr_handler[irq];
+
+		TAILQ_FOREACH(ih, &iq->iq_list, ih_list) {
+			if (ih->ih_level > maxipl)
+				maxipl = ih->ih_level;
+			if (ih->ih_level < minipl)
+				minipl = ih->ih_level;
 		}
-		imen_m = ~irqs;
-		enable_irq(~imen_m);
-	}
-}
-static void
-enable_irq(int x)
-{
-	int state0, state1, v;
-	int irq;
-
-	x &= HWIRQ_MASK;	/* XXX Higher bits are software interrupts. */
-
-	state0 = state1 = 0;
-	while (x) {
-		v = 31 - cntlzw(x);
-		irq = m_hwirq[v];
-		if (irq < 32)
-			state0 |= 1 << irq;
-		else
-			state1 |= 1 << (irq - 32);
 
-		x &= ~(1 << v);
-	}
-
-	if (heathrow_FCR)
-		out32rb(INT_ENABLE_REG1, state1);
-
-	out32rb(INT_ENABLE_REG0, state0);
-}
+		iq->iq_ipl = maxipl;
 
-int m_virq_inited = 0;
+		if (maxipl == IPL_NONE) {
+			minipl = IPL_NONE; /* Interrupt not enabled */
+		} else {
+			for (i = minipl; i <= maxipl; i++)
+				macintr_pri_share[i] = i;
+		}
 
-/*
- * Map 64 irqs into 32 (bits).
- */
-static int
-mapirq(int irq)
-{
-	int v;
-	int i;
+		/* Enable interrupts at lower levels */
 
-	if (m_virq_inited == 0) {
-		m_virq_max = 0;
-		for (i = 0; i < ICU_LEN; i++) {
-			m_virq[i] = 0;
+		if (irq < 32) {
+			for (i = IPL_NONE; i < minipl; i++)
+				macintr_ienable_l[i] |= (1 << irq);
+			for (; i <= IPL_HIGH; i++)
+				macintr_ienable_l[i] &= ~(1 << irq);
+		} else {
+			for (i = IPL_NONE; i < minipl; i++)
+				macintr_ienable_h[i] |= (1 << (irq-32));
+			for (; i <= IPL_HIGH; i++)
+				macintr_ienable_h[i] &= ~(1 << (irq-32));
 		}
-		m_virq_inited = 1;
 	}
 
-	/* irq in table already? */
-	if (m_virq[irq] != 0)
-		return m_virq[irq];
-
-	if (irq < 0 || irq >= 64)
-		panic("invalid irq %d", irq);
-	m_virq_max++;
-	v = m_virq_max;
-	if (v > HWIRQ_MAX)
-		panic("virq overflow");
-
-	m_hwirq[v] = irq;
-	m_virq[irq] = v;
 #if 0
-printf("\nmapirq %x to %x\n", irq, v);
+	for (i = 0; i < IPL_NUM; i++)
+		printf("imask[%d] %x %x\n", i, macintr_ienable_l[i],
+		    macintr_ienable_h[i]);
 #endif
-
-	return v;
-}
-
-/*
- * Count leading zeros.
- */
-static __inline int
-cntlzw(int x)
-{
-	int a;
-
-	__asm __volatile ("cntlzw %0,%1" : "=r"(a) : "r"(x));
-
-	return a;
 }
 
 /*
@@ -499,143 +436,136 @@
 mac_ext_intr()
 {
 	int irq = 0;
-	int o_imen, r_imen;
 	int pcpl;
 	struct cpu_info *ci = curcpu();
+	struct intrq *iq;
 	struct intrhand *ih;
-	volatile unsigned long int_state;
 
 	pcpl = ci->ci_cpl;	/* Turn off all */
 
-	int_state = read_irq();
-	if (int_state == 0)
-		goto out;
-
-start:
-	irq = 31 - cntlzw(int_state);
-
-	o_imen = imen_m;
-	r_imen = 1 << irq;
-
-	if ((ci->ci_cpl & r_imen) != 0) {
-		/* Masked! Mark this as pending. */
-		ci->ci_ipending |= r_imen;
-		imen_m |= r_imen;
-		enable_irq(~imen_m);
-	} else {
-		splraise(m_intrmask[irq]);
+	irq = macintr_read_irq();
+	while (irq != 255) {
+		iq = &macintr_handler[irq];
+		macintr_setipl(iq->iq_ipl);
 
-		ih = m_intrhand[irq];
-		while (ih) {
+		TAILQ_FOREACH(ih, &iq->iq_list, ih_list) {
+			ppc_intr_enable(1);
 			if ((*ih->ih_fun)(ih->ih_arg))
 				ih->ih_count.ec_count++;
-			ih = ih->ih_next;
+			(void)ppc_intr_disable();
 		}
+		macintr_eoi(irq);
+		macintr_setipl(pcpl);
 
 		uvmexp.intrs++;
+
+		irq = macintr_read_irq();
 	}
-	int_state &= ~r_imen;
-	if (int_state)
-		goto start;
 
-out:
+	ppc_intr_enable(1);
 	splx(pcpl);	/* Process pendings. */
 }
 
 void
-mac_intr_do_pending_int()
+macintr_do_pending_int()
 {
 	struct cpu_info *ci = curcpu();
-	struct intrhand *ih;
-	int irq;
-	int pcpl;
-	int hwpend;
-	int s;
-
-	if (ci->ci_iactive)
-		return;
-
-	ci->ci_iactive = 1;
-	pcpl = splhigh();		/* Turn off all */
+	int pcpl = ci->ci_cpl; /* XXX */
+	int s, s2;
 	s = ppc_intr_disable();
-
-	hwpend = ci->ci_ipending & ~pcpl;	/* Do now unmasked pendings */
-	imen_m &= ~hwpend;
-	enable_irq(~imen_m);
-	hwpend &= HWIRQ_MASK;
-	while (hwpend) {
-		irq = 31 - cntlzw(hwpend);
-		hwpend &= ~(1L << irq);
-		ih = m_intrhand[irq];
-		while(ih) {
-			if ((*ih->ih_fun)(ih->ih_arg))
-				ih->ih_count.ec_count++;
-			ih = ih->ih_next;
-		}
+	if (ci->ci_iactive & CI_IACTIVE_PROCESSING_SOFT) {
+		ppc_intr_enable(s);
+		return;
 	}
-
-	/*out32rb(INT_ENABLE_REG, ~imen_m);*/
+	atomic_setbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_SOFT);
 
 	do {
-		if((ci->ci_ipending & SINT_CLOCK) & ~pcpl) {
-			ci->ci_ipending &= ~SINT_CLOCK;
-			softclock();
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) &&  (pcpl < IPL_SOFTTTY)) {
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY);
+			s2 = ci->ci_cpl;
+			ci->ci_cpl = IPL_SOFTTTY;
+			ppc_intr_enable(1);
+			KERNEL_LOCK();
+			softtty();
+			KERNEL_UNLOCK();
+			ppc_intr_disable();
+			ci->ci_cpl = pcpl;
+			continue;
 		}
-		if((ci->ci_ipending & SINT_NET) & ~pcpl) {
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) &&  (pcpl < IPL_SOFTNET)) {
 			extern int netisr;
 			int pisr;
 
-			ci->ci_ipending &= ~SINT_NET;
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET);
 			while ((pisr = netisr) != 0) {
 				atomic_clearbits_int(&netisr, pisr);
+				ci->ci_cpl = IPL_SOFTNET;
+				ppc_intr_enable(1);
+				KERNEL_LOCK();
 				softnet(pisr);
+				KERNEL_UNLOCK();
+				ppc_intr_disable();
+				ci->ci_cpl = pcpl;
 			}
+			continue;
 		}
-		if((ci->ci_ipending & SINT_TTY) & ~pcpl) {
-			ci->ci_ipending &= ~SINT_TTY;
-			softtty();
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) && (pcpl < IPL_SOFTCLOCK)) {
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK);
+			ci->ci_cpl = IPL_SOFTCLOCK;
+			ppc_intr_enable(1);
+			KERNEL_LOCK();
+			softclock();
+			KERNEL_UNLOCK();
+			ppc_intr_disable();
+			ci->ci_cpl = pcpl;
+			continue;
 		}
-	} while ((ci->ci_ipending & SINT_MASK) & ~pcpl);
-	ci->ci_ipending &= pcpl;
-	ci->ci_cpl = pcpl;	/* Don't use splx... we are here already! */
-	ppc_intr_enable(s);
-	ci->ci_iactive = 0;
+	} while (ci->ci_ipending & ppc_smask[pcpl]);
+	macintr_setipl(pcpl);
+	atomic_clearbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_SOFT);
 }
 
-static int
-read_irq()
+void
+macintr_eoi(int irq)
 {
-	int rv = 0;
-	int state0, state1, p;
-	int state0save, state1save;
+	u_int32_t state0, state1;
 
-	state0 = in32rb(INT_STATE_REG0);
-	if (state0)
+	if (irq < 32) {
+		state0 =  1 << irq;
 		out32rb(INT_CLEAR_REG0, state0);
-	state0save = state0;
-	while (state0) {
-		p = 31 - cntlzw(state0);
-		rv |= 1 << m_virq[p];
-		state0 &= ~(1 << p);
+	} else {
+		if (heathrow_FCR) {		/* has heathrow? */
+			state1 = 1 << (irq - 32);
+			out32rb(INT_CLEAR_REG1, state1);
+		}
 	}
+}
+
+int
+macintr_read_irq()
+{
+	struct cpu_info *ci = curcpu();
+	u_int32_t state0, state1, irq_mask;
+	int ipl, irq;
+
+	state0 = in32rb(INT_STATE_REG0);
 
 	if (heathrow_FCR)			/* has heathrow? */
 		state1 = in32rb(INT_STATE_REG1);
 	else
 		state1 = 0;
 
-	if (state1)
-		out32rb(INT_CLEAR_REG1, state1);
-	state1save = state1;
-	while (state1) {
-		p = 31 - cntlzw(state1);
-		rv |= 1 << m_virq[p + 32];
-		state1 &= ~(1 << p);
+	for (ipl = IPL_HIGH; ipl >= ci->ci_cpl; ipl --) {
+		irq_mask = state0 & macintr_ienable_l[ipl];
+		if (irq_mask) {
+			irq = ffs(irq_mask) - 1;
+			return irq;
+		}
+		irq_mask = state1 & macintr_ienable_h[ipl];
+		if (irq_mask) {
+			irq = ffs(irq_mask) + 31;
+			return irq;
+		}
 	}
-#if 0
-printf("mac_intr int_stat 0:%x 1:%x\n", state0save, state1save);
-#endif
-
-	/* 1 << 0 is invalid. */
-	return rv & ~1;
+	return 255;
 }
Index: arch/macppc/dev/openpic.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/dev/openpic.c,v
retrieving revision 1.45
diff -u -r1.45 openpic.c
--- arch/macppc/dev/openpic.c	4 May 2008 20:54:22 -0000	1.45
+++ arch/macppc/dev/openpic.c	20 May 2008 23:23:49 -0000
@@ -1,6 +1,7 @@
 /*	$OpenBSD: openpic.c,v 1.45 2008/05/04 20:54:22 drahn Exp $	*/
 
 /*-
+ * Copyright (c) 2008 Dale Rahn <drahn@openbsd.org>
  * Copyright (c) 1995 Per Fogelstrom
  * Copyright (c) 1993, 1994 Charles M. Hannum.
  * Copyright (c) 1990 The Regents of the University of California.
@@ -56,36 +57,37 @@
 #include <dev/ofw/openfirm.h>
 
 #define ICU_LEN 128
+int openpic_numirq = ICU_LEN;
 #define LEGAL_IRQ(x) ((x >= 0) && (x < ICU_LEN))
 
-int o_intrtype[ICU_LEN], o_intrmaxlvl[ICU_LEN];
-struct intrhand *o_intrhand[ICU_LEN] = { 0 };
-int o_hwirq[ICU_LEN], o_virq[ICU_LEN];
-int o_virq_max;
+int openpic_pri_share[IPL_NUM];
+
+struct intrq openpic_handler[ICU_LEN];
 
-static int fakeintr(void *);
-static char *intr_typename(int type);
 void openpic_calc_mask(void);
-static __inline int cntlzw(int x);
-static int mapirq(int irq);
 int openpic_prog_button(void *arg);
-void openpic_enable_irq_mask(int irq_mask);
 
-#define HWIRQ_MAX 27
-#define HWIRQ_MASK 0x0fffffff
+ppc_splraise_t openpic_splraise;
+ppc_spllower_t openpic_spllower;
+ppc_splx_t openpic_splx;
 
 /* IRQ vector used for inter-processor interrupts. */
 #define IPI_VECTOR	64
 
-static __inline u_int openpic_read(int);
-static __inline void openpic_write(int, u_int);
-void openpic_set_enable_irq(int, int);
-void openpic_enable_irq(int);
-void openpic_disable_irq(int);
-void openpic_init(void);
-void openpic_set_priority(int, int);
-static __inline int openpic_read_irq(int);
-static __inline void openpic_eoi(int);
+void	openpic_enable_irq(int, int);
+void	openpic_disable_irq(int);
+void	openpic_init(void);
+void	openpic_set_priority(int);
+
+typedef void  (void_f) (void);
+extern void_f *pending_int_f;
+
+vaddr_t openpic_base;
+void *	openpic_intr_establish( void * lcv, int irq, int type, int level,
+    int (*ih_fun)(void *), void *ih_arg, char *name);
+void	openpic_intr_disestablish( void *lcp, void *arg);
+void	openpic_collect_preconf_intr(void);
+int	openpic_big_endian;
 
 struct openpic_softc {
 	struct device sc_dev;
@@ -95,7 +97,7 @@
 void	openpic_attach(struct device *, struct device *, void *);
 void	openpic_do_pending_int(void);
 void	openpic_collect_preconf_intr(void);
-void	ext_intr_openpic(void);
+void	openpic_ext_intr(void);
 
 struct cfattach openpic_ca = {
 	sizeof(struct openpic_softc),
@@ -107,6 +109,41 @@
 	NULL, "openpic", DV_DULL
 };
 
+static inline u_int
+openpic_read(int reg)
+{
+	char *addr = (void *)(openpic_base + reg);
+
+	if (openpic_big_endian)
+		return in32(addr);
+	else
+		return in32rb(addr);
+}
+
+static inline void
+openpic_write(int reg, u_int val)
+{
+	char *addr = (void *)(openpic_base + reg);
+
+	if (openpic_big_endian)
+		out32(addr, val);
+	else
+		out32rb(addr, val);
+}
+
+static inline int
+openpic_read_irq(int cpu)
+{
+	return openpic_read(OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK;
+}
+
+static inline void
+openpic_eoi(int cpu)
+{
+	openpic_write(OPENPIC_EOI(cpu), 0);
+	openpic_read(OPENPIC_EOI(cpu));
+}
+
 int
 openpic_match(struct device *parent, void *cf, void *aux)
 {
@@ -134,19 +171,10 @@
 	return 1;
 }
 
-typedef void  (void_f) (void);
-extern void_f *pending_int_f;
-
-vaddr_t openpic_base;
-void * openpic_intr_establish( void * lcv, int irq, int type, int level,
-	int (*ih_fun)(void *), void *ih_arg, char *name);
-void openpic_intr_disestablish( void *lcp, void *arg);
-void openpic_collect_preconf_intr(void);
-int openpic_big_endian;
-
 void
 openpic_attach(struct device *parent, struct device  *self, void *aux)
 {
+	struct cpu_info *ci = curcpu();
 	struct confargs *ca = aux;
 	extern intr_establish_t *intr_establish_func;
 	extern intr_disestablish_t *intr_disestablish_func;
@@ -161,7 +189,12 @@
 	openpic_base = (vaddr_t) mapiodev (ca->ca_baseaddr +
 			ca->ca_reg[0], 0x40000);
 
-	printf(": version 0x%x %s endian", openpic_read(OPENPIC_VENDOR_ID),
+	/* openpic may support more than 128 interupts but driver doesn't */
+	openpic_numirq = ((openpic_read(OPENPIC_FEATURE) >> 16) & 0x7f)+1;
+
+	printf(": version 0x%x feature %x %s endian",
+	    openpic_read(OPENPIC_VENDOR_ID),
+	    openpic_read(OPENPIC_FEATURE),
 		openpic_big_endian ? "big" : "little" );
 
 	openpic_init();
@@ -171,21 +204,74 @@
 	intr_disestablish_func  = openpic_intr_disestablish;
 	mac_intr_establish_func  = openpic_intr_establish;
 	mac_intr_disestablish_func  = openpic_intr_disestablish;
-	install_extint(ext_intr_openpic);
 
-#if 1
+	ppc_smask_init();
+
 	openpic_collect_preconf_intr();
-#endif
 
 #if 1
 	mac_intr_establish(parent, 0x37, IST_LEVEL,
 		IPL_HIGH, openpic_prog_button, (void *)0x37, "progbutton");
 #endif
+	ppc_intr_func.raise = openpic_splraise;
+	ppc_intr_func.lower = openpic_spllower;
+	ppc_intr_func.x = openpic_splx;
+
+	openpic_set_priority(ci->ci_cpl);
+
 	ppc_intr_enable(1);
 
 	printf("\n");
 }
 
+static inline void
+openpic_setipl(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	int s;
+	/* XXX - try do to this without the disable */
+	s = ppc_intr_disable();
+	ci->ci_cpl = newcpl;
+	openpic_set_priority(newcpl);
+	ppc_intr_enable(s);
+}
+
+int
+openpic_splraise(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	newcpl = openpic_pri_share[newcpl];
+	int ocpl = ci->ci_cpl;
+	if (ocpl > newcpl)
+		newcpl = ocpl;
+
+	openpic_setipl(newcpl);
+
+	return ocpl;
+}
+
+int
+openpic_spllower(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+	int ocpl = ci->ci_cpl;
+
+	openpic_splx(newcpl);
+
+	return ocpl;
+}
+
+void
+openpic_splx(int newcpl)
+{
+	struct cpu_info *ci = curcpu();
+
+	openpic_setipl(newcpl);
+
+	if (ci->ci_ipending & ppc_smask[newcpl]);
+		openpic_do_pending_int();
+}
+
 void
 openpic_collect_preconf_intr()
 {
@@ -204,13 +290,6 @@
 	}
 }
 
-static int
-fakeintr(void *arg)
-{
-
-	return 0;
-}
-
 /*
  * Register an interrupt handler.
  */
@@ -218,74 +297,52 @@
 openpic_intr_establish(void *lcv, int irq, int type, int level,
     int (*ih_fun)(void *), void *ih_arg, char *name)
 {
-	struct intrhand **p, *q, *ih;
-	static struct intrhand fakehand;
-
-	fakehand.ih_next = NULL;
-	fakehand.ih_fun  = fakeintr;
-
-#if 0
-printf("mac_intr_establish, hI %d L %d ", irq, type);
-#endif
-
-	irq = mapirq(irq);
-#if 0
-printf("vI %d ", irq);
-#endif
+	struct intrhand *ih;
+	struct intrq *iq;
+	int s;
 
 	/* 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");
+	iq = &openpic_handler[irq];
 
 	if (!LEGAL_IRQ(irq) || type == IST_NONE)
 		panic("intr_establish: bogus irq or type");
 
-	switch (o_intrtype[irq]) {
+	switch (iq->iq_ist) {
 	case IST_NONE:
-		o_intrtype[irq] = type;
+		iq->iq_ist = type;
 		break;
 	case IST_EDGE:
 	case IST_LEVEL:
-		if (type == o_intrtype[irq])
+		if (type == iq->iq_ist)
 			break;
 	case IST_PULSE:
 		if (type != IST_NONE)
 			panic("intr_establish: can't share %s with %s",
-			    intr_typename(o_intrtype[irq]),
-			    intr_typename(type));
+			    ppc_intr_typename(iq->iq_ist),
+			    ppc_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 = &o_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
-		;
+	ih->ih_fun = ih_fun;
+	ih->ih_arg = ih_arg;
+	ih->ih_level = level;
+	ih->ih_irq = irq;
+
+	evcount_attach(&ih->ih_count, name, (void *)&ih->ih_irq,
+	    &evcount_intr);
 
 	/*
-	 * 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.
+	 * Append handler to end of list
 	 */
-	fakehand.ih_level = level;
-	*p = &fakehand;
+	s = ppc_intr_disable();
 
+	TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
 	openpic_calc_mask();
 
-	/*
-	 * Poke the real handler in now.
-	 */
-	ih->ih_fun = ih_fun;
-	ih->ih_arg = ih_arg;
-	ih->ih_next = NULL;
-	ih->ih_level = level;
-	ih->ih_irq = irq;
-	evcount_attach(&ih->ih_count, name, (void *)&o_hwirq[irq],
-	    &evcount_intr);
-	*p = ih;
+	ppc_intr_enable(s);
 
 	return (ih);
 }
@@ -298,51 +355,27 @@
 {
 	struct intrhand *ih = arg;
 	int irq = ih->ih_irq;
-	struct intrhand **p, *q;
+	struct intrq *iq = &openpic_handler[irq];
+	int s;
 
 	if (!LEGAL_IRQ(irq))
 		panic("intr_disestablish: bogus irq");
 
 	/*
 	 * Remove the handler from the chain.
-	 * This is O(n^2), too.
 	 */
-	for (p = &o_intrhand[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
-		;
-	if (q)
-		*p = q->ih_next;
-	else
-		panic("intr_disestablish: handler not registered");
-
-	evcount_detach(&ih->ih_count);
-	free((void *)ih, M_DEVBUF);
+	s = ppc_intr_disable();
 
+	TAILQ_REMOVE(&iq->iq_list, ih, ih_list);
 	openpic_calc_mask();
 
-	if (o_intrhand[irq] == NULL)
-		o_intrtype[irq] = IST_NONE;
-}
-
+	ppc_intr_enable(s);
 
-static char *
-intr_typename(int type)
-{
+	evcount_detach(&ih->ih_count);
+	free((void *)ih, M_DEVBUF);
 
-	switch (type) {
-	case IST_NONE:
-		return ("none");
-	case IST_PULSE:
-		return ("pulsed");
-	case IST_EDGE:
-		return ("edge-triggered");
-	case IST_LEVEL:
-		return ("level-triggered");
-	default:
-		panic("intr_typename: invalid type %d", type);
-#if 1 /* XXX */
-		return ("unknown");
-#endif
-	}
+	if (TAILQ_EMPTY(&iq->iq_list))
+		iq->iq_ist = IST_NONE;
 }
 
 /*
@@ -355,99 +388,46 @@
 void
 openpic_calc_mask()
 {
+	struct cpu_info *ci = curcpu();
 	int irq;
 	struct intrhand *ih;
 	int i;
 
 	/* disable all openpic interrupts */
-	openpic_set_priority(0, 15);
+	openpic_set_priority(15);
 
-	for (irq = 0; irq < ICU_LEN; irq++) {
-		int max = IPL_NONE;
-		int min = IPL_HIGH;
-		int reg;
-		if (o_virq[irq] != 0) {
-			for (ih = o_intrhand[o_virq[irq]]; ih;
-			    ih = ih->ih_next) {
-				if (ih->ih_level > max)
-					max = ih->ih_level;
-				if (ih->ih_level < min)
-					min = ih->ih_level;
-			}
-		}
-
-		o_intrmaxlvl[irq] = max;
+	for (i = IPL_NONE; i < IPL_NUM; i++) {
+		openpic_pri_share[i] = i;
+	}
 
-		/* adjust priority if it changes */
-		reg = openpic_read(OPENPIC_SRC_VECTOR(irq));
-		if (max != ((reg >> OPENPIC_PRIORITY_SHIFT) & 0xf)) {
-			openpic_write(OPENPIC_SRC_VECTOR(irq),
-				(reg & ~(0xf << OPENPIC_PRIORITY_SHIFT)) |
-				(max << OPENPIC_PRIORITY_SHIFT) );
+	for (irq = 0; irq < openpic_numirq; irq++) {
+		int maxipl = IPL_NONE;
+		int minipl = IPL_HIGH;
+		struct intrq *iq = &openpic_handler[irq];
+
+		TAILQ_FOREACH(ih, &iq->iq_list, ih_list) {
+			if (ih->ih_level > maxipl)
+				maxipl = ih->ih_level;
+			if (ih->ih_level < minipl)
+				minipl = ih->ih_level;
 		}
 
-		if (max == IPL_NONE)
-			min = IPL_NONE; /* Interrupt not enabled */
+		if (maxipl == IPL_NONE) {
+			minipl = IPL_NONE; /* Interrupt not enabled */
 
-		if (o_virq[irq] != 0) {
-			/* Enable (dont mask) interrupts at lower levels */ 
-			for (i = IPL_NONE; i < min; i++)
-				imask[i] &= ~(1 << o_virq[irq]);
-			for (; i <= IPL_HIGH; i++)
-				imask[i] |= (1 << o_virq[irq]);
+			openpic_disable_irq(irq);
+		} else {
+			for (i = minipl; i <= maxipl; i++) {
+				openpic_pri_share[i] = maxipl;
+			}
+			openpic_enable_irq(irq, maxipl);
 		}
-	}
-
-	/* restore interrupts */
-	openpic_set_priority(0, 0);
 
-	for (i = IPL_NONE; i <= IPL_HIGH; i++) {
-		if (i > IPL_NONE)
-			imask[i] |= SINT_MASK;
+		iq->iq_ipl = maxipl;
 	}
-	imask[IPL_HIGH] = 0xffffffff;
-}
 
-/*
- * Map 64 irqs into 32 (bits).
- */
-static int
-mapirq(int irq)
-{
-	int v;
-
-	/* irq in table already? */
-	if (o_virq[irq] != 0)
-		return o_virq[irq];
-
-	if (irq < 0 || irq >= ICU_LEN)
-		panic("invalid irq %d", irq);
-
-	o_virq_max++;
-	v = o_virq_max;
-	if (v > HWIRQ_MAX)
-		panic("virq overflow");
-
-	o_hwirq[v] = irq;
-	o_virq[irq] = v;
-#if 0
-printf("\nmapirq %x to %x\n", irq, v);
-#endif
-
-	return v;
-}
-
-/*
- * Count leading zeros.
- */
-static __inline int
-cntlzw(int x)
-{
-	int a;
-
-	__asm __volatile ("cntlzw %0,%1" : "=r"(a) : "r"(x));
-
-	return a;
+	/* restore interrupts */
+	openpic_set_priority(ci->ci_cpl);
 }
 
 void openpic_do_pending_softint(int pcpl);
@@ -456,167 +436,84 @@
 openpic_do_pending_int()
 {
 	struct cpu_info *ci = curcpu();
-	struct intrhand *ih;
-	int irq;
-	int pcpl;
-	int hwpend;
-	int pri, pripending;
+	int pcpl = ci->ci_cpl; /* XXX */
 	int s;
+	int s2;
 
-	if (ci->ci_iactive & CI_IACTIVE_PROCESSING_HARD)
-		return;
-
-	atomic_setbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_HARD);
 	s = ppc_intr_disable();
-	pcpl = ci->ci_cpl;
-
-	hwpend = ci->ci_ipending & ~pcpl;	/* Do now unmasked pendings */
-	hwpend &= HWIRQ_MASK;
-	while (hwpend) {
-		/* this still doesn't handle the interrupts in priority order */
-		for (pri = IPL_HIGH; pri >= IPL_NONE; pri--) {
-			pripending = hwpend & ~imask[pri];
-			irq = 31 - cntlzw(pripending);
-			ci->ci_ipending &= ~(1L << irq);
-			ci->ci_cpl = imask[o_intrmaxlvl[o_hwirq[irq]]];
-			openpic_enable_irq_mask(~ci->ci_cpl);
-			ih = o_intrhand[irq];
-			while(ih) {
-				ppc_intr_enable(1);
-
-				KERNEL_LOCK();
-				if ((*ih->ih_fun)(ih->ih_arg))
-					ih->ih_count.ec_count++;
-				KERNEL_UNLOCK();
-
-				(void)ppc_intr_disable();
-				
-				ih = ih->ih_next;
-			}
-		}
-		hwpend = ci->ci_ipending & ~pcpl;/* Catch new pendings */
-		hwpend &= HWIRQ_MASK;
-	}
-	ci->ci_cpl = pcpl | SINT_MASK;
-	openpic_enable_irq_mask(~ci->ci_cpl);
-	atomic_clearbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_HARD);
-
-	openpic_do_pending_softint(pcpl);
-
-	ppc_intr_enable(s);
-}
-
-void
-openpic_do_pending_softint(int pcpl)
-{
-	struct cpu_info *ci = curcpu();
-
-	if (ci->ci_iactive & CI_IACTIVE_PROCESSING_SOFT)
+	if (ci->ci_iactive & CI_IACTIVE_PROCESSING_SOFT) {
+		ppc_intr_enable(s);
 		return;
+	}
 
 	atomic_setbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_SOFT);
 
 	do {
-		if((ci->ci_ipending & SINT_CLOCK) & ~pcpl) {
-			ci->ci_ipending &= ~SINT_CLOCK;
-			ci->ci_cpl = SINT_CLOCK|SINT_NET|SINT_TTY;
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTTTY)) && (pcpl < IPL_SOFTTTY)) {
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTTTY);
+
+			s2 = ci->ci_cpl;
+			openpic_setipl(IPL_SOFTTTY);
 			ppc_intr_enable(1);
 			KERNEL_LOCK();
-			softclock();
+			softtty();
 			KERNEL_UNLOCK();
 			ppc_intr_disable();
+			openpic_setipl(s2);
 			continue;
 		}
-		if((ci->ci_ipending & SINT_NET) & ~pcpl) {
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTNET)) && (pcpl < IPL_SOFTNET)) {
 			extern int netisr;
 			int pisr;
-		       
-			ci->ci_ipending &= ~SINT_NET;
-			ci->ci_cpl = SINT_NET|SINT_TTY;
+
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTNET);
+			splraise(IPL_SOFTNET);
 			while ((pisr = netisr) != 0) {
 				atomic_clearbits_int(&netisr, pisr);
+				s2 = ci->ci_cpl;
+				openpic_setipl(IPL_SOFTNET);
 				ppc_intr_enable(1);
 				KERNEL_LOCK();
 				softnet(pisr);
 				KERNEL_UNLOCK();
 				ppc_intr_disable();
+				openpic_setipl(s2);
 			}
 			continue;
 		}
-		if((ci->ci_ipending & SINT_TTY) & ~pcpl) {
-			ci->ci_ipending &= ~SINT_TTY;
-			ci->ci_cpl = SINT_TTY;
+		if((ci->ci_ipending & SI_TO_IRQBIT(SI_SOFTCLOCK)) && (pcpl < IPL_SOFTCLOCK)) {
+			ci->ci_ipending &= ~SI_TO_IRQBIT(SI_SOFTCLOCK);
+			s2 = ci->ci_cpl;
+			openpic_setipl(IPL_SOFTCLOCK);
 			ppc_intr_enable(1);
 			KERNEL_LOCK();
-			softtty();
+			softclock();
 			KERNEL_UNLOCK();
 			ppc_intr_disable();
+			openpic_setipl(s2);
 			continue;
 		}
-	} while ((ci->ci_ipending & SINT_MASK) & ~pcpl);
-	ci->ci_cpl = pcpl;	/* Don't use splx... we are here already! */
+		break;
+	} while (ci->ci_ipending & ppc_smask[pcpl]);
+	openpic_setipl(pcpl);	/* Don't use splx... we are here already! */
 
 	atomic_clearbits_int(&ci->ci_iactive, CI_IACTIVE_PROCESSING_SOFT);
+	ppc_intr_enable(s);
 }
 
-u_int
-openpic_read(int reg)
-{
-	char *addr = (void *)(openpic_base + reg);
-
-	if (openpic_big_endian)
-		return in32(addr);
-	else
-		return in32rb(addr);
-}
-
-void
-openpic_write(int reg, u_int val)
-{
-	char *addr = (void *)(openpic_base + reg);
-
-	if (openpic_big_endian)
-		out32(addr, val);
-	else
-		out32rb(addr, val);
-}
-
-void
-openpic_enable_irq_mask(int irq_mask)
-{
-	int irq;
-	for ( irq = 0; irq <= o_virq_max; irq++) {
-		if (irq_mask & (1 << irq))
-			openpic_enable_irq(o_hwirq[irq]);
-		else
-			openpic_disable_irq(o_hwirq[irq]);
-	}
-}
-
-void
-openpic_set_enable_irq(int irq, int type)
-{
-	u_int x;
-
-	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
-	x &= ~(OPENPIC_IMASK|OPENPIC_SENSE_LEVEL|OPENPIC_SENSE_EDGE);
-	if (type == IST_LEVEL)
-		x |= OPENPIC_SENSE_LEVEL;
-	else
-		x |= OPENPIC_SENSE_EDGE;
-	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
-}
 void
-openpic_enable_irq(int irq)
+openpic_enable_irq(int irq, int pri)
 {
 	u_int x;
+	struct intrq *iq = &openpic_handler[irq];
 
-	x = openpic_read(OPENPIC_SRC_VECTOR(irq));
-	x &= ~(OPENPIC_IMASK|OPENPIC_SENSE_LEVEL|OPENPIC_SENSE_EDGE);
-	if (o_intrtype[o_virq[irq]] == IST_LEVEL)
+	x = irq;
+	if (iq->iq_ist == IST_LEVEL)
 		x |= OPENPIC_SENSE_LEVEL;
 	else
 		x |= OPENPIC_SENSE_EDGE;
+	x |= OPENPIC_POLARITY_POSITIVE;
+	x |= pri << OPENPIC_PRIORITY_SHIFT;
 	openpic_write(OPENPIC_SRC_VECTOR(irq), x);
 }
 
@@ -631,27 +528,10 @@
 }
 
 void
-openpic_set_priority(int cpu, int pri)
+openpic_set_priority(int pri)
 {
-	u_int x;
-
-	x = openpic_read(OPENPIC_CPU_PRIORITY(cpu));
-	x &= ~OPENPIC_CPU_PRIORITY_MASK;
-	x |= pri;
-	openpic_write(OPENPIC_CPU_PRIORITY(cpu), x);
-}
-
-int
-openpic_read_irq(int cpu)
-{
-	return openpic_read(OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK;
-}
-
-void
-openpic_eoi(int cpu)
-{
-	openpic_write(OPENPIC_EOI(cpu), 0);
-	openpic_read(OPENPIC_EOI(cpu));
+	struct cpu_info *ci = curcpu();
+	openpic_write(OPENPIC_CPU_PRIORITY(ci->ci_cpuid), pri);
 }
 
 #ifdef MULTIPROCESSOR
@@ -665,64 +545,51 @@
 #endif
 
 void
-ext_intr_openpic()
+openpic_ext_intr()
 {
 	struct cpu_info *ci = curcpu();
-	int irq, realirq;
-	int r_imen;
-	int pcpl, ocpl;
+	int irq;
+	int pcpl;
 	struct intrhand *ih;
+	struct intrq *iq;
 
 	pcpl = ci->ci_cpl;
 
-	realirq = openpic_read_irq(ci->ci_cpuid);
+	irq = openpic_read_irq(ci->ci_cpuid);
 
-	while (realirq != 255) {
+	while (irq != 255) {
 #ifdef MULTIPROCESSOR
-		if (realirq == IPI_VECTOR) {
+		if (irq == IPI_VECTOR) {
 			openpic_eoi(ci->ci_cpuid);
-			realirq = openpic_read_irq(ci->ci_cpuid);
+			irq = openpic_read_irq(ci->ci_cpuid);
 			continue;
 		}
 #endif
+		iq = &openpic_handler[irq];
 
-		irq = o_virq[realirq];
-
-		/* XXX check range */
+		if (iq->iq_ipl <= ci->ci_cpl)
+			printf("invalid interrupt %d lvl %d at %d hw %d\n",
+			    irq, iq->iq_ipl, ci->ci_cpl,
+			    openpic_read(OPENPIC_CPU_PRIORITY(ci->ci_cpuid)));
+		splraise(iq->iq_ipl);
+		openpic_eoi(ci->ci_cpuid);
 
-		r_imen = 1 << irq;
-
-		if ((pcpl & r_imen) != 0) {
-			/* Masked! Mark this as pending. */
-			ci->ci_ipending |= r_imen;
-			openpic_enable_irq_mask(~imask[o_intrmaxlvl[realirq]]);
-			openpic_eoi(ci->ci_cpuid);
-		} else {
-			openpic_enable_irq_mask(~imask[o_intrmaxlvl[realirq]]);
-			openpic_eoi(ci->ci_cpuid);
-			ocpl = splraise(imask[o_intrmaxlvl[realirq]]);
+		TAILQ_FOREACH(ih, &iq->iq_list, ih_list) {
+			ppc_intr_enable(1);
 
-			ih = o_intrhand[irq];
-			while (ih) {
-				ppc_intr_enable(1);
+			KERNEL_LOCK();
+			if ((*ih->ih_fun)(ih->ih_arg))
+				ih->ih_count.ec_count++;
+			KERNEL_UNLOCK();
 
-				KERNEL_LOCK();
-				if ((*ih->ih_fun)(ih->ih_arg))
-					ih->ih_count.ec_count++;
-				KERNEL_UNLOCK();
+			(void)ppc_intr_disable();
+		}
 
-				(void)ppc_intr_disable();
-				ih = ih->ih_next;
-			}
+		uvmexp.intrs++;
 
-			uvmexp.intrs++;
-			__asm__ volatile("":::"memory"); /* don't reorder.... */
-			ci->ci_cpl = ocpl;
-			__asm__ volatile("":::"memory"); /* don't reorder.... */
-			openpic_enable_irq_mask(~pcpl);
-		}
+		openpic_setipl(pcpl);
 
-		realirq = openpic_read_irq(ci->ci_cpuid);
+		irq = openpic_read_irq(ci->ci_cpuid);
 	}
 	ppc_intr_enable(1);
 
@@ -732,22 +599,35 @@
 void
 openpic_init()
 {
+	struct cpu_info *ci = curcpu();
+	struct intrq *iq;
 	int irq;
 	u_int x;
+	int i;
+
+	openpic_set_priority(15);
 
 	/* disable all interrupts */
-	for (irq = 0; irq < 255; irq++)
+	for (irq = 0; irq < openpic_numirq; irq++)
 		openpic_write(OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK);
-	openpic_set_priority(0, 15);
+
+	for (i = 0; i < openpic_numirq; i++) {
+		iq = &openpic_handler[i];
+		TAILQ_INIT(&iq->iq_list);
+	}
 
 	/* we don't need 8259 pass through mode */
 	x = openpic_read(OPENPIC_CONFIG);
 	x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE;
 	openpic_write(OPENPIC_CONFIG, x);
 
-	/* send all interrupts to cpu 0 */
-	for (irq = 0; irq < ICU_LEN; irq++)
-		openpic_write(OPENPIC_IDEST(irq), 1 << 0);
+	/* clear all pending interrunts */
+	for (irq = 0; irq < ICU_LEN; irq++) {
+		openpic_read_irq(ci->ci_cpuid);
+		openpic_eoi(ci->ci_cpuid);
+	}
+
+	/* initialize all vectors to something sane */
 	for (irq = 0; irq < ICU_LEN; irq++) {
 		x = irq;
 		x |= OPENPIC_IMASK;
@@ -757,6 +637,10 @@
 		openpic_write(OPENPIC_SRC_VECTOR(irq), x);
 	}
 
+	/* send all interrupts to cpu 0 */
+	for (irq = 0; irq < openpic_numirq; irq++)
+		openpic_write(OPENPIC_IDEST(irq), 1 << 0);
+
 #ifdef MULTIPROCESSOR
 	/* Set up inter-processor interrupts. */
 	x = openpic_read(OPENPIC_IPI_VECTOR(0));
@@ -765,21 +649,15 @@
 	openpic_write(OPENPIC_IPI_VECTOR(0), x);
 #endif
 
-	/* XXX set spurious intr vector */
-
-	openpic_set_priority(0, 0);
-
-	/* clear all pending interrunts */
-	for (irq = 0; irq < ICU_LEN; irq++) {
-		openpic_read_irq(0);
-		openpic_eoi(0);
-	}
+#if 0
+	openpic_write(OPENPIC_SPURIOUS_VECTOR, 255);
+#endif
 
-	for (irq = 0; irq < ICU_LEN; irq++)
-		openpic_disable_irq(irq);
+	install_extint(openpic_ext_intr);
 
-	install_extint(ext_intr_openpic);
+	openpic_set_priority(0);
 }
+
 /*
  * programmer_button function to fix args to Debugger.
  * deal with any enables/disables, if necessary.
Index: arch/macppc/include/intr.h
===================================================================
RCS file: /cvs/src/sys/arch/macppc/include/intr.h,v
retrieving revision 1.3
diff -u -r1.3 intr.h
--- arch/macppc/include/intr.h	1 May 2008 08:25:32 -0000	1.3
+++ arch/macppc/include/intr.h	20 May 2008 23:23:49 -0000
@@ -6,5 +6,5 @@
 void softtty(void);
 
 void openpic_send_ipi(int);
-void openpic_set_priority(int, int);
+void openpic_set_priority(int);
 #endif
Index: arch/macppc/macppc/clock.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/clock.c,v
retrieving revision 1.22
diff -u -r1.22 clock.c
--- arch/macppc/macppc/clock.c	30 Apr 2008 17:59:33 -0000	1.22
+++ arch/macppc/macppc/clock.c	20 May 2008 23:23:49 -0000
@@ -225,7 +225,7 @@
 	 */
 	ppc_mtdec(nextevent - tb);
 
-	if (curcpu()->ci_cpl & SPL_CLOCK) {
+	if (ci->ci_cpl >= IPL_CLOCK) {
 		ci->ci_statspending += nstats;
 	} else {
 		KERNEL_LOCK();
Index: arch/macppc/macppc/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/cpu.c,v
retrieving revision 1.57
diff -u -r1.57 cpu.c
--- arch/macppc/macppc/cpu.c	2 May 2008 19:10:01 -0000	1.57
+++ arch/macppc/macppc/cpu.c	20 May 2008 23:23:50 -0000
@@ -788,7 +788,7 @@
 	ppc_intr_enable(intrstate);
 
 	/* Enable inter-processor interrupts. */
-	openpic_set_priority(curcpu()->ci_cpuid, 14);
+	openpic_set_priority(14);
 
 	SCHED_LOCK(s);
 	cpu_switchto(NULL, sched_chooseproc());
Index: arch/macppc/macppc/genassym.cf
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/genassym.cf,v
retrieving revision 1.17
diff -u -r1.17 genassym.cf
--- arch/macppc/macppc/genassym.cf	27 Apr 2008 15:59:49 -0000	1.17
+++ arch/macppc/macppc/genassym.cf	20 May 2008 23:23:50 -0000
@@ -86,7 +86,6 @@
 member	ci_curpcb
 member	ci_curpm
 member	ci_want_resched
-member	ci_cpl
 member	ci_intrdepth
 member	ci_intstk
 member	ci_tempsave
Index: arch/macppc/macppc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v
retrieving revision 1.98
diff -u -r1.98 machdep.c
--- arch/macppc/macppc/machdep.c	1 May 2008 08:25:32 -0000	1.98
+++ arch/macppc/macppc/machdep.c	20 May 2008 23:23:50 -0000
@@ -871,8 +871,6 @@
 
 }
 
-int imask[IPL_NUM];
-
 /*
  * this is a hack interface to allow zs to work better until
  * a true soft interrupt mechanism is created.
Dale Rahn				drahn@dalerahn.com
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
MacPPC interrupt controller change testing, Dale Rahn, (Tue May 20, 7:26 pm)
speck-geostationary