1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)kgdb_stub.c 7.2 (Berkeley) 05/25/90 13 */ 14 15 /* 16 * 17 * The following gdb commands are supported: 18 * 19 * command function Return value 20 * 21 * g return the value of the CPU registers hex data or ENN 22 * G set the value of the CPU registers OK or ENN 23 * 24 * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN 25 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN 26 * 27 * c Resume at current address SNN ( signal NN) 28 * cAA..AA Continue at address AA..AA SNN 29 * 30 * s Step one instruction SNN 31 * sAA..AA Step one instruction from AA..AA SNN 32 * 33 * k kill 34 * 35 * ? What was the last sigval ? SNN (signal NN) 36 * 37 * All commands and responses are sent with a packet which includes a 38 * checksum. A packet consists of 39 * 40 * $<packet info>#<checksum>. 41 * 42 * where 43 * <packet info> :: <characters representing the command or response> 44 * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>> 45 * 46 * When a packet is received, it is first acknowledged with either '+' or '-'. 47 * '+' indicates a successful transfer. '-' indicates a failed transfer. 48 * 49 * Example: 50 * 51 * Host: Reply: 52 * $m0,10#2a +$00010203040506070809101112131415#42 53 * 54 ****************************************************************************/ 55 56 #ifdef KGDB 57 #include "param.h" 58 #include "systm.h" 59 #include "trap.h" 60 #include "cpu.h" 61 #include "psl.h" 62 #include "reg.h" 63 #include "frame.h" 64 #include "buf.h" 65 66 extern void printf(); 67 extern void bcopy(); 68 extern int kernacc(); 69 extern void chgkprot(); 70 71 /* # of additional (beyond 4) bytes in 680x0 exception frame format n */ 72 static int frame_bytes[16] = { 73 4, 4, 8, 4, 74 4, 4, 4, 4, 75 54, 16, 28, 88, 76 4, 4, 4, 4 77 }; 78 79 #define USER 040 /* (XXX from trap.c) user-mode flag in type */ 80 81 /* 82 * BUFMAX defines the maximum number of characters in inbound/outbound 83 * buffers. At least NUMREGBYTES*2 are needed for register packets. 84 */ 85 #define BUFMAX 512 86 87 #ifndef KGDBDEV 88 #define KGDBDEV -1 89 #endif 90 #ifndef KGDBRATE 91 #define KGDBRATE 9600 92 #endif 93 94 int kgdb_dev = KGDBDEV; /* remote debugging device (-1 if none) */ 95 int kgdb_rate = KGDBRATE; /* remote debugging baud rate */ 96 int kgdb_debug_init = 0; /* != 0 waits for remote at system init */ 97 int kgdb_debug = 0; /* > 0 prints command & checksum errors */ 98 99 #include "../hp300/cons.h" 100 101 #define GETC \ 102 (constab[major(kgdb_dev)].cn_getc ? \ 103 (*constab[major(kgdb_dev)].cn_getc)(kgdb_dev) : 0) 104 #define PUTC(c) { \ 105 if (constab[major(kgdb_dev)].cn_putc) \ 106 (*constab[major(kgdb_dev)].cn_putc)(kgdb_dev, c); \ 107 } 108 109 static char hexchars[] = "0123456789abcdef"; 110 111 /* 112 * There are 180 bytes of registers on a 68020 w/68881. Many of the fpa 113 * registers are 12 byte (96 bit) registers. 114 */ 115 #define NUMREGBYTES 180 116 117 static char inbuffer[BUFMAX]; 118 static char outbuffer[BUFMAX]; 119 120 static inline int 121 hex(ch) 122 char ch; 123 { 124 if ((ch >= '0') && (ch <= '9')) 125 return (ch - '0'); 126 if ((ch >= 'a') && (ch <= 'f')) 127 return (ch - ('a' - 10)); 128 return (0); 129 } 130 131 /* scan for the sequence $<data>#<checksum> */ 132 static void 133 getpacket(char *buffer) 134 { 135 unsigned char checksum; 136 unsigned char xmitcsum; 137 int i; 138 int count; 139 char ch; 140 141 do { 142 /* 143 * wait around for the start character, ignore all other 144 * characters 145 */ 146 while ((ch = GETC) != '$') 147 ; 148 checksum = 0; 149 count = 0; 150 xmitcsum = 1; 151 152 /* now, read until a # or end of buffer is found */ 153 while (count < BUFMAX) { 154 ch = GETC; 155 if (ch == '#') 156 break; 157 checksum = checksum + ch; 158 buffer[count] = ch; 159 count = count + 1; 160 } 161 buffer[count] = 0; 162 163 if (ch == '#') { 164 xmitcsum = hex(GETC) << 4; 165 xmitcsum += hex(GETC); 166 if (kgdb_debug && (checksum != xmitcsum)) { 167 printf( 168 "bad checksum. My count = 0x%x, sent=0x%x. buf=%s\n", 169 checksum, xmitcsum, buffer); 170 } 171 if (checksum != xmitcsum) { 172 PUTC('-'); /* failed checksum */ 173 } else { 174 PUTC('+'); /* successful transfer */ 175 /* 176 * if a sequence char is present, reply the 177 * sequence ID 178 */ 179 if (buffer[2] == ':') { 180 PUTC(buffer[0]); 181 PUTC(buffer[1]); 182 /* remove sequence chars from buffer */ 183 for (i = 3; i <= count; ++i) 184 buffer[i - 3] = buffer[i]; 185 } 186 } 187 } 188 } while (checksum != xmitcsum); 189 } 190 191 /* 192 * send the packet in buffer. The host gets one chance to read it. This 193 * routine does not wait for a positive acknowledge. 194 */ 195 static void 196 putpacket(char *buffer) 197 { 198 unsigned char checksum; 199 int count; 200 char ch; 201 202 /* $<packet info>#<checksum>. */ 203 do { 204 PUTC('$'); 205 checksum = 0; 206 count = 0; 207 208 while (ch = buffer[count]) { 209 PUTC(ch); 210 checksum += ch; 211 count += 1; 212 } 213 PUTC('#'); 214 PUTC(hexchars[checksum >> 4]); 215 PUTC(hexchars[checksum & 15]); 216 217 } while (0); /* (GETC != '+'); */ 218 219 } 220 221 static inline void 222 debug_error(char *format, char *parm) 223 { 224 if (kgdb_debug) 225 printf(format, parm); 226 } 227 228 /* 229 * Convert at most 'dig' digits of hex data in buf into a value. 230 * Stop on non-hex char. Return a pointer to next char in buf. 231 */ 232 static char * 233 hex2val(char *buf, int *val, int dig) 234 { 235 int i, v; 236 char ch; 237 238 v = 0; 239 for (i = dig; --i >= 0; ) { 240 ch = *buf++; 241 if ((ch >= '0') && (ch <= '9')) 242 v = (v << 4) | (ch - '0'); 243 else if ((ch >= 'a') && (ch <= 'f')) 244 v = (v << 4) | (ch - ('a' - 10)); 245 else { 246 --buf; 247 break; 248 } 249 } 250 *val = v; 251 return (buf); 252 } 253 254 /* 255 * convert the integer value 'val' into 'dig' hex digits, placing 256 * result in buf. Return a pointer to the last char put in buf (null). 257 */ 258 static char * 259 val2hex(char *buf, int val, int dig) 260 { 261 for (dig <<= 2; (dig -= 4) >= 0; ) 262 *buf++ = hexchars[(val >> dig) & 0xf]; 263 *buf = 0; 264 return (buf); 265 } 266 267 /* 268 * convert the memory pointed to by mem into hex, placing result in buf. 269 * return a pointer to the last char put in buf (null). 270 */ 271 static char * 272 mem2hex(char *buf, char *mem, int count) 273 { 274 if ((count & 1) || ((int)mem & 1)) { 275 char ch; 276 277 while(--count >= 0) { 278 ch = *mem++; 279 *buf++ = hexchars[ch >> 4]; 280 *buf++ = hexchars[ch & 15]; 281 } 282 } else { 283 u_short s; 284 u_short *mp = (u_short *)mem; 285 286 for (count >>= 1; --count >= 0; ) { 287 s = *mp++; 288 *buf++ = hexchars[(s >> 12) & 15]; 289 *buf++ = hexchars[(s >> 8) & 15]; 290 *buf++ = hexchars[(s >> 4) & 15]; 291 *buf++ = hexchars[s & 15]; 292 } 293 } 294 *buf = 0; 295 return (buf); 296 } 297 298 /* 299 * Convert the hex array pointed to by buf into binary to be placed in mem. 300 * Return a pointer to next char in buf. 301 */ 302 static char * 303 hex2mem(char *buf, char *mem, int count) 304 { 305 int i; 306 unsigned char ch; 307 308 for (i = 0; i < count; ++i) { 309 ch = hex(*buf++) << 4; 310 ch = ch + hex(*buf++); 311 *mem++ = ch; 312 } 313 return (buf); 314 } 315 316 /* 317 * Translate a trap number into a unix compatible signal value. 318 * (gdb only understands unix signal numbers). 319 */ 320 static int 321 computeSignal(int type) 322 { 323 int sigval; 324 325 switch (type &~ USER) { 326 case T_BUSERR: 327 sigval = SIGBUS; 328 break; /* bus error */ 329 case T_ADDRERR: 330 sigval = SIGBUS; 331 break; /* address error */ 332 case T_ILLINST: 333 sigval = SIGILL; 334 break; /* illegal instruction */ 335 case T_ZERODIV: 336 sigval = SIGFPE; 337 break; /* zero divide */ 338 case T_CHKINST: 339 sigval = SIGFPE; 340 break; /* chk instruction */ 341 case T_TRAPVINST: 342 sigval = SIGFPE; 343 break; /* trapv instruction */ 344 case T_PRIVINST: 345 sigval = SIGILL; 346 break; /* privilege violation */ 347 case T_TRACE: 348 sigval = SIGTRAP; 349 break; /* trace trap */ 350 case T_MMUFLT: 351 sigval = SIGSEGV; 352 break; 353 case T_SSIR: 354 sigval = SIGSEGV; 355 break; 356 case T_FMTERR: 357 sigval = SIGILL; 358 break; 359 case T_FPERR: 360 sigval = SIGFPE; 361 break; 362 case T_COPERR: 363 sigval = SIGFPE; 364 break; 365 case T_AST: 366 sigval = SIGINT; 367 break; 368 case T_TRAP15: 369 sigval = SIGIOT; 370 break; 371 default: 372 sigval = SIGEMT; 373 break; 374 } 375 return (sigval); 376 } 377 378 #define RESPOND(str) (bcopy(str, outbuffer, sizeof(str))) 379 380 /* 381 * This function does all command procesing for interfacing to 382 * a remote gdb. 383 */ 384 int 385 kgdb_trap(int type, unsigned code, unsigned v, struct frame *frame) 386 { 387 int sigval; 388 int addr, length; 389 char *ptr; 390 391 if (kgdb_dev < 0) 392 /* not debugging */ 393 return (0); 394 395 if (kgdb_debug) 396 printf("type=%d, code=%d, vector=0x%x, pc=0x%x, sr=0x%x\n", 397 type, code, frame->f_vector, frame->f_pc, frame->f_sr); 398 399 /* reply to host that an exception has occurred */ 400 sigval = computeSignal(type); 401 outbuffer[0] = 'S'; 402 (void)val2hex(&outbuffer[1], sigval, 2); 403 putpacket(outbuffer); 404 405 while (1) { 406 outbuffer[0] = 0; 407 getpacket(inbuffer); 408 ptr = inbuffer; 409 switch (*ptr++) { 410 case '?': 411 outbuffer[0] = 'S'; 412 (void)val2hex(&outbuffer[1], sigval, 2); 413 break; 414 case 'g': /* return the value of the CPU registers */ 415 ptr = outbuffer; 416 if (type & USER) 417 ptr = mem2hex(ptr, (char *)frame->f_regs, 418 sizeof(frame->f_regs)); 419 else { 420 ptr = mem2hex(ptr, (char *)frame->f_regs, 421 sizeof(frame->f_regs) - 4); 422 addr = (int)&frame->f_pc - 423 frame_bytes[frame->f_format]; 424 ptr = mem2hex(ptr, (char *)&addr, sizeof(addr)); 425 } 426 addr = frame->f_sr; 427 ptr = mem2hex(ptr, (char *)&addr, sizeof(addr)); 428 ptr = mem2hex(ptr, (char *)&frame->f_pc, 429 sizeof(frame->f_pc)); 430 break; 431 case 'G': /* set the value of the CPU registers */ 432 ptr = hex2mem(ptr, (char *)frame->f_regs, 433 sizeof(frame->f_regs) - 4); 434 ptr = hex2mem(ptr, (char *)&addr, sizeof(addr)); 435 ptr = hex2mem(ptr, (char *)&addr, sizeof(addr)); 436 frame->f_sr = addr; 437 ptr = hex2mem(ptr, (char *)&frame->f_pc, 438 sizeof(frame->f_pc)); 439 RESPOND("OK"); 440 break; 441 442 /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ 443 case 'm': 444 ptr = hex2val(ptr, &addr, 8); 445 if (*ptr++ != ',') { 446 RESPOND("E01"); 447 debug_error("malformed read memory cmd: %s\n", 448 inbuffer); 449 break; 450 } 451 ptr = hex2val(ptr, &length, 8); 452 if (length <= 0 || length >= BUFMAX*2) { 453 RESPOND("E02"); 454 if (kgdb_debug) 455 printf("bad read memory length: %d\n", 456 length); 457 break; 458 } 459 if (! kernacc(addr, length, B_READ)) { 460 RESPOND("E03"); 461 if (kgdb_debug) 462 printf("read access violation addr 0x%x len %d\n", addr, length); 463 break; 464 } 465 (void)mem2hex(outbuffer, (char *)addr, length); 466 break; 467 468 /* 469 * MAA..AA,LLLL: Write LLLL bytes at address AA.AA 470 * return OK 471 */ 472 case 'M': 473 ptr = hex2val(ptr, &addr, 8); 474 if (*ptr++ != ',') { 475 RESPOND("E01"); 476 debug_error("malformed write memory cmd: %s\n", 477 inbuffer); 478 break; 479 } 480 ptr = hex2val(ptr, &length, 8); 481 if (*ptr++ != ':') { 482 RESPOND("E01"); 483 debug_error("malformed write memory cmd: %s\n", 484 inbuffer); 485 break; 486 } 487 if (length <= 0 || length >= BUFMAX*2 - 32) { 488 RESPOND("E02"); 489 if (kgdb_debug) 490 printf("bad write memory length: %d\n", 491 length); 492 break; 493 } 494 if (! kernacc(addr, length, B_READ)) { 495 RESPOND("E03"); 496 if (kgdb_debug) 497 printf("write access violation addr 0x%x len %d\n", addr, length); 498 break; 499 } 500 if (! kernacc(addr, length, B_WRITE)) 501 chgkprot(addr, length, B_WRITE); 502 (void)hex2mem(ptr, (char *)addr, length); 503 RESPOND("OK"); 504 break; 505 506 /* 507 * cAA..AA Continue at address AA..AA 508 * sAA..AA Step one instruction from AA..AA 509 * (addresses optional) 510 */ 511 case 'c': 512 case 's': 513 /* 514 * try to read optional start address. 515 */ 516 if (ptr != hex2val(ptr, &addr, 8)) { 517 frame->f_pc = addr; 518 if (kgdb_debug) 519 printf("new pc = 0x%x\n", addr); 520 } 521 /* deal with the trace bit */ 522 if (inbuffer[0] == 's') 523 frame->f_sr |= PSL_T; 524 else 525 frame->f_sr &=~ PSL_T; 526 527 if (kgdb_debug) 528 printf("restarting at 0x%x\n", frame->f_pc); 529 530 return (1); 531 532 /* kill the program (same as continue for now) */ 533 case 'k': 534 return (1); 535 } 536 /* reply to the request */ 537 putpacket(outbuffer); 538 } 539 } 540 #endif 541