Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/powerpc Change from level to ipl since we aren't de...



details:   https://anonhg.NetBSD.org/src/rev/c8f3f4dae765
branches:  trunk
changeset: 766153:c8f3f4dae765
user:      matt <matt%NetBSD.org@localhost>
date:      Fri Jun 17 05:15:22 2011 +0000

description:
Change from level to ipl since we aren't dealing a mask anymore, just a
simple value.
Fix intr_calculatemasks to deal with ipl isn't a mask.  Let establish
and disestablish determine the highest ipl for the interrut source being
modified.  No reason to recompute that for every source when only one changes
at a time.  Only change idepth while in the loop.

diffstat:

 sys/arch/powerpc/include/intr.h |    6 +-
 sys/arch/powerpc/pic/intr.c     |  175 +++++++++++++++++----------------------
 sys/arch/powerpc/pic/picvar.h   |    6 +-
 3 files changed, 83 insertions(+), 104 deletions(-)

diffs (truncated from 398 to 300 lines):

diff -r 15410930a232 -r c8f3f4dae765 sys/arch/powerpc/include/intr.h
--- a/sys/arch/powerpc/include/intr.h   Fri Jun 17 05:11:48 2011 +0000
+++ b/sys/arch/powerpc/include/intr.h   Fri Jun 17 05:15:22 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.h,v 1.6 2011/06/16 02:43:42 macallan Exp $ */
+/*     $NetBSD: intr.h,v 1.7 2011/06/17 05:15:22 matt Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -28,7 +28,7 @@
 
 #ifndef _LOCORE
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.6 2011/06/16 02:43:42 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.h,v 1.7 2011/06/17 05:15:22 matt Exp $");
 #endif
 
 #ifndef POWERPC_INTR_MACHDEP_H
@@ -73,7 +73,7 @@
        int     (*ih_fun)(void *);
        void    *ih_arg;
        struct  intrhand *ih_next;
-       int     ih_level;
+       int     ih_ipl;
        int     ih_irq;
 };
 
diff -r 15410930a232 -r c8f3f4dae765 sys/arch/powerpc/pic/intr.c
--- a/sys/arch/powerpc/pic/intr.c       Fri Jun 17 05:11:48 2011 +0000
+++ b/sys/arch/powerpc/pic/intr.c       Fri Jun 17 05:15:22 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.c,v 1.13 2011/06/16 04:37:48 matt Exp $ */
+/*     $NetBSD: intr.c,v 1.14 2011/06/17 05:15:23 matt Exp $ */
 
 /*-
  * Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.13 2011/06/16 04:37:48 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.14 2011/06/17 05:15:23 matt Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -75,9 +75,7 @@
 void
 pic_init(void)
 {
-       int i;
-
-       for (i = 0; i < NIRQ; i++)
+       for (u_int i = 0; i < NIRQ; i++)
                virq[i] = 0;
        memset(intrsources, 0, sizeof(intrsources));
 }
@@ -113,18 +111,12 @@
 static struct pic_ops *
 find_pic_by_irq(int irq)
 {
-       struct pic_ops *current;
-       int base = 0;
-
-       while (base < num_pics) {
-
-               current = pics[base];
-               if ((irq >= current->pic_intrbase) &&
-                   (irq < (current->pic_intrbase + current->pic_numintrs))) {
-
-                       return current;
+       for (u_int base = 0; base < num_pics; base++) {
+               struct pic_ops * const pic = pics[base];
+               if (pic->pic_intrbase <= irq
+                   && irq < pic->pic_intrbase + pic->pic_numintrs) {
+                       return pic;
                }
-               base++;
        }
        return NULL;
 }
@@ -140,17 +132,17 @@
  * Register an interrupt handler.
  */
 void *
