kgdb_machdep.c revision 1.6 1 /* $NetBSD: kgdb_machdep.c,v 1.6 2005/12/24 20:07:37 perry 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.6 2005/12/24 20:07:37 perry 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 __P((struct pmap *, vaddr_t));
153
154 static inline void kgdb_copy __P((char *, char *, int));
155 static inline void kgdb_zero __P((char *, int));
156
157 /*
158 * This little routine exists simply so that bcopy() can be debugged.
159 */
160 static inline void
161 kgdb_copy(src, dst, len)
162 register char *src, *dst;
163 register int len;
164 {
165
166 while (--len >= 0)
167 *dst++ = *src++;
168 }
169
170 /* ditto for bzero */
171 static inline void
172 kgdb_zero(ptr, len)
173 register char *ptr;
174 register int len;
175 {
176 while (--len >= 0)
177 *ptr++ = (char) 0;
178 }
179
180 /*
181 * Deal with KGDB in a MP environment. XXX need to have "mach cpu" equiv.
182 */
183 #ifdef MULTIPROCESSOR
184
185 #define NOCPU -1
186
187 static int kgdb_suspend_others(void);
188 static void kgdb_resume_others(void);
189 static void kgdb_suspend(void);
190
191 __cpu_simple_lock_t kgdb_lock;
192 int kgdb_cpu = NOCPU;
193
194 static int
195 kgdb_suspend_others(void)
196 {
197 int cpu_me = cpu_number();
198 int win;
199
200 if (cpus == NULL)
201 return 1;
202
203 __cpu_simple_lock(&kgdb_lock);
204 if (kgdb_cpu == NOCPU)
205 kgdb_cpu = cpu_me;
206 win = (kgdb_cpu == cpu_me);
207 __cpu_simple_unlock(&kgdb_lock);
208
209 if (win)
210 mp_pause_cpus();
211
212 return win;
213 }
214
215 static void
216 kgdb_resume_others(void)
217 {
218
219 mp_resume_cpus();
220
221 __cpu_simple_lock(&kgdb_lock);
222 kgdb_cpu = NOCPU;
223 __cpu_simple_unlock(&kgdb_lock);
224 }
225
226 static void
227 kgdb_suspend()
228 {
229
230 while (cpuinfo.flags & CPUFLG_PAUSED)
231 cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags));
232 }
233 #endif
234
235 /*
236 * Trap into kgdb to wait for debugger to connect,
237 * noting on the console why nothing else is going on.
238 */
239 void
240 kgdb_connect(verbose)
241 int verbose;
242 {
243
244 if (kgdb_dev < 0)
245 return;
246 #if NFB > 0
247 fb_unblank();
248 #endif
249 #ifdef MULTIPROCESSOR
250 /* While we're in the debugger, pause all other CPUs */
251 if (!kgdb_suspend_others()) {
252 kgdb_suspend();
253 } else {
254 #endif
255 if (verbose)
256 printf("kgdb waiting...");
257 __asm("ta %0" :: "n" (T_KGDB_EXEC)); /* trap into kgdb */
258
259 kgdb_debug_panic = 1;
260
261 #ifdef MULTIPROCESSOR
262 /* Other CPUs can continue now */
263 kgdb_resume_others();
264 }
265 #endif
266 }
267
268 /*
269 * Decide what to do on panic.
270 */
271 void
272 kgdb_panic()
273 {
274
275 if (kgdb_dev >= 0 && kgdb_debug_panic)
276 kgdb_connect(kgdb_active == 0);
277 }
278
279 /*
280 * Translate a trap number into a unix compatible signal value.
281 * (gdb only understands unix signal numbers).
282 * XXX should this be done at the other end?
283 */
284 int
285 kgdb_signal(type)
286 int type;
287 {
288 int sigval;
289
290 switch (type) {
291
292 case T_AST:
293 sigval = SIGINT;
294 break;
295
296 case T_TEXTFAULT:
297 case T_DATAFAULT:
298 sigval = SIGSEGV;
299 break;
300
301 case T_ALIGN:
302 sigval = SIGBUS;
303 break;
304
305 case T_ILLINST:
306 case T_PRIVINST:
307 case T_DIV0:
308 sigval = SIGILL;
309 break;
310
311 case T_FP_IEEE_754:
312 case T_FP_OTHER:
313 sigval = SIGFPE;
314 break;
315
316 case T_BREAKPOINT:
317 sigval = SIGTRAP;
318 break;
319
320 case T_KGDB_EXEC:
321 sigval = SIGIOT;
322 break;
323
324 default:
325 sigval = SIGEMT;
326 break;
327 }
328 return (sigval);
329 }
330
331 /*
332 * Definitions exported from gdb (& then made prettier).
333 * (see gnu/dist/toolchain/gdb/config/sparc/tm-sp64.h)
334 */
335 #define GDB_G0 0
336 #define GDB_O0 8
337 #define GDB_L0 16
338 #define GDB_I0 24
339 #define GDB_FP0 32
340 #define GDB_PC 80
341 #define GDB_NPC 81
342 #define GDB_CCR 82
343 #define GDB_FSR 83
344 #define GDB_FPRS 84
345 #define GDB_Y 85
346 #define GDB_ASI 86
347
348 #define REGISTER_BYTES (KGDB_NUMREGS * 8)
349 #define REGISTER_BYTE(n) ((n) * 8)
350
351 /*
352 * Translate the values stored in the kernel regs struct to the format
353 * understood by gdb.
354 */
355 void
356 kgdb_getregs(regs, gdb_regs)
357 db_regs_t *regs;
358 kgdb_reg_t *gdb_regs;
359 {
360 struct trapframe64 *tf = ®s->ddb_tf;
361
362 /* %g0..%g7 and %o0..%o7: from trapframe */
363 gdb_regs[0] = 0;
364 kgdb_copy((caddr_t)&tf->tf_global[1], (caddr_t)&gdb_regs[1], 15 * 8);
365
366 /* %l0..%l7 and %i0..%i7: from stack */
367 kgdb_copy((caddr_t)(long)tf->tf_out[6], (caddr_t)&gdb_regs[GDB_L0], 16 * 8);
368
369 /* %f0..%f31 -- fake, kernel does not use FP */
370 kgdb_zero((caddr_t)&gdb_regs[GDB_FP0], 32 * 8);
371
372 /* %y, %psr, %wim, %tbr, %pc, %npc, %fsr, %csr */
373 gdb_regs[GDB_PC] = tf->tf_pc;
374 gdb_regs[GDB_NPC] = tf->tf_npc;
375 }
376
377 /*
378 * Reverse the above.
379 */
380 void
381 kgdb_setregs(regs, gdb_regs)
382 db_regs_t *regs;
383 kgdb_reg_t *gdb_regs;
384 {
385 struct trapframe64 *tf = ®s->ddb_tf;
386
387 kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 8);
388 kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)(long)tf->tf_out[6], 16 * 8);
389 tf->tf_pc = gdb_regs[GDB_PC];
390 tf->tf_npc = gdb_regs[GDB_NPC];
391 }
392
393 /*
394 * Determine if memory at [va..(va+len)] is valid.
395 */
396 int
397 kgdb_acc(va, len)
398 vaddr_t va;
399 size_t len;
400 {
401 int64_t data;
402 vaddr_t eva;
403 struct pmap *pm = &kernel_pmap_;
404
405 eva = round_page(va + len);
406 va = trunc_page(va);
407
408 simple_lock(&pm->pm_lock);
409 for (; va < eva; va += PAGE_SIZE) {
410 data = pseg_get(pm, va);
411 if ((data & TLB_V) == 0) {
412 simple_unlock(&pm->pm_lock);
413 return 0;
414 }
415 }
416 simple_unlock(&pm->pm_lock);
417
418 return (1);
419 }
420 #endif
421