1 /* Remote target communications for the Macraigor Systems BDM Wiggler
2 Copyright 1996 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "gdb_string.h"
32 #include "gdb-stabs.h"
37 #include <sys/types.h>
43 /* Wiggler serial protocol definitions */
45 #define DLE 020 /* Quote char */
46 #define SYN 026 /* Start of packet */
47 #define RAW_SYN ((026 << 8) | 026) /* get_quoted_char found a naked SYN */
51 #define WIGGLER_FLAG_RESET 0x01 /* Target is being reset */
52 #define WIGGLER_FLAG_STOPPED 0x02 /* Target is halted */
53 #define WIGGLER_FLAG_BDM 0x04 /* Target is in BDM */
54 #define WIGGLER_FLAG_PWF 0x08 /* Power failed */
55 #define WIGGLER_FLAG_CABLE_DISC 0x10 /* BDM cable disconnected */
57 #define WIGGLER_AYT 0x0 /* Are you there? */
58 #define WIGGLER_GET_VERSION 0x1 /* Get Version */
59 #define WIGGLER_SET_BAUD_RATE 0x2 /* Set Baud Rate */
60 #define WIGGLER_INIT 0x10 /* Initialize Wiggler */
61 #define WIGGLER_SET_SPEED 0x11 /* Set Speed */
62 #define WIGGLER_GET_STATUS_MASK 0x12 /* Get Status Mask */
63 #define WIGGLER_GET_CTRS 0x13 /* Get Error Counters */
64 #define WIGGLER_SET_FUNC_CODE 0x14 /* Set Function Code */
65 #define WIGGLER_SET_CTL_FLAGS 0x15 /* Set Control Flags */
66 #define WIGGLER_SET_BUF_ADDR 0x16 /* Set Register Buffer Address */
67 #define WIGGLER_RUN 0x20 /* Run Target from PC */
68 #define WIGGLER_RUN_ADDR 0x21 /* Run Target from Specified Address */
69 #define WIGGLER_STOP 0x22 /* Stop Target */
70 #define WIGGLER_RESET_RUN 0x23 /* Reset Target and Run */
71 #define WIGGLER_RESET 0x24 /* Reset Target and Halt */
72 #define WIGGLER_STEP 0x25 /* Single step */
73 #define WIGGLER_READ_REGS 0x30 /* Read Registers */
74 #define WIGGLER_WRITE_REGS 0x31 /* Write Registers */
75 #define WIGGLER_READ_MEM 0x32 /* Read Memory */
76 #define WIGGLER_WRITE_MEM 0x33 /* Write Memory */
77 #define WIGGLER_FILL_MEM 0x34 /* Fill Memory */
78 #define WIGGLER_MOVE_MEM 0x35 /* Move Memory */
80 #define WIGGLER_READ_INT_MEM 0x80 /* Read Internal Memory */
81 #define WIGGLER_WRITE_INT_MEM 0x81 /* Write Internal Memory */
82 #define WIGGLER_JUMP 0x82 /* Jump to Subroutine */
84 #define WIGGLER_SET_STATUS 0x0a /* Set status */
85 #define WIGGLER_FLAG_STOP 0x0 /* Stop the target, enter BDM */
86 #define WIGGLER_FLAG_START 0x01 /* Start the target at PC */
87 #define WIGGLER_FLAG_RETURN_STATUS 0x04 /* Return async status */
89 /* Stuff that should be in tm-xxx files. */
91 #define BDM_NUM_REGS 24
92 #define BDM_REGMAP 0, 1, 2, 3, 4, 5, 6, 7, /* d0 -> d7 */ \
93 8, 9, 10, 11, 12, 13, 14, 15, /* a0 -> a7 */ \
94 18, 16, /* ps, pc */ \
95 -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
96 -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
97 #define BDM_BREAKPOINT 0x4a, 0xfa /* BGND insn */
99 #define BDM_NUM_REGS 24
100 #define BDM_REGMAP 8, 9, 10, 11, 12, 13, 14, 15, /* d0 -> d7 */ \
101 16, 17, 18, 19, 20, 21, 22, 23, /* a0 -> a7 */ \
103 -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
104 -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
108 /* Prototypes for local functions */
110 static void wiggler_stop PARAMS ((void));
112 static void put_packet PARAMS ((unsigned char *packet, int pktlen));
113 static unsigned char * get_packet PARAMS ((int cmd, int *pktlen, int timeout));
115 static int wiggler_write_bytes PARAMS ((CORE_ADDR memaddr,
116 char *myaddr, int len));
118 static int wiggler_read_bytes PARAMS ((CORE_ADDR memaddr,
119 char *myaddr, int len));
121 static void wiggler_files_info PARAMS ((struct target_ops *ignore));
123 static int wiggler_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
124 int len, int should_write,
125 struct target_ops *target));
127 static void wiggler_prepare_to_store PARAMS ((void));
129 static void wiggler_fetch_registers PARAMS ((int regno));
131 static void wiggler_resume PARAMS ((int pid, int step,
132 enum target_signal siggnal));
134 static int wiggler_start_remote PARAMS ((char *dummy));
136 static void wiggler_open PARAMS ((char *name, int from_tty));
138 static void wiggler_close PARAMS ((int quitting));
140 static void wiggler_store_registers PARAMS ((int regno));
142 static void wiggler_mourn PARAMS ((void));
144 static int readchar PARAMS ((int timeout));
146 static void reset_packet PARAMS ((void));
148 static void output_packet PARAMS ((void));
150 static int get_quoted_char PARAMS ((int timeout));
152 static void put_quoted_char PARAMS ((int c));
154 static int wiggler_wait PARAMS ((int pid, struct target_waitstatus *status));
156 static void wiggler_kill PARAMS ((void));
158 static void wiggler_detach PARAMS ((char *args, int from_tty));
160 static void wiggler_interrupt PARAMS ((int signo));
162 static void wiggler_interrupt_twice PARAMS ((int signo));
164 static void interrupt_query PARAMS ((void));
166 static unsigned char * do_command PARAMS ((int cmd, int *statusp, int *lenp));
168 static unsigned char * read_bdm_registers PARAMS ((int first_bdm_regno,
172 extern struct target_ops wiggler_ops; /* Forward decl */
174 static int last_run_status;
176 /* This was 5 seconds, which is a long time to sit and wait.
177 Unless this is going though some terminal server or multiplexer or
178 other form of hairy serial connection, I would think 2 seconds would
181 /* Changed to allow option to set timeout value.
182 was static int remote_timeout = 2; */
183 extern int remote_timeout;
185 /* Descriptor for I/O to remote machine. Initialize it to NULL so that
186 wiggler_open knows that we don't have a file open when the program
188 serial_t wiggler_desc = NULL;
191 wiggler_error (s, error_code)
197 fputs_filtered (s, gdb_stderr);
201 case 1: s = "Unknown fault"; break;
202 case 2: s = "Power failed"; break;
203 case 3: s = "Cable disconnected"; break;
204 case 4: s = "Couldn't enter BDM"; break;
205 case 5: s = "Target stuck in reset"; break;
206 case 6: s = "Port not configured"; break;
207 case 7: s = "Write verify failed"; break;
208 case 11: s = "Bus error"; break;
209 case 12: s = "Checksum error"; break;
210 case 13: s = "Illegal command"; break;
211 case 14: s = "Parameter error"; break;
213 sprintf (buf, "Unknown error code %d", error_code);
219 /* Return nonzero if the thread TH is still alive on the remote system. */
222 wiggler_thread_alive (th)
228 /* Clean up connection to a remote debugger. */
232 wiggler_close (quitting)
236 SERIAL_CLOSE (wiggler_desc);
240 /* Stub for catch_errors. */
243 wiggler_start_remote (dummy)
246 unsigned char buf[10], *p;
252 immediate_quit = 1; /* Allow user to interrupt it */
254 SERIAL_SEND_BREAK (wiggler_desc); /* Wake up the wiggler */
256 do_command (WIGGLER_AYT, &status, &pktlen);
258 p = do_command (WIGGLER_GET_VERSION, &status, &pktlen);
260 printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
261 p[0], p[1], (p[2] << 16) | p[3]);
264 speed = 80; /* Divide clock by 4000 */
266 buf[0] = WIGGLER_INIT;
268 buf[2] = speed & 0xff;
269 buf[3] = 0; /* CPU32 for now */
270 put_packet (buf, 4); /* Init Wiggler params */
271 p = get_packet (buf[0], &pktlen, remote_timeout);
274 error ("Truncated response packet from Wiggler");
280 wiggler_error ("WIGGLER_INIT:", error_code);
284 /* Reset the target */
286 do_command (WIGGLER_RESET_RUN, &status, &pktlen);
287 /* do_command (WIGGLER_RESET, &status, &pktlen);*/
290 /* If processor is still running, stop it. */
292 if (!(status & WIGGLER_FLAG_BDM))
296 buf[0] = WIGGLER_SET_CTL_FLAGS;
298 buf[2] = 1; /* Asynchronously return status when target stops */
301 p = get_packet (buf[0], &pktlen, remote_timeout);
304 error ("Truncated response packet from Wiggler");
310 wiggler_error ("WIGGLER_SET_CTL_FLAGS:", error_code);
315 /* This is really the job of start_remote however, that makes an assumption
316 that the target is about to print out a status message of some sort. That
317 doesn't happen here (in fact, it may not be possible to get the monitor to
318 send the appropriate packet). */
320 flush_cached_frames ();
321 registers_changed ();
322 stop_pc = read_pc ();
323 set_current_frame (create_new_frame (read_fp (), stop_pc));
324 select_frame (get_current_frame (), 0);
325 print_stack_frame (selected_frame, -1, 1);
330 /* Open a connection to a remote debugger.
331 NAME is the filename used for communication. */
333 static DCACHE *wiggler_dcache;
336 wiggler_open (name, from_tty)
341 error ("To open a Wiggler connection, you need to specify what serial\n\
342 device the Wiggler is attached to (e.g. /dev/ttya).");
344 target_preopen (from_tty);
346 unpush_target (&wiggler_ops);
348 wiggler_dcache = dcache_init (wiggler_read_bytes, wiggler_write_bytes);
350 wiggler_desc = SERIAL_OPEN (name);
352 perror_with_name (name);
356 if (SERIAL_SETBAUDRATE (wiggler_desc, baud_rate))
358 SERIAL_CLOSE (wiggler_desc);
359 perror_with_name (name);
363 SERIAL_RAW (wiggler_desc);
365 /* If there is something sitting in the buffer we might take it as a
366 response to a command, which would be bad. */
367 SERIAL_FLUSH_INPUT (wiggler_desc);
371 puts_filtered ("Remote target wiggler connected to ");
372 puts_filtered (name);
373 puts_filtered ("\n");
375 push_target (&wiggler_ops); /* Switch to using remote target now */
377 /* Without this, some commands which require an active target (such as kill)
378 won't work. This variable serves (at least) double duty as both the pid
379 of the target process (if it has such), and as a flag indicating that a
380 target is active. These functions should be split out into seperate
381 variables, especially since GDB will someday have a notion of debugging
382 several processes. */
384 inferior_pid = 42000;
385 /* Start the remote connection; if error (0), discard this target.
386 In particular, if the user quits, be sure to discard it
387 (we'd be in an inconsistent state otherwise). */
388 if (!catch_errors (wiggler_start_remote, (char *)0,
389 "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
393 /* This takes a program previously attached to and detaches it. After
394 this is done, GDB can be used to debug some other program. We
395 better not have left any breakpoints in the target program or it'll
396 die when it hits one. */
399 wiggler_detach (args, from_tty)
404 error ("Argument given to \"detach\" when remotely debugging.");
408 puts_filtered ("Ending remote debugging.\n");
411 /* Tell the remote machine to resume. */
414 wiggler_resume (pid, step, siggnal)
416 enum target_signal siggnal;
420 dcache_flush (wiggler_dcache);
423 do_command (WIGGLER_STEP, &last_run_status, &pktlen);
425 do_command (WIGGLER_RUN, &last_run_status, &pktlen);
434 do_command (WIGGLER_STOP, &status, &pktlen);
436 if (!(status & WIGGLER_FLAG_BDM))
437 error ("Can't stop target via BDM");
440 static volatile int wiggler_interrupt_flag;
442 /* Send ^C to target to halt it. Target will respond, and send us a
446 wiggler_interrupt (signo)
449 /* If this doesn't work, try more severe steps. */
450 signal (signo, wiggler_interrupt_twice);
453 printf_unfiltered ("wiggler_interrupt called\n");
459 buf[0] = WIGGLER_AYT;
461 wiggler_interrupt_flag = 1;
465 static void (*ofunc)();
467 /* The user typed ^C twice. */
469 wiggler_interrupt_twice (signo)
472 signal (signo, ofunc);
476 signal (signo, wiggler_interrupt);
479 /* Ask the user what to do when an interrupt is received. */
484 target_terminal_ours ();
486 if (query ("Interrupted while waiting for the program.\n\
487 Give up (and stop debugging it)? "))
489 target_mourn_inferior ();
490 return_to_top_level (RETURN_QUIT);
493 target_terminal_inferior ();
496 /* If nonzero, ignore the next kill. */
497 static int kill_kludge;
499 /* Wait until the remote machine stops, then return,
500 storing status in STATUS just as `wait' would.
501 Returns "pid" (though it's not clear what, if anything, that
502 means in the case of this target). */
505 wiggler_wait (pid, target_status)
507 struct target_waitstatus *target_status;
510 int error_code, status;
513 wiggler_interrupt_flag = 0;
515 target_status->kind = TARGET_WAITKIND_STOPPED;
516 target_status->value.sig = TARGET_SIGNAL_TRAP;
518 /* Target may already be stopped by the time we get here. */
520 if (!(last_run_status & WIGGLER_FLAG_BDM))
522 ofunc = (void (*)()) signal (SIGINT, wiggler_interrupt);
524 p = get_packet (WIGGLER_AYT, &pktlen, -1);
526 signal (SIGINT, ofunc);
529 error ("Truncated response packet from Wiggler");
535 wiggler_error ("target_wait:", error_code);
537 if (status & WIGGLER_FLAG_PWF)
538 error ("Wiggler lost VCC at BDM interface.");
539 else if (status & WIGGLER_FLAG_CABLE_DISC)
540 error ("BDM cable appears to have been disconnected.");
542 if (!(status & WIGGLER_FLAG_BDM))
543 error ("Wiggler woke up, but wasn't stopped: 0x%x", status);
545 if (wiggler_interrupt_flag)
546 target_status->value.sig = TARGET_SIGNAL_INT;
549 /* This test figures out if we just executed a BGND insn, and if it's one of
550 our breakpoints. If so, then we back up PC. N.B. When a BGND insn is
551 executed, the PC points at the loc just after the insn (ie: it's always
552 two bytes *after* the BGND). So, it's not sufficient to just see if PC-2
553 is a BGND insn because we could have gotten there via a jump. We dis-
554 ambiguate this case by examining the ATEMP register (which is only
555 accessible from BDM). This will tell us if we entered BDM because we
556 executed a BGND insn. */
558 if (breakpoint_inserted_here_p (read_pc () - 2)) /* One of our breakpoints? */
559 { /* Yes, see if we actually executed it */
560 #if 0 /* Temporarily disabled until atemp reading is fixed. */
564 p = read_bdm_registers (23, 23, &numregs);
565 atemp = extract_unsigned_integer (p, 4);
567 if (atemp == 1) /* And, did we hit a breakpoint insn? */
569 write_pc (read_pc () - 2); /* Yes, then back up PC */
575 /* Read the remote registers into the block REGS. */
576 /* Currently we just read all the registers, so we don't use regno. */
579 static unsigned char *
580 read_bdm_registers (first_bdm_regno, last_bdm_regno, numregs)
585 unsigned char buf[10];
589 int error_code, status;
592 buf[0] = WIGGLER_READ_REGS;
593 buf[1] = first_bdm_regno >> 8;
594 buf[2] = first_bdm_regno & 0xff;
595 buf[3] = last_bdm_regno >> 8;
596 buf[4] = last_bdm_regno & 0xff;
599 p = get_packet (WIGGLER_READ_REGS, &pktlen, remote_timeout);
602 error ("Truncated response packet from Wiggler");
608 wiggler_error ("read_bdm_registers:", error_code);
616 error ("Register block size bad: %d", i);
632 regs = read_bdm_registers (0, BDM_NUM_REGS - 1, &numregs);
634 printf_unfiltered ("rpc = 0x%x ",
635 (int)extract_unsigned_integer (regs, 4));
637 printf_unfiltered ("usp = 0x%x ",
638 (int)extract_unsigned_integer (regs, 4));
640 printf_unfiltered ("ssp = 0x%x ",
641 (int)extract_unsigned_integer (regs, 4));
643 printf_unfiltered ("vbr = 0x%x ",
644 (int)extract_unsigned_integer (regs, 4));
646 printf_unfiltered ("sr = 0x%x ",
647 (int)extract_unsigned_integer (regs, 4));
649 printf_unfiltered ("sfc = 0x%x ",
650 (int)extract_unsigned_integer (regs, 4));
652 printf_unfiltered ("dfc = 0x%x ",
653 (int)extract_unsigned_integer (regs, 4));
655 printf_unfiltered ("atemp = 0x%x ",
656 (int)extract_unsigned_integer (regs, 4));
658 printf_unfiltered ("\n");
660 for (i = 0; i <= 7; i++)
661 printf_unfiltered ("d%i = 0x%x ", i,
662 (int)extract_unsigned_integer (regs + i * 4, 4));
664 printf_unfiltered ("\n");
666 for (i = 0; i <= 7; i++)
667 printf_unfiltered ("a%i = 0x%x ", i,
668 (int)extract_unsigned_integer (regs + i * 4, 4));
669 printf_unfiltered ("\n");
672 static int bdm_regmap[] = {BDM_REGMAP};
674 /* Read the remote registers into the block REGS. */
675 /* Currently we just read all the registers, so we don't use regno. */
678 wiggler_fetch_registers (regno)
683 int first_regno, last_regno;
684 int first_bdm_regno, last_bdm_regno;
690 last_regno = NUM_REGS - 1;
693 last_bdm_regno = BDM_NUM_REGS - 1;
700 first_bdm_regno = bdm_regmap [regno];
701 last_bdm_regno = bdm_regmap [regno];
704 if (first_bdm_regno == -1)
706 supply_register (first_regno, NULL);
707 return; /* Unsupported register */
710 regs = read_bdm_registers (first_bdm_regno, last_bdm_regno, &numregs);
712 for (i = first_regno; i <= last_regno; i++)
714 int bdm_regno, regoffset;
716 bdm_regno = bdm_regmap [i];
719 regoffset = bdm_regno - first_bdm_regno;
721 if (regoffset >= numregs)
724 supply_register (i, regs + 4 * regoffset);
727 supply_register (i, NULL); /* Unsupported register */
732 wiggler_prepare_to_store ()
736 /* Store register REGNO, or all registers if REGNO == -1, from the contents
737 of REGISTERS. FIXME: ignores errors. */
740 wiggler_store_registers (regno)
743 unsigned char buf[10 + 256];
746 int error_code, status;
748 int first_regno, last_regno;
749 int first_bdm_regno, last_bdm_regno;
754 last_regno = NUM_REGS - 1;
757 last_bdm_regno = BDM_NUM_REGS - 1;
764 first_bdm_regno = bdm_regmap [regno];
765 last_bdm_regno = bdm_regmap [regno];
768 if (first_bdm_regno == -1)
769 return; /* Unsupported register */
771 buf[0] = WIGGLER_WRITE_REGS;
774 for (i = first_regno; i <= last_regno; i++)
778 bdm_regno = bdm_regmap [i];
780 buf[1] = bdm_regno >> 8;
781 buf[2] = bdm_regno & 0xff;
783 memcpy (&buf[4], ®isters[REGISTER_BYTE (i)], 4);
784 put_packet (buf, 4 + 4);
785 p = get_packet (WIGGLER_WRITE_REGS, &pktlen, remote_timeout);
788 error ("Truncated response packet from Wiggler");
794 wiggler_error ("wiggler_store_registers:", error_code);
798 /* Write memory data directly to the remote machine.
799 This does not inform the data cache; the data cache uses this.
800 MEMADDR is the address in the remote memory space.
801 MYADDR is the address of the buffer in our space.
802 LEN is the number of bytes.
804 Returns number of bytes transferred, or 0 for error. */
807 wiggler_write_bytes (memaddr, myaddr, len)
818 buf[0] = WIGGLER_WRITE_MEM;
819 buf[5] = 1; /* Write as bytes */
820 buf[6] = 0; /* Don't verify */
826 int status, error_code;
828 numbytes = min (len, 256 - 8);
829 /* numbytes = min (len, 40);*/
831 buf[1] = memaddr >> 24;
832 buf[2] = memaddr >> 16;
833 buf[3] = memaddr >> 8;
838 memcpy (&buf[8], myaddr, numbytes);
839 put_packet (buf, 8 + numbytes);
840 p = get_packet (WIGGLER_WRITE_MEM, &pktlen, remote_timeout);
842 error ("Truncated response packet from Wiggler");
847 if (error_code == 11) /* Got a bus error? */
849 CORE_ADDR error_address;
851 error_address = p[3] << 24;
852 error_address |= p[4] << 16;
853 error_address |= p[5] << 8;
854 error_address |= p[6];
855 numbytes = error_address - memaddr;
863 else if (error_code != 0)
864 wiggler_error ("wiggler_store_registers:", error_code);
871 return origlen - len;
874 /* Read memory data directly from the remote machine.
875 This does not use the data cache; the data cache uses this.
876 MEMADDR is the address in the remote memory space.
877 MYADDR is the address of the buffer in our space.
878 LEN is the number of bytes.
880 Returns number of bytes transferred, or 0 for error. */
883 wiggler_read_bytes (memaddr, myaddr, len)
894 buf[0] = WIGGLER_READ_MEM;
895 buf[5] = 1; /* Read as bytes */
901 int status, error_code;
903 numbytes = min (len, 256 - 7);
905 buf[1] = memaddr >> 24;
906 buf[2] = memaddr >> 16;
907 buf[3] = memaddr >> 8;
913 p = get_packet (WIGGLER_READ_MEM, &pktlen, remote_timeout);
915 error ("Truncated response packet from Wiggler");
920 if (error_code == 0x11) /* Got a bus error? */
922 CORE_ADDR error_address;
924 error_address = p[3] << 24;
925 error_address |= p[4] << 16;
926 error_address |= p[5] << 8;
927 error_address |= p[6];
928 numbytes = error_address - memaddr;
936 else if (error_code != 0)
937 wiggler_error ("wiggler_store_registers:", error_code);
939 memcpy (myaddr, &p[4], numbytes);
946 return origlen - len;
949 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
950 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
951 nonzero. Returns length of data written or read; 0 for error. */
955 wiggler_xfer_memory(memaddr, myaddr, len, should_write, target)
960 struct target_ops *target; /* ignored */
962 return dcache_xfer_memory (wiggler_dcache, memaddr, myaddr, len, should_write);
966 wiggler_files_info (ignore)
967 struct target_ops *ignore;
969 puts_filtered ("Debugging a target over a serial line.\n");
972 /* Stuff for dealing with the packets which are part of this protocol.
973 See comment at top of file for details. */
975 /* Read a single character from the remote side, handling wierd errors. */
983 ch = SERIAL_READCHAR (wiggler_desc, timeout);
988 error ("Remote connection closed");
990 perror_with_name ("Remote communication error");
998 /* Read a character from the data stream, dequoting as necessary. SYN is
999 treated special. Any SYNs appearing in the data stream are returned as the
1000 distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
1001 mistaken for real data). */
1004 get_quoted_char (timeout)
1009 ch = readchar (timeout);
1013 case SERIAL_TIMEOUT:
1014 error ("Timeout in mid-packet, aborting");
1018 ch = readchar (timeout);
1027 static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
1038 if (SERIAL_WRITE (wiggler_desc, pkt, pktp - pkt))
1039 perror_with_name ("output_packet: write failed");
1044 /* Output a quoted character. SYNs and DLEs are quoted. Everything else goes
1045 through untouched. */
1062 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
1063 count and a checksum. The byte count only counts the number of bytes
1064 between the count and the checksum. A count of zero actually means 256.
1065 Any SYNs within the packet (including the checksum and count) must be
1066 quoted. The quote character must be quoted as well. Quoting is done by
1067 replacing the character with the two-character sequence DLE, {char} | 0100.
1068 Note that the quoting mechanism has no effect on the byte count.
1072 stu_put_packet (buf, len)
1076 unsigned char checksum;
1079 if (len == 0 || len > 256)
1080 abort (); /* Can't represent 0 length packet */
1086 put_quoted_char (RAW_SYN);
1094 put_quoted_char (c);
1100 put_quoted_char (-checksum & 0xff);
1107 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
1108 count and a checksum. The byte count only counts the number of bytes
1109 between the count and the checksum. A count of zero actually means 256.
1110 Any SYNs within the packet (including the checksum and count) must be
1111 quoted. The quote character must be quoted as well. Quoting is done by
1112 replacing the character with the two-character sequence DLE, {char} | 0100.
1113 Note that the quoting mechanism has no effect on the byte count.
1117 put_packet (buf, len)
1121 unsigned char checksum;
1123 unsigned char *packet, *packet_ptr;
1125 packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
1126 packet_ptr = packet;
1130 *packet_ptr++ = 0x55;
1140 *packet_ptr++ = -checksum;
1141 if (SERIAL_WRITE (wiggler_desc, packet, packet_ptr - packet))
1142 perror_with_name ("output_packet: write failed");
1147 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
1148 of the packet. Subsequent bytes are expected to arrive in time <=
1149 remote_timeout. Returns a pointer to a static buffer containing the payload
1150 of the packet. *LENP contains the length of the packet.
1153 static unsigned char *
1154 stu_get_packet (cmd, lenp, timeout)
1160 static unsigned char buf[256 + 10], *p;
1161 unsigned char checksum;
1165 ch = get_quoted_char (timeout);
1168 error ("get_packet (readchar): %d", ch);
1173 found_syn: /* Found the start of a packet */
1178 len = get_quoted_char (remote_timeout);
1188 len++; /* Include checksum */
1192 ch = get_quoted_char (remote_timeout);
1204 error ("Response phase error. Got 0x%x, expected 0x%x", buf[0], cmd);
1206 *lenp = p - buf - 1;
1212 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
1213 of the packet. Subsequent bytes are expected to arrive in time <=
1214 remote_timeout. Returns a pointer to a static buffer containing the payload
1215 of the packet. *LENP contains the length of the packet.
1218 static unsigned char *
1219 get_packet (cmd, lenp, timeout)
1226 static unsigned char packet[512];
1227 unsigned char *packet_ptr;
1228 unsigned char checksum;
1232 ch = readchar (timeout);
1235 error ("get_packet (readchar): %d", ch);
1240 /* Found the start of a packet */
1242 packet_ptr = packet;
1245 /* Read command char. That sort of tells us how long the packet is. */
1247 ch = readchar (timeout);
1250 error ("get_packet (readchar): %d", ch);
1257 ch = readchar (timeout);
1260 error ("get_packet (readchar): %d", ch);
1264 /* Get error code. */
1266 ch = readchar (timeout);
1269 error ("get_packet (readchar): %d", ch);
1273 switch (ch) /* Figure out length of packet */
1275 case 0x7: /* Write verify error? */
1276 len = 8; /* write address, value read back */
1278 case 0x11: /* Bus error? */
1279 /* write address, read flag */
1280 case 0x15: /* Internal error */
1281 len = 5; /* error code, vector */
1283 default: /* Error w/no params */
1285 case 0x0: /* Normal result */
1288 case WIGGLER_AYT: /* Are You There? */
1289 case WIGGLER_SET_BAUD_RATE: /* Set Baud Rate */
1290 case WIGGLER_INIT: /* Initialize wiggler */
1291 case WIGGLER_SET_SPEED: /* Set Speed */
1292 case WIGGLER_SET_FUNC_CODE: /* Set Function Code */
1293 case WIGGLER_SET_CTL_FLAGS: /* Set Control Flags */
1294 case WIGGLER_SET_BUF_ADDR: /* Set Register Buffer Address */
1295 case WIGGLER_RUN: /* Run Target from PC */
1296 case WIGGLER_RUN_ADDR: /* Run Target from Specified Address */
1297 case WIGGLER_STOP: /* Stop Target */
1298 case WIGGLER_RESET_RUN: /* Reset Target and Run */
1299 case WIGGLER_RESET: /* Reset Target and Halt */
1300 case WIGGLER_STEP: /* Single Step */
1301 case WIGGLER_WRITE_REGS: /* Write Register */
1302 case WIGGLER_WRITE_MEM: /* Write Memory */
1303 case WIGGLER_FILL_MEM: /* Fill Memory */
1304 case WIGGLER_MOVE_MEM: /* Move Memory */
1305 case WIGGLER_WRITE_INT_MEM: /* Write Internal Memory */
1306 case WIGGLER_JUMP: /* Jump to Subroutine */
1309 case WIGGLER_GET_VERSION: /* Get Version */
1312 case WIGGLER_GET_STATUS_MASK: /* Get Status Mask */
1315 case WIGGLER_GET_CTRS: /* Get Error Counters */
1316 case WIGGLER_READ_REGS: /* Read Register */
1317 case WIGGLER_READ_MEM: /* Read Memory */
1318 case WIGGLER_READ_INT_MEM: /* Read Internal Memory */
1322 fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch);
1327 if (len == 257) /* Byte stream? */
1328 { /* Yes, byte streams contain the length */
1329 ch = readchar (timeout);
1332 error ("get_packet (readchar): %d", ch);
1340 while (len-- >= 0) /* Do rest of packet and checksum */
1342 ch = readchar (timeout);
1345 error ("get_packet (readchar): %d", ch);
1353 if (cmd != -1 && cmd != packet[0])
1354 error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd);
1356 *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
1361 /* Execute a simple (one-byte) command. Returns a pointer to the data
1362 following the error code. */
1364 static unsigned char *
1365 do_command (cmd, statusp, lenp)
1370 unsigned char buf[100], *p;
1371 int status, error_code;
1375 put_packet (buf, 1); /* Send command */
1376 p = get_packet (*buf, lenp, remote_timeout);
1379 error ("Truncated response packet from Wiggler");
1384 if (error_code != 0)
1386 sprintf (errbuf, "do_command (0x%x):", cmd);
1387 wiggler_error (errbuf, error_code);
1390 if (status & WIGGLER_FLAG_PWF)
1391 error ("Wiggler can't detect VCC at BDM interface.");
1392 else if (status & WIGGLER_FLAG_CABLE_DISC)
1393 error ("BDM cable appears to be disconnected.");
1403 /* For some mysterious reason, wait_for_inferior calls kill instead of
1404 mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
1408 target_mourn_inferior ();
1412 /* Don't wait for it to die. I'm not really sure it matters whether
1414 target_mourn_inferior ();
1420 unpush_target (&wiggler_ops);
1421 generic_mourn_inferior ();
1424 /* All we actually do is set the PC to the start address of exec_bfd, and start
1425 the program at that point. */
1428 wiggler_create_inferior (exec_file, args, env)
1433 if (args && (*args != '\000'))
1434 error ("Args are not supported by BDM.");
1436 clear_proceed_status ();
1437 proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
1441 wiggler_load (args, from_tty)
1445 generic_load (args, from_tty);
1449 /* BDM (at least on CPU32) uses a different breakpoint */
1452 wiggler_insert_breakpoint (addr, contents_cache)
1454 char *contents_cache;
1456 static char break_insn[] = {BDM_BREAKPOINT};
1459 val = target_read_memory (addr, contents_cache, sizeof break_insn);
1462 val = target_write_memory (addr, break_insn, sizeof break_insn);
1468 bdm_command (args, from_tty)
1472 error ("bdm command must be followed by `reset'");
1476 bdm_reset_command (args, from_tty)
1483 error ("Not connected to wiggler.");
1485 do_command (WIGGLER_RESET, &status, &pktlen);
1486 dcache_flush (wiggler_dcache);
1487 registers_changed ();
1491 bdm_restart_command (args, from_tty)
1498 error ("Not connected to wiggler.");
1500 do_command (WIGGLER_RESET_RUN, &status, &pktlen);
1501 last_run_status = status;
1502 clear_proceed_status ();
1503 wait_for_inferior ();
1507 /* Define the target subroutine names */
1509 struct target_ops wiggler_ops = {
1510 "wiggler", /* to_shortname */
1511 "", /* to_longname */
1513 wiggler_open, /* to_open */
1514 wiggler_close, /* to_close */
1515 NULL, /* to_attach */
1516 wiggler_detach, /* to_detach */
1517 wiggler_resume, /* to_resume */
1518 wiggler_wait, /* to_wait */
1519 wiggler_fetch_registers, /* to_fetch_registers */
1520 wiggler_store_registers, /* to_store_registers */
1521 wiggler_prepare_to_store, /* to_prepare_to_store */
1522 wiggler_xfer_memory, /* to_xfer_memory */
1523 wiggler_files_info, /* to_files_info */
1524 wiggler_insert_breakpoint, /* to_insert_breakpoint */
1525 memory_remove_breakpoint, /* to_remove_breakpoint */
1526 NULL, /* to_terminal_init */
1527 NULL, /* to_terminal_inferior */
1528 NULL, /* to_terminal_ours_for_output */
1529 NULL, /* to_terminal_ours */
1530 NULL, /* to_terminal_info */
1531 wiggler_kill, /* to_kill */
1532 wiggler_load, /* to_load */
1533 NULL, /* to_lookup_symbol */
1534 wiggler_create_inferior, /* to_create_inferior */
1535 wiggler_mourn, /* to_mourn_inferior */
1537 0, /* to_notice_signals */
1538 wiggler_thread_alive, /* to_thread_alive */
1540 process_stratum, /* to_stratum */
1542 1, /* to_has_all_memory */
1543 1, /* to_has_memory */
1544 1, /* to_has_stack */
1545 1, /* to_has_registers */
1546 1, /* to_has_execution */
1547 NULL, /* sections */
1548 NULL, /* sections_end */
1549 OPS_MAGIC /* to_magic */
1553 _initialize_remote_wiggler ()
1555 extern struct cmd_list_element *cmdlist;
1556 static struct cmd_list_element *bdm_cmd_list = NULL;
1558 add_target (&wiggler_ops);
1560 add_show_from_set (add_set_cmd ("remotetimeout", no_class,
1561 var_integer, (char *)&remote_timeout,
1562 "Set timeout value for remote read.\n", &setlist),
1565 add_prefix_cmd ("bdm", class_obscure, bdm_command, "", &bdm_cmd_list, "bdm ",
1568 add_cmd ("reset", class_obscure, bdm_reset_command, "", &bdm_cmd_list);
1569 add_cmd ("restart", class_obscure, bdm_restart_command, "", &bdm_cmd_list);