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