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