dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / mdb / common / kmdb / kaif_start.c
blob79c7868d9e026c23926a8bef2d1445465ec60eab
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * The main CPU-control loops, used to control masters and slaves.
32 #include <sys/types.h>
34 #include <kmdb/kaif.h>
35 #include <kmdb/kaif_start.h>
36 #include <kmdb/kmdb_asmutil.h>
37 #include <kmdb/kmdb_dpi_impl.h>
38 #include <kmdb/kmdb_kdi.h>
40 #define KAIF_SLAVE_CMD_SPIN 0
41 #define KAIF_SLAVE_CMD_SWITCH 1
42 #define KAIF_SLAVE_CMD_RESUME 2
43 #define KAIF_SLAVE_CMD_FLUSH 3
44 #define KAIF_SLAVE_CMD_REBOOT 4
48 * Used to synchronize attempts to set kaif_master_cpuid. kaif_master_cpuid may
49 * be read without kaif_master_lock, and may be written by the current master
50 * CPU.
52 int kaif_master_cpuid = KAIF_MASTER_CPUID_UNSET;
53 static uintptr_t kaif_master_lock = 0;
56 * Used to ensure that all CPUs leave the debugger together. kaif_loop_lock must
57 * be held to write kaif_looping, but need not be held to read it.
59 static volatile uint_t kaif_looping;
60 static uintptr_t kaif_loop_lock;
62 static volatile int kaif_slave_cmd;
63 static volatile int kaif_slave_tgt; /* target cpuid for CMD_SWITCH */
65 static void
66 kaif_lock_enter(uintptr_t *lock)
68 while (cas(lock, 0, 1) != 0)
69 continue;
70 membar_producer();
73 static void
74 kaif_lock_exit(uintptr_t *lock)
76 *lock = 0;
77 membar_producer();
80 static void
81 kaif_start_slaves(int cmd)
83 kaif_slave_cmd = cmd;
84 kmdb_kdi_start_slaves();
87 static int
88 kaif_master_loop(kaif_cpusave_t *cpusave)
90 int notflushed, i;
92 kaif_trap_set_debugger();
95 * If we re-entered due to a ::switch, we need to tell the slave CPUs
96 * to sleep again.
98 kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 0);
100 master_loop:
101 switch (kmdb_dpi_reenter()) {
102 case KMDB_DPI_CMD_SWITCH_CPU:
104 * We assume that the target CPU is a valid slave. There's no
105 * easy way to complain here, so we'll assume that the caller
106 * has done the proper checking.
108 if (kmdb_dpi_switch_target == cpusave->krs_cpu_id)
109 break;
111 kaif_slave_tgt = kaif_master_cpuid = kmdb_dpi_switch_target;
112 cpusave->krs_cpu_state = KAIF_CPU_STATE_SLAVE;
113 membar_producer();
116 * Switch back to the saved trap table before we switch CPUs --
117 * we need to make sure that only one CPU is on the debugger's
118 * table at a time.
120 kaif_trap_set_saved(cpusave);
122 kaif_start_slaves(KAIF_SLAVE_CMD_SWITCH);
124 /* The new master is now awake */
125 return (KAIF_CPU_CMD_SWITCH);
127 case KMDB_DPI_CMD_RESUME_ALL:
128 case KMDB_DPI_CMD_RESUME_UNLOAD:
130 * Resume everyone, clean up for next entry.
132 kaif_master_cpuid = KAIF_MASTER_CPUID_UNSET;
133 membar_producer();
134 kaif_start_slaves(KAIF_SLAVE_CMD_RESUME);
136 if (kmdb_dpi_work_required())
137 kmdb_dpi_wrintr_fire();
139 kaif_trap_set_saved(cpusave);
141 return (KAIF_CPU_CMD_RESUME);
143 case KMDB_DPI_CMD_RESUME_MASTER:
145 * Single-CPU resume, which is performed on the debugger's
146 * trap table (so no need to switch back).
148 return (KAIF_CPU_CMD_RESUME_MASTER);
150 case KMDB_DPI_CMD_FLUSH_CACHES:
151 kaif_start_slaves(KAIF_SLAVE_CMD_FLUSH);
154 * Wait for the other cpus to finish flushing their caches.
156 do {
157 notflushed = 0;
158 for (i = 0; i < kaif_ncpusave; i++) {
159 kaif_cpusave_t *save = &kaif_cpusave[i];
161 if (save->krs_cpu_state ==
162 KAIF_CPU_STATE_SLAVE &&
163 !save->krs_cpu_flushed) {
164 notflushed++;
165 break;
168 } while (notflushed > 0);
170 kaif_slave_cmd = KAIF_SLAVE_CMD_SPIN;
171 break;
173 #if defined(__i386) || defined(__amd64)
174 case KMDB_DPI_CMD_REBOOT:
176 * Reboot must be initiated by CPU 0. I could ask why, but I'm
177 * afraid that I don't want to know the answer.
179 if (cpusave->krs_cpu_id == 0)
180 kmdb_kdi_reboot();
182 kaif_start_slaves(KAIF_SLAVE_CMD_REBOOT);
185 * Spin forever, waiting for CPU 0 (apparently a slave) to
186 * reboot the system.
188 for (;;)
189 continue;
191 /*NOTREACHED*/
192 break;
193 #endif
196 goto master_loop;
199 static int
200 kaif_slave_loop(kaif_cpusave_t *cpusave)
202 int slavecmd, rv;
205 /* Wait for duty to call */
206 for (;;) {
207 slavecmd = kaif_slave_cmd;
209 if (slavecmd == KAIF_SLAVE_CMD_SWITCH &&
210 kaif_slave_tgt == cpusave->krs_cpu_id) {
211 kaif_slave_cmd = KAIF_SLAVE_CMD_SPIN;
212 cpusave->krs_cpu_state = KAIF_CPU_STATE_MASTER;
213 rv = KAIF_CPU_CMD_SWITCH;
214 break;
216 } else if (slavecmd == KAIF_SLAVE_CMD_FLUSH) {
217 kmdb_kdi_flush_caches();
218 cpusave->krs_cpu_flushed = 1;
219 continue;
221 #if defined(__i386) || defined(__amd64)
222 } else if (slavecmd == KAIF_SLAVE_CMD_REBOOT &&
223 cpusave->krs_cpu_id == 0) {
224 rv = 0;
225 kmdb_kdi_reboot();
226 break;
227 #endif
229 } else if (slavecmd == KAIF_SLAVE_CMD_RESUME) {
230 rv = KAIF_CPU_CMD_RESUME;
231 break;
234 kmdb_kdi_slave_wait();
238 return (rv);
241 static void
242 kaif_select_master(kaif_cpusave_t *cpusave)
244 kaif_lock_enter(&kaif_master_lock);
246 if (kaif_master_cpuid == KAIF_MASTER_CPUID_UNSET) {
247 /* This is the master. */
248 kaif_master_cpuid = cpusave->krs_cpu_id;
249 cpusave->krs_cpu_state = KAIF_CPU_STATE_MASTER;
250 kaif_slave_cmd = KAIF_SLAVE_CMD_SPIN;
252 membar_producer();
254 kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 1);
255 } else {
256 /* The master was already chosen - go be a slave */
257 cpusave->krs_cpu_state = KAIF_CPU_STATE_SLAVE;
258 membar_producer();
261 kaif_lock_exit(&kaif_master_lock);
265 kaif_main_loop(kaif_cpusave_t *cpusave)
267 int cmd;
269 if (kaif_master_cpuid == KAIF_MASTER_CPUID_UNSET) {
270 if (!kmdb_dpi_resume_requested &&
271 kmdb_kdi_get_unload_request()) {
273 * Special case: Unload requested before first debugger
274 * entry. Don't stop the world, as there's nothing to
275 * clean up that can't be handled by the running kernel.
277 cpusave->krs_cpu_state = KAIF_CPU_STATE_NONE;
278 return (KAIF_CPU_CMD_RESUME);
281 kaif_select_master(cpusave);
283 } else if (kaif_master_cpuid == cpusave->krs_cpu_id) {
284 cpusave->krs_cpu_state = KAIF_CPU_STATE_MASTER;
285 } else {
286 cpusave->krs_cpu_state = KAIF_CPU_STATE_SLAVE;
289 cpusave->krs_cpu_flushed = 0;
291 kaif_lock_enter(&kaif_loop_lock);
292 kaif_looping++;
293 kaif_lock_exit(&kaif_loop_lock);
296 * We know who the master and slaves are, so now they can go off
297 * to their respective loops.
299 do {
300 if (kaif_master_cpuid == cpusave->krs_cpu_id)
301 cmd = kaif_master_loop(cpusave);
302 else
303 cmd = kaif_slave_loop(cpusave);
304 } while (cmd == KAIF_CPU_CMD_SWITCH);
306 kaif_lock_enter(&kaif_loop_lock);
307 kaif_looping--;
308 kaif_lock_exit(&kaif_loop_lock);
310 cpusave->krs_cpu_state = KAIF_CPU_STATE_NONE;
312 if (cmd == KAIF_CPU_CMD_RESUME) {
314 * By this point, the master has directed the slaves to resume,
315 * and everyone is making their way to this point. We're going
316 * to block here until all CPUs leave the master and slave
317 * loops. When all have arrived, we'll turn them all loose.
318 * This barrier is required for two reasons:
320 * 1. There exists a race condition whereby a CPU could reenter
321 * the debugger while another CPU is still in the slave loop
322 * from this debugger entry. This usually happens when the
323 * current master releases the slaves, and makes it back to
324 * the world before the slaves notice the release. The
325 * former master then triggers a debugger entry, and attempts
326 * to stop the slaves for this entry before they've even
327 * resumed from the last one. When the slaves arrive here,
328 * they'll have re-disabled interrupts, and will thus ignore
329 * cross-calls until they finish resuming.
331 * 2. At the time of this writing, there exists a SPARC bug that
332 * causes an apparently unsolicited interrupt vector trap
333 * from OBP to one of the slaves. This wouldn't normally be
334 * a problem but for the fact that the cross-called CPU
335 * encounters some sort of failure while in OBP. OBP
336 * recovers by executing the debugger-hook word, which sends
337 * the slave back into the debugger, triggering a debugger
338 * fault. This problem seems to only happen during resume,
339 * the result being that all CPUs save for the cross-called
340 * one make it back into the world, while the cross-called
341 * one is stuck at the debugger fault prompt. Leave the
342 * world in that state too long, and you'll get a mondo
343 * timeout panic. If we hold everyone here, we can give the
344 * the user a chance to trigger a panic for further analysis.
345 * To trigger the bug, "pool_unlock:b :c" and "while : ; do
346 * psrset -p ; done".
348 * When the second item is fixed, the barrier can move into
349 * kaif_select_master(), immediately prior to the setting of
350 * kaif_master_cpuid.
352 while (kaif_looping != 0)
353 continue;
356 return (cmd);