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 <[EMAIL PROTECTED]>
  * 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 <[EMAIL PROTECTED]>
  * 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                               [EMAIL PROTECTED]

Reply via email to