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