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  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by the University of
   19  *      California, Berkeley and its contributors.
   20  * 4. Neither the name of the University nor the names of its contributors
   21  *    may be used to endorse or promote products derived from this software
   22  *    without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 /*-
   37  * Copyright (c) 2001 Jake Burkholder.
   38  * All rights reserved.
   39  *
   40  * Redistribution and use in source and binary forms, with or without
   41  * modification, are permitted provided that the following conditions
   42  * are met:
   43  * 1. Redistributions of source code must retain the above copyright
   44  *    notice, this list of conditions and the following disclaimer.
   45  * 2. Redistributions in binary form must reproduce the above copyright
   46  *    notice, this list of conditions and the following disclaimer in the
   47  *    documentation and/or other materials provided with the distribution.
   48  *
   49  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   50  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   51  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   52  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   53  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   54  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   55  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   57  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   58  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   59  * SUCH DAMAGE.
   60  *
   61  *      from: @(#)isa.c 7.2 (Berkeley) 5/13/91
   62  *      form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
   63  *
   64  * $FreeBSD: releng/5.2/sys/sparc64/sparc64/intr_machdep.c 119291 2003-08-22 07:39:05Z imp $
   65  */
   66 
   67 #include <sys/param.h>
   68 #include <sys/systm.h>
   69 #include <sys/queue.h>
   70 #include <sys/bus.h>
   71 #include <sys/interrupt.h>
   72 #include <sys/lock.h>
   73 #include <sys/mutex.h>
   74 #include <sys/pcpu.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 u_int16_t       pil_countp[PIL_MAX];
   86 
   87 struct  intr_vector intr_vectors[IV_MAX];
   88 u_long  intr_stray_count[IV_MAX];
   89 u_int16_t       intr_countp[IV_MAX];
   90 
   91 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_stray_level(struct trapframe *tf);
  107 static void intr_stray_vector(void *cookie);
  108 
  109 /*
  110  * not MPSAFE
  111  */
  112 static void
  113 update_intrname(int vec, const char *name, int ispil)
  114 {
  115         char buf[32];
  116         char *cp;
  117         int off, name_index;
  118 
  119         if (intrnames[0] == '\0') {
  120                 /* for bitbucket */
  121                 if (bootverbose)
  122                         printf("initalizing intr_countp\n");
  123                 off = sprintf(intrnames, "???") + 1;
  124 
  125                 off += sprintf(intrnames + off, "stray") + 1;
  126                 for (name_index = 0; name_index < IV_MAX; name_index++)
  127                         intr_countp[name_index] = 1;
  128 
  129                 off += sprintf(intrnames + off, "pil") + 1;
  130                 for (name_index = 0; name_index < PIL_MAX; name_index++)
  131                         pil_countp[name_index] = 2;
  132         }
  133 
  134         if (name == NULL)
  135                 name = "???";
  136 
  137         if (snprintf(buf, sizeof(buf), "%s %s%d", name, ispil ? "pil" : "vec",
  138             vec) >= sizeof(buf))
  139                 goto use_bitbucket;
  140 
  141         /*
  142          * Search for `buf' in `intrnames'.  In the usual case when it is
  143          * not found, append it to the end if there is enough space (the \0
  144          * terminator for the previous string, if any, becomes a separator).
  145          */
  146         for (cp = intrnames, name_index = 0; cp != eintrnames &&
  147             name_index < IV_MAX; cp += strlen(cp) + 1, name_index++) {
  148                 if (*cp == '\0') {
  149                         if (strlen(buf) >= eintrnames - cp)
  150                                 break;
  151                         strcpy(cp, buf);
  152                         goto found;
  153                 }
  154                 if (strcmp(cp, buf) == 0)
  155                         goto found;
  156         }
  157 
  158 use_bitbucket:
  159         name_index = 0;
  160 found:
  161         if (!ispil)
  162                 intr_countp[vec] = name_index;
  163         else
  164                 pil_countp[vec] = name_index;
  165 }
  166 
  167 void
  168 intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
  169 {
  170         u_long ps;
  171 
  172         ps = intr_disable();
  173         if (vec != -1) {
  174                 intr_vectors[vec].iv_func = ivf;
  175                 intr_vectors[vec].iv_arg = iva;
  176                 intr_vectors[vec].iv_pri = pri;
  177                 intr_vectors[vec].iv_vec = vec;
  178         }
  179         update_intrname(pri, pil_names[pri], 1);
  180         intr_handlers[pri] = ihf;
  181         intr_restore(ps);
  182 }
  183 
  184 static void
  185 intr_stray_level(struct trapframe *tf)
  186 {
  187         printf("stray level interrupt %ld\n", tf->tf_level);
  188 }
  189 
  190 static void
  191 intr_stray_vector(void *cookie)
  192 {
  193         struct intr_vector *iv;
  194 
  195         iv = cookie;
  196         if (intr_stray_count[iv->iv_vec] < MAX_STRAY_LOG) {
  197                 printf("stray vector interrupt %d\n", iv->iv_vec);
  198                 atomic_add_long(&intr_stray_count[iv->iv_vec], 1);
  199                 if (intr_stray_count[iv->iv_vec] >= MAX_STRAY_LOG)
  200                         printf("got %d stray interrupt %d's: not logging "
  201                             "anymore\n", MAX_STRAY_LOG, iv->iv_vec);
  202         }
  203 }
  204 
  205 void
  206 intr_init1()
  207 {
  208         int i;
  209 
  210         /* Mark all interrupts as being stray. */
  211         for (i = 0; i < PIL_MAX; i++)
  212                 intr_handlers[i] = intr_stray_level;
  213         for (i = 0; i < IV_MAX; i++) {
  214                 intr_vectors[i].iv_func = intr_stray_vector;
  215                 intr_vectors[i].iv_arg = &intr_vectors[i];
  216                 intr_vectors[i].iv_pri = PIL_LOW;
  217                 intr_vectors[i].iv_vec = i;
  218         }
  219         intr_handlers[PIL_LOW] = intr_fast;
  220 }
  221 
  222 void
  223 intr_init2()
  224 {
  225 
  226         mtx_init(&intr_table_lock, "ithread table lock", NULL, MTX_SPIN);
  227 }
  228 
  229 /* Schedule a heavyweight interrupt process. */
  230 static void 
  231 sched_ithd(void *cookie)
  232 {
  233         struct intr_vector *iv;
  234         int error;
  235 
  236         iv = cookie;
  237 #ifdef notyet
  238         error = ithread_schedule(iv->iv_ithd);
  239 #else
  240         error = ithread_schedule(iv->iv_ithd, 0);
  241 #endif
  242         if (error == EINVAL)
  243                 intr_stray_vector(iv);
  244 }
  245 
  246 int
  247 inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
  248     int flags, void **cookiep)
  249 {
  250         struct intr_vector *iv;
  251         struct ithd *ithd;              /* descriptor for the IRQ */
  252         int errcode = 0;
  253         int created_ithd = 0;
  254 
  255         /*
  256          * Work around a race where more than one CPU may be registering
  257          * handlers on the same IRQ at the same time.
  258          */
  259         iv = &intr_vectors[vec];
  260         mtx_lock_spin(&intr_table_lock);
  261         ithd = iv->iv_ithd;
  262         mtx_unlock_spin(&intr_table_lock);
  263         if (ithd == NULL) {
  264                 errcode = ithread_create(&ithd, vec, 0, NULL, NULL, "intr%d:",
  265                     vec);
  266                 if (errcode)
  267                         return (errcode);
  268                 mtx_lock_spin(&intr_table_lock);
  269                 if (iv->iv_ithd == NULL) {
  270                         iv->iv_ithd = ithd;
  271                         created_ithd++;
  272                         mtx_unlock_spin(&intr_table_lock);
  273                 } else {
  274                         struct ithd *orphan;
  275 
  276                         orphan = ithd;
  277                         ithd = iv->iv_ithd;
  278                         mtx_unlock_spin(&intr_table_lock);
  279                         ithread_destroy(orphan);
  280                 }
  281         }
  282 
  283         errcode = ithread_add_handler(ithd, name, handler, arg,
  284             ithread_priority(flags), flags, cookiep);
  285         
  286         if ((flags & INTR_FAST) == 0 || errcode) {
  287                 intr_setup(PIL_ITHREAD, intr_fast, vec, sched_ithd, iv);
  288                 errcode = 0;
  289         }
  290 
  291         if (errcode)
  292                 return (errcode);
  293         
  294         if (flags & INTR_FAST)
  295                 intr_setup(PIL_FAST, intr_fast, vec, handler, arg);
  296 
  297         intr_stray_count[vec] = 0;
  298 
  299         update_intrname(vec, name, 0);
  300 
  301         return (0);
  302 }
  303 
  304 int
  305 inthand_remove(int vec, void *cookie)
  306 {
  307         struct intr_vector *iv;
  308         int error;
  309         
  310         error = ithread_remove_handler(cookie);
  311         if (error == 0) {
  312                 /*
  313                  * XXX: maybe this should be done regardless of whether
  314                  * ithread_remove_handler() succeeded?
  315                  */
  316                 iv = &intr_vectors[vec];
  317                 mtx_lock_spin(&intr_table_lock);
  318                 if (iv->iv_ithd == NULL) {
  319                         intr_setup(PIL_ITHREAD, intr_fast, vec,
  320                             intr_stray_vector, iv);
  321                 } else {
  322                         intr_setup(PIL_LOW, intr_fast, vec, sched_ithd, iv);
  323                 }
  324                 mtx_unlock_spin(&intr_table_lock);
  325         }
  326         return (error);
  327 }

Cache object: e5eaf0821711af01d58cb08445bca74c


[ 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.