Home | History | Annotate | Line # | Download | only in sparc64
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 = &regs->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 = &regs->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