kgdb_machdep.c revision 1.7 1 /* $NetBSD: kgdb_machdep.c,v 1.7 2006/02/11 17:57:32 cdi 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.7 2006/02/11 17:57:32 cdi 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 while (cpuinfo.flags & CPUFLG_PAUSED)
227 cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags));
228 }
229 #endif
230
231 /*
232 * Trap into kgdb to wait for debugger to connect,
233 * noting on the console why nothing else is going on.
234 */
235 void
236 kgdb_connect(verbose)
237 int verbose;
238 {
239
240 if (kgdb_dev < 0)
241 return;
242 #if NFB > 0
243 fb_unblank();
244 #endif
245 #ifdef MULTIPROCESSOR
246 /* While we're in the debugger, pause all other CPUs */
247 if (!kgdb_suspend_others()) {
248 kgdb_suspend();
249 } else {
250 #endif
251 if (verbose)
252 printf("kgdb waiting...");
253 __asm("ta %0" :: "n" (T_KGDB_EXEC)); /* trap into kgdb */
254
255 kgdb_debug_panic = 1;
256
257 #ifdef MULTIPROCESSOR
258 /* Other CPUs can continue now */
259 kgdb_resume_others();
260 }
261 #endif
262 }
263
264 /*
265 * Decide what to do on panic.
266 */
267 void
268 kgdb_panic()
269 {
270
271 if (kgdb_dev >= 0 && kgdb_debug_panic)
272 kgdb_connect(kgdb_active == 0);
273 }
274
275 /*
276 * Translate a trap number into a unix compatible signal value.
277 * (gdb only understands unix signal numbers).
278 * XXX should this be done at the other end?
279 */
280 int
281 kgdb_signal(type)
282 int type;
283 {
284 int sigval;
285
286 switch (type) {
287
288 case T_AST:
289 sigval = SIGINT;
290 break;
291
292 case T_TEXTFAULT:
293 case T_DATAFAULT:
294 sigval = SIGSEGV;
295 break;
296
297 case T_ALIGN:
298 sigval = SIGBUS;
299 break;
300
301 case T_ILLINST:
302 case T_PRIVINST:
303 case T_DIV0:
304 sigval = SIGILL;
305 break;
306
307 case T_FP_IEEE_754:
308 case T_FP_OTHER:
309 sigval = SIGFPE;
310 break;
311
312 case T_BREAKPOINT:
313 sigval = SIGTRAP;
314 break;
315
316 case T_KGDB_EXEC:
317 sigval = SIGIOT;
318 break;
319
320 default:
321 sigval = SIGEMT;
322 break;
323 }
324 return (sigval);
325 }
326
327 /*
328 * Definitions exported from gdb (& then made prettier).
329 * (see gnu/dist/toolchain/gdb/config/sparc/tm-sp64.h)
330 */
331 #define GDB_G0 0
332 #define GDB_O0 8
333 #define GDB_L0 16
334 #define GDB_I0 24
335 #define GDB_FP0 32
336 #define GDB_PC 80
337 #define GDB_NPC 81
338 #define GDB_CCR 82
339 #define GDB_FSR 83
340 #define GDB_FPRS 84
341 #define GDB_Y 85
342 #define GDB_ASI 86
343
344 #define REGISTER_BYTES (KGDB_NUMREGS * 8)
345 #define REGISTER_BYTE(n) ((n) * 8)
346
347 /*
348 * Translate the values stored in the kernel regs struct to the format
349 * understood by gdb.
350 */
351 void
352 kgdb_getregs(regs, gdb_regs)
353 db_regs_t *regs;
354 kgdb_reg_t *gdb_regs;
355 {
356 struct trapframe64 *tf = ®s->ddb_tf;
357
358 /* %g0..%g7 and %o0..%o7: from trapframe */
359 gdb_regs[0] = 0;
360 kgdb_copy((caddr_t)&tf->tf_global[1], (caddr_t)&gdb_regs[1], 15 * 8);
361
362 /* %l0..%l7 and %i0..%i7: from stack */
363 kgdb_copy((caddr_t)(long)tf->tf_out[6], (caddr_t)&gdb_regs[GDB_L0], 16 * 8);
364
365 /* %f0..%f31 -- fake, kernel does not use FP */
366 kgdb_zero((caddr_t)&gdb_regs[GDB_FP0], 32 * 8);
367
368 /* %y, %psr, %wim, %tbr, %pc, %npc, %fsr, %csr */
369 gdb_regs[GDB_PC] = tf->tf_pc;
370 gdb_regs[GDB_NPC] = tf->tf_npc;
371 }
372
373 /*
374 * Reverse the above.
375 */
376 void
377 kgdb_setregs(regs, gdb_regs)
378 db_regs_t *regs;
379 kgdb_reg_t *gdb_regs;
380 {
381 struct trapframe64 *tf = ®s->ddb_tf;
382
383 kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 8);
384 kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)(long)tf->tf_out[6], 16 * 8);
385 tf->tf_pc = gdb_regs[GDB_PC];
386 tf->tf_npc = gdb_regs[GDB_NPC];
387 }
388
389 /*
390 * Determine if memory at [va..(va+len)] is valid.
391 */
392 int
393 kgdb_acc(va, len)
394 vaddr_t va;
395 size_t len;
396 {
397 int64_t data;
398 vaddr_t eva;
399 struct pmap *pm = &kernel_pmap_;
400
401 eva = round_page(va + len);
402 va = trunc_page(va);
403
404 simple_lock(&pm->pm_lock);
405 for (; va < eva; va += PAGE_SIZE) {
406 data = pseg_get(pm, va);
407 if ((data & TLB_V) == 0) {
408 simple_unlock(&pm->pm_lock);
409 return 0;
410 }
411 }
412 simple_unlock(&pm->pm_lock);
413
414 return (1);
415 }
416 #endif
417