]> Git Repo - binutils.git/blob - gdb/remote-wiggler.c
* gdb.base/default.exp: Don't set match_max.
[binutils.git] / gdb / remote-wiggler.c
1 /* Remote target communications for the Macraigor Systems BDM Wiggler
2    Copyright 1996 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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.  */
19
20 #include "defs.h"
21 #include "gdbcore.h"
22 #include "gdb_string.h"
23 #include <fcntl.h>
24 #include "frame.h"
25 #include "inferior.h"
26 #include "bfd.h"
27 #include "symfile.h"
28 #include "target.h"
29 #include "wait.h"
30 #include "gdbcmd.h"
31 #include "objfiles.h"
32 #include "gdb-stabs.h"
33
34 #include "dcache.h"
35
36 #ifdef USG
37 #include <sys/types.h>
38 #endif
39
40 #include <signal.h>
41 #include "serial.h"
42
43 /* Wiggler serial protocol definitions */
44
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 */
48
49 /* Status flags */
50
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 */
56
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 */
79
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 */
83
84 #define WIGGLER_ERASE_FLASH 0x90 /* Erase flash memory */
85 #define WIGGLER_PROGRAM_FLASH 0x91 /* Write flash memory */
86 #define WIGGLER_EXIT_MON 0x93   /* Exit the flash programming monitor  */
87 #define WIGGLER_ENTER_MON 0x94  /* Enter the flash programming monitor  */
88
89 #define WIGGLER_SET_STATUS 0x0a /* Set status */
90 #define   WIGGLER_FLAG_STOP 0x0 /* Stop the target, enter BDM */
91 #define   WIGGLER_FLAG_START 0x01 /* Start the target at PC */
92 #define   WIGGLER_FLAG_RETURN_STATUS 0x04 /* Return async status */
93
94 /* Stuff that should be in tm-xxx files. */
95 #if 1
96 #define BDM_NUM_REGS 24
97 #define BDM_REGMAP   0,  1,  2,  3,  4,  5,  6,  7, /* d0 -> d7 */ \
98                      8,  9, 10, 11, 12, 13, 14, 15, /* a0 -> a7 */ \
99                     18, 16,                         /* ps, pc */ \
100                     -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
101                     -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
102 #define BDM_BREAKPOINT 0x4a, 0xfa /* BGND insn */
103 #else
104 #define BDM_NUM_REGS 24
105 #define BDM_REGMAP   8,  9, 10, 11, 12, 13, 14, 15, /* d0 -> d7 */ \
106                     16, 17, 18, 19, 20, 21, 22, 23, /* a0 -> a7 */ \
107                      4,  0,                         /* ps, pc */ \
108                     -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
109                     -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
110 #define WIGGLER_POLL
111 #endif
112
113 /* Prototypes for local functions */
114
115 static void wiggler_stop PARAMS ((void));
116
117 static void put_packet PARAMS ((unsigned char *packet, int pktlen));
118 static unsigned char * get_packet PARAMS ((int cmd, int *pktlen, int timeout));
119
120 static int wiggler_write_bytes PARAMS ((CORE_ADDR memaddr,
121                                        char *myaddr, int len));
122
123 static int wiggler_read_bytes PARAMS ((CORE_ADDR memaddr,
124                                       char *myaddr, int len));
125
126 static void wiggler_files_info PARAMS ((struct target_ops *ignore));
127
128 static int wiggler_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
129                                        int len, int should_write,
130                                        struct target_ops *target));
131
132 static void wiggler_prepare_to_store PARAMS ((void));
133
134 static void wiggler_fetch_registers PARAMS ((int regno));
135
136 static void wiggler_resume PARAMS ((int pid, int step,
137                                    enum target_signal siggnal));
138
139 static int wiggler_start_remote PARAMS ((char *dummy));
140
141 static void wiggler_open PARAMS ((char *name, int from_tty));
142
143 static void wiggler_close PARAMS ((int quitting));
144
145 static void wiggler_store_registers PARAMS ((int regno));
146
147 static void wiggler_mourn PARAMS ((void));
148
149 static int readchar PARAMS ((int timeout));
150
151 static void reset_packet PARAMS ((void));
152
153 static void output_packet PARAMS ((void));
154
155 static int get_quoted_char PARAMS ((int timeout));
156
157 static void put_quoted_char PARAMS ((int c));
158
159 static int wiggler_wait PARAMS ((int pid, struct target_waitstatus *status));
160
161 static void wiggler_kill PARAMS ((void));
162
163 static void wiggler_detach PARAMS ((char *args, int from_tty));
164
165 static void wiggler_interrupt PARAMS ((int signo));
166
167 static void wiggler_interrupt_twice PARAMS ((int signo));
168
169 static void interrupt_query PARAMS ((void));
170
171 static unsigned char * do_command PARAMS ((int cmd, int *statusp, int *lenp));
172
173 static unsigned char * read_bdm_registers PARAMS ((int first_bdm_regno,
174                                                    int last_bdm_regno,
175                                                    int *numregs));
176
177 extern struct target_ops wiggler_ops;   /* Forward decl */
178
179 static int last_run_status;
180
181 /* This was 5 seconds, which is a long time to sit and wait.
182    Unless this is going though some terminal server or multiplexer or
183    other form of hairy serial connection, I would think 2 seconds would
184    be plenty.  */
185
186 /* Changed to allow option to set timeout value.
187    was static int remote_timeout = 2; */
188 extern int remote_timeout;
189
190 /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
191    wiggler_open knows that we don't have a file open when the program
192    starts.  */
193 serial_t wiggler_desc = NULL;
194 \f
195 static void
196 wiggler_error (s, error_code)
197      char *s;
198      int error_code;
199 {
200   char buf[100];
201
202   fputs_filtered (s, gdb_stderr);
203   fputs_filtered (" ", gdb_stderr);
204
205   switch (error_code)
206     {
207     case 0x1: s = "Unknown fault"; break;
208     case 0x2: s = "Power failed"; break;
209     case 0x3: s = "Cable disconnected"; break;
210     case 0x4: s = "Couldn't enter BDM"; break;
211     case 0x5: s = "Target stuck in reset"; break;
212     case 0x6: s = "Port not configured"; break;
213     case 0x7: s = "Write verify failed"; break;
214     case 0x11: s = "Bus error"; break;
215     case 0x12: s = "Checksum error"; break;
216     case 0x13: s = "Illegal command"; break;
217     case 0x14: s = "Parameter error"; break;
218     case 0x15: s = "Internal error"; break;
219     case 0x16: s = "Register buffer error"; break;
220     case 0x80: s = "Flash erase error"; break;
221     default:
222       sprintf (buf, "Unknown error code %d", error_code);
223       s = buf;
224     }
225
226   error (s);
227 }
228
229 /*  Return nonzero if the thread TH is still alive on the remote system.  */
230
231 static int
232 wiggler_thread_alive (th)
233      int th;
234 {
235   return 1;
236 }
237 \f
238 /* Clean up connection to a remote debugger.  */
239
240 /* ARGSUSED */
241 static void
242 wiggler_close (quitting)
243      int quitting;
244 {
245   if (wiggler_desc)
246     SERIAL_CLOSE (wiggler_desc);
247   wiggler_desc = NULL;
248 }
249
250 /* Stub for catch_errors.  */
251
252 static int
253 wiggler_start_remote (dummy)
254      char *dummy;
255 {
256   unsigned char buf[10], *p;
257   int pktlen;
258   int status;
259   int error_code;
260   int speed;
261
262   immediate_quit = 1;           /* Allow user to interrupt it */
263
264   SERIAL_SEND_BREAK (wiggler_desc); /* Wake up the wiggler */
265
266   do_command (WIGGLER_AYT, &status, &pktlen);
267
268   p = do_command (WIGGLER_GET_VERSION, &status, &pktlen);
269
270   printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
271                      p[0], p[1], (p[2] << 16) | p[3]);
272
273 #if 1
274   speed = 80;                   /* Divide clock by 4000 */
275
276   buf[0] = WIGGLER_INIT;
277   buf[1] = speed >> 8;
278   buf[2] = speed & 0xff;
279   buf[3] = 0;                   /* CPU32 for now */
280   put_packet (buf, 4);          /* Init Wiggler params */
281   p = get_packet (buf[0], &pktlen, remote_timeout);
282
283   if (pktlen < 2)
284     error ("Truncated response packet from Wiggler");
285
286   status = p[1];
287   error_code = p[2];
288
289   if (error_code != 0)
290     wiggler_error ("WIGGLER_INIT:", error_code);
291 #endif
292
293 #if 0
294   /* Reset the target */
295
296   do_command (WIGGLER_RESET_RUN, &status, &pktlen);
297 /*  do_command (WIGGLER_RESET, &status, &pktlen);*/
298 #endif
299
300   /* If processor is still running, stop it.  */
301
302   if (!(status & WIGGLER_FLAG_BDM))
303     wiggler_stop ();
304
305 #if 1
306   buf[0] = WIGGLER_SET_CTL_FLAGS;
307   buf[1] = 0;
308   buf[2] = 1;           /* Asynchronously return status when target stops */
309   put_packet (buf, 3);
310
311   p = get_packet (buf[0], &pktlen, remote_timeout);
312
313   if (pktlen < 2)
314     error ("Truncated response packet from Wiggler");
315
316   status = p[1];
317   error_code = p[2];
318
319   if (error_code != 0)
320     wiggler_error ("WIGGLER_SET_CTL_FLAGS:", error_code);
321 #endif
322
323   immediate_quit = 0;
324
325 /* This is really the job of start_remote however, that makes an assumption
326    that the target is about to print out a status message of some sort.  That
327    doesn't happen here (in fact, it may not be possible to get the monitor to
328    send the appropriate packet).  */
329
330   flush_cached_frames ();
331   registers_changed ();
332   stop_pc = read_pc ();
333   set_current_frame (create_new_frame (read_fp (), stop_pc));
334   select_frame (get_current_frame (), 0);
335   print_stack_frame (selected_frame, -1, 1);
336
337   return 1;
338 }
339
340 /* Open a connection to a remote debugger.
341    NAME is the filename used for communication.  */
342
343 static DCACHE *wiggler_dcache;
344
345 static void
346 wiggler_open (name, from_tty)
347      char *name;
348      int from_tty;
349 {
350   if (name == 0)
351     error ("To open a Wiggler connection, you need to specify what serial\n\
352 device the Wiggler is attached to (e.g. /dev/ttya).");
353
354   target_preopen (from_tty);
355
356   unpush_target (&wiggler_ops);
357
358   wiggler_dcache = dcache_init (wiggler_read_bytes, wiggler_write_bytes);
359
360   wiggler_desc = SERIAL_OPEN (name);
361   if (!wiggler_desc)
362     perror_with_name (name);
363
364   if (baud_rate != -1)
365     {
366       if (SERIAL_SETBAUDRATE (wiggler_desc, baud_rate))
367         {
368           SERIAL_CLOSE (wiggler_desc);
369           perror_with_name (name);
370         }
371     }
372
373   SERIAL_RAW (wiggler_desc);
374
375   /* If there is something sitting in the buffer we might take it as a
376      response to a command, which would be bad.  */
377   SERIAL_FLUSH_INPUT (wiggler_desc);
378
379   if (from_tty)
380     {
381       puts_filtered ("Remote target wiggler connected to ");
382       puts_filtered (name);
383       puts_filtered ("\n");
384     }
385   push_target (&wiggler_ops);   /* Switch to using remote target now */
386
387   /* Without this, some commands which require an active target (such as kill)
388      won't work.  This variable serves (at least) double duty as both the pid
389      of the target process (if it has such), and as a flag indicating that a
390      target is active.  These functions should be split out into seperate
391      variables, especially since GDB will someday have a notion of debugging
392      several processes.  */
393
394   inferior_pid = 42000;
395   /* Start the remote connection; if error (0), discard this target.
396      In particular, if the user quits, be sure to discard it
397      (we'd be in an inconsistent state otherwise).  */
398   if (!catch_errors (wiggler_start_remote, (char *)0, 
399                      "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
400     pop_target();
401 }
402
403 /* This takes a program previously attached to and detaches it.  After
404    this is done, GDB can be used to debug some other program.  We
405    better not have left any breakpoints in the target program or it'll
406    die when it hits one.  */
407
408 static void
409 wiggler_detach (args, from_tty)
410      char *args;
411      int from_tty;
412 {
413   if (args)
414     error ("Argument given to \"detach\" when remotely debugging.");
415
416   pop_target ();
417   if (from_tty)
418     puts_filtered ("Ending remote debugging.\n");
419 }
420 \f
421 /* Tell the remote machine to resume.  */
422
423 static void
424 wiggler_resume (pid, step, siggnal)
425      int pid, step;
426      enum target_signal siggnal;
427 {
428   int pktlen;
429
430   dcache_flush (wiggler_dcache);
431
432   if (step)
433     do_command (WIGGLER_STEP, &last_run_status, &pktlen);
434   else
435     do_command (WIGGLER_RUN, &last_run_status, &pktlen);
436 }
437 \f
438 static void
439 wiggler_stop ()
440 {
441   int status;
442   int pktlen;
443
444   do_command (WIGGLER_STOP, &status, &pktlen);
445
446   if (!(status & WIGGLER_FLAG_BDM))
447     error ("Can't stop target via BDM");
448 }
449
450 static volatile int wiggler_interrupt_flag;
451
452 /* Send ^C to target to halt it.  Target will respond, and send us a
453    packet.  */
454
455 static void
456 wiggler_interrupt (signo)
457      int signo;
458 {
459   /* If this doesn't work, try more severe steps.  */
460   signal (signo, wiggler_interrupt_twice);
461   
462   if (remote_debug)
463     printf_unfiltered ("wiggler_interrupt called\n");
464
465   {
466     char buf[1];
467
468     wiggler_stop ();
469     buf[0] = WIGGLER_AYT;
470     put_packet (buf, 1);
471     wiggler_interrupt_flag = 1;
472   }
473 }
474
475 static void (*ofunc)();
476
477 /* The user typed ^C twice.  */
478 static void
479 wiggler_interrupt_twice (signo)
480      int signo;
481 {
482   signal (signo, ofunc);
483   
484   interrupt_query ();
485
486   signal (signo, wiggler_interrupt);
487 }
488
489 /* Ask the user what to do when an interrupt is received.  */
490
491 static void
492 interrupt_query ()
493 {
494   target_terminal_ours ();
495
496   if (query ("Interrupted while waiting for the program.\n\
497 Give up (and stop debugging it)? "))
498     {
499       target_mourn_inferior ();
500       return_to_top_level (RETURN_QUIT);
501     }
502
503   target_terminal_inferior ();
504 }
505
506 /* If nonzero, ignore the next kill.  */
507 static int kill_kludge;
508
509 /* Wait until the remote machine stops, then return,
510    storing status in STATUS just as `wait' would.
511    Returns "pid" (though it's not clear what, if anything, that
512    means in the case of this target).  */
513
514 static int
515 wiggler_wait (pid, target_status)
516      int pid;
517      struct target_waitstatus *target_status;
518 {
519   unsigned char *p;
520   int error_code, status;
521   int pktlen;
522
523   wiggler_interrupt_flag = 0;
524
525   target_status->kind = TARGET_WAITKIND_STOPPED;
526   target_status->value.sig = TARGET_SIGNAL_TRAP;
527
528   /* Target may already be stopped by the time we get here. */
529
530   if (!(last_run_status & WIGGLER_FLAG_BDM))
531     {
532       ofunc = (void (*)()) signal (SIGINT, wiggler_interrupt);
533
534       p = get_packet (WIGGLER_AYT, &pktlen, -1);
535
536       signal (SIGINT, ofunc);
537
538       if (pktlen < 2)
539         error ("Truncated response packet from Wiggler");
540
541       status = p[1];
542       error_code = p[2];
543
544       if (error_code != 0)
545         wiggler_error ("target_wait:", error_code);
546
547       if (status & WIGGLER_FLAG_PWF)
548         error ("Wiggler lost VCC at BDM interface.");
549       else if (status & WIGGLER_FLAG_CABLE_DISC)
550         error ("BDM cable appears to have been disconnected.");
551
552       if (!(status & WIGGLER_FLAG_BDM))
553         error ("Wiggler woke up, but wasn't stopped: 0x%x", status);
554
555       if (wiggler_interrupt_flag)
556         target_status->value.sig = TARGET_SIGNAL_INT;
557     }
558
559   /* This test figures out if we just executed a BGND insn, and if it's one of
560      our breakpoints.  If so, then we back up PC.  N.B. When a BGND insn is
561      executed, the PC points at the loc just after the insn (ie: it's always
562      two bytes *after* the BGND).  So, it's not sufficient to just see if PC-2
563      is a BGND insn because we could have gotten there via a jump.  We dis-
564      ambiguate this case by examining the ATEMP register (which is only
565      accessible from BDM).  This will tell us if we entered BDM because we
566      executed a BGND insn.  */
567
568   if (breakpoint_inserted_here_p (read_pc () - 2)) /* One of our breakpoints? */
569     {                           /* Yes, see if we actually executed it */
570 #if 0   /* Temporarily disabled until atemp reading is fixed. */
571       int atemp;
572       int numregs;
573
574       p = read_bdm_registers (23, 23, &numregs);
575       atemp = extract_unsigned_integer (p, 4);
576
577       if (atemp == 1)           /* And, did we hit a breakpoint insn? */
578 #endif
579         write_pc (read_pc () - 2); /* Yes, then back up PC */
580     }
581
582   return inferior_pid;
583 }
584
585 /* Read the remote registers into the block REGS.  */
586 /* Currently we just read all the registers, so we don't use regno.  */
587 /* ARGSUSED */
588
589 static unsigned char *
590 read_bdm_registers (first_bdm_regno, last_bdm_regno, numregs)
591      int first_bdm_regno;
592      int last_bdm_regno;
593      int *numregs;
594 {
595   unsigned char buf[10];
596   int i;
597   unsigned char *p;
598   unsigned char *regs;
599   int error_code, status;
600   int pktlen;
601
602   buf[0] = WIGGLER_READ_REGS;
603   buf[1] = first_bdm_regno >> 8;
604   buf[2] = first_bdm_regno & 0xff;
605   buf[3] = last_bdm_regno >> 8;
606   buf[4] = last_bdm_regno & 0xff;
607
608   put_packet (buf, 5);
609   p = get_packet (WIGGLER_READ_REGS, &pktlen, remote_timeout);
610
611   if (pktlen < 5)
612     error ("Truncated response packet from Wiggler");
613
614   status = p[1];
615   error_code = p[2];
616
617   if (error_code != 0)
618     wiggler_error ("read_bdm_registers:", error_code);
619
620   i = p[3];
621   if (i == 0)
622     i = 256;
623
624   if (i > pktlen - 4
625       || ((i & 3) != 0))
626     error ("Register block size bad:  %d", i);
627
628   *numregs = i / 4;
629
630   regs = p + 4;
631
632   return regs;
633 }
634
635 static void
636 dump_all_bdm_regs ()
637 {
638   unsigned char *regs;
639   int numregs;
640   int i;
641
642   regs = read_bdm_registers (0, BDM_NUM_REGS - 1, &numregs);
643
644   printf_unfiltered ("rpc = 0x%x ",
645                      (int)extract_unsigned_integer (regs, 4));
646   regs += 4;
647   printf_unfiltered ("usp = 0x%x ",
648                      (int)extract_unsigned_integer (regs, 4));
649   regs += 4;
650   printf_unfiltered ("ssp = 0x%x ",
651                      (int)extract_unsigned_integer (regs, 4));
652   regs += 4;
653   printf_unfiltered ("vbr = 0x%x ",
654                      (int)extract_unsigned_integer (regs, 4));
655   regs += 4;
656   printf_unfiltered ("sr = 0x%x ",
657                      (int)extract_unsigned_integer (regs, 4));
658   regs += 4;
659   printf_unfiltered ("sfc = 0x%x ",
660                      (int)extract_unsigned_integer (regs, 4));
661   regs += 4;
662   printf_unfiltered ("dfc = 0x%x ",
663                      (int)extract_unsigned_integer (regs, 4));
664   regs += 4;
665   printf_unfiltered ("atemp = 0x%x ",
666                      (int)extract_unsigned_integer (regs, 4));
667   regs += 4;
668   printf_unfiltered ("\n");
669
670   for (i = 0; i <= 7; i++)
671     printf_unfiltered ("d%i = 0x%x ", i,
672                        (int)extract_unsigned_integer (regs + i * 4, 4));
673   regs += 8 * 4;
674   printf_unfiltered ("\n");
675
676   for (i = 0; i <= 7; i++)
677     printf_unfiltered ("a%i = 0x%x ", i,
678                        (int)extract_unsigned_integer (regs + i * 4, 4));
679   printf_unfiltered ("\n");
680 }
681
682 static int bdm_regmap[] = {BDM_REGMAP};
683
684 /* Read the remote registers into the block REGS.  */
685 /* Currently we just read all the registers, so we don't use regno.  */
686 /* ARGSUSED */
687 static void
688 wiggler_fetch_registers (regno)
689      int regno;
690 {
691   int i;
692   unsigned char *regs;
693   int first_regno, last_regno;
694   int first_bdm_regno, last_bdm_regno;
695   int numregs;
696
697   if (regno == -1)
698     {
699       first_regno = 0;
700       last_regno = NUM_REGS - 1;
701
702       first_bdm_regno = 0;
703       last_bdm_regno = BDM_NUM_REGS - 1;
704     }
705   else
706     {
707       first_regno = regno;
708       last_regno = regno;
709
710       first_bdm_regno = bdm_regmap [regno];
711       last_bdm_regno = bdm_regmap [regno];
712     }
713
714   if (first_bdm_regno == -1)
715     {
716       supply_register (first_regno, NULL);
717       return;                   /* Unsupported register */
718     }
719
720   regs = read_bdm_registers (first_bdm_regno, last_bdm_regno, &numregs);
721
722   for (i = first_regno; i <= last_regno; i++)
723     {
724       int bdm_regno, regoffset;
725
726       bdm_regno = bdm_regmap [i];
727       if (bdm_regno != -1)
728         {
729           regoffset = bdm_regno - first_bdm_regno;
730
731           if (regoffset >= numregs)
732             continue;
733
734           supply_register (i, regs + 4 * regoffset);
735         }
736       else
737         supply_register (i, NULL); /* Unsupported register */
738     }
739 }
740
741 static void 
742 wiggler_prepare_to_store ()
743 {
744 }
745
746 /* Store register REGNO, or all registers if REGNO == -1, from the contents
747    of REGISTERS.  FIXME: ignores errors.  */
748
749 static void
750 wiggler_store_registers (regno)
751      int regno;
752 {
753   unsigned char buf[10 + 256];
754   int i;
755   unsigned char *p;
756   int error_code, status;
757   int pktlen;
758   int first_regno, last_regno;
759   int first_bdm_regno, last_bdm_regno;
760
761   if (regno == -1)
762     {
763       first_regno = 0;
764       last_regno = NUM_REGS - 1;
765
766       first_bdm_regno = 0;
767       last_bdm_regno = BDM_NUM_REGS - 1;
768     }
769   else
770     {
771       first_regno = regno;
772       last_regno = regno;
773
774       first_bdm_regno = bdm_regmap [regno];
775       last_bdm_regno = bdm_regmap [regno];
776     }
777
778   if (first_bdm_regno == -1)
779     return;                     /* Unsupported register */
780
781   buf[0] = WIGGLER_WRITE_REGS;
782   buf[3] = 4;
783
784   for (i = first_regno; i <= last_regno; i++)
785     {
786       int bdm_regno;
787
788       bdm_regno = bdm_regmap [i];
789
790       buf[1] = bdm_regno >> 8;
791       buf[2] = bdm_regno & 0xff;
792
793       memcpy (&buf[4], &registers[REGISTER_BYTE (i)], 4);
794       put_packet (buf, 4 + 4);
795       p = get_packet (WIGGLER_WRITE_REGS, &pktlen, remote_timeout);
796
797       if (pktlen < 3)
798         error ("Truncated response packet from Wiggler");
799
800       status = p[1];
801       error_code = p[2];
802
803       if (error_code != 0)
804         wiggler_error ("wiggler_store_registers:", error_code);
805     }
806 }
807 \f
808 /* Write memory data directly to the remote machine.
809    This does not inform the data cache; the data cache uses this.
810    MEMADDR is the address in the remote memory space.
811    MYADDR is the address of the buffer in our space.
812    LEN is the number of bytes.
813
814    Returns number of bytes transferred, or 0 for error.  */
815
816 static int
817 wiggler_write_bytes (memaddr, myaddr, len)
818      CORE_ADDR memaddr;
819      char *myaddr;
820      int len;
821 {
822   char buf[256 + 10];
823   unsigned char *p;
824   int origlen;
825
826   origlen = len;
827
828   buf[0] = WIGGLER_WRITE_MEM;
829   buf[5] = 1;                   /* Write as bytes */
830   buf[6] = 0;                   /* Don't verify */
831
832   while (len > 0)
833     {
834       int numbytes;
835       int pktlen;
836       int status, error_code;
837
838       numbytes = min (len, 256 - 8);
839
840       buf[1] = memaddr >> 24;
841       buf[2] = memaddr >> 16;
842       buf[3] = memaddr >> 8;
843       buf[4] = memaddr;
844
845       buf[7] = numbytes;
846
847       memcpy (&buf[8], myaddr, numbytes);
848       put_packet (buf, 8 + numbytes);
849       p = get_packet (WIGGLER_WRITE_MEM, &pktlen, remote_timeout);
850       if (pktlen < 3)
851         error ("Truncated response packet from Wiggler");
852
853       status = p[1];
854       error_code = p[2];
855
856       if (error_code == 0x11)   /* Got a bus error? */
857         {
858           CORE_ADDR error_address;
859
860           error_address = p[3] << 24;
861           error_address |= p[4] << 16;
862           error_address |= p[5] << 8;
863           error_address |= p[6];
864           numbytes = error_address - memaddr;
865
866           len -= numbytes;
867
868           errno = EIO;
869
870           break;
871         }
872       else if (error_code != 0)
873         wiggler_error ("wiggler_write_bytes:", error_code);
874
875       len -= numbytes;
876       memaddr += numbytes;
877       myaddr += numbytes;
878     }
879
880   return origlen - len;
881 }
882
883 /* Read memory data directly from the remote machine.
884    This does not use the data cache; the data cache uses this.
885    MEMADDR is the address in the remote memory space.
886    MYADDR is the address of the buffer in our space.
887    LEN is the number of bytes.
888
889    Returns number of bytes transferred, or 0 for error.  */
890
891 static int
892 wiggler_read_bytes (memaddr, myaddr, len)
893      CORE_ADDR memaddr;
894      char *myaddr;
895      int len;
896 {
897   char buf[256 + 10];
898   unsigned char *p;
899   int origlen;
900
901   origlen = len;
902
903   buf[0] = WIGGLER_READ_MEM;
904   buf[5] = 1;                   /* Read as bytes */
905
906   while (len > 0)
907     {
908       int numbytes;
909       int pktlen;
910       int status, error_code;
911
912       numbytes = min (len, 256 - 7);
913
914       buf[1] = memaddr >> 24;
915       buf[2] = memaddr >> 16;
916       buf[3] = memaddr >> 8;
917       buf[4] = memaddr;
918
919       buf[6] = numbytes;
920
921       put_packet (buf, 7);
922       p = get_packet (WIGGLER_READ_MEM, &pktlen, remote_timeout);
923       if (pktlen < 4)
924         error ("Truncated response packet from Wiggler");
925
926       status = p[1];
927       error_code = p[2];
928
929       if (error_code == 0x11)   /* Got a bus error? */
930         {
931           CORE_ADDR error_address;
932
933           error_address = p[3] << 24;
934           error_address |= p[4] << 16;
935           error_address |= p[5] << 8;
936           error_address |= p[6];
937           numbytes = error_address - memaddr;
938
939           len -= numbytes;
940
941           errno = EIO;
942
943           break;
944         }
945       else if (error_code != 0)
946         wiggler_error ("wiggler_read_bytes:", error_code);
947
948       memcpy (myaddr, &p[4], numbytes);
949
950       len -= numbytes;
951       memaddr += numbytes;
952       myaddr += numbytes;
953     }
954
955   return origlen - len;
956 }
957 \f
958 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
959    to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
960    nonzero.  Returns length of data written or read; 0 for error.  */
961
962 /* ARGSUSED */
963 static int
964 wiggler_xfer_memory (memaddr, myaddr, len, should_write, target)
965      CORE_ADDR memaddr;
966      char *myaddr;
967      int len;
968      int should_write;
969      struct target_ops *target;                 /* ignored */
970 {
971   return dcache_xfer_memory (wiggler_dcache, memaddr, myaddr, len, should_write);
972 }
973 \f
974 static void
975 wiggler_files_info (ignore)
976      struct target_ops *ignore;
977 {
978   puts_filtered ("Debugging a target over a serial line.\n");
979 }
980 \f
981 /* Stuff for dealing with the packets which are part of this protocol.
982    See comment at top of file for details.  */
983
984 /* Read a single character from the remote side, handling wierd errors. */
985
986 static int
987 readchar (timeout)
988      int timeout;
989 {
990   int ch;
991
992   ch = SERIAL_READCHAR (wiggler_desc, timeout);
993
994   switch (ch)
995     {
996     case SERIAL_EOF:
997       error ("Remote connection closed");
998     case SERIAL_ERROR:
999       perror_with_name ("Remote communication error");
1000     case SERIAL_TIMEOUT:
1001     default:
1002       return ch;
1003     }
1004 }
1005
1006 #if 0
1007 /* Read a character from the data stream, dequoting as necessary.  SYN is
1008    treated special.  Any SYNs appearing in the data stream are returned as the
1009    distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
1010    mistaken for real data).  */
1011
1012 static int
1013 get_quoted_char (timeout)
1014      int timeout;
1015 {
1016   int ch;
1017
1018   ch = readchar (timeout);
1019
1020   switch (ch)
1021     {
1022     case SERIAL_TIMEOUT:
1023       error ("Timeout in mid-packet, aborting");
1024     case SYN:
1025       return RAW_SYN;
1026     case DLE:
1027       ch = readchar (timeout);
1028       if (ch == SYN)
1029         return RAW_SYN;
1030       return ch & ~0100;
1031     default:
1032       return ch;
1033     }
1034 }
1035
1036 static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
1037
1038 static void
1039 reset_packet ()
1040 {
1041   pktp = pkt;
1042 }
1043
1044 static void
1045 output_packet ()
1046 {
1047   if (SERIAL_WRITE (wiggler_desc, pkt, pktp - pkt))
1048     perror_with_name ("output_packet: write failed");
1049
1050   reset_packet ();
1051 }
1052
1053 /* Output a quoted character.  SYNs and DLEs are quoted.  Everything else goes
1054    through untouched.  */
1055
1056 static void
1057 put_quoted_char (c)
1058      int c;
1059 {
1060   switch (c)
1061     {
1062     case SYN:
1063     case DLE:
1064       *pktp++ = DLE;
1065       c |= 0100;
1066     }
1067
1068   *pktp++ = c;
1069 }
1070
1071 /* Send a packet to the Wiggler.  The packet framed by a SYN character, a byte
1072    count and a checksum.  The byte count only counts the number of bytes
1073    between the count and the checksum.  A count of zero actually means 256.
1074    Any SYNs within the packet (including the checksum and count) must be
1075    quoted.  The quote character must be quoted as well.  Quoting is done by
1076    replacing the character with the two-character sequence DLE, {char} | 0100.
1077    Note that the quoting mechanism has no effect on the byte count.
1078  */
1079
1080 static void
1081 stu_put_packet (buf, len)
1082      unsigned char *buf;
1083      int len;
1084 {
1085   unsigned char checksum;
1086   unsigned char c;
1087
1088   if (len == 0 || len > 256)
1089     abort ();                   /* Can't represent 0 length packet */
1090
1091   reset_packet ();
1092
1093   checksum = 0;
1094
1095   put_quoted_char (RAW_SYN);
1096
1097   c = len;
1098
1099   do
1100     {
1101       checksum += c;
1102
1103       put_quoted_char (c);
1104
1105       c = *buf++;
1106     }
1107   while (len-- > 0);
1108
1109   put_quoted_char (-checksum & 0xff);
1110
1111   output_packet ();
1112 }
1113
1114 #else
1115
1116 /* Send a packet to the Wiggler.  The packet framed by a SYN character, a byte
1117    count and a checksum.  The byte count only counts the number of bytes
1118    between the count and the checksum.  A count of zero actually means 256.
1119    Any SYNs within the packet (including the checksum and count) must be
1120    quoted.  The quote character must be quoted as well.  Quoting is done by
1121    replacing the character with the two-character sequence DLE, {char} | 0100.
1122    Note that the quoting mechanism has no effect on the byte count.
1123  */
1124
1125 static void
1126 put_packet (buf, len)
1127      unsigned char *buf;
1128      int len;
1129 {
1130   unsigned char checksum;
1131   unsigned char c;
1132   unsigned char *packet, *packet_ptr;
1133
1134   packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
1135   packet_ptr = packet;
1136
1137   checksum = 0;
1138
1139   *packet_ptr++ = 0x55;
1140
1141   while (len-- > 0)
1142     {
1143       c = *buf++;
1144
1145       checksum += c;
1146       *packet_ptr++ = c;
1147     }
1148
1149   *packet_ptr++ = -checksum;
1150   if (SERIAL_WRITE (wiggler_desc, packet, packet_ptr - packet))
1151     perror_with_name ("output_packet: write failed");
1152 }
1153 #endif
1154
1155 #if 0
1156 /* Get a packet from the Wiggler.  Timeout is only enforced for the first byte
1157    of the packet.  Subsequent bytes are expected to arrive in time <= 
1158    remote_timeout.  Returns a pointer to a static buffer containing the payload
1159    of the packet.  *LENP contains the length of the packet.
1160 */
1161
1162 static unsigned char *
1163 stu_get_packet (cmd, lenp, timeout)
1164      unsigned char cmd;
1165      int *lenp;
1166 {
1167   int ch;
1168   int len;
1169   static unsigned char buf[256 + 10], *p;
1170   unsigned char checksum;
1171
1172  find_packet:
1173
1174   ch = get_quoted_char (timeout);
1175
1176   if (ch < 0)
1177     error ("get_packet (readchar): %d", ch);
1178
1179   if (ch != RAW_SYN)
1180     goto find_packet;
1181
1182  found_syn:                     /* Found the start of a packet */
1183
1184   p = buf;
1185   checksum = 0;
1186
1187   len = get_quoted_char (remote_timeout);
1188
1189   if (len == RAW_SYN)
1190     goto found_syn;
1191
1192   checksum += len;
1193
1194   if (len == 0)
1195     len = 256;
1196
1197   len++;                        /* Include checksum */
1198
1199   while (len-- > 0)
1200     {
1201       ch = get_quoted_char (remote_timeout);
1202       if (ch == RAW_SYN)
1203         goto found_syn;
1204
1205       *p++ = ch;
1206       checksum += ch;
1207     }
1208
1209   if (checksum != 0)
1210     goto find_packet;
1211
1212   if (cmd != buf[0])
1213     error ("Response phase error.  Got 0x%x, expected 0x%x", buf[0], cmd);
1214
1215   *lenp = p - buf - 1;
1216   return buf;
1217 }
1218
1219 #else
1220
1221 /* Get a packet from the Wiggler.  Timeout is only enforced for the first byte
1222    of the packet.  Subsequent bytes are expected to arrive in time <= 
1223    remote_timeout.  Returns a pointer to a static buffer containing the payload
1224    of the packet.  *LENP contains the length of the packet.
1225 */
1226
1227 static unsigned char *
1228 get_packet (cmd, lenp, timeout)
1229      int cmd;
1230      int *lenp;
1231 {
1232   int ch;
1233   int len;
1234   int i;
1235   static unsigned char packet[512];
1236   unsigned char *packet_ptr;
1237   unsigned char checksum;
1238
1239  find_packet:
1240
1241   ch = readchar (timeout);
1242
1243   if (ch < 0)
1244     error ("get_packet (readchar): %d", ch);
1245
1246   if (ch != 0x55)
1247     goto find_packet;
1248
1249 /* Found the start of a packet */
1250
1251   packet_ptr = packet;
1252   checksum = 0;
1253
1254 /* Read command char.  That sort of tells us how long the packet is. */
1255
1256   ch = readchar (timeout);
1257
1258   if (ch < 0)
1259     error ("get_packet (readchar): %d", ch);
1260
1261   *packet_ptr++ = ch;
1262   checksum += ch;
1263
1264 /* Get status. */
1265
1266   ch = readchar (timeout);
1267
1268   if (ch < 0)
1269     error ("get_packet (readchar): %d", ch);
1270   *packet_ptr++ = ch;
1271   checksum += ch;
1272
1273 /* Get error code. */
1274
1275   ch = readchar (timeout);
1276
1277   if (ch < 0)
1278     error ("get_packet (readchar): %d", ch);
1279   *packet_ptr++ = ch;
1280   checksum += ch;
1281
1282   switch (ch)                   /* Figure out length of packet */
1283     {
1284     case 0x7:                   /* Write verify error? */
1285       len = 8;                  /* write address, value read back */
1286       break;
1287     case 0x11:                  /* Bus error? */
1288                                 /* write address, read flag */
1289     case 0x15:                  /* Internal error */
1290       len = 5;                  /* error code, vector */
1291       break;
1292     default:                    /* Error w/no params */
1293       len = 0;
1294     case 0x0:                   /* Normal result */
1295       switch (packet[0])
1296         {
1297         case WIGGLER_AYT:       /* Are You There? */
1298         case WIGGLER_SET_BAUD_RATE: /* Set Baud Rate */
1299         case WIGGLER_INIT:      /* Initialize wiggler */
1300         case WIGGLER_SET_SPEED: /* Set Speed */
1301         case WIGGLER_SET_FUNC_CODE: /* Set Function Code */
1302         case WIGGLER_SET_CTL_FLAGS: /* Set Control Flags */
1303         case WIGGLER_SET_BUF_ADDR: /* Set Register Buffer Address */
1304         case WIGGLER_RUN:       /* Run Target from PC  */
1305         case WIGGLER_RUN_ADDR:  /* Run Target from Specified Address  */
1306         case WIGGLER_STOP:      /* Stop Target */
1307         case WIGGLER_RESET_RUN: /* Reset Target and Run */
1308         case WIGGLER_RESET:     /* Reset Target and Halt */
1309         case WIGGLER_STEP:      /* Single Step */
1310         case WIGGLER_WRITE_REGS: /* Write Register */
1311         case WIGGLER_WRITE_MEM: /* Write Memory */
1312         case WIGGLER_FILL_MEM:  /* Fill Memory */
1313         case WIGGLER_MOVE_MEM:  /* Move Memory */
1314         case WIGGLER_WRITE_INT_MEM: /* Write Internal Memory */
1315         case WIGGLER_JUMP:      /* Jump to Subroutine */
1316         case WIGGLER_ERASE_FLASH: /* Erase flash memory */
1317         case WIGGLER_PROGRAM_FLASH: /* Write flash memory */
1318         case WIGGLER_EXIT_MON:  /* Exit the flash programming monitor  */
1319         case WIGGLER_ENTER_MON: /* Enter the flash programming monitor  */
1320           len = 0;
1321           break;
1322         case WIGGLER_GET_VERSION: /* Get Version */
1323           len = 4;
1324           break;
1325         case WIGGLER_GET_STATUS_MASK: /* Get Status Mask */
1326           len = 1;
1327           break;
1328         case WIGGLER_GET_CTRS:  /* Get Error Counters */
1329         case WIGGLER_READ_REGS: /* Read Register */
1330         case WIGGLER_READ_MEM:  /* Read Memory */
1331         case WIGGLER_READ_INT_MEM: /* Read Internal Memory */
1332           len = 257;
1333           break;
1334         default:
1335           fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch);
1336           goto find_packet;
1337         }
1338     }
1339
1340   if (len == 257)               /* Byte stream? */
1341     {                           /* Yes, byte streams contain the length */
1342       ch = readchar (timeout);
1343
1344       if (ch < 0)
1345         error ("get_packet (readchar): %d", ch);
1346       *packet_ptr++ = ch;
1347       checksum += ch;
1348       len = ch;
1349       if (len == 0)
1350         len = 256;
1351     }
1352
1353   while (len-- >= 0)            /* Do rest of packet and checksum */
1354     {
1355       ch = readchar (timeout);
1356
1357       if (ch < 0)
1358         error ("get_packet (readchar): %d", ch);
1359       *packet_ptr++ = ch;
1360       checksum += ch;
1361     }
1362
1363   if (checksum != 0)
1364     goto find_packet;
1365
1366   if (cmd != -1 && cmd != packet[0])
1367     error ("Response phase error.  Got 0x%x, expected 0x%x", packet[0], cmd);
1368
1369   *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
1370   return packet;
1371 }
1372 #endif
1373
1374 /* Execute a simple (one-byte) command.  Returns a pointer to the data
1375    following the error code.  */
1376
1377 static unsigned char *
1378 do_command (cmd, statusp, lenp)
1379      int cmd;
1380      int *statusp;
1381      int *lenp;
1382 {
1383   unsigned char buf[100], *p;
1384   int status, error_code;
1385   char errbuf[100];
1386
1387   buf[0] = cmd;
1388   put_packet (buf, 1);          /* Send command */
1389   p = get_packet (*buf, lenp, remote_timeout);
1390
1391   if (*lenp < 3)
1392     error ("Truncated response packet from Wiggler");
1393
1394   status = p[1];
1395   error_code = p[2];
1396
1397   if (error_code != 0)
1398     {
1399       sprintf (errbuf, "do_command (0x%x):", cmd);
1400       wiggler_error (errbuf, error_code);
1401     }
1402
1403   if (status & WIGGLER_FLAG_PWF)
1404     error ("Wiggler can't detect VCC at BDM interface.");
1405   else if (status & WIGGLER_FLAG_CABLE_DISC)
1406     error ("BDM cable appears to be disconnected.");
1407
1408   *statusp = status;
1409
1410   return p + 3;
1411 }
1412 \f
1413 static void
1414 wiggler_kill ()
1415 {
1416   /* For some mysterious reason, wait_for_inferior calls kill instead of
1417      mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
1418   if (kill_kludge)
1419     {
1420       kill_kludge = 0;
1421       target_mourn_inferior ();
1422       return;
1423     }
1424
1425   /* Don't wait for it to die.  I'm not really sure it matters whether
1426      we do or not.  */
1427   target_mourn_inferior ();
1428 }
1429
1430 static void
1431 wiggler_mourn ()
1432 {
1433   unpush_target (&wiggler_ops);
1434   generic_mourn_inferior ();
1435 }
1436
1437 /* All we actually do is set the PC to the start address of exec_bfd, and start
1438    the program at that point.  */
1439
1440 static void
1441 wiggler_create_inferior (exec_file, args, env)
1442      char *exec_file;
1443      char *args;
1444      char **env;
1445 {
1446   if (args && (*args != '\000'))
1447     error ("Args are not supported by BDM.");
1448
1449   clear_proceed_status ();
1450   proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
1451 }
1452
1453 static void
1454 wiggler_load (args, from_tty)
1455      char *args;
1456      int from_tty;
1457 {
1458   generic_load (args, from_tty);
1459
1460   inferior_pid = 0;
1461
1462 /* This is necessary because many things were based on the PC at the time that
1463    we attached to the monitor, which is no longer valid now that we have loaded
1464    new code (and just changed the PC).  Another way to do this might be to call
1465    normal_stop, except that the stack may not be valid, and things would get
1466    horribly confused... */
1467
1468   clear_symtab_users ();
1469 }
1470
1471 /* BDM (at least on CPU32) uses a different breakpoint */
1472
1473 static int
1474 wiggler_insert_breakpoint (addr, contents_cache)
1475      CORE_ADDR addr;
1476      char *contents_cache;
1477 {
1478   static char break_insn[] = {BDM_BREAKPOINT};
1479   int val;
1480
1481   val = target_read_memory (addr, contents_cache, sizeof break_insn);
1482
1483   if (val == 0)
1484     val = target_write_memory (addr, break_insn, sizeof break_insn);
1485
1486   return val;
1487 }
1488
1489 static void
1490 bdm_command (args, from_tty)
1491      char *args;
1492      int from_tty;
1493 {
1494   error ("bdm command must be followed by `reset'");
1495 }
1496
1497 static void
1498 bdm_reset_command (args, from_tty)
1499      char *args;
1500      int from_tty;
1501 {
1502   int status, pktlen;
1503
1504   if (!wiggler_desc)
1505     error ("Not connected to wiggler.");
1506
1507   do_command (WIGGLER_RESET, &status, &pktlen);
1508   dcache_flush (wiggler_dcache);
1509   registers_changed ();
1510 }
1511
1512 static void
1513 bdm_restart_command (args, from_tty)
1514      char *args;
1515      int from_tty;
1516 {
1517   int status, pktlen;
1518
1519   if (!wiggler_desc)
1520     error ("Not connected to wiggler.");
1521
1522   do_command (WIGGLER_RESET_RUN, &status, &pktlen);
1523   last_run_status = status;
1524   clear_proceed_status ();
1525   wait_for_inferior ();
1526   normal_stop ();
1527 }
1528
1529 static int
1530 flash_xfer_memory (memaddr, myaddr, len, should_write, target)
1531      CORE_ADDR memaddr;
1532      char *myaddr;
1533      int len;
1534      int should_write;
1535      struct target_ops *target;                 /* ignored */
1536 {
1537   char buf[256 + 10];
1538   unsigned char *p;
1539   int origlen;
1540
1541   if (!should_write)
1542     abort ();
1543
1544   origlen = len;
1545
1546   buf[0] = WIGGLER_PROGRAM_FLASH;
1547
1548   while (len > 0)
1549     {
1550       int numbytes;
1551       int pktlen;
1552       int status, error_code;
1553
1554       numbytes = min (len, 256 - 6);
1555
1556       buf[1] = memaddr >> 24;
1557       buf[2] = memaddr >> 16;
1558       buf[3] = memaddr >> 8;
1559       buf[4] = memaddr;
1560
1561       buf[5] = numbytes;
1562
1563       memcpy (&buf[6], myaddr, numbytes);
1564       put_packet (buf, 6 + numbytes);
1565       p = get_packet (WIGGLER_PROGRAM_FLASH, &pktlen, remote_timeout);
1566       if (pktlen < 3)
1567         error ("Truncated response packet from Wiggler");
1568
1569       status = p[1];
1570       error_code = p[2];
1571
1572       if (error_code != 0)      
1573         wiggler_error ("flash_xfer_memory:", error_code);
1574
1575       len -= numbytes;
1576       memaddr += numbytes;
1577       myaddr += numbytes;
1578     }
1579
1580   return origlen - len;
1581 }
1582
1583 static void
1584 bdm_update_flash_command (args, from_tty)
1585      char *args;
1586      int from_tty;
1587 {
1588   int status, pktlen;
1589   struct cleanup *old_chain;
1590
1591   if (!wiggler_desc)
1592     error ("Not connected to wiggler.");
1593
1594   if (!args)
1595     error ("Must specify file containing new Wiggler code.");
1596
1597 /*  old_chain = make_cleanup (flash_cleanup, 0);*/
1598
1599   do_command (WIGGLER_ENTER_MON, &status, &pktlen);
1600
1601   do_command (WIGGLER_ERASE_FLASH, &status, &pktlen);
1602
1603   wiggler_ops.to_xfer_memory = flash_xfer_memory;
1604
1605   generic_load (args, from_tty);
1606
1607   wiggler_ops.to_xfer_memory = wiggler_xfer_memory;
1608
1609   do_command (WIGGLER_EXIT_MON, &status, &pktlen);
1610
1611 /*  discard_cleanups (old_chain);*/
1612 }
1613 \f
1614 /* Define the target subroutine names */
1615
1616 struct target_ops wiggler_ops = {
1617   "wiggler",                    /* to_shortname */
1618   "",                           /* to_longname */
1619   "",                           /* to_doc */
1620   wiggler_open,                 /* to_open */
1621   wiggler_close,                /* to_close */
1622   NULL,                         /* to_attach */
1623   wiggler_detach,               /* to_detach */
1624   wiggler_resume,               /* to_resume */
1625   wiggler_wait,                 /* to_wait */
1626   wiggler_fetch_registers,      /* to_fetch_registers */
1627   wiggler_store_registers,      /* to_store_registers */
1628   wiggler_prepare_to_store,     /* to_prepare_to_store */
1629   wiggler_xfer_memory,          /* to_xfer_memory */
1630   wiggler_files_info,           /* to_files_info */
1631   wiggler_insert_breakpoint,    /* to_insert_breakpoint */
1632   memory_remove_breakpoint,     /* to_remove_breakpoint */
1633   NULL,                         /* to_terminal_init */
1634   NULL,                         /* to_terminal_inferior */
1635   NULL,                         /* to_terminal_ours_for_output */
1636   NULL,                         /* to_terminal_ours */
1637   NULL,                         /* to_terminal_info */
1638   wiggler_kill,                 /* to_kill */
1639   wiggler_load,                 /* to_load */
1640   NULL,                         /* to_lookup_symbol */
1641   wiggler_create_inferior,      /* to_create_inferior */
1642   wiggler_mourn,                /* to_mourn_inferior */
1643   0,                            /* to_can_run */
1644   0,                            /* to_notice_signals */
1645   wiggler_thread_alive,         /* to_thread_alive */
1646   0,                            /* to_stop */
1647   process_stratum,              /* to_stratum */
1648   NULL,                         /* to_next */
1649   1,                            /* to_has_all_memory */
1650   1,                            /* to_has_memory */
1651   1,                            /* to_has_stack */
1652   1,                            /* to_has_registers */
1653   1,                            /* to_has_execution */
1654   NULL,                         /* sections */
1655   NULL,                         /* sections_end */
1656   OPS_MAGIC                     /* to_magic */
1657 };
1658
1659 void
1660 _initialize_remote_wiggler ()
1661 {
1662   extern struct cmd_list_element *cmdlist;
1663   static struct cmd_list_element *bdm_cmd_list = NULL;
1664
1665   add_target (&wiggler_ops);
1666
1667   add_show_from_set (add_set_cmd ("remotetimeout", no_class,
1668                                   var_integer, (char *)&remote_timeout,
1669                                   "Set timeout value for remote read.\n", &setlist),
1670                      &showlist);
1671
1672   add_prefix_cmd ("bdm", class_obscure, bdm_command, "", &bdm_cmd_list, "bdm ",
1673                   0, &cmdlist);
1674
1675   add_cmd ("reset", class_obscure, bdm_reset_command, "", &bdm_cmd_list);
1676   add_cmd ("restart", class_obscure, bdm_restart_command, "", &bdm_cmd_list);
1677   add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &bdm_cmd_list);
1678 }
This page took 0.11606 seconds and 4 git commands to generate.