Home | History | Annotate | Line # | Download | only in sparc
      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
    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
    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
    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
    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
    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
    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
    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
    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
    340 kgdb_getregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
    341 {
    342 	struct trapframe *tf = &regs->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
    369 kgdb_setregs(db_regs_t *regs, kgdb_reg_t *gdb_regs)
    370 {
    371 	struct trapframe *tf = &regs->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
    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