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