1 /* $NetBSD: kgdb_stub.c,v 1.12 2002/01/05 22:57:38 dbj Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratories. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 45 */ 46 47 /* 48 * "Stub" to allow remote cpu to debug over a serial line using gdb. 49 */ 50 51 #include <sys/cdefs.h> 52 __KERNEL_RCSID(0, "$NetBSD: kgdb_stub.c,v 1.12 2002/01/05 22:57:38 dbj Exp $"); 53 54 #include "opt_kgdb.h" 55 56 #include <sys/param.h> 57 #include <sys/systm.h> 58 #include <sys/kgdb.h> 59 60 /* #define DEBUG_KGDB XXX */ 61 62 /* XXX: Maybe these should be in the MD files? */ 63 #ifndef KGDB_DEV 64 #define KGDB_DEV NODEV 65 #endif 66 #ifndef KGDB_DEVRATE 67 #define KGDB_DEVRATE 19200 68 #endif 69 70 int kgdb_dev = KGDB_DEV; /* remote debugging device (NODEV if none) */ 71 int kgdb_rate = KGDB_DEVRATE; /* remote debugging baud rate */ 72 int kgdb_active = 0; /* remote debugging active if != 0 */ 73 int kgdb_debug_init = 0; /* != 0 waits for remote at system init */ 74 int kgdb_debug_panic = 0; /* != 0 waits for remote on panic */ 75 label_t *kgdb_recover = 0; 76 77 static void kgdb_copy __P((void *, void *, int)); 78 /* static void kgdb_zero __P((void *, int)); */ 79 static void kgdb_send __P((u_char *)); 80 static int kgdb_recv __P((u_char *, int)); 81 static int digit2i __P((u_char)); 82 static u_char i2digit __P((int)); 83 static void mem2hex __P((void *, void *, int)); 84 static u_char *hex2mem __P((void *, u_char *, int)); 85 static vaddr_t hex2i __P((u_char **)); 86 87 static int (*kgdb_getc) __P((void *)); 88 static void (*kgdb_putc) __P((void *, int)); 89 static void *kgdb_ioarg; 90 91 /* KGDB_BUFLEN must be at least (2*KGDB_NUMREGS*sizeof(kgdb_reg_t)+1) */ 92 static u_char buffer[KGDB_BUFLEN]; 93 static kgdb_reg_t gdb_regs[KGDB_NUMREGS]; 94 95 #define GETC() ((*kgdb_getc)(kgdb_ioarg)) 96 #define PUTC(c) ((*kgdb_putc)(kgdb_ioarg, c)) 97 98 /* 99 * db_trap_callback can be hooked by MD port code to handle special 100 * cases such as disabling hardware watchdogs while in kgdb. Name 101 * is shared with DDB. 102 */ 103 void (*db_trap_callback)(int); 104 105 /* 106 * This little routine exists simply so that bcopy() can be debugged. 107 */ 108 static void 109 kgdb_copy(vsrc, vdst, len) 110 void *vsrc, *vdst; 111 int len; 112 { 113 char *src = vsrc; 114 char *dst = vdst; 115 116 while (--len >= 0) 117 *dst++ = *src++; 118 } 119 120 #if 0 121 /* ditto for bzero */ 122 static void 123 kgdb_zero(vptr, len) 124 void *vptr; 125 int len; 126 { 127 char *ptr = vptr; 128 129 while (--len >= 0) 130 *ptr++ = (char) 0; 131 } 132 #endif 133 134 /* 135 * Convert a hex digit into an integer. 136 * This returns -1 if the argument passed is no 137 * valid hex digit. 138 */ 139 static int 140 digit2i(c) 141 u_char c; 142 { 143 if (c >= '0' && c <= '9') 144 return (c - '0'); 145 else if (c >= 'a' && c <= 'f') 146 return (c - 'a' + 10); 147 else if (c >= 'A' && c <= 'F') 148 149 return (c - 'A' + 10); 150 else 151 return (-1); 152 } 153 154 /* 155 * Convert the low 4 bits of an integer into 156 * an hex digit. 157 */ 158 static u_char 159 i2digit(n) 160 int n; 161 { 162 return ("0123456789abcdef"[n & 0x0f]); 163 } 164 165 /* 166 * Convert a byte array into an hex string. 167 */ 168 static void 169 mem2hex(vdst, vsrc, len) 170 void *vdst, *vsrc; 171 int len; 172 { 173 u_char *dst = vdst; 174 u_char *src = vsrc; 175 176 while (len--) { 177 *dst++ = i2digit(*src >> 4); 178 *dst++ = i2digit(*src++); 179 } 180 *dst = '\0'; 181 } 182 183 /* 184 * Convert an hex string into a byte array. 185 * This returns a pointer to the character following 186 * the last valid hex digit. If the string ends in 187 * the middle of a byte, NULL is returned. 188 */ 189 static u_char * 190 hex2mem(vdst, src, maxlen) 191 void *vdst; 192 u_char *src; 193 int maxlen; 194 { 195 u_char *dst = vdst; 196 int msb, lsb; 197 198 while (*src && maxlen--) { 199 msb = digit2i(*src++); 200 if (msb < 0) 201 return (src - 1); 202 lsb = digit2i(*src++); 203 if (lsb < 0) 204 return (NULL); 205 *dst++ = (msb << 4) | lsb; 206 } 207 return (src); 208 } 209 210 /* 211 * Convert an hex string into an integer. 212 * This returns a pointer to the character following 213 * the last valid hex digit. 214 */ 215 static vaddr_t 216 hex2i(srcp) 217 u_char **srcp; 218 { 219 char *src = *srcp; 220 vaddr_t r = 0; 221 int nibble; 222 223 while ((nibble = digit2i(*src)) >= 0) { 224 r *= 16; 225 r += nibble; 226 src++; 227 } 228 *srcp = src; 229 return (r); 230 } 231 232 /* 233 * Send a packet. 234 */ 235 static void 236 kgdb_send(bp) 237 u_char *bp; 238 { 239 u_char *p; 240 u_char csum, c; 241 242 #ifdef DEBUG_KGDB 243 printf("kgdb_send: %s\n", bp); 244 #endif 245 do { 246 p = bp; 247 PUTC(KGDB_START); 248 for (csum = 0; (c = *p); p++) { 249 PUTC(c); 250 csum += c; 251 } 252 PUTC(KGDB_END); 253 PUTC(i2digit(csum >> 4)); 254 PUTC(i2digit(csum)); 255 } while ((c = GETC() & 0x7f) == KGDB_BADP); 256 } 257 258 /* 259 * Receive a packet. 260 */ 261 static int 262 kgdb_recv(bp, maxlen) 263 u_char *bp; 264 int maxlen; 265 { 266 u_char *p; 267 int c, csum; 268 int len; 269 270 do { 271 p = bp; 272 csum = len = 0; 273 while ((c = GETC()) != KGDB_START) 274 ; 275 276 while ((c = GETC()) != KGDB_END && len < maxlen) { 277 c &= 0x7f; 278 csum += c; 279 *p++ = c; 280 len++; 281 } 282 csum &= 0xff; 283 *p = '\0'; 284 285 if (len >= maxlen) { 286 PUTC(KGDB_BADP); 287 continue; 288 } 289 290 csum -= digit2i(GETC()) * 16; 291 csum -= digit2i(GETC()); 292 293 if (csum == 0) { 294 PUTC(KGDB_GOODP); 295 /* Sequence present? */ 296 if (bp[2] == ':') { 297 PUTC(bp[0]); 298 PUTC(bp[1]); 299 len -= 3; 300 kgdb_copy(bp + 3, bp, len); 301 } 302 break; 303 } 304 PUTC(KGDB_BADP); 305 } while (1); 306 #ifdef DEBUG_KGDB 307 printf("kgdb_recv: %s\n", bp); 308 #endif 309 return (len); 310 } 311 312 /* 313 * This is called by the appropriate tty driver. 314 */ 315 void 316 kgdb_attach(getfn, putfn, ioarg) 317 int (*getfn) __P((void *)); 318 void (*putfn) __P((void *, int)); 319 void *ioarg; 320 { 321 kgdb_getc = getfn; 322 kgdb_putc = putfn; 323 kgdb_ioarg = ioarg; 324 } 325 326 /* 327 * This function does all command processing for interfacing to 328 * a remote gdb. Note that the error codes are ignored by gdb 329 * at present, but might eventually become meaningful. (XXX) 330 * It might makes sense to use POSIX errno values, because 331 * that is what the gdb/remote.c functions want to return. 332 */ 333 int 334 kgdb_trap(type, regs) 335 int type; 336 db_regs_t *regs; 337 { 338 label_t jmpbuf; 339 vaddr_t addr; 340 size_t len; 341 u_char *p; 342 343 if (kgdb_dev < 0 || kgdb_getc == NULL) { 344 /* not debugging */ 345 return (0); 346 } 347 348 db_clear_single_step(regs); 349 350 if (db_trap_callback) db_trap_callback(1); 351 352 /* Detect and recover from unexpected traps. */ 353 if (kgdb_recover != 0) { 354 printf("kgdb: caught trap 0x%x at %p\n", 355 type, (void*)PC_REGS(regs)); 356 kgdb_send("E0E"); /* 14==EFAULT */ 357 longjmp(kgdb_recover); 358 } 359 360 /* 361 * The first entry to this function is normally through 362 * a breakpoint trap in kgdb_connect(), in which case we 363 * must advance past the breakpoint because gdb will not. 364 * 365 * Machines vary as to where they leave the PC after a 366 * breakpoint trap. Those that leave the PC set to the 367 * address of the trap instruction (i.e. pc532) will not 368 * define FIXUP_PC_AFTER_BREAK(), and therefore will just 369 * advance the PC. On machines that leave the PC set to 370 * the instruction after the trap, FIXUP_PC_AFTER_BREAK 371 * will be defined to back-up the PC, so that after the 372 * "first-time" part of the if statement below has run, 373 * the PC will be the same as it was on entry. 374 * 375 * On the first entry here, we expect that gdb is not yet 376 * listening to us, so just enter the interaction loop. 377 * After the debugger is "active" (connected) it will be 378 * waiting for a "signaled" message from us. 379 */ 380 if (kgdb_active == 0) { 381 if (!IS_BREAKPOINT_TRAP(type, 0)) { 382 /* No debugger active -- let trap handle this. */ 383 if (db_trap_callback) db_trap_callback(0); 384 return (0); 385 } 386 /* Make the PC point at the breakpoint... */ 387 #ifdef FIXUP_PC_AFTER_BREAK 388 FIXUP_PC_AFTER_BREAK(regs); 389 #endif 390 /* ... and then advance past it. */ 391 #ifdef PC_ADVANCE 392 PC_ADVANCE(regs); 393 #else 394 PC_REGS(regs) += BKPT_SIZE; 395 #endif 396 kgdb_active = 1; 397 } else { 398 /* Tell remote host that an exception has occurred. */ 399 sprintf(buffer, "S%02x", kgdb_signal(type)); 400 kgdb_send(buffer); 401 } 402 403 /* Stick frame regs into our reg cache. */ 404 kgdb_getregs(regs, gdb_regs); 405 406 /* 407 * Interact with gdb until it lets us go. 408 * If we cause a trap, resume here. 409 */ 410 (void)setjmp((kgdb_recover = &jmpbuf)); 411 for (;;) { 412 kgdb_recv(buffer, sizeof(buffer)); 413 switch (buffer[0]) { 414 415 default: 416 /* Unknown command. */ 417 kgdb_send(""); 418 continue; 419 420 case KGDB_SIGNAL: 421 /* 422 * if this command came from a running gdb, 423 * answer it -- the other guy has no way of 424 * knowing if we're in or out of this loop 425 * when he issues a "remote-signal". 426 */ 427 sprintf(buffer, "S%02x", kgdb_signal(type)); 428 kgdb_send(buffer); 429 continue; 430 431 case KGDB_REG_R: 432 mem2hex(buffer, gdb_regs, sizeof(gdb_regs)); 433 kgdb_send(buffer); 434 continue; 435 436 case KGDB_REG_W: 437 p = hex2mem(gdb_regs, buffer + 1, sizeof(gdb_regs)); 438 if (p == NULL || *p != '\0') 439 kgdb_send("E01"); 440 else { 441 kgdb_setregs(regs, gdb_regs); 442 kgdb_send("OK"); 443 } 444 continue; 445 446 case KGDB_MEM_R: 447 p = buffer + 1; 448 addr = hex2i(&p); 449 if (*p++ != ',') { 450 kgdb_send("E02"); 451 continue; 452 } 453 len = hex2i(&p); 454 if (*p != '\0') { 455 kgdb_send("E03"); 456 continue; 457 } 458 if (len > sizeof(buffer) / 2) { 459 kgdb_send("E04"); 460 continue; 461 } 462 if (kgdb_acc(addr, len) == 0) { 463 kgdb_send("E05"); 464 continue; 465 } 466 db_read_bytes(addr, (size_t)len, 467 (char *)buffer + sizeof(buffer) / 2); 468 mem2hex(buffer, buffer + sizeof(buffer) / 2, len); 469 kgdb_send(buffer); 470 continue; 471 472 case KGDB_MEM_W: 473 p = buffer + 1; 474 addr = hex2i(&p); 475 if (*p++ != ',') { 476 kgdb_send("E06"); 477 continue; 478 } 479 len = hex2i(&p); 480 if (*p++ != ':') { 481 kgdb_send("E07"); 482 continue; 483 } 484 if (len > (sizeof(buffer) - (p - buffer))) { 485 kgdb_send("E08"); 486 continue; 487 } 488 p = hex2mem(buffer, p, sizeof(buffer)); 489 if (p == NULL) { 490 kgdb_send("E09"); 491 continue; 492 } 493 if (kgdb_acc(addr, len) == 0) { 494 kgdb_send("E0A"); 495 continue; 496 } 497 db_write_bytes(addr, (size_t)len, (char *)buffer); 498 kgdb_send("OK"); 499 continue; 500 501 case KGDB_DETACH: 502 case KGDB_KILL: 503 kgdb_active = 0; 504 printf("kgdb detached\n"); 505 db_clear_single_step(regs); 506 kgdb_send("OK"); 507 goto out; 508 509 case KGDB_CONT: 510 if (buffer[1]) { 511 p = buffer + 1; 512 addr = hex2i(&p); 513 if (*p) { 514 kgdb_send("E0B"); 515 continue; 516 } 517 PC_REGS(regs) = addr; 518 } 519 db_clear_single_step(regs); 520 goto out; 521 522 case KGDB_STEP: 523 if (buffer[1]) { 524 p = buffer + 1; 525 addr = hex2i(&p); 526 if (*p) { 527 kgdb_send("E0B"); 528 continue; 529 } 530 PC_REGS(regs) = addr; 531 } 532 db_set_single_step(regs); 533 goto out; 534 } 535 } 536 out: 537 if (db_trap_callback) db_trap_callback(0); 538 kgdb_recover = 0; 539 return (1); 540 } 541