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