This source file includes following definitions.
- i386_ipi_halt
- i386_ipi_flush_fpu
- i386_ipi_synch_fpu
- i386_spurious
- i386_send_ipi
- i386_fast_ipi
- i386_self_ipi
- i386_broadcast_ipi
- i386_ipi_handler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 #include <sys/cdefs.h>
44
45
46
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
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 }