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