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