root/arch/i386/i386/ipifuncs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i386_ipi_halt
  2. i386_ipi_flush_fpu
  3. i386_ipi_synch_fpu
  4. i386_spurious
  5. i386_send_ipi
  6. i386_fast_ipi
  7. i386_self_ipi
  8. i386_broadcast_ipi
  9. i386_ipi_handler

    1 /*      $OpenBSD: ipifuncs.c,v 1.8 2007/05/25 15:55:26 art Exp $        */
    2 /* $NetBSD: ipifuncs.c,v 1.1.2.3 2000/06/26 02:04:06 sommerfeld Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 2000 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by RedBack Networks Inc.
   10  *
   11  * Author: Bill Sommerfeld
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. All advertising materials mentioning features or use of this software
   22  *    must display the following acknowledgement:
   23  *        This product includes software developed by the NetBSD
   24  *        Foundation, Inc. and its contributors.
   25  * 4. Neither the name of The NetBSD Foundation nor the names of its
   26  *    contributors may be used to endorse or promote products derived
   27  *    from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   30  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   32  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   33  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   39  * POSSIBILITY OF SUCH DAMAGE.
   40  */
   41 
   42 
   43 #include <sys/cdefs.h>                  /* RCS ID & Copyright macro defns */
   44 
   45 /*
   46  * Interprocessor interrupt handlers.
   47  */
   48 
   49 #include "npx.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/device.h>
   53 #include <sys/systm.h>
   54 
   55 #include <machine/cpufunc.h>
   56 #include <machine/cpuvar.h>
   57 #include <machine/intr.h>
   58 #include <machine/atomic.h>
   59 #include <machine/i82093var.h>
   60 #include <machine/db_machdep.h>
   61 
   62 #include <uvm/uvm_extern.h>
   63 
   64 void i386_ipi_halt(struct cpu_info *);
   65 
   66 #if NNPX > 0
   67 void i386_ipi_synch_fpu(struct cpu_info *);
   68 void i386_ipi_flush_fpu(struct cpu_info *);
   69 #else
   70 #define i386_ipi_synch_fpu 0
   71 #define i386_ipi_flush_fpu 0
   72 #endif
   73 
   74 void (*ipifunc[I386_NIPI])(struct cpu_info *) =
   75 {
   76         i386_ipi_halt,
   77         i386_ipi_microset,
   78         i386_ipi_flush_fpu,
   79         i386_ipi_synch_fpu,
   80         NULL,
   81 #if 0
   82         i386_reload_mtrr,
   83         gdt_reload_cpu,
   84 #else
   85         0,
   86         0,
   87 #endif
   88 #ifdef DDB
   89         i386_ipi_db,
   90 #else
   91         0,
   92 #endif
   93         i386_setperf_ipi,
   94 };
   95 
   96 void
   97 i386_ipi_halt(struct cpu_info *ci)
   98 {
   99         disable_intr();
  100 
  101         printf("%s: shutting down\n", ci->ci_dev.dv_xname);
  102         for(;;) {
  103                 asm volatile("hlt");
  104         }
  105 }
  106 
  107 #if NNPX > 0
  108 void
  109 i386_ipi_flush_fpu(struct cpu_info *ci)
  110 {
  111         npxsave_cpu(ci, 0);
  112 }
  113 
  114 void
  115 i386_ipi_synch_fpu(struct cpu_info *ci)
  116 {
  117         npxsave_cpu(ci, 1);
  118 }
  119 #endif
  120 
  121 void
  122 i386_spurious(void)
  123 {
  124         printf("spurious intr\n");
  125 }
  126 
  127 int
  128 i386_send_ipi(struct cpu_info *ci, int ipimask)
  129 {
  130         int ret;
  131 
  132         i386_atomic_setbits_l(&ci->ci_ipis, ipimask);
  133 
  134         /* Don't send IPI to cpu which isn't (yet) running. */
  135         if (!(ci->ci_flags & CPUF_RUNNING))
  136                 return ENOENT;
  137 
  138         ret = i386_ipi(LAPIC_IPI_VECTOR, ci->ci_cpuid, LAPIC_DLMODE_FIXED);
  139         if (ret != 0) {
  140                 printf("ipi of %x from %s to %s failed\n",
  141                     ipimask, curcpu()->ci_dev.dv_xname, ci->ci_dev.dv_xname);
  142         }
  143 
  144         return ret;
  145 }
  146 
  147 int
  148 i386_fast_ipi(struct cpu_info *ci, int ipi)
  149 {
  150         if (!(ci->ci_flags & CPUF_RUNNING))
  151                 return (ENOENT);
  152 
  153         return (i386_ipi(ipi, ci->ci_cpuid, LAPIC_DLMODE_FIXED));
  154 }
  155 
  156 void
  157 i386_self_ipi(int vector)
  158 {
  159         i82489_writereg(LAPIC_ICRLO,
  160             vector | LAPIC_DLMODE_FIXED | LAPIC_LVL_ASSERT | LAPIC_DEST_SELF);
  161 }
  162 
  163 
  164 void
  165 i386_broadcast_ipi(int ipimask)
  166 {
  167         struct cpu_info *ci, *self = curcpu();
  168         CPU_INFO_ITERATOR cii;
  169         int count = 0;
  170 
  171         CPU_INFO_FOREACH(cii, ci) {
  172                 if (ci == self)
  173                         continue;
  174                 if ((ci->ci_flags & CPUF_RUNNING) == 0)
  175                         continue;
  176                 i386_atomic_setbits_l(&ci->ci_ipis, ipimask);
  177                 count++;
  178         }
  179         if (!count)
  180                 return;
  181 
  182         i386_ipi(LAPIC_IPI_VECTOR, LAPIC_DEST_ALLEXCL, LAPIC_DLMODE_FIXED); 
  183 }
  184 
  185 void
  186 i386_ipi_handler(void)
  187 {
  188         extern struct evcount ipi_count;
  189         struct cpu_info *ci = curcpu();
  190         u_int32_t pending;
  191         int bit;
  192 
  193         pending = i386_atomic_testset_ul(&ci->ci_ipis, 0);
  194 
  195         for (bit = 0; bit < I386_NIPI && pending; bit++) {
  196                 if (pending & (1<<bit)) {
  197                         pending &= ~(1<<bit);
  198                         (*ipifunc[bit])(ci);
  199                         ipi_count.ec_count++;
  200                 }
  201         }
  202 }

/* [<][>][^][v][top][bottom][index][help] */