Annotation of sys/arch/i386/i386/ipifuncs.c, Revision 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