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