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