ocd.c revision 98944
1/* Target communications support for Macraigor Systems' On-Chip Debugging 2 3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software 4 Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place - Suite 330, 21 Boston, MA 02111-1307, USA. */ 22 23#include "defs.h" 24#include "gdbcore.h" 25#include "gdb_string.h" 26#include <fcntl.h> 27#include "frame.h" 28#include "inferior.h" 29#include "bfd.h" 30#include "symfile.h" 31#include "target.h" 32#include "gdbcmd.h" 33#include "objfiles.h" 34#include "gdb-stabs.h" 35#include <sys/types.h> 36#include <signal.h> 37#include "serial.h" 38#include "ocd.h" 39#include "regcache.h" 40 41/* Prototypes for local functions */ 42 43static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len); 44 45static int ocd_start_remote (PTR dummy); 46 47static int readchar (int timeout); 48 49static void reset_packet (void); 50 51static void output_packet (void); 52 53static int get_quoted_char (int timeout); 54 55static void put_quoted_char (int c); 56 57static void ocd_interrupt (int signo); 58 59static void ocd_interrupt_twice (int signo); 60 61static void interrupt_query (void); 62 63static unsigned char *ocd_do_command (int cmd, int *statusp, int *lenp); 64 65static void ocd_put_packet (unsigned char *packet, int pktlen); 66 67static unsigned char *ocd_get_packet (int cmd, int *pktlen, int timeout); 68 69static struct target_ops *current_ops = NULL; 70 71static int last_run_status; 72 73/* This was 5 seconds, which is a long time to sit and wait. 74 Unless this is going though some terminal server or multiplexer or 75 other form of hairy serial connection, I would think 2 seconds would 76 be plenty. */ 77 78#if 0 79/* FIXME: Change to allow option to set timeout value on a per target 80 basis. */ 81static int remote_timeout = 2; 82#endif 83 84/* Descriptor for I/O to remote machine. Initialize it to NULL so that 85 ocd_open knows that we don't have a file open when the program 86 starts. */ 87static struct serial *ocd_desc = NULL; 88 89void 90ocd_error (char *s, int error_code) 91{ 92 char buf[100]; 93 94 fputs_filtered (s, gdb_stderr); 95 fputs_filtered (" ", gdb_stderr); 96 97 switch (error_code) 98 { 99 case 0x1: 100 s = "Unknown fault"; 101 break; 102 case 0x2: 103 s = "Power failed"; 104 break; 105 case 0x3: 106 s = "Cable disconnected"; 107 break; 108 case 0x4: 109 s = "Couldn't enter OCD mode"; 110 break; 111 case 0x5: 112 s = "Target stuck in reset"; 113 break; 114 case 0x6: 115 s = "OCD hasn't been initialized"; 116 break; 117 case 0x7: 118 s = "Write verify failed"; 119 break; 120 case 0x8: 121 s = "Reg buff error (during MPC5xx fp reg read/write)"; 122 break; 123 case 0x9: 124 s = "Invalid CPU register access attempt failed"; 125 break; 126 case 0x11: 127 s = "Bus error"; 128 break; 129 case 0x12: 130 s = "Checksum error"; 131 break; 132 case 0x13: 133 s = "Illegal command"; 134 break; 135 case 0x14: 136 s = "Parameter error"; 137 break; 138 case 0x15: 139 s = "Internal error"; 140 break; 141 case 0x80: 142 s = "Flash erase error"; 143 break; 144 default: 145 sprintf (buf, "Unknown error code %d", error_code); 146 s = buf; 147 } 148 149 error (s); 150} 151 152/* Return nonzero if the thread TH is still alive on the remote system. */ 153 154int 155ocd_thread_alive (ptid_t th) 156{ 157 return 1; 158} 159 160/* Clean up connection to a remote debugger. */ 161 162/* ARGSUSED */ 163void 164ocd_close (int quitting) 165{ 166 if (ocd_desc) 167 serial_close (ocd_desc); 168 ocd_desc = NULL; 169} 170 171/* Stub for catch_errors. */ 172 173static int 174ocd_start_remote (PTR dummy) 175{ 176 unsigned char buf[10], *p; 177 int pktlen; 178 int status; 179 int error_code; 180 int speed; 181 enum ocd_target_type target_type; 182 183 target_type = *(enum ocd_target_type *) dummy; 184 185 immediate_quit++; /* Allow user to interrupt it */ 186 187 serial_send_break (ocd_desc); /* Wake up the wiggler */ 188 189 speed = 80; /* Divide clock by 4000 */ 190 191 buf[0] = OCD_INIT; 192 buf[1] = speed >> 8; 193 buf[2] = speed & 0xff; 194 buf[3] = target_type; 195 ocd_put_packet (buf, 4); /* Init OCD params */ 196 p = ocd_get_packet (buf[0], &pktlen, remote_timeout); 197 198 if (pktlen < 2) 199 error ("Truncated response packet from OCD device"); 200 201 status = p[1]; 202 error_code = p[2]; 203 204 if (error_code != 0) 205 ocd_error ("OCD_INIT:", error_code); 206 207 ocd_do_command (OCD_AYT, &status, &pktlen); 208 209 p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen); 210 211 printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n", 212 p[0], p[1], (p[2] << 16) | p[3]); 213 214#if 0 215 /* Reset the target */ 216 217 ocd_do_command (OCD_RESET_RUN, &status, &pktlen); 218/* ocd_do_command (OCD_RESET, &status, &pktlen); */ 219#endif 220 221 /* If processor is still running, stop it. */ 222 223 if (!(status & OCD_FLAG_BDM)) 224 ocd_stop (); 225 226#if 1 227 /* When using a target box, we want to asynchronously return status when 228 target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll 229 when using a parallel Wiggler */ 230 buf[0] = OCD_SET_CTL_FLAGS; 231 buf[1] = 0; 232 buf[2] = 1; 233 ocd_put_packet (buf, 3); 234 235 p = ocd_get_packet (buf[0], &pktlen, remote_timeout); 236 237 if (pktlen < 2) 238 error ("Truncated response packet from OCD device"); 239 240 status = p[1]; 241 error_code = p[2]; 242 243 if (error_code != 0) 244 ocd_error ("OCD_SET_CTL_FLAGS:", error_code); 245#endif 246 247 immediate_quit--; 248 249/* This is really the job of start_remote however, that makes an assumption 250 that the target is about to print out a status message of some sort. That 251 doesn't happen here (in fact, it may not be possible to get the monitor to 252 send the appropriate packet). */ 253 254 flush_cached_frames (); 255 registers_changed (); 256 stop_pc = read_pc (); 257 set_current_frame (create_new_frame (read_fp (), stop_pc)); 258 select_frame (get_current_frame (), 0); 259 print_stack_frame (selected_frame, -1, 1); 260 261 buf[0] = OCD_LOG_FILE; 262 buf[1] = 3; /* close existing WIGGLERS.LOG */ 263 ocd_put_packet (buf, 2); 264 p = ocd_get_packet (buf[0], &pktlen, remote_timeout); 265 266 buf[0] = OCD_LOG_FILE; 267 buf[1] = 2; /* append to existing WIGGLERS.LOG */ 268 ocd_put_packet (buf, 2); 269 p = ocd_get_packet (buf[0], &pktlen, remote_timeout); 270 271 return 1; 272} 273 274/* Open a connection to a remote debugger. 275 NAME is the filename used for communication. */ 276 277void 278ocd_open (char *name, int from_tty, enum ocd_target_type target_type, 279 struct target_ops *ops) 280{ 281 unsigned char buf[10], *p; 282 int pktlen; 283 284 if (name == 0) 285 error ("To open an OCD connection, you need to specify the\n\ 286device the OCD device is attached to (e.g. /dev/ttya)."); 287 288 target_preopen (from_tty); 289 290 current_ops = ops; 291 292 unpush_target (current_ops); 293 294 ocd_desc = serial_open (name); 295 if (!ocd_desc) 296 perror_with_name (name); 297 298 if (baud_rate != -1) 299 { 300 if (serial_setbaudrate (ocd_desc, baud_rate)) 301 { 302 serial_close (ocd_desc); 303 perror_with_name (name); 304 } 305 } 306 307 serial_raw (ocd_desc); 308 309 /* If there is something sitting in the buffer we might take it as a 310 response to a command, which would be bad. */ 311 serial_flush_input (ocd_desc); 312 313 if (from_tty) 314 { 315 puts_filtered ("Remote target wiggler connected to "); 316 puts_filtered (name); 317 puts_filtered ("\n"); 318 } 319 push_target (current_ops); /* Switch to using remote target now */ 320 321 /* Without this, some commands which require an active target (such as kill) 322 won't work. This variable serves (at least) double duty as both the pid 323 of the target process (if it has such), and as a flag indicating that a 324 target is active. These functions should be split out into seperate 325 variables, especially since GDB will someday have a notion of debugging 326 several processes. */ 327 328 inferior_ptid = pid_to_ptid (42000); 329 /* Start the remote connection; if error (0), discard this target. 330 In particular, if the user quits, be sure to discard it 331 (we'd be in an inconsistent state otherwise). */ 332 if (!catch_errors (ocd_start_remote, &target_type, 333 "Couldn't establish connection to remote target\n", 334 RETURN_MASK_ALL)) 335 { 336 pop_target (); 337 error ("Failed to connect to OCD."); 338 } 339} 340 341/* This takes a program previously attached to and detaches it. After 342 this is done, GDB can be used to debug some other program. We 343 better not have left any breakpoints in the target program or it'll 344 die when it hits one. */ 345 346void 347ocd_detach (char *args, int from_tty) 348{ 349 if (args) 350 error ("Argument given to \"detach\" when remotely debugging."); 351 352 pop_target (); 353 if (from_tty) 354 puts_filtered ("Ending remote debugging.\n"); 355} 356 357/* Tell the remote machine to resume. */ 358 359void 360ocd_resume (ptid_t ptid, int step, enum target_signal siggnal) 361{ 362 int pktlen; 363 364 if (step) 365 ocd_do_command (OCD_STEP, &last_run_status, &pktlen); 366 else 367 ocd_do_command (OCD_RUN, &last_run_status, &pktlen); 368} 369 370void 371ocd_stop (void) 372{ 373 int status; 374 int pktlen; 375 376 ocd_do_command (OCD_STOP, &status, &pktlen); 377 378 if (!(status & OCD_FLAG_BDM)) 379 error ("Can't stop target via BDM"); 380} 381 382static volatile int ocd_interrupt_flag; 383 384/* Send ^C to target to halt it. Target will respond, and send us a 385 packet. */ 386 387static void 388ocd_interrupt (int signo) 389{ 390 /* If this doesn't work, try more severe steps. */ 391 signal (signo, ocd_interrupt_twice); 392 393 if (remote_debug) 394 printf_unfiltered ("ocd_interrupt called\n"); 395 396 { 397 char buf[1]; 398 399 ocd_stop (); 400 buf[0] = OCD_AYT; 401 ocd_put_packet (buf, 1); 402 ocd_interrupt_flag = 1; 403 } 404} 405 406static void (*ofunc) (); 407 408/* The user typed ^C twice. */ 409static void 410ocd_interrupt_twice (int signo) 411{ 412 signal (signo, ofunc); 413 414 interrupt_query (); 415 416 signal (signo, ocd_interrupt); 417} 418 419/* Ask the user what to do when an interrupt is received. */ 420 421static void 422interrupt_query (void) 423{ 424 target_terminal_ours (); 425 426 if (query ("Interrupted while waiting for the program.\n\ 427Give up (and stop debugging it)? ")) 428 { 429 target_mourn_inferior (); 430 throw_exception (RETURN_QUIT); 431 } 432 433 target_terminal_inferior (); 434} 435 436/* If nonzero, ignore the next kill. */ 437static int kill_kludge; 438 439/* Wait until the remote machine stops, then return, 440 storing status in STATUS just as `wait' would. 441 Returns "pid" (though it's not clear what, if anything, that 442 means in the case of this target). */ 443 444int 445ocd_wait (void) 446{ 447 unsigned char *p; 448 int error_code; 449 int pktlen; 450 char buf[1]; 451 452 ocd_interrupt_flag = 0; 453 454 /* Target might already be stopped by the time we get here. */ 455 /* If we aren't already stopped, we need to loop until we've dropped 456 back into BDM mode */ 457 458 while (!(last_run_status & OCD_FLAG_BDM)) 459 { 460 buf[0] = OCD_AYT; 461 ocd_put_packet (buf, 1); 462 p = ocd_get_packet (OCD_AYT, &pktlen, -1); 463 464 ofunc = (void (*)()) signal (SIGINT, ocd_interrupt); 465 signal (SIGINT, ofunc); 466 467 if (pktlen < 2) 468 error ("Truncated response packet from OCD device"); 469 470 last_run_status = p[1]; 471 error_code = p[2]; 472 473 if (error_code != 0) 474 ocd_error ("target_wait:", error_code); 475 476 if (last_run_status & OCD_FLAG_PWF) 477 error ("OCD device lost VCC at BDM interface."); 478 else if (last_run_status & OCD_FLAG_CABLE_DISC) 479 error ("OCD device cable appears to have been disconnected."); 480 } 481 482 if (ocd_interrupt_flag) 483 return 1; 484 else 485 return 0; 486} 487 488/* Read registers from the OCD device. Specify the starting and ending 489 register number. Return the number of regs actually read in *NUMREGS. 490 Returns a pointer to a static array containing the register contents. */ 491 492unsigned char * 493ocd_read_bdm_registers (int first_bdm_regno, int last_bdm_regno, int *reglen) 494{ 495 unsigned char buf[10]; 496 int i; 497 unsigned char *p; 498 unsigned char *regs; 499 int error_code, status; 500 int pktlen; 501 502 buf[0] = OCD_READ_REGS; 503 buf[1] = first_bdm_regno >> 8; 504 buf[2] = first_bdm_regno & 0xff; 505 buf[3] = last_bdm_regno >> 8; 506 buf[4] = last_bdm_regno & 0xff; 507 508 ocd_put_packet (buf, 5); 509 p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout); 510 511 status = p[1]; 512 error_code = p[2]; 513 514 if (error_code != 0) 515 ocd_error ("read_bdm_registers:", error_code); 516 517 i = p[3]; 518 if (i == 0) 519 i = 256; 520 521 if (i > pktlen - 4 522 || ((i & 3) != 0)) 523 error ("Register block size bad: %d", i); 524 525 *reglen = i; 526 527 regs = p + 4; 528 529 return regs; 530} 531 532/* Read register BDM_REGNO and returns its value ala read_register() */ 533 534CORE_ADDR 535ocd_read_bdm_register (int bdm_regno) 536{ 537 int reglen; 538 unsigned char *p; 539 CORE_ADDR regval; 540 541 p = ocd_read_bdm_registers (bdm_regno, bdm_regno, ®len); 542 regval = extract_unsigned_integer (p, reglen); 543 544 return regval; 545} 546 547void 548ocd_write_bdm_registers (int first_bdm_regno, unsigned char *regptr, int reglen) 549{ 550 unsigned char *buf; 551 unsigned char *p; 552 int error_code, status; 553 int pktlen; 554 555 buf = alloca (4 + reglen); 556 557 buf[0] = OCD_WRITE_REGS; 558 buf[1] = first_bdm_regno >> 8; 559 buf[2] = first_bdm_regno & 0xff; 560 buf[3] = reglen; 561 memcpy (buf + 4, regptr, reglen); 562 563 ocd_put_packet (buf, 4 + reglen); 564 p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout); 565 566 if (pktlen < 3) 567 error ("Truncated response packet from OCD device"); 568 569 status = p[1]; 570 error_code = p[2]; 571 572 if (error_code != 0) 573 ocd_error ("ocd_write_bdm_registers:", error_code); 574} 575 576void 577ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg) 578{ 579 unsigned char buf[4]; 580 581 store_unsigned_integer (buf, 4, reg); 582 583 ocd_write_bdm_registers (bdm_regno, buf, 4); 584} 585 586void 587ocd_prepare_to_store (void) 588{ 589} 590 591/* Write memory data directly to the remote machine. 592 This does not inform the data cache; the data cache uses this. 593 MEMADDR is the address in the remote memory space. 594 MYADDR is the address of the buffer in our space. 595 LEN is the number of bytes. 596 597 Returns number of bytes transferred, or 0 for error. */ 598 599static int write_mem_command = OCD_WRITE_MEM; 600 601int 602ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len) 603{ 604 char buf[256 + 10]; 605 unsigned char *p; 606 int origlen; 607 608 origlen = len; 609 610 buf[0] = write_mem_command; 611 buf[5] = 1; /* Write as bytes */ 612 buf[6] = 0; /* Don't verify */ 613 614 while (len > 0) 615 { 616 int numbytes; 617 int pktlen; 618 int status, error_code; 619 620 numbytes = min (len, 256 - 8); 621 622 buf[1] = memaddr >> 24; 623 buf[2] = memaddr >> 16; 624 buf[3] = memaddr >> 8; 625 buf[4] = memaddr; 626 627 buf[7] = numbytes; 628 629 memcpy (&buf[8], myaddr, numbytes); 630 ocd_put_packet (buf, 8 + numbytes); 631 p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout); 632 if (pktlen < 3) 633 error ("Truncated response packet from OCD device"); 634 635 status = p[1]; 636 error_code = p[2]; 637 638 if (error_code == 0x11) /* Got a bus error? */ 639 { 640 CORE_ADDR error_address; 641 642 error_address = p[3] << 24; 643 error_address |= p[4] << 16; 644 error_address |= p[5] << 8; 645 error_address |= p[6]; 646 numbytes = error_address - memaddr; 647 648 len -= numbytes; 649 650 errno = EIO; 651 652 break; 653 } 654 else if (error_code != 0) 655 ocd_error ("ocd_write_bytes:", error_code); 656 657 len -= numbytes; 658 memaddr += numbytes; 659 myaddr += numbytes; 660 } 661 662 return origlen - len; 663} 664 665/* Read memory data directly from the remote machine. 666 This does not use the data cache; the data cache uses this. 667 MEMADDR is the address in the remote memory space. 668 MYADDR is the address of the buffer in our space. 669 LEN is the number of bytes. 670 671 Returns number of bytes transferred, or 0 for error. */ 672 673static int 674ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len) 675{ 676 char buf[256 + 10]; 677 unsigned char *p; 678 int origlen; 679 680 origlen = len; 681 682 buf[0] = OCD_READ_MEM; 683 buf[5] = 1; /* Read as bytes */ 684 685 while (len > 0) 686 { 687 int numbytes; 688 int pktlen; 689 int status, error_code; 690 691 numbytes = min (len, 256 - 7); 692 693 buf[1] = memaddr >> 24; 694 buf[2] = memaddr >> 16; 695 buf[3] = memaddr >> 8; 696 buf[4] = memaddr; 697 698 buf[6] = numbytes; 699 700 ocd_put_packet (buf, 7); 701 p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout); 702 if (pktlen < 4) 703 error ("Truncated response packet from OCD device"); 704 705 status = p[1]; 706 error_code = p[2]; 707 708 if (error_code == 0x11) /* Got a bus error? */ 709 { 710 CORE_ADDR error_address; 711 712 error_address = p[3] << 24; 713 error_address |= p[4] << 16; 714 error_address |= p[5] << 8; 715 error_address |= p[6]; 716 numbytes = error_address - memaddr; 717 718 len -= numbytes; 719 720 errno = EIO; 721 722 break; 723 } 724 else if (error_code != 0) 725 ocd_error ("ocd_read_bytes:", error_code); 726 727 memcpy (myaddr, &p[4], numbytes); 728 729 len -= numbytes; 730 memaddr += numbytes; 731 myaddr += numbytes; 732 } 733 734 return origlen - len; 735} 736 737/* Read or write LEN bytes from inferior memory at MEMADDR, transferring 738 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is 739 nonzero. Returns length of data written or read; 0 for error. TARGET 740 is ignored. */ 741 742/* ARGSUSED */ 743int 744ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write, 745 struct mem_attrib *attrib, struct target_ops *target) 746{ 747 int res; 748 749 if (should_write) 750 res = ocd_write_bytes (memaddr, myaddr, len); 751 else 752 res = ocd_read_bytes (memaddr, myaddr, len); 753 754 return res; 755} 756 757void 758ocd_files_info (struct target_ops *ignore) 759{ 760 puts_filtered ("Debugging a target over a serial line.\n"); 761} 762 763/* Stuff for dealing with the packets which are part of this protocol. 764 See comment at top of file for details. */ 765 766/* Read a single character from the remote side, handling wierd errors. */ 767 768static int 769readchar (int timeout) 770{ 771 int ch; 772 773 ch = serial_readchar (ocd_desc, timeout); 774 775 switch (ch) 776 { 777 case SERIAL_EOF: 778 error ("Remote connection closed"); 779 case SERIAL_ERROR: 780 perror_with_name ("Remote communication error"); 781 case SERIAL_TIMEOUT: 782 default: 783 return ch; 784 } 785} 786 787#if 0 788/* Read a character from the data stream, dequoting as necessary. SYN is 789 treated special. Any SYNs appearing in the data stream are returned as the 790 distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be 791 mistaken for real data). */ 792 793static int 794get_quoted_char (int timeout) 795{ 796 int ch; 797 798 ch = readchar (timeout); 799 800 switch (ch) 801 { 802 case SERIAL_TIMEOUT: 803 error ("Timeout in mid-packet, aborting"); 804 case SYN: 805 return RAW_SYN; 806 case DLE: 807 ch = readchar (timeout); 808 if (ch == SYN) 809 return RAW_SYN; 810 return ch & ~0100; 811 default: 812 return ch; 813 } 814} 815 816static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */ 817 818static void 819reset_packet (void) 820{ 821 pktp = pkt; 822} 823 824static void 825output_packet (void) 826{ 827 if (serial_write (ocd_desc, pkt, pktp - pkt)) 828 perror_with_name ("output_packet: write failed"); 829 830 reset_packet (); 831} 832 833/* Output a quoted character. SYNs and DLEs are quoted. Everything else goes 834 through untouched. */ 835 836static void 837put_quoted_char (int c) 838{ 839 switch (c) 840 { 841 case SYN: 842 case DLE: 843 *pktp++ = DLE; 844 c |= 0100; 845 } 846 847 *pktp++ = c; 848} 849 850/* Send a packet to the OCD device. The packet framed by a SYN character, 851 a byte count and a checksum. The byte count only counts the number of 852 bytes between the count and the checksum. A count of zero actually 853 means 256. Any SYNs within the packet (including the checksum and 854 count) must be quoted. The quote character must be quoted as well. 855 Quoting is done by replacing the character with the two-character sequence 856 DLE, {char} | 0100. Note that the quoting mechanism has no effect on the 857 byte count. */ 858 859static void 860stu_put_packet (unsigned char *buf, int len) 861{ 862 unsigned char checksum; 863 unsigned char c; 864 865 if (len == 0 || len > 256) 866 internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Can't represent 0 length packet */ 867 868 reset_packet (); 869 870 checksum = 0; 871 872 put_quoted_char (RAW_SYN); 873 874 c = len; 875 876 do 877 { 878 checksum += c; 879 880 put_quoted_char (c); 881 882 c = *buf++; 883 } 884 while (len-- > 0); 885 886 put_quoted_char (-checksum & 0xff); 887 888 output_packet (); 889} 890 891#else 892 893/* Send a packet to the OCD device. The packet framed by a SYN character, 894 a byte count and a checksum. The byte count only counts the number of 895 bytes between the count and the checksum. A count of zero actually 896 means 256. Any SYNs within the packet (including the checksum and 897 count) must be quoted. The quote character must be quoted as well. 898 Quoting is done by replacing the character with the two-character sequence 899 DLE, {char} | 0100. Note that the quoting mechanism has no effect on the 900 byte count. */ 901 902static void 903ocd_put_packet (unsigned char *buf, int len) 904{ 905 unsigned char checksum; 906 unsigned char c; 907 unsigned char *packet, *packet_ptr; 908 909 packet = alloca (len + 1 + 1); /* packet + SYN + checksum */ 910 packet_ptr = packet; 911 912 checksum = 0; 913 914 *packet_ptr++ = 0x55; 915 916 while (len-- > 0) 917 { 918 c = *buf++; 919 920 checksum += c; 921 *packet_ptr++ = c; 922 } 923 924 *packet_ptr++ = -checksum; 925 if (serial_write (ocd_desc, packet, packet_ptr - packet)) 926 perror_with_name ("output_packet: write failed"); 927} 928#endif 929 930#if 0 931/* Get a packet from the OCD device. Timeout is only enforced for the 932 first byte of the packet. Subsequent bytes are expected to arrive in 933 time <= remote_timeout. Returns a pointer to a static buffer containing 934 the payload of the packet. *LENP contains the length of the packet. 935 */ 936 937static unsigned char * 938stu_get_packet (unsigned char cmd, int *lenp, int timeout) 939{ 940 int ch; 941 int len; 942 static unsigned char buf[256 + 10], *p; 943 unsigned char checksum; 944 945find_packet: 946 947 ch = get_quoted_char (timeout); 948 949 if (ch < 0) 950 error ("get_packet (readchar): %d", ch); 951 952 if (ch != RAW_SYN) 953 goto find_packet; 954 955found_syn: /* Found the start of a packet */ 956 957 p = buf; 958 checksum = 0; 959 960 len = get_quoted_char (remote_timeout); 961 962 if (len == RAW_SYN) 963 goto found_syn; 964 965 checksum += len; 966 967 if (len == 0) 968 len = 256; 969 970 len++; /* Include checksum */ 971 972 while (len-- > 0) 973 { 974 ch = get_quoted_char (remote_timeout); 975 if (ch == RAW_SYN) 976 goto found_syn; 977 978 *p++ = ch; 979 checksum += ch; 980 } 981 982 if (checksum != 0) 983 goto find_packet; 984 985 if (cmd != buf[0]) 986 error ("Response phase error. Got 0x%x, expected 0x%x", buf[0], cmd); 987 988 *lenp = p - buf - 1; 989 return buf; 990} 991 992#else 993 994/* Get a packet from the OCD device. Timeout is only enforced for the 995 first byte of the packet. Subsequent bytes are expected to arrive in 996 time <= remote_timeout. Returns a pointer to a static buffer containing 997 the payload of the packet. *LENP contains the length of the packet. 998 */ 999 1000static unsigned char * 1001ocd_get_packet (int cmd, int *lenp, int timeout) 1002{ 1003 int ch; 1004 int len; 1005 static unsigned char packet[512]; 1006 unsigned char *packet_ptr; 1007 unsigned char checksum; 1008 1009 ch = readchar (timeout); 1010 1011 if (ch < 0) 1012 error ("ocd_get_packet (readchar): %d", ch); 1013 1014 if (ch != 0x55) 1015 error ("ocd_get_packet (readchar): %d", ch); 1016 1017/* Found the start of a packet */ 1018 1019 packet_ptr = packet; 1020 checksum = 0; 1021 1022/* Read command char. That sort of tells us how long the packet is. */ 1023 1024 ch = readchar (timeout); 1025 1026 if (ch < 0) 1027 error ("ocd_get_packet (readchar): %d", ch); 1028 1029 *packet_ptr++ = ch; 1030 checksum += ch; 1031 1032/* Get status. */ 1033 1034 ch = readchar (timeout); 1035 1036 if (ch < 0) 1037 error ("ocd_get_packet (readchar): %d", ch); 1038 *packet_ptr++ = ch; 1039 checksum += ch; 1040 1041/* Get error code. */ 1042 1043 ch = readchar (timeout); 1044 1045 if (ch < 0) 1046 error ("ocd_get_packet (readchar): %d", ch); 1047 *packet_ptr++ = ch; 1048 checksum += ch; 1049 1050 switch (ch) /* Figure out length of packet */ 1051 { 1052 case 0x7: /* Write verify error? */ 1053 len = 8; /* write address, value read back */ 1054 break; 1055 case 0x11: /* Bus error? */ 1056 /* write address, read flag */ 1057 case 0x15: /* Internal error */ 1058 len = 5; /* error code, vector */ 1059 break; 1060 default: /* Error w/no params */ 1061 len = 0; 1062 break; 1063 case 0x0: /* Normal result */ 1064 switch (packet[0]) 1065 { 1066 case OCD_AYT: /* Are You There? */ 1067 case OCD_SET_BAUD_RATE: /* Set Baud Rate */ 1068 case OCD_INIT: /* Initialize OCD device */ 1069 case OCD_SET_SPEED: /* Set Speed */ 1070 case OCD_SET_FUNC_CODE: /* Set Function Code */ 1071 case OCD_SET_CTL_FLAGS: /* Set Control Flags */ 1072 case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */ 1073 case OCD_RUN: /* Run Target from PC */ 1074 case OCD_RUN_ADDR: /* Run Target from Specified Address */ 1075 case OCD_STOP: /* Stop Target */ 1076 case OCD_RESET_RUN: /* Reset Target and Run */ 1077 case OCD_RESET: /* Reset Target and Halt */ 1078 case OCD_STEP: /* Single Step */ 1079 case OCD_WRITE_REGS: /* Write Register */ 1080 case OCD_WRITE_MEM: /* Write Memory */ 1081 case OCD_FILL_MEM: /* Fill Memory */ 1082 case OCD_MOVE_MEM: /* Move Memory */ 1083 case OCD_WRITE_INT_MEM: /* Write Internal Memory */ 1084 case OCD_JUMP: /* Jump to Subroutine */ 1085 case OCD_ERASE_FLASH: /* Erase flash memory */ 1086 case OCD_PROGRAM_FLASH: /* Write flash memory */ 1087 case OCD_EXIT_MON: /* Exit the flash programming monitor */ 1088 case OCD_ENTER_MON: /* Enter the flash programming monitor */ 1089 case OCD_LOG_FILE: /* Make Wigglers.dll save Wigglers.log */ 1090 case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */ 1091 len = 0; 1092 break; 1093 case OCD_GET_VERSION: /* Get Version */ 1094 len = 10; 1095 break; 1096 case OCD_GET_STATUS_MASK: /* Get Status Mask */ 1097 len = 1; 1098 break; 1099 case OCD_GET_CTRS: /* Get Error Counters */ 1100 case OCD_READ_REGS: /* Read Register */ 1101 case OCD_READ_MEM: /* Read Memory */ 1102 case OCD_READ_INT_MEM: /* Read Internal Memory */ 1103 len = 257; 1104 break; 1105 default: 1106 error ("ocd_get_packet: unknown packet type 0x%x\n", ch); 1107 } 1108 } 1109 1110 if (len == 257) /* Byte stream? */ 1111 { /* Yes, byte streams contain the length */ 1112 ch = readchar (timeout); 1113 1114 if (ch < 0) 1115 error ("ocd_get_packet (readchar): %d", ch); 1116 *packet_ptr++ = ch; 1117 checksum += ch; 1118 len = ch; 1119 if (len == 0) 1120 len = 256; 1121 } 1122 1123 while (len-- >= 0) /* Do rest of packet and checksum */ 1124 { 1125 ch = readchar (timeout); 1126 1127 if (ch < 0) 1128 error ("ocd_get_packet (readchar): %d", ch); 1129 *packet_ptr++ = ch; 1130 checksum += ch; 1131 } 1132 1133 if (checksum != 0) 1134 error ("ocd_get_packet: bad packet checksum"); 1135 1136 if (cmd != -1 && cmd != packet[0]) 1137 error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd); 1138 1139 *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */ 1140 return packet; 1141} 1142#endif 1143 1144/* Execute a simple (one-byte) command. Returns a pointer to the data 1145 following the error code. */ 1146 1147static unsigned char * 1148ocd_do_command (int cmd, int *statusp, int *lenp) 1149{ 1150 unsigned char buf[100], *p; 1151 int status, error_code; 1152 char errbuf[100]; 1153 1154 unsigned char logbuf[100]; 1155 int logpktlen; 1156 1157 buf[0] = cmd; 1158 ocd_put_packet (buf, 1); /* Send command */ 1159 p = ocd_get_packet (*buf, lenp, remote_timeout); 1160 1161 if (*lenp < 3) 1162 error ("Truncated response packet from OCD device"); 1163 1164 status = p[1]; 1165 error_code = p[2]; 1166 1167 if (error_code != 0) 1168 { 1169 sprintf (errbuf, "ocd_do_command (0x%x):", cmd); 1170 ocd_error (errbuf, error_code); 1171 } 1172 1173 if (status & OCD_FLAG_PWF) 1174 error ("OCD device can't detect VCC at BDM interface."); 1175 else if (status & OCD_FLAG_CABLE_DISC) 1176 error ("BDM cable appears to be disconnected."); 1177 1178 *statusp = status; 1179 1180 logbuf[0] = OCD_LOG_FILE; 1181 logbuf[1] = 3; /* close existing WIGGLERS.LOG */ 1182 ocd_put_packet (logbuf, 2); 1183 ocd_get_packet (logbuf[0], &logpktlen, remote_timeout); 1184 1185 logbuf[0] = OCD_LOG_FILE; 1186 logbuf[1] = 2; /* append to existing WIGGLERS.LOG */ 1187 ocd_put_packet (logbuf, 2); 1188 ocd_get_packet (logbuf[0], &logpktlen, remote_timeout); 1189 1190 return p + 3; 1191} 1192 1193void 1194ocd_kill (void) 1195{ 1196 /* For some mysterious reason, wait_for_inferior calls kill instead of 1197 mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */ 1198 if (kill_kludge) 1199 { 1200 kill_kludge = 0; 1201 target_mourn_inferior (); 1202 return; 1203 } 1204 1205 /* Don't wait for it to die. I'm not really sure it matters whether 1206 we do or not. */ 1207 target_mourn_inferior (); 1208} 1209 1210void 1211ocd_mourn (void) 1212{ 1213 unpush_target (current_ops); 1214 generic_mourn_inferior (); 1215} 1216 1217/* All we actually do is set the PC to the start address of exec_bfd, and start 1218 the program at that point. */ 1219 1220void 1221ocd_create_inferior (char *exec_file, char *args, char **env) 1222{ 1223 if (args && (*args != '\000')) 1224 error ("Args are not supported by BDM."); 1225 1226 clear_proceed_status (); 1227 proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0); 1228} 1229 1230void 1231ocd_load (char *args, int from_tty) 1232{ 1233 generic_load (args, from_tty); 1234 1235 inferior_ptid = null_ptid; 1236 1237/* This is necessary because many things were based on the PC at the time that 1238 we attached to the monitor, which is no longer valid now that we have loaded 1239 new code (and just changed the PC). Another way to do this might be to call 1240 normal_stop, except that the stack may not be valid, and things would get 1241 horribly confused... */ 1242 1243 clear_symtab_users (); 1244} 1245 1246/* This should be defined for each target */ 1247/* But we want to be able to compile this file for some configurations 1248 not yet supported fully */ 1249 1250#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */ 1251#if 0 1252#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */ 1253#endif 1254 1255/* BDM (at least on CPU32) uses a different breakpoint */ 1256 1257int 1258ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache) 1259{ 1260 static char break_insn[] = BDM_BREAKPOINT; 1261 int val; 1262 1263 val = target_read_memory (addr, contents_cache, sizeof (break_insn)); 1264 1265 if (val == 0) 1266 val = target_write_memory (addr, break_insn, sizeof (break_insn)); 1267 1268 return val; 1269} 1270 1271int 1272ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache) 1273{ 1274 static char break_insn[] = BDM_BREAKPOINT; 1275 int val; 1276 1277 val = target_write_memory (addr, contents_cache, sizeof (break_insn)); 1278 1279 return val; 1280} 1281 1282static void 1283bdm_command (char *args, int from_tty) 1284{ 1285 error ("bdm command must be followed by `reset'"); 1286} 1287 1288static void 1289bdm_reset_command (char *args, int from_tty) 1290{ 1291 int status, pktlen; 1292 1293 if (!ocd_desc) 1294 error ("Not connected to OCD device."); 1295 1296 ocd_do_command (OCD_RESET, &status, &pktlen); 1297 dcache_invalidate (target_dcache); 1298 registers_changed (); 1299} 1300 1301static void 1302bdm_restart_command (char *args, int from_tty) 1303{ 1304 int status, pktlen; 1305 1306 if (!ocd_desc) 1307 error ("Not connected to OCD device."); 1308 1309 ocd_do_command (OCD_RESET_RUN, &status, &pktlen); 1310 last_run_status = status; 1311 clear_proceed_status (); 1312 wait_for_inferior (); 1313 normal_stop (); 1314} 1315 1316/* Temporary replacement for target_store_registers(). This prevents 1317 generic_load from trying to set the PC. */ 1318 1319static void 1320noop_store_registers (int regno) 1321{ 1322} 1323 1324static void 1325bdm_update_flash_command (char *args, int from_tty) 1326{ 1327 int status, pktlen; 1328 struct cleanup *old_chain; 1329 void (*store_registers_tmp) (int); 1330 1331 if (!ocd_desc) 1332 error ("Not connected to OCD device."); 1333 1334 if (!args) 1335 error ("Must specify file containing new OCD code."); 1336 1337/* old_chain = make_cleanup (flash_cleanup, 0); */ 1338 1339 ocd_do_command (OCD_ENTER_MON, &status, &pktlen); 1340 1341 ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen); 1342 1343 write_mem_command = OCD_PROGRAM_FLASH; 1344 store_registers_tmp = current_target.to_store_registers; 1345 current_target.to_store_registers = noop_store_registers; 1346 1347 generic_load (args, from_tty); 1348 1349 current_target.to_store_registers = store_registers_tmp; 1350 write_mem_command = OCD_WRITE_MEM; 1351 1352 ocd_do_command (OCD_EXIT_MON, &status, &pktlen); 1353 1354/* discard_cleanups (old_chain); */ 1355} 1356 1357static void 1358bdm_read_register_command (char *args, int from_tty) 1359{ 1360 /* XXX repeat should go on to the next register */ 1361 1362 if (!ocd_desc) 1363 error ("Not connected to OCD device."); 1364 1365 if (!args) 1366 error ("Must specify BDM register number."); 1367 1368} 1369 1370void 1371_initialize_remote_ocd (void) 1372{ 1373 extern struct cmd_list_element *cmdlist; 1374 static struct cmd_list_element *ocd_cmd_list = NULL; 1375 1376 add_show_from_set (add_set_cmd ("remotetimeout", no_class, 1377 var_integer, (char *) &remote_timeout, 1378 "Set timeout value for remote read.\n", &setlist), 1379 &showlist); 1380 1381 add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ", 1382 0, &cmdlist); 1383 1384 add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list); 1385 add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list); 1386 add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list); 1387 /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */ 1388} 1389