1 /* Remote target communications for the Macraigor Systems BDM Wiggler
2 Copyright 1996, 1997 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"
34 #include <sys/types.h>
39 /* Prototypes for local functions */
41 static int wiggler_write_bytes
PARAMS ((CORE_ADDR memaddr
,
42 char *myaddr
, int len
));
44 static int wiggler_read_bytes
PARAMS ((CORE_ADDR memaddr
,
45 char *myaddr
, int len
));
47 static int wiggler_start_remote
PARAMS ((char *dummy
));
49 static int readchar
PARAMS ((int timeout
));
51 static void reset_packet
PARAMS ((void));
53 static void output_packet
PARAMS ((void));
55 static int get_quoted_char
PARAMS ((int timeout
));
57 static void put_quoted_char
PARAMS ((int c
));
59 static void wiggler_interrupt
PARAMS ((int signo
));
61 static void wiggler_interrupt_twice
PARAMS ((int signo
));
63 static void interrupt_query
PARAMS ((void));
65 static unsigned char * do_command
PARAMS ((int cmd
, int *statusp
, int *lenp
));
67 static void wiggler_put_packet
PARAMS ((unsigned char *packet
, int pktlen
));
69 static unsigned char * wiggler_get_packet
PARAMS ((int cmd
, int *pktlen
, int timeout
));
71 static struct target_ops
*current_ops
= NULL
;
73 static int last_run_status
;
75 /* This was 5 seconds, which is a long time to sit and wait.
76 Unless this is going though some terminal server or multiplexer or
77 other form of hairy serial connection, I would think 2 seconds would
80 /* Changed to allow option to set timeout value.
81 was static int remote_timeout = 2; */
82 extern int remote_timeout
;
84 /* Descriptor for I/O to remote machine. Initialize it to NULL so that
85 wiggler_open knows that we don't have a file open when the program
87 static serial_t wiggler_desc
= NULL
;
90 wiggler_error (s
, error_code
)
96 fputs_filtered (s
, gdb_stderr
);
97 fputs_filtered (" ", gdb_stderr
);
101 case 0x1: s
= "Unknown fault"; break;
102 case 0x2: s
= "Power failed"; break;
103 case 0x3: s
= "Cable disconnected"; break;
104 case 0x4: s
= "Couldn't enter BDM"; break;
105 case 0x5: s
= "Target stuck in reset"; break;
106 case 0x6: s
= "Port not configured"; break;
107 case 0x7: s
= "Write verify failed"; break;
108 case 0x11: s
= "Bus error"; break;
109 case 0x12: s
= "Checksum error"; break;
110 case 0x13: s
= "Illegal command"; break;
111 case 0x14: s
= "Parameter error"; break;
112 case 0x15: s
= "Internal error"; break;
113 case 0x16: s
= "Register buffer error"; break;
114 case 0x80: s
= "Flash erase error"; break;
116 sprintf (buf
, "Unknown error code %d", error_code
);
123 /* Return nonzero if the thread TH is still alive on the remote system. */
126 wiggler_thread_alive (th
)
132 /* Clean up connection to a remote debugger. */
136 wiggler_close (quitting
)
140 SERIAL_CLOSE (wiggler_desc
);
144 /* Stub for catch_errors. */
147 wiggler_start_remote (dummy
)
150 unsigned char buf
[10], *p
;
155 enum wiggler_target_type target_type
;
157 target_type
= (enum wiggler_target_type
)dummy
;
159 immediate_quit
= 1; /* Allow user to interrupt it */
161 SERIAL_SEND_BREAK (wiggler_desc
); /* Wake up the wiggler */
163 do_command (WIGGLER_AYT
, &status
, &pktlen
);
165 p
= do_command (WIGGLER_GET_VERSION
, &status
, &pktlen
);
167 printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
168 p
[0], p
[1], (p
[2] << 16) | p
[3]);
171 speed
= 80; /* Divide clock by 4000 */
173 buf
[0] = WIGGLER_INIT
;
175 buf
[2] = speed
& 0xff;
176 buf
[3] = target_type
;
177 wiggler_put_packet (buf
, 4); /* Init Wiggler params */
178 p
= wiggler_get_packet (buf
[0], &pktlen
, remote_timeout
);
181 error ("Truncated response packet from Wiggler");
187 wiggler_error ("WIGGLER_INIT:", error_code
);
191 /* Reset the target */
193 do_command (WIGGLER_RESET_RUN
, &status
, &pktlen
);
194 /* do_command (WIGGLER_RESET, &status, &pktlen);*/
197 /* If processor is still running, stop it. */
199 if (!(status
& WIGGLER_FLAG_BDM
))
203 buf
[0] = WIGGLER_SET_CTL_FLAGS
;
205 buf
[2] = 1; /* Asynchronously return status when target stops */
206 wiggler_put_packet (buf
, 3);
208 p
= wiggler_get_packet (buf
[0], &pktlen
, remote_timeout
);
211 error ("Truncated response packet from Wiggler");
217 wiggler_error ("WIGGLER_SET_CTL_FLAGS:", error_code
);
222 /* This is really the job of start_remote however, that makes an assumption
223 that the target is about to print out a status message of some sort. That
224 doesn't happen here (in fact, it may not be possible to get the monitor to
225 send the appropriate packet). */
227 flush_cached_frames ();
228 registers_changed ();
229 stop_pc
= read_pc ();
230 set_current_frame (create_new_frame (read_fp (), stop_pc
));
231 select_frame (get_current_frame (), 0);
232 print_stack_frame (selected_frame
, -1, 1);
237 /* Open a connection to a remote debugger.
238 NAME is the filename used for communication. */
240 static DCACHE
*wiggler_dcache
;
243 wiggler_open (name
, from_tty
, target_type
, ops
)
246 enum wiggler_target_type target_type
;
247 struct target_ops
*ops
;
250 error ("To open a Wiggler connection, you need to specify what serial\n\
251 device the Wiggler is attached to (e.g. /dev/ttya).");
253 target_preopen (from_tty
);
257 unpush_target (current_ops
);
259 wiggler_dcache
= dcache_init (wiggler_read_bytes
, wiggler_write_bytes
);
261 wiggler_desc
= SERIAL_OPEN (name
);
263 perror_with_name (name
);
267 if (SERIAL_SETBAUDRATE (wiggler_desc
, baud_rate
))
269 SERIAL_CLOSE (wiggler_desc
);
270 perror_with_name (name
);
274 SERIAL_RAW (wiggler_desc
);
276 /* If there is something sitting in the buffer we might take it as a
277 response to a command, which would be bad. */
278 SERIAL_FLUSH_INPUT (wiggler_desc
);
282 puts_filtered ("Remote target wiggler connected to ");
283 puts_filtered (name
);
284 puts_filtered ("\n");
286 push_target (current_ops
); /* Switch to using remote target now */
288 /* Without this, some commands which require an active target (such as kill)
289 won't work. This variable serves (at least) double duty as both the pid
290 of the target process (if it has such), and as a flag indicating that a
291 target is active. These functions should be split out into seperate
292 variables, especially since GDB will someday have a notion of debugging
293 several processes. */
295 inferior_pid
= 42000;
296 /* Start the remote connection; if error (0), discard this target.
297 In particular, if the user quits, be sure to discard it
298 (we'd be in an inconsistent state otherwise). */
299 if (!catch_errors (wiggler_start_remote
, (char *)target_type
,
300 "Couldn't establish connection to remote target\n", RETURN_MASK_ALL
))
304 /* This takes a program previously attached to and detaches it. After
305 this is done, GDB can be used to debug some other program. We
306 better not have left any breakpoints in the target program or it'll
307 die when it hits one. */
310 wiggler_detach (args
, from_tty
)
315 error ("Argument given to \"detach\" when remotely debugging.");
319 puts_filtered ("Ending remote debugging.\n");
322 /* Tell the remote machine to resume. */
325 wiggler_resume (pid
, step
, siggnal
)
327 enum target_signal siggnal
;
331 dcache_flush (wiggler_dcache
);
334 do_command (WIGGLER_STEP
, &last_run_status
, &pktlen
);
336 do_command (WIGGLER_RUN
, &last_run_status
, &pktlen
);
345 do_command (WIGGLER_STOP
, &status
, &pktlen
);
347 if (!(status
& WIGGLER_FLAG_BDM
))
348 error ("Can't stop target via BDM");
351 static volatile int wiggler_interrupt_flag
;
353 /* Send ^C to target to halt it. Target will respond, and send us a
357 wiggler_interrupt (signo
)
360 /* If this doesn't work, try more severe steps. */
361 signal (signo
, wiggler_interrupt_twice
);
364 printf_unfiltered ("wiggler_interrupt called\n");
370 buf
[0] = WIGGLER_AYT
;
371 wiggler_put_packet (buf
, 1);
372 wiggler_interrupt_flag
= 1;
376 static void (*ofunc
)();
378 /* The user typed ^C twice. */
380 wiggler_interrupt_twice (signo
)
383 signal (signo
, ofunc
);
387 signal (signo
, wiggler_interrupt
);
390 /* Ask the user what to do when an interrupt is received. */
395 target_terminal_ours ();
397 if (query ("Interrupted while waiting for the program.\n\
398 Give up (and stop debugging it)? "))
400 target_mourn_inferior ();
401 return_to_top_level (RETURN_QUIT
);
404 target_terminal_inferior ();
407 /* If nonzero, ignore the next kill. */
408 static int kill_kludge
;
410 /* Wait until the remote machine stops, then return,
411 storing status in STATUS just as `wait' would.
412 Returns "pid" (though it's not clear what, if anything, that
413 means in the case of this target). */
419 int error_code
, status
;
422 wiggler_interrupt_flag
= 0;
424 /* Target may already be stopped by the time we get here. */
426 if (!(last_run_status
& WIGGLER_FLAG_BDM
))
428 ofunc
= (void (*)()) signal (SIGINT
, wiggler_interrupt
);
430 p
= wiggler_get_packet (WIGGLER_AYT
, &pktlen
, -1);
432 signal (SIGINT
, ofunc
);
435 error ("Truncated response packet from Wiggler");
441 wiggler_error ("target_wait:", error_code
);
443 if (status
& WIGGLER_FLAG_PWF
)
444 error ("Wiggler lost VCC at BDM interface.");
445 else if (status
& WIGGLER_FLAG_CABLE_DISC
)
446 error ("BDM cable appears to have been disconnected.");
448 if (!(status
& WIGGLER_FLAG_BDM
))
449 error ("Wiggler woke up, but wasn't stopped: 0x%x", status
);
452 if (wiggler_interrupt_flag
)
458 /* Read registers from the Wiggler. Specify the starting and ending register
459 number. Return the number of regs actually read in *NUMREGS. Returns a
460 pointer to a static array containing the register contents. */
463 wiggler_read_bdm_registers (first_bdm_regno
, last_bdm_regno
, reglen
)
468 unsigned char buf
[10];
472 int error_code
, status
;
475 buf
[0] = WIGGLER_READ_REGS
;
476 buf
[1] = first_bdm_regno
>> 8;
477 buf
[2] = first_bdm_regno
& 0xff;
478 buf
[3] = last_bdm_regno
>> 8;
479 buf
[4] = last_bdm_regno
& 0xff;
481 wiggler_put_packet (buf
, 5);
482 p
= wiggler_get_packet (WIGGLER_READ_REGS
, &pktlen
, remote_timeout
);
488 wiggler_error ("read_bdm_registers:", error_code
);
496 error ("Register block size bad: %d", i
);
505 /* Read register BDM_REGNO and returns its value ala read_register() */
508 wiggler_read_bdm_register (bdm_regno
)
515 p
= wiggler_read_bdm_registers (bdm_regno
, bdm_regno
, ®len
);
516 regval
= extract_unsigned_integer (p
, reglen
);
522 wiggler_write_bdm_registers (first_bdm_regno
, regptr
, reglen
)
524 unsigned char *regptr
;
529 int error_code
, status
;
532 buf
= alloca (4 + reglen
);
534 buf
[0] = WIGGLER_WRITE_REGS
;
535 buf
[1] = first_bdm_regno
>> 8;
536 buf
[2] = first_bdm_regno
& 0xff;
538 memcpy (buf
+ 4, regptr
, reglen
);
540 wiggler_put_packet (buf
, 4 + reglen
);
541 p
= wiggler_get_packet (WIGGLER_WRITE_REGS
, &pktlen
, remote_timeout
);
544 error ("Truncated response packet from Wiggler");
550 wiggler_error ("wiggler_write_bdm_registers:", error_code
);
554 wiggler_write_bdm_register (bdm_regno
, reg
)
558 unsigned char buf
[4];
560 store_unsigned_integer (buf
, 4, reg
);
562 wiggler_write_bdm_registers (bdm_regno
, buf
, 4);
566 wiggler_prepare_to_store ()
570 /* Write memory data directly to the remote machine.
571 This does not inform the data cache; the data cache uses this.
572 MEMADDR is the address in the remote memory space.
573 MYADDR is the address of the buffer in our space.
574 LEN is the number of bytes.
576 Returns number of bytes transferred, or 0 for error. */
578 static int write_mem_command
= WIGGLER_WRITE_MEM
;
581 wiggler_write_bytes (memaddr
, myaddr
, len
)
592 buf
[0] = write_mem_command
;
593 buf
[5] = 1; /* Write as bytes */
594 buf
[6] = 0; /* Don't verify */
600 int status
, error_code
;
602 numbytes
= min (len
, 256 - 8);
604 buf
[1] = memaddr
>> 24;
605 buf
[2] = memaddr
>> 16;
606 buf
[3] = memaddr
>> 8;
611 memcpy (&buf
[8], myaddr
, numbytes
);
612 wiggler_put_packet (buf
, 8 + numbytes
);
613 p
= wiggler_get_packet (WIGGLER_WRITE_MEM
, &pktlen
, remote_timeout
);
615 error ("Truncated response packet from Wiggler");
620 if (error_code
== 0x11) /* Got a bus error? */
622 CORE_ADDR error_address
;
624 error_address
= p
[3] << 24;
625 error_address
|= p
[4] << 16;
626 error_address
|= p
[5] << 8;
627 error_address
|= p
[6];
628 numbytes
= error_address
- memaddr
;
636 else if (error_code
!= 0)
637 wiggler_error ("wiggler_write_bytes:", error_code
);
644 return origlen
- len
;
647 /* Read memory data directly from the remote machine.
648 This does not use the data cache; the data cache uses this.
649 MEMADDR is the address in the remote memory space.
650 MYADDR is the address of the buffer in our space.
651 LEN is the number of bytes.
653 Returns number of bytes transferred, or 0 for error. */
656 wiggler_read_bytes (memaddr
, myaddr
, len
)
667 buf
[0] = WIGGLER_READ_MEM
;
668 buf
[5] = 1; /* Read as bytes */
674 int status
, error_code
;
676 numbytes
= min (len
, 256 - 7);
678 buf
[1] = memaddr
>> 24;
679 buf
[2] = memaddr
>> 16;
680 buf
[3] = memaddr
>> 8;
685 wiggler_put_packet (buf
, 7);
686 p
= wiggler_get_packet (WIGGLER_READ_MEM
, &pktlen
, remote_timeout
);
688 error ("Truncated response packet from Wiggler");
693 if (error_code
== 0x11) /* Got a bus error? */
695 CORE_ADDR error_address
;
697 error_address
= p
[3] << 24;
698 error_address
|= p
[4] << 16;
699 error_address
|= p
[5] << 8;
700 error_address
|= p
[6];
701 numbytes
= error_address
- memaddr
;
709 else if (error_code
!= 0)
710 wiggler_error ("wiggler_read_bytes:", error_code
);
712 memcpy (myaddr
, &p
[4], numbytes
);
719 return origlen
- len
;
722 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
723 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
724 nonzero. Returns length of data written or read; 0 for error. */
728 wiggler_xfer_memory (memaddr
, myaddr
, len
, should_write
, target
)
733 struct target_ops
*target
; /* ignored */
735 return dcache_xfer_memory (wiggler_dcache
, memaddr
, myaddr
, len
, should_write
);
739 wiggler_files_info (ignore
)
740 struct target_ops
*ignore
;
742 puts_filtered ("Debugging a target over a serial line.\n");
745 /* Stuff for dealing with the packets which are part of this protocol.
746 See comment at top of file for details. */
748 /* Read a single character from the remote side, handling wierd errors. */
756 ch
= SERIAL_READCHAR (wiggler_desc
, timeout
);
761 error ("Remote connection closed");
763 perror_with_name ("Remote communication error");
771 /* Read a character from the data stream, dequoting as necessary. SYN is
772 treated special. Any SYNs appearing in the data stream are returned as the
773 distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
774 mistaken for real data). */
777 get_quoted_char (timeout
)
782 ch
= readchar (timeout
);
787 error ("Timeout in mid-packet, aborting");
791 ch
= readchar (timeout
);
800 static unsigned char pkt
[256 * 2 + 10], *pktp
; /* Worst case */
811 if (SERIAL_WRITE (wiggler_desc
, pkt
, pktp
- pkt
))
812 perror_with_name ("output_packet: write failed");
817 /* Output a quoted character. SYNs and DLEs are quoted. Everything else goes
818 through untouched. */
835 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
836 count and a checksum. The byte count only counts the number of bytes
837 between the count and the checksum. A count of zero actually means 256.
838 Any SYNs within the packet (including the checksum and count) must be
839 quoted. The quote character must be quoted as well. Quoting is done by
840 replacing the character with the two-character sequence DLE, {char} | 0100.
841 Note that the quoting mechanism has no effect on the byte count.
845 stu_put_packet (buf
, len
)
849 unsigned char checksum
;
852 if (len
== 0 || len
> 256)
853 abort (); /* Can't represent 0 length packet */
859 put_quoted_char (RAW_SYN
);
873 put_quoted_char (-checksum
& 0xff);
880 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
881 count and a checksum. The byte count only counts the number of bytes
882 between the count and the checksum. A count of zero actually means 256.
883 Any SYNs within the packet (including the checksum and count) must be
884 quoted. The quote character must be quoted as well. Quoting is done by
885 replacing the character with the two-character sequence DLE, {char} | 0100.
886 Note that the quoting mechanism has no effect on the byte count.
890 wiggler_put_packet (buf
, len
)
894 unsigned char checksum
;
896 unsigned char *packet
, *packet_ptr
;
898 packet
= alloca (len
+ 1 + 1); /* packet + SYN + checksum */
903 *packet_ptr
++ = 0x55;
913 *packet_ptr
++ = -checksum
;
914 if (SERIAL_WRITE (wiggler_desc
, packet
, packet_ptr
- packet
))
915 perror_with_name ("output_packet: write failed");
920 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
921 of the packet. Subsequent bytes are expected to arrive in time <=
922 remote_timeout. Returns a pointer to a static buffer containing the payload
923 of the packet. *LENP contains the length of the packet.
926 static unsigned char *
927 stu_get_packet (cmd
, lenp
, timeout
)
933 static unsigned char buf
[256 + 10], *p
;
934 unsigned char checksum
;
938 ch
= get_quoted_char (timeout
);
941 error ("get_packet (readchar): %d", ch
);
946 found_syn
: /* Found the start of a packet */
951 len
= get_quoted_char (remote_timeout
);
961 len
++; /* Include checksum */
965 ch
= get_quoted_char (remote_timeout
);
977 error ("Response phase error. Got 0x%x, expected 0x%x", buf
[0], cmd
);
985 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
986 of the packet. Subsequent bytes are expected to arrive in time <=
987 remote_timeout. Returns a pointer to a static buffer containing the payload
988 of the packet. *LENP contains the length of the packet.
991 static unsigned char *
992 wiggler_get_packet (cmd
, lenp
, timeout
)
999 static unsigned char packet
[512];
1000 unsigned char *packet_ptr
;
1001 unsigned char checksum
;
1005 ch
= readchar (timeout
);
1008 error ("wiggler_get_packet (readchar): %d", ch
);
1013 /* Found the start of a packet */
1015 packet_ptr
= packet
;
1018 /* Read command char. That sort of tells us how long the packet is. */
1020 ch
= readchar (timeout
);
1023 error ("wiggler_get_packet (readchar): %d", ch
);
1030 ch
= readchar (timeout
);
1033 error ("wiggler_get_packet (readchar): %d", ch
);
1037 /* Get error code. */
1039 ch
= readchar (timeout
);
1042 error ("wiggler_get_packet (readchar): %d", ch
);
1046 switch (ch
) /* Figure out length of packet */
1048 case 0x7: /* Write verify error? */
1049 len
= 8; /* write address, value read back */
1051 case 0x11: /* Bus error? */
1052 /* write address, read flag */
1053 case 0x15: /* Internal error */
1054 len
= 5; /* error code, vector */
1056 default: /* Error w/no params */
1059 case 0x0: /* Normal result */
1062 case WIGGLER_AYT
: /* Are You There? */
1063 case WIGGLER_SET_BAUD_RATE
: /* Set Baud Rate */
1064 case WIGGLER_INIT
: /* Initialize wiggler */
1065 case WIGGLER_SET_SPEED
: /* Set Speed */
1066 case WIGGLER_SET_FUNC_CODE
: /* Set Function Code */
1067 case WIGGLER_SET_CTL_FLAGS
: /* Set Control Flags */
1068 case WIGGLER_SET_BUF_ADDR
: /* Set Register Buffer Address */
1069 case WIGGLER_RUN
: /* Run Target from PC */
1070 case WIGGLER_RUN_ADDR
: /* Run Target from Specified Address */
1071 case WIGGLER_STOP
: /* Stop Target */
1072 case WIGGLER_RESET_RUN
: /* Reset Target and Run */
1073 case WIGGLER_RESET
: /* Reset Target and Halt */
1074 case WIGGLER_STEP
: /* Single Step */
1075 case WIGGLER_WRITE_REGS
: /* Write Register */
1076 case WIGGLER_WRITE_MEM
: /* Write Memory */
1077 case WIGGLER_FILL_MEM
: /* Fill Memory */
1078 case WIGGLER_MOVE_MEM
: /* Move Memory */
1079 case WIGGLER_WRITE_INT_MEM
: /* Write Internal Memory */
1080 case WIGGLER_JUMP
: /* Jump to Subroutine */
1081 case WIGGLER_ERASE_FLASH
: /* Erase flash memory */
1082 case WIGGLER_PROGRAM_FLASH
: /* Write flash memory */
1083 case WIGGLER_EXIT_MON
: /* Exit the flash programming monitor */
1084 case WIGGLER_ENTER_MON
: /* Enter the flash programming monitor */
1087 case WIGGLER_GET_VERSION
: /* Get Version */
1090 case WIGGLER_GET_STATUS_MASK
: /* Get Status Mask */
1093 case WIGGLER_GET_CTRS
: /* Get Error Counters */
1094 case WIGGLER_READ_REGS
: /* Read Register */
1095 case WIGGLER_READ_MEM
: /* Read Memory */
1096 case WIGGLER_READ_INT_MEM
: /* Read Internal Memory */
1100 fprintf_filtered (gdb_stderr
, "Unknown packet type 0x%x\n", ch
);
1105 if (len
== 257) /* Byte stream? */
1106 { /* Yes, byte streams contain the length */
1107 ch
= readchar (timeout
);
1110 error ("wiggler_get_packet (readchar): %d", ch
);
1118 while (len
-- >= 0) /* Do rest of packet and checksum */
1120 ch
= readchar (timeout
);
1123 error ("wiggler_get_packet (readchar): %d", ch
);
1131 if (cmd
!= -1 && cmd
!= packet
[0])
1132 error ("Response phase error. Got 0x%x, expected 0x%x", packet
[0], cmd
);
1134 *lenp
= packet_ptr
- packet
- 1; /* Subtract checksum byte */
1139 /* Execute a simple (one-byte) command. Returns a pointer to the data
1140 following the error code. */
1142 static unsigned char *
1143 do_command (cmd
, statusp
, lenp
)
1148 unsigned char buf
[100], *p
;
1149 int status
, error_code
;
1153 wiggler_put_packet (buf
, 1); /* Send command */
1154 p
= wiggler_get_packet (*buf
, lenp
, remote_timeout
);
1157 error ("Truncated response packet from Wiggler");
1162 if (error_code
!= 0)
1164 sprintf (errbuf
, "do_command (0x%x):", cmd
);
1165 wiggler_error (errbuf
, error_code
);
1168 if (status
& WIGGLER_FLAG_PWF
)
1169 error ("Wiggler can't detect VCC at BDM interface.");
1170 else if (status
& WIGGLER_FLAG_CABLE_DISC
)
1171 error ("BDM cable appears to be disconnected.");
1181 /* For some mysterious reason, wait_for_inferior calls kill instead of
1182 mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
1186 target_mourn_inferior ();
1190 /* Don't wait for it to die. I'm not really sure it matters whether
1192 target_mourn_inferior ();
1198 unpush_target (current_ops
);
1199 generic_mourn_inferior ();
1202 /* All we actually do is set the PC to the start address of exec_bfd, and start
1203 the program at that point. */
1206 wiggler_create_inferior (exec_file
, args
, env
)
1211 if (args
&& (*args
!= '\000'))
1212 error ("Args are not supported by BDM.");
1214 clear_proceed_status ();
1215 proceed (bfd_get_start_address (exec_bfd
), TARGET_SIGNAL_0
, 0);
1219 wiggler_load (args
, from_tty
)
1223 generic_load (args
, from_tty
);
1227 /* This is necessary because many things were based on the PC at the time that
1228 we attached to the monitor, which is no longer valid now that we have loaded
1229 new code (and just changed the PC). Another way to do this might be to call
1230 normal_stop, except that the stack may not be valid, and things would get
1231 horribly confused... */
1233 clear_symtab_users ();
1236 /* BDM (at least on CPU32) uses a different breakpoint */
1239 wiggler_insert_breakpoint (addr
, contents_cache
)
1241 char *contents_cache
;
1243 static char break_insn
[] = {BDM_BREAKPOINT
};
1246 val
= target_read_memory (addr
, contents_cache
, sizeof break_insn
);
1249 val
= target_write_memory (addr
, break_insn
, sizeof break_insn
);
1255 bdm_command (args
, from_tty
)
1259 error ("bdm command must be followed by `reset'");
1263 bdm_reset_command (args
, from_tty
)
1270 error ("Not connected to wiggler.");
1272 do_command (WIGGLER_RESET
, &status
, &pktlen
);
1273 dcache_flush (wiggler_dcache
);
1274 registers_changed ();
1278 bdm_restart_command (args
, from_tty
)
1285 error ("Not connected to wiggler.");
1287 do_command (WIGGLER_RESET_RUN
, &status
, &pktlen
);
1288 last_run_status
= status
;
1289 clear_proceed_status ();
1290 wait_for_inferior ();
1294 /* Temporary replacement for target_store_registers(). This prevents
1295 generic_load from trying to set the PC. */
1298 noop_store_registers (regno
)
1304 bdm_update_flash_command (args
, from_tty
)
1309 struct cleanup
*old_chain
;
1310 void (*store_registers_tmp
) PARAMS ((int));
1313 error ("Not connected to wiggler.");
1316 error ("Must specify file containing new Wiggler code.");
1318 /* old_chain = make_cleanup (flash_cleanup, 0);*/
1320 do_command (WIGGLER_ENTER_MON
, &status
, &pktlen
);
1322 do_command (WIGGLER_ERASE_FLASH
, &status
, &pktlen
);
1324 write_mem_command
= WIGGLER_PROGRAM_FLASH
;
1325 store_registers_tmp
= current_target
.to_store_registers
;
1326 current_target
.to_store_registers
= noop_store_registers
;
1328 generic_load (args
, from_tty
);
1330 current_target
.to_store_registers
= store_registers_tmp
;
1331 write_mem_command
= WIGGLER_WRITE_MEM
;
1333 do_command (WIGGLER_EXIT_MON
, &status
, &pktlen
);
1335 /* discard_cleanups (old_chain);*/
1339 bdm_read_register_command (args
, from_tty
)
1343 /* XXX repeat should go on to the next register */
1346 error ("Not connected to wiggler.");
1349 error ("Must specify BDM register number.");
1354 _initialize_remote_wiggler ()
1356 extern struct cmd_list_element
*cmdlist
;
1357 static struct cmd_list_element
*bdm_cmd_list
= NULL
;
1359 add_show_from_set (add_set_cmd ("remotetimeout", no_class
,
1360 var_integer
, (char *)&remote_timeout
,
1361 "Set timeout value for remote read.\n", &setlist
),
1364 add_prefix_cmd ("bdm", class_obscure
, bdm_command
, "", &bdm_cmd_list
, "bdm ",
1367 add_cmd ("reset", class_obscure
, bdm_reset_command
, "", &bdm_cmd_list
);
1368 add_cmd ("restart", class_obscure
, bdm_restart_command
, "", &bdm_cmd_list
);
1369 add_cmd ("update-flash", class_obscure
, bdm_update_flash_command
, "", &bdm_cmd_list
);
1370 /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &bdm_cmd_list);*/