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 0x1: s
= "Unknown fault"; break;
202 case 0x2: s
= "Power failed"; break;
203 case 0x3: s
= "Cable disconnected"; break;
204 case 0x4: s
= "Couldn't enter BDM"; break;
205 case 0x5: s
= "Target stuck in reset"; break;
206 case 0x6: s
= "Port not configured"; break;
207 case 0x7: s
= "Write verify failed"; break;
208 case 0x11: s
= "Bus error"; break;
209 case 0x12: s
= "Checksum error"; break;
210 case 0x13: s
= "Illegal command"; break;
211 case 0x14: s
= "Parameter error"; break;
212 case 0x15: s
= "Internal error"; break;
213 case 0x16: s
= "Register buffer error"; break;
215 sprintf (buf
, "Unknown error code %d", error_code
);
222 /* Return nonzero if the thread TH is still alive on the remote system. */
225 wiggler_thread_alive (th
)
231 /* Clean up connection to a remote debugger. */
235 wiggler_close (quitting
)
239 SERIAL_CLOSE (wiggler_desc
);
243 /* Stub for catch_errors. */
246 wiggler_start_remote (dummy
)
249 unsigned char buf
[10], *p
;
255 immediate_quit
= 1; /* Allow user to interrupt it */
257 SERIAL_SEND_BREAK (wiggler_desc
); /* Wake up the wiggler */
259 do_command (WIGGLER_AYT
, &status
, &pktlen
);
261 p
= do_command (WIGGLER_GET_VERSION
, &status
, &pktlen
);
263 printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
264 p
[0], p
[1], (p
[2] << 16) | p
[3]);
267 speed
= 80; /* Divide clock by 4000 */
269 buf
[0] = WIGGLER_INIT
;
271 buf
[2] = speed
& 0xff;
272 buf
[3] = 0; /* CPU32 for now */
273 put_packet (buf
, 4); /* Init Wiggler params */
274 p
= get_packet (buf
[0], &pktlen
, remote_timeout
);
277 error ("Truncated response packet from Wiggler");
283 wiggler_error ("WIGGLER_INIT:", error_code
);
287 /* Reset the target */
289 do_command (WIGGLER_RESET_RUN
, &status
, &pktlen
);
290 /* do_command (WIGGLER_RESET, &status, &pktlen);*/
293 /* If processor is still running, stop it. */
295 if (!(status
& WIGGLER_FLAG_BDM
))
299 buf
[0] = WIGGLER_SET_CTL_FLAGS
;
301 buf
[2] = 1; /* Asynchronously return status when target stops */
304 p
= get_packet (buf
[0], &pktlen
, remote_timeout
);
307 error ("Truncated response packet from Wiggler");
313 wiggler_error ("WIGGLER_SET_CTL_FLAGS:", error_code
);
318 /* This is really the job of start_remote however, that makes an assumption
319 that the target is about to print out a status message of some sort. That
320 doesn't happen here (in fact, it may not be possible to get the monitor to
321 send the appropriate packet). */
323 flush_cached_frames ();
324 registers_changed ();
325 stop_pc
= read_pc ();
326 set_current_frame (create_new_frame (read_fp (), stop_pc
));
327 select_frame (get_current_frame (), 0);
328 print_stack_frame (selected_frame
, -1, 1);
333 /* Open a connection to a remote debugger.
334 NAME is the filename used for communication. */
336 static DCACHE
*wiggler_dcache
;
339 wiggler_open (name
, from_tty
)
344 error ("To open a Wiggler connection, you need to specify what serial\n\
345 device the Wiggler is attached to (e.g. /dev/ttya).");
347 target_preopen (from_tty
);
349 unpush_target (&wiggler_ops
);
351 wiggler_dcache
= dcache_init (wiggler_read_bytes
, wiggler_write_bytes
);
353 wiggler_desc
= SERIAL_OPEN (name
);
355 perror_with_name (name
);
359 if (SERIAL_SETBAUDRATE (wiggler_desc
, baud_rate
))
361 SERIAL_CLOSE (wiggler_desc
);
362 perror_with_name (name
);
366 SERIAL_RAW (wiggler_desc
);
368 /* If there is something sitting in the buffer we might take it as a
369 response to a command, which would be bad. */
370 SERIAL_FLUSH_INPUT (wiggler_desc
);
374 puts_filtered ("Remote target wiggler connected to ");
375 puts_filtered (name
);
376 puts_filtered ("\n");
378 push_target (&wiggler_ops
); /* Switch to using remote target now */
380 /* Without this, some commands which require an active target (such as kill)
381 won't work. This variable serves (at least) double duty as both the pid
382 of the target process (if it has such), and as a flag indicating that a
383 target is active. These functions should be split out into seperate
384 variables, especially since GDB will someday have a notion of debugging
385 several processes. */
387 inferior_pid
= 42000;
388 /* Start the remote connection; if error (0), discard this target.
389 In particular, if the user quits, be sure to discard it
390 (we'd be in an inconsistent state otherwise). */
391 if (!catch_errors (wiggler_start_remote
, (char *)0,
392 "Couldn't establish connection to remote target\n", RETURN_MASK_ALL
))
396 /* This takes a program previously attached to and detaches it. After
397 this is done, GDB can be used to debug some other program. We
398 better not have left any breakpoints in the target program or it'll
399 die when it hits one. */
402 wiggler_detach (args
, from_tty
)
407 error ("Argument given to \"detach\" when remotely debugging.");
411 puts_filtered ("Ending remote debugging.\n");
414 /* Tell the remote machine to resume. */
417 wiggler_resume (pid
, step
, siggnal
)
419 enum target_signal siggnal
;
423 dcache_flush (wiggler_dcache
);
426 do_command (WIGGLER_STEP
, &last_run_status
, &pktlen
);
428 do_command (WIGGLER_RUN
, &last_run_status
, &pktlen
);
437 do_command (WIGGLER_STOP
, &status
, &pktlen
);
439 if (!(status
& WIGGLER_FLAG_BDM
))
440 error ("Can't stop target via BDM");
443 static volatile int wiggler_interrupt_flag
;
445 /* Send ^C to target to halt it. Target will respond, and send us a
449 wiggler_interrupt (signo
)
452 /* If this doesn't work, try more severe steps. */
453 signal (signo
, wiggler_interrupt_twice
);
456 printf_unfiltered ("wiggler_interrupt called\n");
462 buf
[0] = WIGGLER_AYT
;
464 wiggler_interrupt_flag
= 1;
468 static void (*ofunc
)();
470 /* The user typed ^C twice. */
472 wiggler_interrupt_twice (signo
)
475 signal (signo
, ofunc
);
479 signal (signo
, wiggler_interrupt
);
482 /* Ask the user what to do when an interrupt is received. */
487 target_terminal_ours ();
489 if (query ("Interrupted while waiting for the program.\n\
490 Give up (and stop debugging it)? "))
492 target_mourn_inferior ();
493 return_to_top_level (RETURN_QUIT
);
496 target_terminal_inferior ();
499 /* If nonzero, ignore the next kill. */
500 static int kill_kludge
;
502 /* Wait until the remote machine stops, then return,
503 storing status in STATUS just as `wait' would.
504 Returns "pid" (though it's not clear what, if anything, that
505 means in the case of this target). */
508 wiggler_wait (pid
, target_status
)
510 struct target_waitstatus
*target_status
;
513 int error_code
, status
;
516 wiggler_interrupt_flag
= 0;
518 target_status
->kind
= TARGET_WAITKIND_STOPPED
;
519 target_status
->value
.sig
= TARGET_SIGNAL_TRAP
;
521 /* Target may already be stopped by the time we get here. */
523 if (!(last_run_status
& WIGGLER_FLAG_BDM
))
525 ofunc
= (void (*)()) signal (SIGINT
, wiggler_interrupt
);
527 p
= get_packet (WIGGLER_AYT
, &pktlen
, -1);
529 signal (SIGINT
, ofunc
);
532 error ("Truncated response packet from Wiggler");
538 wiggler_error ("target_wait:", error_code
);
540 if (status
& WIGGLER_FLAG_PWF
)
541 error ("Wiggler lost VCC at BDM interface.");
542 else if (status
& WIGGLER_FLAG_CABLE_DISC
)
543 error ("BDM cable appears to have been disconnected.");
545 if (!(status
& WIGGLER_FLAG_BDM
))
546 error ("Wiggler woke up, but wasn't stopped: 0x%x", status
);
548 if (wiggler_interrupt_flag
)
549 target_status
->value
.sig
= TARGET_SIGNAL_INT
;
552 /* This test figures out if we just executed a BGND insn, and if it's one of
553 our breakpoints. If so, then we back up PC. N.B. When a BGND insn is
554 executed, the PC points at the loc just after the insn (ie: it's always
555 two bytes *after* the BGND). So, it's not sufficient to just see if PC-2
556 is a BGND insn because we could have gotten there via a jump. We dis-
557 ambiguate this case by examining the ATEMP register (which is only
558 accessible from BDM). This will tell us if we entered BDM because we
559 executed a BGND insn. */
561 if (breakpoint_inserted_here_p (read_pc () - 2)) /* One of our breakpoints? */
562 { /* Yes, see if we actually executed it */
563 #if 0 /* Temporarily disabled until atemp reading is fixed. */
567 p
= read_bdm_registers (23, 23, &numregs
);
568 atemp
= extract_unsigned_integer (p
, 4);
570 if (atemp
== 1) /* And, did we hit a breakpoint insn? */
572 write_pc (read_pc () - 2); /* Yes, then back up PC */
578 /* Read the remote registers into the block REGS. */
579 /* Currently we just read all the registers, so we don't use regno. */
582 static unsigned char *
583 read_bdm_registers (first_bdm_regno
, last_bdm_regno
, numregs
)
588 unsigned char buf
[10];
592 int error_code
, status
;
595 buf
[0] = WIGGLER_READ_REGS
;
596 buf
[1] = first_bdm_regno
>> 8;
597 buf
[2] = first_bdm_regno
& 0xff;
598 buf
[3] = last_bdm_regno
>> 8;
599 buf
[4] = last_bdm_regno
& 0xff;
602 p
= get_packet (WIGGLER_READ_REGS
, &pktlen
, remote_timeout
);
605 error ("Truncated response packet from Wiggler");
611 wiggler_error ("read_bdm_registers:", error_code
);
619 error ("Register block size bad: %d", i
);
635 regs
= read_bdm_registers (0, BDM_NUM_REGS
- 1, &numregs
);
637 printf_unfiltered ("rpc = 0x%x ",
638 (int)extract_unsigned_integer (regs
, 4));
640 printf_unfiltered ("usp = 0x%x ",
641 (int)extract_unsigned_integer (regs
, 4));
643 printf_unfiltered ("ssp = 0x%x ",
644 (int)extract_unsigned_integer (regs
, 4));
646 printf_unfiltered ("vbr = 0x%x ",
647 (int)extract_unsigned_integer (regs
, 4));
649 printf_unfiltered ("sr = 0x%x ",
650 (int)extract_unsigned_integer (regs
, 4));
652 printf_unfiltered ("sfc = 0x%x ",
653 (int)extract_unsigned_integer (regs
, 4));
655 printf_unfiltered ("dfc = 0x%x ",
656 (int)extract_unsigned_integer (regs
, 4));
658 printf_unfiltered ("atemp = 0x%x ",
659 (int)extract_unsigned_integer (regs
, 4));
661 printf_unfiltered ("\n");
663 for (i
= 0; i
<= 7; i
++)
664 printf_unfiltered ("d%i = 0x%x ", i
,
665 (int)extract_unsigned_integer (regs
+ i
* 4, 4));
667 printf_unfiltered ("\n");
669 for (i
= 0; i
<= 7; i
++)
670 printf_unfiltered ("a%i = 0x%x ", i
,
671 (int)extract_unsigned_integer (regs
+ i
* 4, 4));
672 printf_unfiltered ("\n");
675 static int bdm_regmap
[] = {BDM_REGMAP
};
677 /* Read the remote registers into the block REGS. */
678 /* Currently we just read all the registers, so we don't use regno. */
681 wiggler_fetch_registers (regno
)
686 int first_regno
, last_regno
;
687 int first_bdm_regno
, last_bdm_regno
;
693 last_regno
= NUM_REGS
- 1;
696 last_bdm_regno
= BDM_NUM_REGS
- 1;
703 first_bdm_regno
= bdm_regmap
[regno
];
704 last_bdm_regno
= bdm_regmap
[regno
];
707 if (first_bdm_regno
== -1)
709 supply_register (first_regno
, NULL
);
710 return; /* Unsupported register */
713 regs
= read_bdm_registers (first_bdm_regno
, last_bdm_regno
, &numregs
);
715 for (i
= first_regno
; i
<= last_regno
; i
++)
717 int bdm_regno
, regoffset
;
719 bdm_regno
= bdm_regmap
[i
];
722 regoffset
= bdm_regno
- first_bdm_regno
;
724 if (regoffset
>= numregs
)
727 supply_register (i
, regs
+ 4 * regoffset
);
730 supply_register (i
, NULL
); /* Unsupported register */
735 wiggler_prepare_to_store ()
739 /* Store register REGNO, or all registers if REGNO == -1, from the contents
740 of REGISTERS. FIXME: ignores errors. */
743 wiggler_store_registers (regno
)
746 unsigned char buf
[10 + 256];
749 int error_code
, status
;
751 int first_regno
, last_regno
;
752 int first_bdm_regno
, last_bdm_regno
;
757 last_regno
= NUM_REGS
- 1;
760 last_bdm_regno
= BDM_NUM_REGS
- 1;
767 first_bdm_regno
= bdm_regmap
[regno
];
768 last_bdm_regno
= bdm_regmap
[regno
];
771 if (first_bdm_regno
== -1)
772 return; /* Unsupported register */
774 buf
[0] = WIGGLER_WRITE_REGS
;
777 for (i
= first_regno
; i
<= last_regno
; i
++)
781 bdm_regno
= bdm_regmap
[i
];
783 buf
[1] = bdm_regno
>> 8;
784 buf
[2] = bdm_regno
& 0xff;
786 memcpy (&buf
[4], ®isters
[REGISTER_BYTE (i
)], 4);
787 put_packet (buf
, 4 + 4);
788 p
= get_packet (WIGGLER_WRITE_REGS
, &pktlen
, remote_timeout
);
791 error ("Truncated response packet from Wiggler");
797 wiggler_error ("wiggler_store_registers:", error_code
);
801 /* Write memory data directly to the remote machine.
802 This does not inform the data cache; the data cache uses this.
803 MEMADDR is the address in the remote memory space.
804 MYADDR is the address of the buffer in our space.
805 LEN is the number of bytes.
807 Returns number of bytes transferred, or 0 for error. */
810 wiggler_write_bytes (memaddr
, myaddr
, len
)
821 buf
[0] = WIGGLER_WRITE_MEM
;
822 buf
[5] = 1; /* Write as bytes */
823 buf
[6] = 0; /* Don't verify */
829 int status
, error_code
;
831 numbytes
= min (len
, 256 - 8);
832 /* numbytes = min (len, 40);*/
834 buf
[1] = memaddr
>> 24;
835 buf
[2] = memaddr
>> 16;
836 buf
[3] = memaddr
>> 8;
841 memcpy (&buf
[8], myaddr
, numbytes
);
842 put_packet (buf
, 8 + numbytes
);
843 p
= get_packet (WIGGLER_WRITE_MEM
, &pktlen
, remote_timeout
);
845 error ("Truncated response packet from Wiggler");
850 if (error_code
== 11) /* Got a bus error? */
852 CORE_ADDR error_address
;
854 error_address
= p
[3] << 24;
855 error_address
|= p
[4] << 16;
856 error_address
|= p
[5] << 8;
857 error_address
|= p
[6];
858 numbytes
= error_address
- memaddr
;
866 else if (error_code
!= 0)
867 wiggler_error ("wiggler_store_registers:", error_code
);
874 return origlen
- len
;
877 /* Read memory data directly from the remote machine.
878 This does not use the data cache; the data cache uses this.
879 MEMADDR is the address in the remote memory space.
880 MYADDR is the address of the buffer in our space.
881 LEN is the number of bytes.
883 Returns number of bytes transferred, or 0 for error. */
886 wiggler_read_bytes (memaddr
, myaddr
, len
)
897 buf
[0] = WIGGLER_READ_MEM
;
898 buf
[5] = 1; /* Read as bytes */
904 int status
, error_code
;
906 numbytes
= min (len
, 256 - 7);
908 buf
[1] = memaddr
>> 24;
909 buf
[2] = memaddr
>> 16;
910 buf
[3] = memaddr
>> 8;
916 p
= get_packet (WIGGLER_READ_MEM
, &pktlen
, remote_timeout
);
918 error ("Truncated response packet from Wiggler");
923 if (error_code
== 0x11) /* Got a bus error? */
925 CORE_ADDR error_address
;
927 error_address
= p
[3] << 24;
928 error_address
|= p
[4] << 16;
929 error_address
|= p
[5] << 8;
930 error_address
|= p
[6];
931 numbytes
= error_address
- memaddr
;
939 else if (error_code
!= 0)
940 wiggler_error ("wiggler_store_registers:", error_code
);
942 memcpy (myaddr
, &p
[4], numbytes
);
949 return origlen
- len
;
952 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
953 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
954 nonzero. Returns length of data written or read; 0 for error. */
958 wiggler_xfer_memory(memaddr
, myaddr
, len
, should_write
, target
)
963 struct target_ops
*target
; /* ignored */
965 return dcache_xfer_memory (wiggler_dcache
, memaddr
, myaddr
, len
, should_write
);
969 wiggler_files_info (ignore
)
970 struct target_ops
*ignore
;
972 puts_filtered ("Debugging a target over a serial line.\n");
975 /* Stuff for dealing with the packets which are part of this protocol.
976 See comment at top of file for details. */
978 /* Read a single character from the remote side, handling wierd errors. */
986 ch
= SERIAL_READCHAR (wiggler_desc
, timeout
);
991 error ("Remote connection closed");
993 perror_with_name ("Remote communication error");
1001 /* Read a character from the data stream, dequoting as necessary. SYN is
1002 treated special. Any SYNs appearing in the data stream are returned as the
1003 distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
1004 mistaken for real data). */
1007 get_quoted_char (timeout
)
1012 ch
= readchar (timeout
);
1016 case SERIAL_TIMEOUT
:
1017 error ("Timeout in mid-packet, aborting");
1021 ch
= readchar (timeout
);
1030 static unsigned char pkt
[256 * 2 + 10], *pktp
; /* Worst case */
1041 if (SERIAL_WRITE (wiggler_desc
, pkt
, pktp
- pkt
))
1042 perror_with_name ("output_packet: write failed");
1047 /* Output a quoted character. SYNs and DLEs are quoted. Everything else goes
1048 through untouched. */
1065 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
1066 count and a checksum. The byte count only counts the number of bytes
1067 between the count and the checksum. A count of zero actually means 256.
1068 Any SYNs within the packet (including the checksum and count) must be
1069 quoted. The quote character must be quoted as well. Quoting is done by
1070 replacing the character with the two-character sequence DLE, {char} | 0100.
1071 Note that the quoting mechanism has no effect on the byte count.
1075 stu_put_packet (buf
, len
)
1079 unsigned char checksum
;
1082 if (len
== 0 || len
> 256)
1083 abort (); /* Can't represent 0 length packet */
1089 put_quoted_char (RAW_SYN
);
1097 put_quoted_char (c
);
1103 put_quoted_char (-checksum
& 0xff);
1110 /* Send a packet to the Wiggler. The packet framed by a SYN character, a byte
1111 count and a checksum. The byte count only counts the number of bytes
1112 between the count and the checksum. A count of zero actually means 256.
1113 Any SYNs within the packet (including the checksum and count) must be
1114 quoted. The quote character must be quoted as well. Quoting is done by
1115 replacing the character with the two-character sequence DLE, {char} | 0100.
1116 Note that the quoting mechanism has no effect on the byte count.
1120 put_packet (buf
, len
)
1124 unsigned char checksum
;
1126 unsigned char *packet
, *packet_ptr
;
1128 packet
= alloca (len
+ 1 + 1); /* packet + SYN + checksum */
1129 packet_ptr
= packet
;
1133 *packet_ptr
++ = 0x55;
1143 *packet_ptr
++ = -checksum
;
1144 if (SERIAL_WRITE (wiggler_desc
, packet
, packet_ptr
- packet
))
1145 perror_with_name ("output_packet: write failed");
1150 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
1151 of the packet. Subsequent bytes are expected to arrive in time <=
1152 remote_timeout. Returns a pointer to a static buffer containing the payload
1153 of the packet. *LENP contains the length of the packet.
1156 static unsigned char *
1157 stu_get_packet (cmd
, lenp
, timeout
)
1163 static unsigned char buf
[256 + 10], *p
;
1164 unsigned char checksum
;
1168 ch
= get_quoted_char (timeout
);
1171 error ("get_packet (readchar): %d", ch
);
1176 found_syn
: /* Found the start of a packet */
1181 len
= get_quoted_char (remote_timeout
);
1191 len
++; /* Include checksum */
1195 ch
= get_quoted_char (remote_timeout
);
1207 error ("Response phase error. Got 0x%x, expected 0x%x", buf
[0], cmd
);
1209 *lenp
= p
- buf
- 1;
1215 /* Get a packet from the Wiggler. Timeout is only enforced for the first byte
1216 of the packet. Subsequent bytes are expected to arrive in time <=
1217 remote_timeout. Returns a pointer to a static buffer containing the payload
1218 of the packet. *LENP contains the length of the packet.
1221 static unsigned char *
1222 get_packet (cmd
, lenp
, timeout
)
1229 static unsigned char packet
[512];
1230 unsigned char *packet_ptr
;
1231 unsigned char checksum
;
1235 ch
= readchar (timeout
);
1238 error ("get_packet (readchar): %d", ch
);
1243 /* Found the start of a packet */
1245 packet_ptr
= packet
;
1248 /* Read command char. That sort of tells us how long the packet is. */
1250 ch
= readchar (timeout
);
1253 error ("get_packet (readchar): %d", ch
);
1260 ch
= readchar (timeout
);
1263 error ("get_packet (readchar): %d", ch
);
1267 /* Get error code. */
1269 ch
= readchar (timeout
);
1272 error ("get_packet (readchar): %d", ch
);
1276 switch (ch
) /* Figure out length of packet */
1278 case 0x7: /* Write verify error? */
1279 len
= 8; /* write address, value read back */
1281 case 0x11: /* Bus error? */
1282 /* write address, read flag */
1283 case 0x15: /* Internal error */
1284 len
= 5; /* error code, vector */
1286 default: /* Error w/no params */
1288 case 0x0: /* Normal result */
1291 case WIGGLER_AYT
: /* Are You There? */
1292 case WIGGLER_SET_BAUD_RATE
: /* Set Baud Rate */
1293 case WIGGLER_INIT
: /* Initialize wiggler */
1294 case WIGGLER_SET_SPEED
: /* Set Speed */
1295 case WIGGLER_SET_FUNC_CODE
: /* Set Function Code */
1296 case WIGGLER_SET_CTL_FLAGS
: /* Set Control Flags */
1297 case WIGGLER_SET_BUF_ADDR
: /* Set Register Buffer Address */
1298 case WIGGLER_RUN
: /* Run Target from PC */
1299 case WIGGLER_RUN_ADDR
: /* Run Target from Specified Address */
1300 case WIGGLER_STOP
: /* Stop Target */
1301 case WIGGLER_RESET_RUN
: /* Reset Target and Run */
1302 case WIGGLER_RESET
: /* Reset Target and Halt */
1303 case WIGGLER_STEP
: /* Single Step */
1304 case WIGGLER_WRITE_REGS
: /* Write Register */
1305 case WIGGLER_WRITE_MEM
: /* Write Memory */
1306 case WIGGLER_FILL_MEM
: /* Fill Memory */
1307 case WIGGLER_MOVE_MEM
: /* Move Memory */
1308 case WIGGLER_WRITE_INT_MEM
: /* Write Internal Memory */
1309 case WIGGLER_JUMP
: /* Jump to Subroutine */
1312 case WIGGLER_GET_VERSION
: /* Get Version */
1315 case WIGGLER_GET_STATUS_MASK
: /* Get Status Mask */
1318 case WIGGLER_GET_CTRS
: /* Get Error Counters */
1319 case WIGGLER_READ_REGS
: /* Read Register */
1320 case WIGGLER_READ_MEM
: /* Read Memory */
1321 case WIGGLER_READ_INT_MEM
: /* Read Internal Memory */
1325 fprintf_filtered (gdb_stderr
, "Unknown packet type 0x%x\n", ch
);
1330 if (len
== 257) /* Byte stream? */
1331 { /* Yes, byte streams contain the length */
1332 ch
= readchar (timeout
);
1335 error ("get_packet (readchar): %d", ch
);
1343 while (len
-- >= 0) /* Do rest of packet and checksum */
1345 ch
= readchar (timeout
);
1348 error ("get_packet (readchar): %d", ch
);
1356 if (cmd
!= -1 && cmd
!= packet
[0])
1357 error ("Response phase error. Got 0x%x, expected 0x%x", packet
[0], cmd
);
1359 *lenp
= packet_ptr
- packet
- 1; /* Subtract checksum byte */
1364 /* Execute a simple (one-byte) command. Returns a pointer to the data
1365 following the error code. */
1367 static unsigned char *
1368 do_command (cmd
, statusp
, lenp
)
1373 unsigned char buf
[100], *p
;
1374 int status
, error_code
;
1378 put_packet (buf
, 1); /* Send command */
1379 p
= get_packet (*buf
, lenp
, remote_timeout
);
1382 error ("Truncated response packet from Wiggler");
1387 if (error_code
!= 0)
1389 sprintf (errbuf
, "do_command (0x%x):", cmd
);
1390 wiggler_error (errbuf
, error_code
);
1393 if (status
& WIGGLER_FLAG_PWF
)
1394 error ("Wiggler can't detect VCC at BDM interface.");
1395 else if (status
& WIGGLER_FLAG_CABLE_DISC
)
1396 error ("BDM cable appears to be disconnected.");
1406 /* For some mysterious reason, wait_for_inferior calls kill instead of
1407 mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
1411 target_mourn_inferior ();
1415 /* Don't wait for it to die. I'm not really sure it matters whether
1417 target_mourn_inferior ();
1423 unpush_target (&wiggler_ops
);
1424 generic_mourn_inferior ();
1427 /* All we actually do is set the PC to the start address of exec_bfd, and start
1428 the program at that point. */
1431 wiggler_create_inferior (exec_file
, args
, env
)
1436 if (args
&& (*args
!= '\000'))
1437 error ("Args are not supported by BDM.");
1439 clear_proceed_status ();
1440 proceed (bfd_get_start_address (exec_bfd
), TARGET_SIGNAL_0
, 0);
1444 wiggler_load (args
, from_tty
)
1448 generic_load (args
, from_tty
);
1452 /* BDM (at least on CPU32) uses a different breakpoint */
1455 wiggler_insert_breakpoint (addr
, contents_cache
)
1457 char *contents_cache
;
1459 static char break_insn
[] = {BDM_BREAKPOINT
};
1462 val
= target_read_memory (addr
, contents_cache
, sizeof break_insn
);
1465 val
= target_write_memory (addr
, break_insn
, sizeof break_insn
);
1471 bdm_command (args
, from_tty
)
1475 error ("bdm command must be followed by `reset'");
1479 bdm_reset_command (args
, from_tty
)
1486 error ("Not connected to wiggler.");
1488 do_command (WIGGLER_RESET
, &status
, &pktlen
);
1489 dcache_flush (wiggler_dcache
);
1490 registers_changed ();
1494 bdm_restart_command (args
, from_tty
)
1501 error ("Not connected to wiggler.");
1503 do_command (WIGGLER_RESET_RUN
, &status
, &pktlen
);
1504 last_run_status
= status
;
1505 clear_proceed_status ();
1506 wait_for_inferior ();
1510 /* Define the target subroutine names */
1512 struct target_ops wiggler_ops
= {
1513 "wiggler", /* to_shortname */
1514 "", /* to_longname */
1516 wiggler_open
, /* to_open */
1517 wiggler_close
, /* to_close */
1518 NULL
, /* to_attach */
1519 wiggler_detach
, /* to_detach */
1520 wiggler_resume
, /* to_resume */
1521 wiggler_wait
, /* to_wait */
1522 wiggler_fetch_registers
, /* to_fetch_registers */
1523 wiggler_store_registers
, /* to_store_registers */
1524 wiggler_prepare_to_store
, /* to_prepare_to_store */
1525 wiggler_xfer_memory
, /* to_xfer_memory */
1526 wiggler_files_info
, /* to_files_info */
1527 wiggler_insert_breakpoint
, /* to_insert_breakpoint */
1528 memory_remove_breakpoint
, /* to_remove_breakpoint */
1529 NULL
, /* to_terminal_init */
1530 NULL
, /* to_terminal_inferior */
1531 NULL
, /* to_terminal_ours_for_output */
1532 NULL
, /* to_terminal_ours */
1533 NULL
, /* to_terminal_info */
1534 wiggler_kill
, /* to_kill */
1535 wiggler_load
, /* to_load */
1536 NULL
, /* to_lookup_symbol */
1537 wiggler_create_inferior
, /* to_create_inferior */
1538 wiggler_mourn
, /* to_mourn_inferior */
1540 0, /* to_notice_signals */
1541 wiggler_thread_alive
, /* to_thread_alive */
1543 process_stratum
, /* to_stratum */
1545 1, /* to_has_all_memory */
1546 1, /* to_has_memory */
1547 1, /* to_has_stack */
1548 1, /* to_has_registers */
1549 1, /* to_has_execution */
1550 NULL
, /* sections */
1551 NULL
, /* sections_end */
1552 OPS_MAGIC
/* to_magic */
1556 _initialize_remote_wiggler ()
1558 extern struct cmd_list_element
*cmdlist
;
1559 static struct cmd_list_element
*bdm_cmd_list
= NULL
;
1561 add_target (&wiggler_ops
);
1563 add_show_from_set (add_set_cmd ("remotetimeout", no_class
,
1564 var_integer
, (char *)&remote_timeout
,
1565 "Set timeout value for remote read.\n", &setlist
),
1568 add_prefix_cmd ("bdm", class_obscure
, bdm_command
, "", &bdm_cmd_list
, "bdm ",
1571 add_cmd ("reset", class_obscure
, bdm_reset_command
, "", &bdm_cmd_list
);
1572 add_cmd ("restart", class_obscure
, bdm_restart_command
, "", &bdm_cmd_list
);