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