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