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 = ®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 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 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