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