1 /* $NetBSD: kgdb_machdep.c,v 1.11 2002/07/17 15:57:12 thorpej 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 * Copyright (c) 1995 42 * The President and Fellows of Harvard College. All rights reserved. 43 * 44 * This software was developed by the Computer Systems Engineering group 45 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 46 * contributed to Berkeley. 47 * 48 * All advertising materials mentioning features or use of this software 49 * must display the following acknowledgements: 50 * This product includes software developed by the University of 51 * California, Lawrence Berkeley Laboratory. 52 * 53 * This product includes software developed by Harvard University. 54 * 55 * Redistribution and use in source and binary forms, with or without 56 * modification, are permitted provided that the following conditions 57 * are met: 58 * 1. Redistributions of source code must retain the above copyright 59 * notice, this list of conditions and the following disclaimer. 60 * 2. Redistributions in binary form must reproduce the above copyright 61 * notice, this list of conditions and the following disclaimer in the 62 * documentation and/or other materials provided with the distribution. 63 * 3. All advertising materials mentioning features or use of this software 64 * must display the following acknowledgement: 65 * This product includes software developed by the University of 66 * California, Berkeley and its contributors. 67 * 4. Neither the name of the University nor the names of its contributors 68 * may be used to endorse or promote products derived from this software 69 * without specific prior written permission. 70 * 71 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 72 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 73 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 74 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 75 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 76 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 77 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 78 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 79 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 80 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 81 * SUCH DAMAGE. 82 * 83 * @(#)kgdb_stub.c 8.1 (Berkeley) 6/11/93 84 */ 85 86 /* 87 * Machine dependent routines needed by kern/kgdb_stub.c 88 */ 89 90 #include "opt_kgdb.h" 91 #include "opt_multiprocessor.h" 92 #include "opt_sparc_arch.h" 93 94 #ifdef KGDB 95 96 #include <sys/param.h> 97 #include <sys/systm.h> 98 #include <sys/buf.h> 99 #include <sys/kgdb.h> 100 101 #include <machine/ctlreg.h> 102 #include <machine/psl.h> 103 #include <machine/reg.h> 104 #include <machine/trap.h> 105 #include <machine/cpu.h> 106 107 #include <sparc/sparc/asm.h> 108 109 static __inline void kgdb_copy __P((char *, char *, int)); 110 static __inline void kgdb_zero __P((char *, int)); 111 112 /* 113 * This little routine exists simply so that bcopy() can be debugged. 114 */ 115 static __inline void 116 kgdb_copy(src, dst, len) 117 register char *src, *dst; 118 register int len; 119 { 120 121 while (--len >= 0) 122 *dst++ = *src++; 123 } 124 125 /* ditto for bzero */ 126 static __inline void 127 kgdb_zero(ptr, len) 128 register char *ptr; 129 register int len; 130 { 131 while (--len >= 0) 132 *ptr++ = (char) 0; 133 } 134 135 /* 136 * Deal with KGDB in a MP environment. XXX need to have "mach cpu" equiv. 137 */ 138 #ifdef MULTIPROCESSOR 139 140 #define NOCPU -1 141 142 static int kgdb_suspend_others(void); 143 static void kgdb_resume_others(void); 144 static void kgdb_suspend(void); 145 146 __cpu_simple_lock_t kgdb_lock; 147 int kgdb_cpu = NOCPU; 148 149 static int 150 kgdb_suspend_others(void) 151 { 152 int cpu_me = cpu_number(); 153 int win; 154 155 if (cpus == NULL) 156 return 1; 157 158 __cpu_simple_lock(&kgdb_lock); 159 if (kgdb_cpu == NOCPU) 160 kgdb_cpu = cpu_me; 161 win = (kgdb_cpu == cpu_me); 162 __cpu_simple_unlock(&kgdb_lock); 163 164 if (win) 165 mp_pause_cpus(); 166 167 return win; 168 } 169 170 static void 171 kgdb_resume_others(void) 172 { 173 174 mp_resume_cpus(); 175 176 __cpu_simple_lock(&kgdb_lock); 177 kgdb_cpu = NOCPU; 178 __cpu_simple_unlock(&kgdb_lock); 179 } 180 181 static void 182 kgdb_suspend() 183 { 184 185 while (cpuinfo.flags & CPUFLG_PAUSED) 186 cpuinfo.cache_flush((caddr_t)&cpuinfo.flags, sizeof(cpuinfo.flags)); 187 } 188 #endif 189 190 /* 191 * Trap into kgdb to wait for debugger to connect, 192 * noting on the console why nothing else is going on. 193 */ 194 void 195 kgdb_connect(verbose) 196 int verbose; 197 { 198 199 if (kgdb_dev < 0) 200 return; 201 #if NFB > 0 202 fb_unblank(); 203 #endif 204 #ifdef MULTIPROCESSOR 205 /* While we're in the debugger, pause all other CPUs */ 206 if (!kgdb_suspend_others()) { 207 kgdb_suspend(); 208 } else { 209 #endif 210 if (verbose) 211 printf("kgdb waiting..."); 212 __asm("ta %0" :: "n" (T_KGDB_EXEC)); /* trap into kgdb */ 213 214 kgdb_debug_panic = 1; 215 216 #ifdef MULTIPROCESSOR 217 /* Other CPUs can continue now */ 218 kgdb_resume_others(); 219 } 220 #endif 221 } 222 223 /* 224 * Decide what to do on panic. 225 */ 226 void 227 kgdb_panic() 228 { 229 230 if (kgdb_dev >= 0 && kgdb_debug_panic) 231 kgdb_connect(kgdb_active == 0); 232 } 233 234 /* 235 * Translate a trap number into a unix compatible signal value. 236 * (gdb only understands unix signal numbers). 237 * XXX should this be done at the other end? 238 */ 239 int 240 kgdb_signal(type) 241 int type; 242 { 243 int sigval; 244 245 switch (type) { 246 247 case T_AST: 248 sigval = SIGINT; 249 break; 250 251 case T_TEXTFAULT: 252 case T_DATAFAULT: 253 sigval = SIGSEGV; 254 break; 255 256 case T_ALIGN: 257 sigval = SIGBUS; 258 break; 259 260 case T_ILLINST: 261 case T_PRIVINST: 262 case T_DIV0: 263 sigval = SIGILL; 264 break; 265 266 case T_FPE: 267 sigval = SIGFPE; 268 break; 269 270 case T_BREAKPOINT: 271 sigval = SIGTRAP; 272 break; 273 274 case T_KGDB_EXEC: 275 sigval = SIGIOT; 276 break; 277 278 default: 279 sigval = SIGEMT; 280 break; 281 } 282 return (sigval); 283 } 284 285 /* 286 * Definitions exported from gdb (& then made prettier). 287 */ 288 #define GDB_G0 0 289 #define GDB_O0 8 290 #define GDB_L0 16 291 #define GDB_I0 24 292 #define GDB_FP0 32 293 #define GDB_Y 64 294 #define GDB_PSR 65 295 #define GDB_WIM 66 296 #define GDB_TBR 67 297 #define GDB_PC 68 298 #define GDB_NPC 69 299 #define GDB_FSR 70 300 #define GDB_CSR 71 301 302 #define REGISTER_BYTES (KGDB_NUMREGS * 4) 303 #define REGISTER_BYTE(n) ((n) * 4) 304 305 /* 306 * Translate the values stored in the kernel regs struct to the format 307 * understood by gdb. 308 */ 309 void 310 kgdb_getregs(regs, gdb_regs) 311 db_regs_t *regs; 312 kgdb_reg_t *gdb_regs; 313 { 314 struct trapframe *tf = ®s->db_tf; 315 316 /* %g0..%g7 and %o0..%o7: from trapframe */ 317 gdb_regs[0] = 0; 318 kgdb_copy((caddr_t)&tf->tf_global[1], (caddr_t)&gdb_regs[1], 15 * 4); 319 320 /* %l0..%l7 and %i0..%i7: from stack */ 321 kgdb_copy((caddr_t)tf->tf_out[6], (caddr_t)&gdb_regs[GDB_L0], 16 * 4); 322 323 /* %f0..%f31 -- fake, kernel does not use FP */ 324 kgdb_zero((caddr_t)&gdb_regs[GDB_FP0], 32 * 4); 325 326 /* %y, %psr, %wim, %tbr, %pc, %npc, %fsr, %csr */ 327 gdb_regs[GDB_Y] = tf->tf_y; 328 gdb_regs[GDB_PSR] = tf->tf_psr; 329 gdb_regs[GDB_WIM] = tf->tf_global[0]; /* input only! */ 330 gdb_regs[GDB_TBR] = 0; /* fake */ 331 gdb_regs[GDB_PC] = tf->tf_pc; 332 gdb_regs[GDB_NPC] = tf->tf_npc; 333 gdb_regs[GDB_FSR] = 0; /* fake */ 334 gdb_regs[GDB_CSR] = 0; /* fake */ 335 } 336 337 /* 338 * Reverse the above. 339 */ 340 void 341 kgdb_setregs(regs, gdb_regs) 342 db_regs_t *regs; 343 kgdb_reg_t *gdb_regs; 344 { 345 struct trapframe *tf = ®s->db_tf; 346 347 kgdb_copy((caddr_t)&gdb_regs[1], (caddr_t)&tf->tf_global[1], 15 * 4); 348 kgdb_copy((caddr_t)&gdb_regs[GDB_L0], (caddr_t)tf->tf_out[6], 16 * 4); 349 tf->tf_y = gdb_regs[GDB_Y]; 350 tf->tf_psr = gdb_regs[GDB_PSR]; 351 tf->tf_pc = gdb_regs[GDB_PC]; 352 tf->tf_npc = gdb_regs[GDB_NPC]; 353 } 354 355 /* 356 * Determine if memory at [va..(va+len)] is valid. 357 */ 358 int 359 kgdb_acc(va, len) 360 vaddr_t va; 361 size_t len; 362 { 363 int pte; 364 vaddr_t eva; 365 366 eva = round_page(va + len); 367 va = trunc_page(va); 368 369 /* XXX icky: valid address but causes timeout */ 370 if (va >= (vaddr_t)0xfffff000) 371 return (0); 372 373 for (; va < eva; va += NBPG) { 374 #if defined(SUN4M) || defined(SUN4D) 375 if (CPU_HAS_SRMMU) { 376 pte = getpte4m(va); 377 if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) 378 return (0); 379 } 380 #endif 381 #if defined(SUN4) || defined(SUN4C) 382 if (CPU_ISSUN4C || CPU_ISSUN4) { 383 pte = getpte4(va); 384 if ((pte & PG_V) == 0) 385 return (0); 386 } 387 #endif 388 } 389 390 return (1); 391 } 392 #endif 393