xref: /openbsd/gnu/usr.bin/binutils/gdb/ocd.c (revision d415bd75)
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 
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 
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 (), 0, SRC_AND_LOC);
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 
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 
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 
555 void
556 ocd_prepare_to_store (void)
557 {
558 }
559 
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 
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 
725 void
726 ocd_files_info (struct target_ops *ignore)
727 {
728   puts_filtered ("Debugging a target over a serial line.\n");
729 }
730 
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 
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, int from_tty)
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 
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   deprecated_add_show_from_set
1159     (add_set_cmd ("remotetimeout", no_class,
1160 		  var_integer, (char *) &remote_timeout,
1161 		  "Set timeout value for remote read.\n", &setlist),
1162      &showlist);
1163 
1164   add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
1165 		  0, &cmdlist);
1166 
1167   add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
1168   add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
1169   add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
1170 }
1171