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