1 /* 2 * Copyright (c) 1990 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Van Jacobson and Steven McCanne of Lawrence Berkeley Laboratory. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)kgdb_stub.c 7.14 (Berkeley) 10/11/92 11 */ 12 13 /* 14 * "Stub" to allow remote cpu to debug over a serial line using gdb. 15 */ 16 #ifdef KGDB 17 #ifndef lint 18 static char rcsid[] = "$Header: kgdb_stub.c,v 1.2 92/07/23 19:37:50 mccanne Exp $"; 19 #endif 20 21 #include <sys/param.h> 22 #include <sys/systm.h> 23 24 #include <machine/trap.h> 25 #include <machine/cpu.h> 26 #include <machine/psl.h> 27 #include <machine/reg.h> 28 #include <machine/frame.h> 29 30 #include <sys/buf.h> 31 #include <hp/dev/cons.h> 32 33 #include <hp300/hp300/kgdb_proto.h> 34 #include <machine/remote-sl.h> 35 36 extern int kernacc(); 37 extern void chgkprot(); 38 39 #ifndef KGDBDEV 40 #define KGDBDEV NODEV 41 #endif 42 #ifndef KGDBRATE 43 #define KGDBRATE 9600 44 #endif 45 46 dev_t kgdb_dev = KGDBDEV; /* remote debugging device (NODEV if none) */ 47 int kgdb_rate = KGDBRATE; /* remote debugging baud rate */ 48 int kgdb_active = 0; /* remote debugging active if != 0 */ 49 int kgdb_debug_init = 0; /* != 0 waits for remote at system init */ 50 int kgdb_debug_panic = 1; /* != 0 waits for remote on panic */ 51 int kgdb_debug = 0; 52 53 #define GETC ((*kgdb_getc)(kgdb_dev)) 54 #define PUTC(c) ((*kgdb_putc)(kgdb_dev, c)) 55 #define PUTESC(c) { \ 56 if (c == FRAME_END) { \ 57 PUTC(FRAME_ESCAPE); \ 58 c = TRANS_FRAME_END; \ 59 } else if (c == FRAME_ESCAPE) { \ 60 PUTC(FRAME_ESCAPE); \ 61 c = TRANS_FRAME_ESCAPE; \ 62 } else if (c == FRAME_START) { \ 63 PUTC(FRAME_ESCAPE); \ 64 c = TRANS_FRAME_START; \ 65 } \ 66 PUTC(c); \ 67 } 68 static int (*kgdb_getc)(); 69 static int (*kgdb_putc)(); 70 71 /* 72 * Send a message. The host gets one chance to read it. 73 */ 74 static void 75 kgdb_send(type, bp, len) 76 register u_char type; 77 register u_char *bp; 78 register int len; 79 { 80 register u_char csum; 81 register u_char *ep = bp + len; 82 83 PUTC(FRAME_START); 84 PUTESC(type); 85 86 csum = type; 87 while (bp < ep) { 88 type = *bp++; 89 csum += type; 90 PUTESC(type) 91 } 92 csum = -csum; 93 PUTESC(csum) 94 PUTC(FRAME_END); 95 } 96 97 static int 98 kgdb_recv(bp, lenp) 99 u_char *bp; 100 int *lenp; 101 { 102 register u_char c, csum; 103 register int escape, len; 104 register int type; 105 106 restart: 107 csum = len = escape = 0; 108 type = -1; 109 while (1) { 110 c = GETC; 111 switch (c) { 112 113 case FRAME_ESCAPE: 114 escape = 1; 115 continue; 116 117 case TRANS_FRAME_ESCAPE: 118 if (escape) 119 c = FRAME_ESCAPE; 120 break; 121 122 case TRANS_FRAME_END: 123 if (escape) 124 c = FRAME_END; 125 break; 126 127 case TRANS_FRAME_START: 128 if (escape) 129 c = FRAME_START; 130 break; 131 132 case FRAME_START: 133 goto restart; 134 135 case FRAME_END: 136 if (type < 0 || --len < 0) { 137 csum = len = escape = 0; 138 type = -1; 139 continue; 140 } 141 if (csum != 0) { 142 return (0); 143 } 144 *lenp = len; 145 return type; 146 } 147 csum += c; 148 if (type < 0) { 149 type = c; 150 escape = 0; 151 continue; 152 } 153 if (++len > SL_RPCSIZE) { 154 while (GETC != FRAME_END) 155 ; 156 return (0); 157 } 158 *bp++ = c; 159 escape = 0; 160 } 161 } 162 163 /* 164 * Translate a trap number into a unix compatible signal value. 165 * (gdb only understands unix signal numbers). 166 */ 167 static int 168 computeSignal(type) 169 int type; 170 { 171 int sigval; 172 173 switch (type) { 174 case T_BUSERR: 175 sigval = SIGBUS; 176 break; 177 case T_ADDRERR: 178 sigval = SIGBUS; 179 break; 180 case T_ILLINST: 181 sigval = SIGILL; 182 break; 183 case T_ZERODIV: 184 sigval = SIGFPE; 185 break; 186 case T_CHKINST: 187 sigval = SIGFPE; 188 break; 189 case T_TRAPVINST: 190 sigval = SIGFPE; 191 break; 192 case T_PRIVINST: 193 sigval = SIGILL; 194 break; 195 case T_TRACE: 196 sigval = SIGTRAP; 197 break; 198 case T_MMUFLT: 199 sigval = SIGSEGV; 200 break; 201 case T_SSIR: 202 sigval = SIGSEGV; 203 break; 204 case T_FMTERR: 205 sigval = SIGILL; 206 break; 207 case T_FPERR: 208 sigval = SIGFPE; 209 break; 210 case T_COPERR: 211 sigval = SIGFPE; 212 break; 213 case T_ASTFLT: 214 sigval = SIGINT; 215 break; 216 case T_TRAP15: 217 sigval = SIGTRAP; 218 break; 219 default: 220 sigval = SIGEMT; 221 break; 222 } 223 return (sigval); 224 } 225 226 /* 227 * Trap into kgdb to wait for debugger to connect, 228 * noting on the console why nothing else is going on. 229 */ 230 kgdb_connect(verbose) 231 int verbose; 232 { 233 234 if (verbose) 235 printf("kgdb waiting..."); 236 /* trap into kgdb */ 237 asm("trap #15;"); 238 if (verbose) 239 printf("connected.\n"); 240 } 241 242 /* 243 * Decide what to do on panic. 244 */ 245 kgdb_panic() 246 { 247 248 if (kgdb_active == 0 && kgdb_debug_panic && kgdb_dev != NODEV) 249 kgdb_connect(1); 250 } 251 252 /* 253 * Definitions exported from gdb. 254 */ 255 #define NUM_REGS 18 256 #define REGISTER_BYTES ((16+2)*4) 257 #define REGISTER_BYTE(N) ((N)*4) 258 259 #define GDB_SR 16 260 #define GDB_PC 17 261 262 static inline void 263 kgdb_copy(register u_char *src, register u_char *dst, register u_int nbytes) 264 { 265 register u_char *ep = src + nbytes; 266 267 while (src < ep) 268 *dst++ = *src++; 269 } 270 271 #define regs_to_gdb(fp, regs) \ 272 (kgdb_copy((u_char *)((fp)->f_regs), (u_char *)(regs), REGISTER_BYTES)) 273 274 #define gdb_to_regs(fp, regs) \ 275 (kgdb_copy((u_char *)(regs), (u_char *)((fp)->f_regs), REGISTER_BYTES)) 276 277 static u_long reg_cache[NUM_REGS]; 278 static u_char inbuffer[SL_RPCSIZE+1]; 279 static u_char outbuffer[SL_RPCSIZE]; 280 281 /* 282 * This function does all command procesing for interfacing to 283 * a remote gdb. 284 */ 285 int 286 kgdb_trap(int type, struct frame *frame) 287 { 288 register u_long len; 289 u_char *addr; 290 register u_char *cp; 291 register u_char out, in; 292 register int outlen; 293 int inlen; 294 u_long gdb_regs[NUM_REGS]; 295 296 if (kgdb_dev < 0) { 297 /* not debugging */ 298 return (0); 299 } 300 if (kgdb_active == 0) { 301 if (type != T_TRAP15) { 302 /* No debugger active -- let trap handle this. */ 303 return (0); 304 } 305 kgdb_getc = 0; 306 for (inlen = 0; constab[inlen].cn_probe; inlen++) 307 if (major(constab[inlen].cn_dev) == major(kgdb_dev)) { 308 kgdb_getc = constab[inlen].cn_getc; 309 kgdb_putc = constab[inlen].cn_putc; 310 break; 311 } 312 if (kgdb_getc == 0 || kgdb_putc == 0) 313 return (0); 314 /* 315 * If the packet that woke us up isn't an exec packet, 316 * ignore it since there is no active debugger. Also, 317 * we check that it's not an ack to be sure that the 318 * remote side doesn't send back a response after the 319 * local gdb has exited. Otherwise, the local host 320 * could trap into gdb if it's running a gdb kernel too. 321 */ 322 in = GETC; 323 /* 324 * If we came in asynchronously through the serial line, 325 * the framing character is eaten by the receive interrupt, 326 * but if we come in through a synchronous trap (i.e., via 327 * kgdb_connect()), we will see the extra character. 328 */ 329 if (in == FRAME_START) 330 in = GETC; 331 332 /* 333 * Check that this is a debugger exec message. If so, 334 * slurp up the entire message then ack it, and fall 335 * through to the recv loop. 336 */ 337 if (KGDB_CMD(in) != KGDB_EXEC || (in & KGDB_ACK) != 0) 338 return (0); 339 while (GETC != FRAME_END) 340 ; 341 /* 342 * Do the printf *before* we ack the message. This way 343 * we won't drop any inbound characters while we're 344 * doing the polling printf. 345 */ 346 printf("kgdb started from device %x\n", kgdb_dev); 347 kgdb_send(in | KGDB_ACK, (u_char *)0, 0); 348 kgdb_active = 1; 349 } 350 /* 351 * Stick frame regs into our reg cache then tell remote host 352 * that an exception has occured. 353 */ 354 regs_to_gdb(frame, gdb_regs); 355 if (type != T_TRAP15) { 356 /* 357 * Only send an asynchronous SIGNAL message when we hit 358 * a breakpoint. Otherwise, we will drop the incoming 359 * packet while we output this one (and on entry the other 360 * side isn't interested in the SIGNAL type -- if it is, 361 * it will have used a signal packet.) 362 */ 363 outbuffer[0] = computeSignal(type); 364 kgdb_send(KGDB_SIGNAL, outbuffer, 1); 365 } 366 367 while (1) { 368 in = kgdb_recv(inbuffer, &inlen); 369 if (in == 0 || (in & KGDB_ACK)) 370 /* Ignore inbound acks and error conditions. */ 371 continue; 372 373 out = in | KGDB_ACK; 374 switch (KGDB_CMD(in)) { 375 376 case KGDB_SIGNAL: 377 /* 378 * if this command came from a running gdb, 379 * answer it -- the other guy has no way of 380 * knowing if we're in or out of this loop 381 * when he issues a "remote-signal". (Note 382 * that without the length check, we could 383 * loop here forever if the ourput line is 384 * looped back or the remote host is echoing.) 385 */ 386 if (inlen == 0) { 387 outbuffer[0] = computeSignal(type); 388 kgdb_send(KGDB_SIGNAL, outbuffer, 1); 389 } 390 continue; 391 392 case KGDB_REG_R: 393 case KGDB_REG_R | KGDB_DELTA: 394 cp = outbuffer; 395 outlen = 0; 396 for (len = inbuffer[0]; len < NUM_REGS; ++len) { 397 if (reg_cache[len] != gdb_regs[len] || 398 (in & KGDB_DELTA) == 0) { 399 if (outlen + 5 > SL_MAXDATA) { 400 out |= KGDB_MORE; 401 break; 402 } 403 cp[outlen] = len; 404 kgdb_copy((u_char *)&gdb_regs[len], 405 &cp[outlen + 1], 4); 406 reg_cache[len] = gdb_regs[len]; 407 outlen += 5; 408 } 409 } 410 break; 411 412 case KGDB_REG_W: 413 case KGDB_REG_W | KGDB_DELTA: 414 cp = inbuffer; 415 for (len = 0; len < inlen; len += 5) { 416 register int j = cp[len]; 417 418 kgdb_copy(&cp[len + 1], 419 (u_char *)&gdb_regs[j], 4); 420 reg_cache[j] = gdb_regs[j]; 421 } 422 gdb_to_regs(frame, gdb_regs); 423 outlen = 0; 424 break; 425 426 case KGDB_MEM_R: 427 len = inbuffer[0]; 428 kgdb_copy(&inbuffer[1], (u_char *)&addr, 4); 429 if (len > SL_MAXDATA) { 430 outlen = 1; 431 outbuffer[0] = E2BIG; 432 } else if (!kgdb_acc(addr, len, B_READ)) { 433 outlen = 1; 434 outbuffer[0] = EFAULT; 435 } else { 436 outlen = len + 1; 437 outbuffer[0] = 0; 438 kgdb_copy(addr, &outbuffer[1], len); 439 } 440 break; 441 442 case KGDB_MEM_W: 443 len = inlen - 4; 444 kgdb_copy(inbuffer, (u_char *)&addr, 4); 445 outlen = 1; 446 if (!kgdb_acc(addr, len, B_READ)) 447 outbuffer[0] = EFAULT; 448 else { 449 outbuffer[0] = 0; 450 if (!kgdb_acc(addr, len, B_WRITE)) 451 chgkprot(addr, len, B_WRITE); 452 kgdb_copy(&inbuffer[4], addr, len); 453 ICIA(); 454 } 455 break; 456 457 case KGDB_KILL: 458 kgdb_active = 0; 459 printf("kgdb detached\n"); 460 /* fall through */ 461 case KGDB_CONT: 462 kgdb_send(out, 0, 0); 463 frame->f_sr &=~ PSL_T; 464 return (1); 465 466 case KGDB_STEP: 467 kgdb_send(out, 0, 0); 468 frame->f_sr |= PSL_T; 469 return (1); 470 471 case KGDB_EXEC: 472 default: 473 /* Unknown command. Ack with a null message. */ 474 outlen = 0; 475 break; 476 } 477 /* Send the reply */ 478 kgdb_send(out, outbuffer, outlen); 479 } 480 } 481 482 /* 483 * XXX do kernacc call if safe, otherwise attempt 484 * to simulate by simple bounds-checking. 485 */ 486 kgdb_acc(addr, len, rw) 487 caddr_t addr; 488 { 489 extern char proc0paddr[], kstack[]; /* XXX */ 490 extern char *kernel_map; /* XXX! */ 491 492 if (kernel_map != NULL) 493 return (kernacc(addr, len, rw)); 494 if (addr < proc0paddr + UPAGES * NBPG || 495 kstack <= addr && addr < kstack + UPAGES * NBPG) 496 return (1); 497 return (0); 498 } 499 #endif 500