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