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