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