kgdb_machdep.c revision 1.9 1 /* $NetBSD: kgdb_machdep.c,v 1.9 2006/10/07 18:14:42 rjs Exp $ */
2 /*-
3 * Copyright (c) 1997 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Paul Kranenburg.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * Copyright (c) 1992, 1993
40 * The Regents of the University of California. All rights reserved.
41 *
42 * This software was developed by the Computer Systems Engineering group
43 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
44 * contributed to Berkeley.
45 *
46 * All advertising materials mentioning features or use of this software
47 * must display the following acknowledgements:
48 * This product includes software developed by the University of
49 * California, Lawrence Berkeley Laboratory.
50 *
51 * This product includes software developed by Harvard University.
52 *
53 * Redistribution and use in source and binary forms, with or without
54 * modification, are permitted provided that the following conditions
55 * are met:
56 * 1. Redistributions of source code must retain the above copyright
57 * notice, this list of conditions and the following disclaimer.
58 * 2. Redistributions in binary form must reproduce the above copyright
59 * notice, this list of conditions and the following disclaimer in the
60 * documentation and/or other materials provided with the distribution.
61 * 3. Neither the name of the University nor the names of its contributors
62 * may be used to endorse or promote products derived from this software
63 * without specific prior written permission.
64 *
65 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
66 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
69 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
73 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
74 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75 * SUCH DAMAGE.
76 *
77 * @(#)kgdb_stub.c 8.1 (Berkeley) 6/11/93
78 */
79
80 /*
81 * Copyright (c) 1995
82 * The President and Fellows of Harvard College. All rights reserved.
83 *
84 * This software was developed by the Computer Systems Engineering group
85 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
86 * contributed to Berkeley.
87 *
88 * All advertising materials mentioning features or use of this software
89 * must display the following acknowledgements:
90 * This product includes software developed by the University of
91 * California, Lawrence Berkeley Laboratory.
92 *
93 * This product includes software developed by Harvard University.
94 *
95 * Redistribution and use in source and binary forms, with or without
96 * modification, are permitted provided that the following conditions
97 * are met:
98 * 1. Redistributions of source code must retain the above copyright
99 * notice, this list of conditions and the following disclaimer.
100 * 2. Redistributions in binary form must reproduce the above copyright
101 * notice, this list of conditions and the following disclaimer in the
102 * documentation and/or other materials provided with the distribution.
103 * 3. All advertising materials mentioning features or use of this software
104 * must display the following acknowledgement:
105 * This product includes software developed by the University of
106 * California, Berkeley and its contributors.
107 * 4. Neither the name of the University nor the names of its contributors
108 * may be used to endorse or promote products derived from this software
109 * without specific prior written permission.
110 *
111 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
112 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
113 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
114 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
115 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
116 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
117 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
118 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
119 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
120 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
121 * SUCH DAMAGE.
122 *
123 * @(#)kgdb_stub.c 8.1 (Berkeley) 6/11/93
124 */
125
126 /*
127 * Machine dependent routines needed by kern/kgdb_stub.c
128 */
129
130 #include <sys/cdefs.h>
131 __KERNEL_RCSID(0, "$NetBSD: kgdb_machdep.c,v 1.9 2006/10/07 18:14:42 rjs Exp $");
132
133 #include "opt_kgdb.h"
134 #include "opt_multiprocessor.h"
135 #include "opt_sparc_arch.h"
136
137 #ifdef KGDB
138
139 #include <sys/param.h>
140 #include <sys/systm.h>
141 #include <sys/buf.h>
142 #include <sys/kgdb.h>
143
144 #include <machine/ctlreg.h>
145 #include <machine/psl.h>
146 #include <machine/reg.h>
147 #include <machine/trap.h>
148 #include <machine/cpu.h>
149
150 #include <sparc/sparc/asm.h>
151
152 extern int64_t pseg_get(struct pmap *, vaddr_t);
153
154 static inline void kgdb_copy(register char *, register char *, register int);
155 static inline void kgdb_zero(register char *, register int);
156
157 /*
158 * This little routine exists simply so that bcopy() can be debugged.
159 */
160 static inline void
161 kgdb_copy(register char *src, register char *dst, register int len)
162 {
163
164 while (--len >= 0)
165 *dst++ = *src++;
166 }
167
168 /* ditto for bzero */
169 static inline void
170 kgdb_zero(register char *ptr, register int len)
171 {
172 while (--len >= 0)
173 *ptr++ = (char) 0;
174 }
175
176 /*
177 * Deal with KGDB in a MP environment. XXX need to have "mach cpu" equiv.
178 */
179 #ifdef MULTIPROCESSOR
180
181 #define NOCPU -1
182
183 static int kgdb_suspend_others(void);
184 static void kgdb_resume_others(void);
185 static void kgdb_suspend(void);
186
187 __cpu_simple_lock_t kgdb_lock;
188 int kgdb_cpu = NOCPU;
189
190 static int
191 kgdb_suspend_others(void)
192 {
193 int cpu_me = cpu_number();
194 int win;
195
196 if (cpus == NULL)
197 return 1;
198
199 __cpu_simple_lock(&kgdb_lock);
200 if (kgdb_cpu == NOCPU)
201 kgdb_cpu = cpu_me;
202 win = (kgdb_cpu == cpu_me);
203 __cpu_simple_unlock(&kgdb_lock);
204
205 if (win)
206 mp_pause_cpus();
207
208 return win;
209 }
210
211 static void
212 kgdb_resume_others(void)
213 {
214
215 mp_resume_cpus();
216
217 __cpu_simple_lock(&kgdb_lock);
218 kgdb_cpu = NOCPU;
219 __cpu_simple_unlock(&kgdb_lock);
220 }
221
222 static void
223 kgdb_suspend()
224 {
225
226 sparc64_ipi_pause_thiscpu(NULL);
227 }
228 #endif /* MULTIPROCESSOR */
229
230 /*
231 * Trap into kgdb to wait for debugger to connect,
232 * noting on the console why nothing else is going on.
233 */
234 void
235 kgdb_connect(verbose)
236 int verbose;
237 {
238
239 if (kgdb_dev < 0)
240 return;
241 #if NFB > 0
242 fb_unblank();
243 #endif
244 #ifdef MULTIPROCESSOR
245 /* While we're in the debugger, pause all other CPUs */
246 if (!kgdb_suspend_others()) {
247 kgdb_suspend();
248 } else {
249 #endif /* MULTIPROCESSOR */
250 if (verbose)
251 printf("kgdb waiting...");
252 __asm("ta %0" :: "n" (T_KGDB_EXEC)); /* trap into kgdb */
253
254 kgdb_debug_panic = 1;
255
256 #ifdef MULTIPROCESSOR
257 /* Other CPUs can continue now */
258 kgdb_resume_others();
259 }
260 #endif /* MULTIPROCESSOR */
261 }
262
263 /*
264 * Decide what to do on panic.
265 */
266 void
267 kgdb_panic()
268 {
269
270 if (kgdb_dev >= 0 && kgdb_debug_panic)
271 kgdb_connect(kgdb_active == 0);
272 }
273
274 /*
275 * Translate a trap number into a unix compatible signal value.
276 * (gdb only understands unix signal numbers).
277 * XXX should this be done at the other end?
278 */
279 int
280 kgdb_signal(type)
281 int type;
282 {
283 int sigval;
284
285 switch (type) {
286
287 case T_AST:
288 sigval = SIGINT;
289 break;
290
291 case T_TEXTFAULT:
292 case T_DATAFAULT:
293 sigval = SIGSEGV;
294 break;
295
296 case T_ALIGN:
297 sigval = SIGBUS;
298 break;
299
300 case T_ILLINST:
301 case T_PRIVINST:
302 case T_DIV0:
303 sigval = SIGILL;
304 break;
305
306 case T_FP_IEEE_754:
307 case T_FP_OTHER:
308 sigval = SIGFPE;
309 break;
310
311 case T_BREAKPOINT:
312 sigval = SIGTRAP;
313 break;
314
315 case T_KGDB_EXEC:
316 sigval = SIGIOT;
317 break;
318
319 default:
320 sigval = SIGEMT;
321 break;
322 }
323 return (sigval);
324 }
325
326 /*
327 * Definitions exported from gdb (& then made prettier).
328 * (see gnu/dist/toolchain/gdb/config/sparc/tm-sp64.h)
329 */
330 #define GDB_G0 0
331 #define GDB_O0 8
332 #define GDB_L0 16
333 #define GDB_I0 24
334 #define GDB_FP0 32
335 #define GDB_PC 80
336 #define GDB_NPC 81
337 #define GDB_CCR 82
338 #define GDB_FSR 83
339 #define GDB_FPRS 84
340 #define GDB_Y 85
341 #define GDB_ASI 86
342
343 #define REGISTER_BYTES (KGDB_NUMREGS * 8)
344 #define REGISTER_BYTE(n) ((n) * 8)
345
346 /*
347 * Translate the values stored in the kernel regs struct to the format
348 * understood by gdb.
349 */
350 void
351 kgdb_getregs(regs, gdb_regs)
352 db_regs_t *regs;
353 kgdb_reg_t *gdb_regs;
354 {
355 struct trapframe64 *tf = ®s->db_tf;
356
357 /* %g0..%g7 and %o0..%o7: from trapframe */
358 gdb_regs[0] = 0;
359 kgdb_copy((caddr_t)&tf->tf_global[1], (caddr_t)&gdb_regs[1], 15 * 8);
360
361 /* %l0..%l7 and %i0..%i7: from stack */
362 kgdb_copy((caddr_t)(long)tf->tf_out[6], (caddr_t)&gdb_regs[GDB_L0], 16 * 8);
363
364 /* %f0..%f31 -- fake, kernel does not use FP */
365 kgdb_zero((caddr_t)&gdb_regs[GDB_FP0], 32 * 8);
366
367 /* %y, %psr, %wim, %tbr, %pc, %npc, %fsr, %csr */
368 gdb_regs[GDB_PC] = tf->tf_pc;
369 gdb_regs[GDB_NPC] = tf->tf_npc;
370 }
371
372 /*
373 * Reverse the above.
374 */
375 void
376 kgdb_setregs(regs, gdb_regs)
377 db_regs_t *regs;
378 kgdb_reg_t *gdb_regs;
379 {
380 struct trapframe64 *tf = ®s->db_tf;
381
382 kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 8);
383 kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)(long)tf->tf_out[6], 16 * 8);
384 tf->tf_pc = gdb_regs[GDB_PC];
385 tf->tf_npc = gdb_regs[GDB_NPC];
386 }
387
388 /*
389 * Determine if memory at [va..(va+len)] is valid.
390 */
391 int
392 kgdb_acc(va, len)
393 vaddr_t va;
394 size_t len;
395 {
396 int64_t data;
397 vaddr_t eva;
398 struct pmap *pm = &kernel_pmap_;
399
400 eva = round_page(va + len);
401 va = trunc_page(va);
402
403 simple_lock(&pm->pm_lock);
404 for (; va < eva; va += PAGE_SIZE) {
405 data = pseg_get(pm, va);
406 if ((data & TLB_V) == 0) {
407 simple_unlock(&pm->pm_lock);
408 return 0;
409 }
410 }
411 simple_unlock(&pm->pm_lock);
412
413 return (1);
414 }
415 #endif
416