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