[BACK]Return to ipifuncs.c CVS log [TXT][DIR] Up to [local] / sys / arch / i386 / i386

Annotation of sys/arch/i386/i386/ipifuncs.c, Revision 1.1.1.1

1.1       nbrk        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: }

CVSweb