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