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