The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/sparc64/sparc64/intr_machdep.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1991 The Regents of the University of California.
    3  * All rights reserved.
    4  *
    5  * This code is derived from software contributed to Berkeley by
    6  * William Jolitz.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 4. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 /*-
   33  * Copyright (c) 2001 Jake Burkholder.
   34  * All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  *
   45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   55  * SUCH DAMAGE.
   56  *
   57  *      from: @(#)isa.c 7.2 (Berkeley) 5/13/91
   58  *      form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __FBSDID("$FreeBSD: releng/6.0/sys/sparc64/sparc64/intr_machdep.c 145153 2005-04-16 15:05:56Z marius $");
   63 
   64 #include <sys/param.h>
   65 #include <sys/systm.h>
   66 #include <sys/queue.h>
   67 #include <sys/bus.h>
   68 #include <sys/errno.h>
   69 #include <sys/interrupt.h>
   70 #include <sys/ktr.h>
   71 #include <sys/lock.h>
   72 #include <sys/mutex.h>
   73 #include <sys/pcpu.h>
   74 #include <sys/proc.h>
   75 #include <sys/vmmeter.h>
   76 
   77 #include <machine/frame.h>
   78 #include <machine/intr_machdep.h>
   79 
   80 #define MAX_STRAY_LOG   5
   81 
   82 CTASSERT((1 << IV_SHIFT) == sizeof(struct intr_vector));
   83 
   84 ih_func_t *intr_handlers[PIL_MAX];
   85 uint16_t pil_countp[PIL_MAX];
   86 
   87 struct intr_vector intr_vectors[IV_MAX];
   88 uint16_t intr_countp[IV_MAX];
   89 static u_long intr_stray_count[IV_MAX];
   90 
   91 static char *pil_names[] = {
   92         "stray",
   93         "low",          /* PIL_LOW */
   94         "ithrd",        /* PIL_ITHREAD */
   95         "rndzvs",       /* PIL_RENDEZVOUS */
   96         "ast",          /* PIL_AST */
   97         "stop",         /* PIL_STOP */
   98         "stray", "stray", "stray", "stray", "stray", "stray", "stray",
   99         "fast",         /* PIL_FAST */
  100         "tick",         /* PIL_TICK */
  101 };
  102         
  103 /* protect the intr_vectors table */
  104 static struct mtx intr_table_lock;
  105 
  106 static void intr_execute_handlers(void *);
  107 static void intr_stray_level(struct trapframe *);
  108 static void intr_stray_vector(void *);
  109 static int intrcnt_setname(const char *, int);
  110 static void intrcnt_updatename(int, const char *, int);
  111 
  112 /*
  113  * not MPSAFE
  114  */
  115 static void
  116 intrcnt_updatename(int vec, const char *name, int ispil)
  117 {
  118         static int intrcnt_index, stray_pil_index, stray_vec_index;
  119         int name_index;
  120 
  121         if (intrnames[0] == '\0') {
  122                 /* for bitbucket */
  123                 if (bootverbose)
  124                         printf("initalizing intr_countp\n");
  125                 intrcnt_setname("???", intrcnt_index++);
  126 
  127                 stray_vec_index = intrcnt_index++;
  128                 intrcnt_setname("stray", stray_vec_index);
  129                 for (name_index = 0; name_index < IV_MAX; name_index++)
  130                         intr_countp[name_index] = stray_vec_index;
  131 
  132                 stray_pil_index = intrcnt_index++;
  133                 intrcnt_setname("pil", stray_pil_index);
  134                 for (name_index = 0; name_index < PIL_MAX; name_index++)
  135                         pil_countp[name_index] = stray_pil_index;
  136         }
  137 
  138         if (name == NULL)
  139                 name = "???";
  140 
  141         if (!ispil && intr_countp[vec] != stray_vec_index)
  142                 name_index = intr_countp[vec];
  143         else if (ispil && pil_countp[vec] != stray_pil_index)
  144                 name_index = pil_countp[vec];
  145         else
  146                 name_index = intrcnt_index++;
  147 
  148         if (intrcnt_setname(name, name_index))
  149                 name_index = 0;
  150 
  151         if (!ispil)
  152                 intr_countp[vec] = name_index;
  153         else
  154                 pil_countp[vec] = name_index;
  155 }
  156 
  157 static int
  158 intrcnt_setname(const char *name, int index)
  159 {
  160 
  161         if (intrnames + (MAXCOMLEN + 1) * index >= eintrnames)
  162                 return (E2BIG);
  163         snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
  164             MAXCOMLEN, name);
  165         return (0);
  166 }
  167 
  168 void
  169 intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
  170 {
  171         char pilname[MAXCOMLEN + 1];
  172         u_long ps;
  173 
  174         ps = intr_disable();
  175         if (vec != -1) {
  176                 intr_vectors[vec].iv_func = ivf;
  177                 intr_vectors[vec].iv_arg = iva;
  178                 intr_vectors[vec].iv_pri = pri;
  179                 intr_vectors[vec].iv_vec = vec;
  180         }
  181         snprintf(pilname, MAXCOMLEN + 1, "pil%d: %s", pri, pil_names[pri]);
  182         intrcnt_updatename(pri, pilname, 1);
  183         intr_handlers[pri] = ihf;
  184         intr_restore(ps);
  185 }
  186 
  187 static void
  188 intr_stray_level(struct trapframe *tf)
  189 {
  190 
  191         printf("stray level interrupt %ld\n", tf->tf_level);
  192 }
  193 
  194 static void
  195 intr_stray_vector(void *cookie)
  196 {
  197         struct intr_vector *iv;
  198 
  199         iv = cookie;
  200         if (intr_stray_count[iv->iv_vec] < MAX_STRAY_LOG) {
  201                 printf("stray vector interrupt %d\n", iv->iv_vec);
  202                 intr_stray_count[iv->iv_vec]++;
  203                 if (intr_stray_count[iv->iv_vec] >= MAX_STRAY_LOG)
  204                         printf("got %d stray interrupt %d's: not logging "
  205                             "anymore\n", MAX_STRAY_LOG, iv->iv_vec);
  206         }
  207 }
  208 
  209 void
  210 intr_init1()
  211 {
  212         int i;
  213 
  214         /* Mark all interrupts as being stray. */
  215         for (i = 0; i < PIL_MAX; i++)
  216                 intr_handlers[i] = intr_stray_level;
  217         for (i = 0; i < IV_MAX; i++) {
  218                 intr_vectors[i].iv_func = intr_stray_vector;
  219                 intr_vectors[i].iv_arg = &intr_vectors[i];
  220                 intr_vectors[i].iv_pri = PIL_LOW;
  221                 intr_vectors[i].iv_vec = i;
  222         }
  223         intr_handlers[PIL_LOW] = intr_fast;
  224 }
  225 
  226 void
  227 intr_init2()
  228 {
  229 
  230         mtx_init(&intr_table_lock, "ithread table lock", NULL, MTX_SPIN);
  231 }
  232 
  233 static void
  234 intr_execute_handlers(void *cookie)
  235 {
  236         struct intr_vector *iv;
  237         struct ithd *ithd;
  238         struct intrhand *ih;
  239         int error;
  240 
  241         iv = cookie;
  242         ithd = iv->iv_ithd;
  243 
  244         if (ithd == NULL)
  245                 ih = NULL;
  246         else
  247                 ih = TAILQ_FIRST(&ithd->it_handlers);
  248         if (ih != NULL && ih->ih_flags & IH_FAST) {
  249                 /* Execute fast interrupt handlers directly. */
  250                 TAILQ_FOREACH(ih, &ithd->it_handlers, ih_next) {
  251                         MPASS(ih->ih_flags & IH_FAST &&
  252                             ih->ih_argument != NULL);
  253                         CTR3(KTR_INTR, "%s: executing handler %p(%p)",
  254                             __func__, ih->ih_handler, ih->ih_argument);
  255                         ih->ih_handler(ih->ih_argument);
  256                 }
  257                 return;
  258         }
  259 
  260         /* Schedule a heavyweight interrupt process. */
  261         error = ithread_schedule(ithd);
  262         if (error == EINVAL)
  263                 intr_stray_vector(iv);
  264 }
  265 
  266 int
  267 inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
  268     int flags, void **cookiep)
  269 {
  270         struct intr_vector *iv;
  271         struct ithd *ithd;              /* descriptor for the IRQ */
  272         struct ithd *orphan;
  273         int errcode;
  274 
  275         /*
  276          * Work around a race where more than one CPU may be registering
  277          * handlers on the same IRQ at the same time.
  278          */
  279         iv = &intr_vectors[vec];
  280         mtx_lock_spin(&intr_table_lock);
  281         ithd = iv->iv_ithd;
  282         mtx_unlock_spin(&intr_table_lock);
  283         if (ithd == NULL) {
  284                 errcode = ithread_create(&ithd, vec, 0, NULL, NULL, "vec%d:",
  285                     vec);
  286                 if (errcode)
  287                         return (errcode);
  288                 mtx_lock_spin(&intr_table_lock);
  289                 if (iv->iv_ithd == NULL) {
  290                         iv->iv_ithd = ithd;
  291                         mtx_unlock_spin(&intr_table_lock);
  292                 } else {
  293                         orphan = ithd;
  294                         ithd = iv->iv_ithd;
  295                         mtx_unlock_spin(&intr_table_lock);
  296                         ithread_destroy(orphan);
  297                 }
  298         }
  299 
  300         errcode = ithread_add_handler(ithd, name, handler, arg,
  301             ithread_priority(flags), flags, cookiep);
  302         if (errcode)
  303                 return (errcode);
  304         
  305         intr_setup(flags & INTR_FAST ? PIL_FAST : PIL_ITHREAD, intr_fast, vec,
  306             intr_execute_handlers, iv);
  307 
  308         intr_stray_count[vec] = 0;
  309 
  310         intrcnt_updatename(vec, ithd->it_td->td_proc->p_comm, 0);
  311 
  312         return (0);
  313 }
  314 
  315 int
  316 inthand_remove(int vec, void *cookie)
  317 {
  318         struct intr_vector *iv;
  319         int error;
  320         
  321         error = ithread_remove_handler(cookie);
  322         if (error == 0) {
  323                 /*
  324                  * XXX: maybe this should be done regardless of whether
  325                  * ithread_remove_handler() succeeded?
  326                  */
  327                 iv = &intr_vectors[vec];
  328                 mtx_lock_spin(&intr_table_lock);
  329                 if (iv->iv_ithd == NULL)
  330                         intr_setup(PIL_ITHREAD, intr_fast, vec,
  331                             intr_stray_vector, iv);
  332                 else
  333                         intr_setup(PIL_LOW, intr_fast, vec,
  334                             intr_execute_handlers, iv);
  335                 mtx_unlock_spin(&intr_table_lock);
  336         }
  337         return (error);
  338 }

Cache object: 7888257af819df6501b0fb4b7b6d7094


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.