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