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