xref: /netbsd/sys/arch/sparc64/sparc64/kgdb_machdep.c (revision 6550d01e)
1 /*	$NetBSD: kgdb_machdep.c,v 1.14 2009/03/18 10:22: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  * 	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.14 2009/03/18 10:22:37 cegger 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
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
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
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
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
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
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
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
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
342 kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
343 {
344 	struct trapframe64 *tf = &regs->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
365 kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
366 {
367 	struct trapframe64 *tf = &regs->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
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 	simple_lock(&pm->pm_lock);
389 	for (; va < eva; va += PAGE_SIZE) {
390 		data = pseg_get(pm, va);
391 		if ((data & TLB_V) == 0) {
392 			simple_unlock(&pm->pm_lock);
393 			return 0;
394 		}
395 	}
396 	simple_unlock(&pm->pm_lock);
397 
398 	return (1);
399 }
400 #endif
401