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 
71 void
ocd_error(char * s,int error_code)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
ocd_thread_alive(ptid_t th)137 ocd_thread_alive (ptid_t th)
138 {
139   return 1;
140 }
141 
142 /* Clean up connection to a remote debugger.  */
143 
144 void
ocd_close(int quitting)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
ocd_start_remote(void * dummy)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
ocd_open(char * name,int from_tty,enum ocd_target_type target_type,struct target_ops * ops)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
ocd_detach(char * args,int from_tty)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 
327 /* Tell the remote machine to resume.  */
328 
329 void
ocd_resume(ptid_t ptid,int step,enum target_signal siggnal)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 
340 void
ocd_stop(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
ocd_interrupt(int signo)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
ocd_interrupt_twice(int signo)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
interrupt_query(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
ocd_wait(void)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 *
ocd_read_bdm_registers(int first_bdm_regno,int last_bdm_regno,int * reglen)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
ocd_read_bdm_register(int bdm_regno)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
ocd_write_bdm_registers(int first_bdm_regno,unsigned char * regptr,int reglen)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
ocd_write_bdm_register(int bdm_regno,CORE_ADDR reg)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 
556 void
ocd_prepare_to_store(void)557 ocd_prepare_to_store (void)
558 {
559 }
560 
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
ocd_write_bytes(CORE_ADDR memaddr,char * myaddr,int len)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
ocd_read_bytes(CORE_ADDR memaddr,char * myaddr,int len)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 
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
ocd_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int should_write,struct mem_attrib * attrib,struct target_ops * target)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 
726 void
ocd_files_info(struct target_ops * ignore)727 ocd_files_info (struct target_ops *ignore)
728 {
729   puts_filtered ("Debugging a target over a serial line.\n");
730 }
731 
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
readchar(int timeout)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
ocd_put_packet(unsigned char * buf,int len)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 *
ocd_get_packet(int cmd,int * lenp,int timeout)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 *
ocd_do_command(int cmd,int * statusp,int * lenp)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 
990 void
ocd_kill(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
ocd_mourn(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
ocd_create_inferior(char * exec_file,char * args,char ** env,int from_tty)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
ocd_load(char * args,int from_tty)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
ocd_insert_breakpoint(CORE_ADDR addr,char * contents_cache)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
ocd_remove_breakpoint(CORE_ADDR addr,char * contents_cache)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
bdm_command(char * args,int from_tty)1077 bdm_command (char *args, int from_tty)
1078 {
1079   error (_("bdm command must be followed by `reset'"));
1080 }
1081 
1082 static void
bdm_reset_command(char * args,int from_tty)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
bdm_restart_command(char * args,int from_tty)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
noop_store_registers(int regno)1114 noop_store_registers (int regno)
1115 {
1116 }
1117 
1118 static void
bdm_update_flash_command(char * args,int from_tty)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 
1151 extern initialize_file_ftype _initialize_remote_ocd; /* -Wmissing-prototypes */
1152 
1153 void
_initialize_remote_ocd(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   add_setshow_integer_cmd ("remotetimeout", no_class, &remote_timeout, _("\
1160 Set timeout value for remote read."), _("\
1161 Show timeout value for remote read."), NULL,
1162 			   NULL,
1163 			   NULL, /* FIXME: i18n: */
1164 			   &setlist, &showlist);
1165 
1166   /* FIXME: i18n: What documentation?  */
1167   add_prefix_cmd ("ocd", class_obscure, bdm_command, (""), &ocd_cmd_list,
1168 		  "ocd ", 0, &cmdlist);
1169 
1170   /* FIXME: i18n: what documentation? */
1171   add_cmd ("reset", class_obscure, bdm_reset_command, (""), &ocd_cmd_list);
1172   add_cmd ("restart", class_obscure, bdm_restart_command, (""), &ocd_cmd_list);
1173   add_cmd ("update-flash", class_obscure, bdm_update_flash_command, (""), &ocd_cmd_list);
1174 }
1175