-intr_establish(int hwirq, int type, int level, int (*ih_fun)(void *),
+intr_establish(int hwirq, int type, int ipl, int (*ih_fun)(void *),
     void *ih_arg)
 {
        struct intrhand **p, *q, *ih;
        struct intr_source *is;
        struct pic_ops *pic;
        static struct intrhand fakehand;
-       int irq, maxlevel = level;
+       int irq, maxipl = ipl;
 
-       if (maxlevel == IPL_NONE)
-               maxlevel = IPL_HIGH;
+       if (maxipl == IPL_NONE)
+               maxipl = IPL_HIGH;
 
        if (hwirq >= max_base) {
 
@@ -204,8 +196,7 @@
         * generally small.
         */
        for (p = &is->is_hand; (q = *p) != NULL; p = &q->ih_next) {
-
-               maxlevel = max(maxlevel, q->ih_level);
+               maxipl = max(maxipl, q->ih_ipl);
        }
 
        /*
@@ -213,7 +204,7 @@
         * this with interrupts enabled and don't want the real routine called
         * until masking is set up.
         */
-       fakehand.ih_level = level;
+       fakehand.ih_ipl = ipl;
        fakehand.ih_fun = fakeintr;
        *p = &fakehand;
 
@@ -223,13 +214,18 @@
        ih->ih_fun = ih_fun;
        ih->ih_arg = ih_arg;
        ih->ih_next = NULL;
-       ih->ih_level = level;
+       ih->ih_ipl = ipl;
        ih->ih_irq = irq;
        *p = ih;
 
        if (pic->pic_establish_irq != NULL)
                pic->pic_establish_irq(pic, hwirq - pic->pic_intrbase,
-                   is->is_type, maxlevel);
+                   is->is_type, maxipl);
+
+       /*
+        * Remember the highest IPL used by this handler.
+        */
+       is->is_ipl = maxipl;
 
        /*
         * now that the handler is established we're actually ready to
@@ -252,10 +248,11 @@
 void
 intr_disestablish(void *arg)
 {
-       struct intrhand *ih = arg;
-       int irq = ih->ih_irq;
-       struct intr_source *is = &intrsources[irq];
-       struct intrhand **p, *q;
+       struct intrhand * const ih = arg;
+       const int irq = ih->ih_irq;
+       struct intr_source * const is = &intrsources[irq];
+       struct intrhand **p, **q;
+       int maxipl = IPL_NONE;
 
        if (!LEGAL_VIRQ(irq))
                panic("intr_disestablish: bogus irq %d", irq);
@@ -264,14 +261,25 @@
         * Remove the handler from the chain.
         * This is O(n^2), too.
         */
-       for (p = &is->is_hand; (q = *p) != NULL && q != ih; p = &q->ih_next)
-               ;
+       for (p = &is->is_hand, q = NULL; (*p) != NULL; p = &(*p)->ih_next) {
+               struct intrhand * const tmp_ih = *p;
+               if (tmp_ih == ih) {
+                       q = p;
+               } else {
+                       maxipl = max(maxipl, tmp_ih->ih_ipl);
+               }
+       }
        if (q)
-               *p = q->ih_next;
+               *q = ih->ih_next;
        else
                panic("intr_disestablish: handler not registered");
        free((void *)ih, M_DEVBUF);
 
+       /*
+        * Reset the IPL for this source now that we've removed a handler.
+        */
+       is->is_ipl = maxipl;
+
        intr_calculatemasks();
 
        if (is->is_hand == NULL) {
@@ -336,88 +344,59 @@
 static void
 intr_calculatemasks(void)
 {
+       imask_t newmask[NIPL] = { [IPL_NONE...IPL_HIGH] = 0 };
        struct intr_source *is;
-       struct intrhand *q;
-       struct pic_ops *current;
-       int irq, level, i, base;
+       int irq;
 
-       /* First, figure out which levels each IRQ uses. */
-       for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) {
-               register int levels = 0;
-               for (q = is->is_hand; q; q = q->ih_next)
-                       levels |= 1 << q->ih_level;
-               is->is_level = levels;
+       for (u_int ipl = IPL_NONE; ipl < NIPL; ipl++) {
+               newmask[ipl] = 0;
        }
 
-       /* Then figure out which IRQs use each level. */
-       for (level = 0; level < NIPL; level++) {
-               register imask_t irqs = 0;
-               for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++)
-                       if (is->is_level & (1 << level))
-                               irqs |= 1ULL << irq;
-               imask[level] = irqs;
+       /* First, figure out which ipl each IRQ uses. */
+       for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) {
+               newmask[is->is_ipl] |= 1ULL << irq;
        }
 
        /*
         * IPL_NONE is used for hardware interrupts that are never blocked,
         * and do not block anything else.
         */
-       imask[IPL_NONE] = 0;
-
-#ifdef SLOPPY_IPLS
-       /*
-        * Enforce a sloppy hierarchy as in spl(9)
-        */
-       /* everything above softclock must block softclock */
-       for (i = IPL_SOFTCLOCK; i < NIPL; i++)
-               imask[i] |= imask[IPL_SOFTCLOCK];
-
-       /* everything above softnet must block softnet */
-       for (i = IPL_SOFTNET; i < NIPL; i++)
-               imask[i] |= imask[IPL_SOFTNET];
+       newmask[IPL_NONE] = 0;
 
-       /* IPL_TTY must block softserial */
-       imask[IPL_TTY] |= imask[IPL_SOFTSERIAL];
-
-       /* IPL_VM must block net, block IO and tty */
-       imask[IPL_VM] |= (imask[IPL_NET] | imask[IPL_BIO] | imask[IPL_TTY]);
-
-       /* IPL_SERIAL must block IPL_TTY */
-       imask[IPL_SERIAL] |= imask[IPL_TTY];
-
-       /* IPL_HIGH must block all other priority levels */
-       for (i = IPL_NONE; i < IPL_HIGH; i++)
-               imask[IPL_HIGH] |= imask[i];
-#else  /* !SLOPPY_IPLS */
        /*
         * strict hierarchy - all IPLs block everything blocked by any lower
         * IPL
         */
-       for (i = 1; i < NIPL; i++)
-               imask[i] |= imask[i - 1];
-#endif /* !SLOPPY_IPLS */
+       for (u_int ipl = 1; ipl < NIPL; ipl++) {
+               newmask[ipl] |= newmask[ipl - 1];
+       }
 
 #ifdef DEBUG_IPL
-       for (i = 0; i < NIPL; i++) {
-               printf("%2d: %08x\n", i, imask[i]);
+       for (u_int ipl = 0; ipl < NIPL; ipl++) {
+               printf("%u: %08x -> %08x\n", ipl, imask[ipl], newmask[ipl]);
        }
 #endif
 
-       /* And eventually calculate the complete masks. */
-       for (irq = 0, is = intrsources; irq < NVIRQ; irq++, is++) {
-               register imask_t irqs = 1ULL << irq;
-               for (q = is->is_hand; q; q = q->ih_next)
-                       irqs |= imask[q->ih_level];
-               is->is_mask = irqs;
+       /*
+        * Disable all interrupts.
+        */
+       for (u_int base = 0; base < num_pics; base++) {
+               struct pic_ops * const pic = pics[base];
+               for (u_int i = 0; i < pic->pic_numintrs; i++) {
+                       pic->pic_disable_irq(pic, i);
+               }
        }
 
-       /* Lastly, enable IRQs actually in use. */
-       for (base = 0; base < num_pics; base++) {
-               current = pics[base];
-               for (i = 0; i < current->pic_numintrs; i++)
-                       current->pic_disable_irq(current, i);
+       /*
+        * Now that all interrupts are disabled, update the ipl masks.
+        */
+       for (u_int ipl = 0; ipl < NIPL; ipl++) {
+               imask[ipl] = newmask[ipl];
        }
 
+       /*



Home | Main Index | Thread Index | Old Index