Sun Aug 10 16:49:09 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 /* 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 = 0; /* 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       ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
459
460       p = ocd_get_packet (OCD_AYT, &pktlen, -1);
461
462       signal (SIGINT, ofunc);
463
464       if (pktlen < 2)
465         error ("Truncated response packet from OCD device");
466
467       status = p[1];
468       error_code = p[2];
469
470       if (error_code != 0)
471         ocd_error ("target_wait:", error_code);
472
473       if (status & OCD_FLAG_PWF)
474         error ("OCD device lost VCC at BDM interface.");
475       else if (status & OCD_FLAG_CABLE_DISC)
476         error ("BDM cable appears to have been disconnected.");
477
478       if (!(status & OCD_FLAG_BDM))
479         error ("OCD device woke up, but wasn't stopped: 0x%x", status);
480     }
481
482   if (ocd_interrupt_flag)
483     return 1;
484   else
485     return 0;
486 }
487
488 /* Read registers from the OCD device.  Specify the starting and ending
489    register number.  Return the number of regs actually read in *NUMREGS.
490    Returns a pointer to a static array containing the register contents.  */
491
492 unsigned char *
493 ocd_read_bdm_registers (first_bdm_regno, last_bdm_regno, reglen)
494      int first_bdm_regno;
495      int last_bdm_regno;
496      int *reglen;
497 {
498   unsigned char buf[10];
499   int i;
500   unsigned char *p;
501   unsigned char *regs;
502   int error_code, status;
503   int pktlen;
504
505   buf[0] = OCD_READ_REGS;
506   buf[1] = first_bdm_regno >> 8;
507   buf[2] = first_bdm_regno & 0xff;
508   buf[3] = last_bdm_regno >> 8;
509   buf[4] = last_bdm_regno & 0xff;
510
511   ocd_put_packet (buf, 5);
512   p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout);
513
514   status = p[1];
515   error_code = p[2];
516
517   if (error_code != 0)
518     ocd_error ("read_bdm_registers:", error_code);
519
520   i = p[3];
521   if (i == 0)
522     i = 256;
523
524   if (i > pktlen - 4
525       || ((i & 3) != 0))
526     error ("Register block size bad:  %d", i);
527
528   *reglen = i;
529
530   regs = p + 4;
531
532   return regs;
533 }
534
535 /* Read register BDM_REGNO and returns its value ala read_register() */
536
537 CORE_ADDR
538 ocd_read_bdm_register (bdm_regno)
539      int bdm_regno;
540 {
541   int reglen;
542   unsigned char *p;
543   CORE_ADDR regval;
544
545   p = ocd_read_bdm_registers (bdm_regno, bdm_regno, &reglen);
546   regval = extract_unsigned_integer (p, reglen);
547
548   return regval;
549 }
550
551 void
552 ocd_write_bdm_registers (first_bdm_regno, regptr, reglen)
553      int first_bdm_regno;
554      unsigned char *regptr;
555      int reglen;
556 {
557   unsigned char *buf;
558   unsigned char *p;
559   int error_code, status;
560   int pktlen;
561
562   buf = alloca (4 + reglen);
563
564   buf[0] = OCD_WRITE_REGS;
565   buf[1] = first_bdm_regno >> 8;
566   buf[2] = first_bdm_regno & 0xff;
567   buf[3] = reglen;
568   memcpy (buf + 4, regptr, reglen);
569
570   ocd_put_packet (buf, 4 + reglen);
571   p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout);
572
573   if (pktlen < 3)
574     error ("Truncated response packet from OCD device");
575
576   status = p[1];
577   error_code = p[2];
578
579   if (error_code != 0)
580     ocd_error ("ocd_write_bdm_registers:", error_code);
581 }
582
583 void
584 ocd_write_bdm_register (bdm_regno, reg)
585      int bdm_regno;
586      CORE_ADDR reg;
587 {
588   unsigned char buf[4];
589
590   store_unsigned_integer (buf, 4, reg);
591
592   ocd_write_bdm_registers (bdm_regno, buf, 4);
593 }
594 \f
595 void 
596 ocd_prepare_to_store ()
597 {
598 }
599 \f
600 /* Write memory data directly to the remote machine.
601    This does not inform the data cache; the data cache uses this.
602    MEMADDR is the address in the remote memory space.
603    MYADDR is the address of the buffer in our space.
604    LEN is the number of bytes.
605
606    Returns number of bytes transferred, or 0 for error.  */
607
608 static int write_mem_command = OCD_WRITE_MEM;
609
610 int
611 ocd_write_bytes (memaddr, myaddr, len)
612      CORE_ADDR memaddr;
613      char *myaddr;
614      int len;
615 {
616   char buf[256 + 10];
617   unsigned char *p;
618   int origlen;
619
620   origlen = len;
621
622   buf[0] = write_mem_command;
623   buf[5] = 1;                   /* Write as bytes */
624   buf[6] = 0;                   /* Don't verify */
625
626   while (len > 0)
627     {
628       int numbytes;
629       int pktlen;
630       int status, error_code;
631
632       numbytes = min (len, 256 - 8);
633
634       buf[1] = memaddr >> 24;
635       buf[2] = memaddr >> 16;
636       buf[3] = memaddr >> 8;
637       buf[4] = memaddr;
638
639       buf[7] = numbytes;
640
641       memcpy (&buf[8], myaddr, numbytes);
642       ocd_put_packet (buf, 8 + numbytes);
643       p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout);
644       if (pktlen < 3)
645         error ("Truncated response packet from OCD device");
646
647       status = p[1];
648       error_code = p[2];
649
650       if (error_code == 0x11)   /* Got a bus error? */
651         {
652           CORE_ADDR error_address;
653
654           error_address = p[3] << 24;
655           error_address |= p[4] << 16;
656           error_address |= p[5] << 8;
657           error_address |= p[6];
658           numbytes = error_address - memaddr;
659
660           len -= numbytes;
661
662           errno = EIO;
663
664           break;
665         }
666       else if (error_code != 0)
667         ocd_error ("ocd_write_bytes:", error_code);
668
669       len -= numbytes;
670       memaddr += numbytes;
671       myaddr += numbytes;
672     }
673
674   return origlen - len;
675 }
676
677 /* Read memory data directly from the remote machine.
678    This does not use the data cache; the data cache uses this.
679    MEMADDR is the address in the remote memory space.
680    MYADDR is the address of the buffer in our space.
681    LEN is the number of bytes.
682
683    Returns number of bytes transferred, or 0 for error.  */
684
685 static int
686 ocd_read_bytes (memaddr, myaddr, len)
687      CORE_ADDR memaddr;
688      char *myaddr;
689      int len;
690 {
691   char buf[256 + 10];
692   unsigned char *p;
693   int origlen;
694
695   origlen = len;
696
697   buf[0] = OCD_READ_MEM;
698   buf[5] = 1;                   /* Read as bytes */
699
700   while (len > 0)
701     {
702       int numbytes;
703       int pktlen;
704       int status, error_code;
705
706       numbytes = min (len, 256 - 7);
707
708       buf[1] = memaddr >> 24;
709       buf[2] = memaddr >> 16;
710       buf[3] = memaddr >> 8;
711       buf[4] = memaddr;
712
713       buf[6] = numbytes;
714
715       ocd_put_packet (buf, 7);
716       p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout);
717       if (pktlen < 4)
718         error ("Truncated response packet from OCD device");
719
720       status = p[1];
721       error_code = p[2];
722
723       if (error_code == 0x11)   /* Got a bus error? */
724         {
725           CORE_ADDR error_address;
726
727           error_address = p[3] << 24;
728           error_address |= p[4] << 16;
729           error_address |= p[5] << 8;
730           error_address |= p[6];
731           numbytes = error_address - memaddr;
732
733           len -= numbytes;
734
735           errno = EIO;
736
737           break;
738         }
739       else if (error_code != 0)
740         ocd_error ("ocd_read_bytes:", error_code);
741
742       memcpy (myaddr, &p[4], numbytes);
743
744       len -= numbytes;
745       memaddr += numbytes;
746       myaddr += numbytes;
747     }
748
749   return origlen - len;
750 }
751 \f
752 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
753    to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
754    nonzero.  Returns length of data written or read; 0 for error.  */
755
756 /* ARGSUSED */
757 int
758 ocd_xfer_memory (memaddr, myaddr, len, should_write, target)
759      CORE_ADDR memaddr;
760      char *myaddr;
761      int len;
762      int should_write;
763      struct target_ops *target;                 /* ignored */
764 {
765   return dcache_xfer_memory (ocd_dcache, memaddr, myaddr, len, should_write);
766 }
767 \f
768 void
769 ocd_files_info (ignore)
770      struct target_ops *ignore;
771 {
772   puts_filtered ("Debugging a target over a serial line.\n");
773 }
774 \f
775 /* Stuff for dealing with the packets which are part of this protocol.
776    See comment at top of file for details.  */
777
778 /* Read a single character from the remote side, handling wierd errors. */
779
780 static int
781 readchar (timeout)
782      int timeout;
783 {
784   int ch;
785
786   ch = SERIAL_READCHAR (ocd_desc, timeout);
787
788   switch (ch)
789     {
790     case SERIAL_EOF:
791       error ("Remote connection closed");
792     case SERIAL_ERROR:
793       perror_with_name ("Remote communication error");
794     case SERIAL_TIMEOUT:
795     default:
796       return ch;
797     }
798 }
799
800 #if 0
801 /* Read a character from the data stream, dequoting as necessary.  SYN is
802    treated special.  Any SYNs appearing in the data stream are returned as the
803    distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
804    mistaken for real data).  */
805
806 static int
807 get_quoted_char (timeout)
808      int timeout;
809 {
810   int ch;
811
812   ch = readchar (timeout);
813
814   switch (ch)
815     {
816     case SERIAL_TIMEOUT:
817       error ("Timeout in mid-packet, aborting");
818     case SYN:
819       return RAW_SYN;
820     case DLE:
821       ch = readchar (timeout);
822       if (ch == SYN)
823         return RAW_SYN;
824       return ch & ~0100;
825     default:
826       return ch;
827     }
828 }
829
830 static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
831
832 static void
833 reset_packet ()
834 {
835   pktp = pkt;
836 }
837
838 static void
839 output_packet ()
840 {
841   if (SERIAL_WRITE (ocd_desc, pkt, pktp - pkt))
842     perror_with_name ("output_packet: write failed");
843
844   reset_packet ();
845 }
846
847 /* Output a quoted character.  SYNs and DLEs are quoted.  Everything else goes
848    through untouched.  */
849
850 static void
851 put_quoted_char (c)
852      int c;
853 {
854   switch (c)
855     {
856     case SYN:
857     case DLE:
858       *pktp++ = DLE;
859       c |= 0100;
860     }
861
862   *pktp++ = c;
863 }
864
865 /* Send a packet to the OCD device.  The packet framed by a SYN character,
866    a byte count and a checksum.  The byte count only counts the number of
867    bytes between the count and the checksum.  A count of zero actually
868    means 256.  Any SYNs within the packet (including the checksum and
869    count) must be quoted.  The quote character must be quoted as well.
870    Quoting is done by replacing the character with the two-character sequence
871    DLE, {char} | 0100.  Note that the quoting mechanism has no effect on the
872    byte count. */
873
874 static void
875 stu_put_packet (buf, len)
876      unsigned char *buf;
877      int len;
878 {
879   unsigned char checksum;
880   unsigned char c;
881
882   if (len == 0 || len > 256)
883     abort ();                   /* Can't represent 0 length packet */
884
885   reset_packet ();
886
887   checksum = 0;
888
889   put_quoted_char (RAW_SYN);
890
891   c = len;
892
893   do
894     {
895       checksum += c;
896
897       put_quoted_char (c);
898
899       c = *buf++;
900     }
901   while (len-- > 0);
902
903   put_quoted_char (-checksum & 0xff);
904
905   output_packet ();
906 }
907
908 #else
909
910 /* Send a packet to the OCD device.  The packet framed by a SYN character,
911    a byte count and a checksum.  The byte count only counts the number of
912    bytes between the count and the checksum.  A count of zero actually
913    means 256.  Any SYNs within the packet (including the checksum and
914    count) must be quoted.  The quote character must be quoted as well.
915    Quoting is done by replacing the character with the two-character sequence
916    DLE, {char} | 0100.  Note that the quoting mechanism has no effect on the
917    byte count.  */
918
919 static void
920 ocd_put_packet (buf, len)
921      unsigned char *buf;
922      int len;
923 {
924   unsigned char checksum;
925   unsigned char c;
926   unsigned char *packet, *packet_ptr;
927
928   packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
929   packet_ptr = packet;
930
931   checksum = 0;
932
933   *packet_ptr++ = 0x55;
934
935   while (len-- > 0)
936     {
937       c = *buf++;
938
939       checksum += c;
940       *packet_ptr++ = c;
941     }
942
943   *packet_ptr++ = -checksum;
944   if (SERIAL_WRITE (ocd_desc, packet, packet_ptr - packet))
945     perror_with_name ("output_packet: write failed");
946 }
947 #endif
948
949 #if 0
950 /* Get a packet from the OCD device.  Timeout is only enforced for the
951    first byte of the packet.  Subsequent bytes are expected to arrive in
952    time <= remote_timeout.  Returns a pointer to a static buffer containing
953    the payload of the packet.  *LENP contains the length of the packet.
954 */
955
956 static unsigned char *
957 stu_get_packet (cmd, lenp, timeout)
958      unsigned char cmd;
959      int *lenp;
960 {
961   int ch;
962   int len;
963   static unsigned char buf[256 + 10], *p;
964   unsigned char checksum;
965
966  find_packet:
967
968   ch = get_quoted_char (timeout);
969
970   if (ch < 0)
971     error ("get_packet (readchar): %d", ch);
972
973   if (ch != RAW_SYN)
974     goto find_packet;
975
976  found_syn:                     /* Found the start of a packet */
977
978   p = buf;
979   checksum = 0;
980
981   len = get_quoted_char (remote_timeout);
982
983   if (len == RAW_SYN)
984     goto found_syn;
985
986   checksum += len;
987
988   if (len == 0)
989     len = 256;
990
991   len++;                        /* Include checksum */
992
993   while (len-- > 0)
994     {
995       ch = get_quoted_char (remote_timeout);
996       if (ch == RAW_SYN)
997         goto found_syn;
998
999       *p++ = ch;
1000       checksum += ch;
1001     }
1002
1003   if (checksum != 0)
1004     goto find_packet;
1005
1006   if (cmd != buf[0])
1007     error ("Response phase error.  Got 0x%x, expected 0x%x", buf[0], cmd);
1008
1009   *lenp = p - buf - 1;
1010   return buf;
1011 }
1012
1013 #else
1014
1015 /* Get a packet from the OCD device.  Timeout is only enforced for the
1016    first byte of the packet.  Subsequent bytes are expected to arrive in
1017    time <= remote_timeout.  Returns a pointer to a static buffer containing
1018    the payload of the packet.  *LENP contains the length of the packet.
1019 */
1020
1021 static unsigned char *
1022 ocd_get_packet (cmd, lenp, timeout)
1023      int cmd;
1024      int *lenp;
1025 {
1026   int ch;
1027   int len;
1028   int i;
1029   static unsigned char packet[512];
1030   unsigned char *packet_ptr;
1031   unsigned char checksum;
1032
1033  find_packet:
1034
1035   ch = readchar (timeout);
1036
1037   if (ch < 0)
1038     error ("ocd_get_packet (readchar): %d", ch);
1039
1040   if (ch != 0x55)
1041     goto find_packet;
1042
1043 /* Found the start of a packet */
1044
1045   packet_ptr = packet;
1046   checksum = 0;
1047
1048 /* Read command char.  That sort of tells us how long the packet is. */
1049
1050   ch = readchar (timeout);
1051
1052   if (ch < 0)
1053     error ("ocd_get_packet (readchar): %d", ch);
1054
1055   *packet_ptr++ = ch;
1056   checksum += ch;
1057
1058 /* Get status. */
1059
1060   ch = readchar (timeout);
1061
1062   if (ch < 0)
1063     error ("ocd_get_packet (readchar): %d", ch);
1064   *packet_ptr++ = ch;
1065   checksum += ch;
1066
1067 /* Get error code. */
1068
1069   ch = readchar (timeout);
1070
1071   if (ch < 0)
1072     error ("ocd_get_packet (readchar): %d", ch);
1073   *packet_ptr++ = ch;
1074   checksum += ch;
1075
1076   switch (ch)                   /* Figure out length of packet */
1077     {
1078     case 0x7:                   /* Write verify error? */
1079       len = 8;                  /* write address, value read back */
1080       break;
1081     case 0x11:                  /* Bus error? */
1082                                 /* write address, read flag */
1083     case 0x15:                  /* Internal error */
1084       len = 5;                  /* error code, vector */
1085       break;
1086     default:                    /* Error w/no params */
1087       len = 0;
1088       break;
1089     case 0x0:                   /* Normal result */
1090       switch (packet[0])
1091         {
1092         case OCD_AYT:   /* Are You There? */
1093         case OCD_SET_BAUD_RATE: /* Set Baud Rate */
1094         case OCD_INIT:  /* Initialize OCD device */
1095         case OCD_SET_SPEED:     /* Set Speed */
1096         case OCD_SET_FUNC_CODE: /* Set Function Code */
1097         case OCD_SET_CTL_FLAGS: /* Set Control Flags */
1098         case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */
1099         case OCD_RUN:   /* Run Target from PC  */
1100         case OCD_RUN_ADDR:      /* Run Target from Specified Address  */
1101         case OCD_STOP:  /* Stop Target */
1102         case OCD_RESET_RUN:     /* Reset Target and Run */
1103         case OCD_RESET: /* Reset Target and Halt */
1104         case OCD_STEP:  /* Single Step */
1105         case OCD_WRITE_REGS: /* Write Register */
1106         case OCD_WRITE_MEM:     /* Write Memory */
1107         case OCD_FILL_MEM:      /* Fill Memory */
1108         case OCD_MOVE_MEM:      /* Move Memory */
1109         case OCD_WRITE_INT_MEM: /* Write Internal Memory */
1110         case OCD_JUMP:  /* Jump to Subroutine */
1111         case OCD_ERASE_FLASH: /* Erase flash memory */
1112         case OCD_PROGRAM_FLASH: /* Write flash memory */
1113         case OCD_EXIT_MON:      /* Exit the flash programming monitor  */
1114         case OCD_ENTER_MON:     /* Enter the flash programming monitor  */
1115         case OCD_LOG_FILE:      /* Make Wigglers.dll save Wigglers.log */
1116         case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */
1117           len = 0;
1118           break;
1119         case OCD_GET_VERSION: /* Get Version */
1120           len = 10;
1121           break;
1122         case OCD_GET_STATUS_MASK: /* Get Status Mask */
1123           len = 1;
1124           break;
1125         case OCD_GET_CTRS:      /* Get Error Counters */
1126         case OCD_READ_REGS:     /* Read Register */
1127         case OCD_READ_MEM:      /* Read Memory */
1128         case OCD_READ_INT_MEM: /* Read Internal Memory */
1129           len = 257;
1130           break;
1131         default:
1132           fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch);
1133           goto find_packet;
1134         }
1135     }
1136
1137   if (len == 257)               /* Byte stream? */
1138     {                           /* Yes, byte streams contain the length */
1139       ch = readchar (timeout);
1140
1141       if (ch < 0)
1142         error ("ocd_get_packet (readchar): %d", ch);
1143       *packet_ptr++ = ch;
1144       checksum += ch;
1145       len = ch;
1146       if (len == 0)
1147         len = 256;
1148     }
1149
1150   while (len-- >= 0)            /* Do rest of packet and checksum */
1151     {
1152       ch = readchar (timeout);
1153
1154       if (ch < 0)
1155         error ("ocd_get_packet (readchar): %d", ch);
1156       *packet_ptr++ = ch;
1157       checksum += ch;
1158     }
1159
1160   if (checksum != 0)
1161     goto find_packet;
1162
1163   if (cmd != -1 && cmd != packet[0])
1164     error ("Response phase error.  Got 0x%x, expected 0x%x", packet[0], cmd);
1165
1166   *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
1167   return packet;
1168 }
1169 #endif
1170
1171 /* Execute a simple (one-byte) command.  Returns a pointer to the data
1172    following the error code.  */
1173
1174 static unsigned char *
1175 ocd_do_command (cmd, statusp, lenp)
1176      int cmd;
1177      int *statusp;
1178      int *lenp;
1179 {
1180   unsigned char buf[100], *p;
1181   int status, error_code;
1182   char errbuf[100];
1183
1184   unsigned char logbuf[100];
1185   int logpktlen;
1186
1187   buf[0] = cmd;
1188   ocd_put_packet (buf, 1);              /* Send command */
1189   p = ocd_get_packet (*buf, lenp, remote_timeout);
1190
1191   if (*lenp < 3)
1192     error ("Truncated response packet from OCD device");
1193
1194   status = p[1];
1195   error_code = p[2];
1196
1197   if (error_code != 0)
1198     {
1199       sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
1200       ocd_error (errbuf, error_code);
1201     }
1202
1203   if (status & OCD_FLAG_PWF)
1204     error ("OCD device can't detect VCC at BDM interface.");
1205   else if (status & OCD_FLAG_CABLE_DISC)
1206     error ("BDM cable appears to be disconnected.");
1207
1208   *statusp = status;
1209
1210   logbuf[0] = OCD_LOG_FILE;
1211   logbuf[1] = 3;   /* close existing WIGGLERS.LOG */
1212   ocd_put_packet (logbuf, 2);
1213   ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1214
1215   logbuf[0] = OCD_LOG_FILE;
1216   logbuf[1] = 2;   /* append to existing WIGGLERS.LOG */
1217   ocd_put_packet (logbuf, 2);
1218   ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1219
1220   return p + 3;
1221 }
1222 \f
1223 void
1224 ocd_kill ()
1225 {
1226   /* For some mysterious reason, wait_for_inferior calls kill instead of
1227      mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
1228   if (kill_kludge)
1229     {
1230       kill_kludge = 0;
1231       target_mourn_inferior ();
1232       return;
1233     }
1234
1235   /* Don't wait for it to die.  I'm not really sure it matters whether
1236      we do or not.  */
1237   target_mourn_inferior ();
1238 }
1239
1240 void
1241 ocd_mourn ()
1242 {
1243   unpush_target (current_ops);
1244   generic_mourn_inferior ();
1245 }
1246
1247 /* All we actually do is set the PC to the start address of exec_bfd, and start
1248    the program at that point.  */
1249
1250 void
1251 ocd_create_inferior (exec_file, args, env)
1252      char *exec_file;
1253      char *args;
1254      char **env;
1255 {
1256   if (args && (*args != '\000'))
1257     error ("Args are not supported by BDM.");
1258
1259   clear_proceed_status ();
1260   proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
1261 }
1262
1263 void
1264 ocd_load (args, from_tty)
1265      char *args;
1266      int from_tty;
1267 {
1268   generic_load (args, from_tty);
1269
1270   inferior_pid = 0;
1271
1272 /* This is necessary because many things were based on the PC at the time that
1273    we attached to the monitor, which is no longer valid now that we have loaded
1274    new code (and just changed the PC).  Another way to do this might be to call
1275    normal_stop, except that the stack may not be valid, and things would get
1276    horribly confused... */
1277
1278   clear_symtab_users ();
1279 }
1280
1281 /* This should be defined in each targets tm.h file */
1282 /* But we want to be able to compile this file for some configurations
1283    not yet supported fully */
1284    
1285 #ifndef BDM_BREAKPOINT
1286 #define BDM_BREAKPOINT 0x4a, 0xfa /* BGND insn on CPU32*/
1287 #endif
1288
1289 /* BDM (at least on CPU32) uses a different breakpoint */
1290
1291 int
1292 ocd_insert_breakpoint (addr, contents_cache)
1293      CORE_ADDR addr;
1294      char *contents_cache;
1295 {
1296   static char break_insn[] = {BDM_BREAKPOINT};
1297   int val;
1298
1299   val = target_read_memory (addr, contents_cache, sizeof (break_insn));
1300
1301   if (val == 0)
1302     val = target_write_memory (addr, break_insn, sizeof (break_insn));
1303
1304   return val;
1305 }
1306
1307 int
1308 ocd_remove_breakpoint (addr, contents_cache)
1309      CORE_ADDR addr;
1310      char *contents_cache;
1311 {
1312   static char break_insn[] = {BDM_BREAKPOINT};
1313   int val;
1314
1315   val = target_write_memory (addr, contents_cache, sizeof (break_insn));
1316
1317   return val;
1318 }
1319
1320 static void
1321 bdm_command (args, from_tty)
1322      char *args;
1323      int from_tty;
1324 {
1325   error ("bdm command must be followed by `reset'");
1326 }
1327
1328 static void
1329 bdm_reset_command (args, from_tty)
1330      char *args;
1331      int from_tty;
1332 {
1333   int status, pktlen;
1334
1335   if (!ocd_desc)
1336     error ("Not connected to OCD device.");
1337
1338   ocd_do_command (OCD_RESET, &status, &pktlen);
1339   dcache_flush (ocd_dcache);
1340   registers_changed ();
1341 }
1342
1343 static void
1344 bdm_restart_command (args, from_tty)
1345      char *args;
1346      int from_tty;
1347 {
1348   int status, pktlen;
1349
1350   if (!ocd_desc)
1351     error ("Not connected to OCD device.");
1352
1353   ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
1354   last_run_status = status;
1355   clear_proceed_status ();
1356   wait_for_inferior ();
1357   normal_stop ();
1358 }
1359
1360 /* Temporary replacement for target_store_registers().  This prevents
1361    generic_load from trying to set the PC.  */
1362
1363 static void
1364 noop_store_registers (regno)
1365      int regno;
1366 {
1367 }
1368
1369 static void
1370 bdm_update_flash_command (args, from_tty)
1371      char *args;
1372      int from_tty;
1373 {
1374   int status, pktlen;
1375   struct cleanup *old_chain;
1376   void (*store_registers_tmp) PARAMS ((int));
1377
1378   if (!ocd_desc)
1379     error ("Not connected to OCD device.");
1380
1381   if (!args)
1382     error ("Must specify file containing new OCD code.");
1383
1384 /*  old_chain = make_cleanup (flash_cleanup, 0);*/
1385
1386   ocd_do_command (OCD_ENTER_MON, &status, &pktlen);
1387
1388   ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen);
1389
1390   write_mem_command = OCD_PROGRAM_FLASH;
1391   store_registers_tmp = current_target.to_store_registers;
1392   current_target.to_store_registers = noop_store_registers;
1393
1394   generic_load (args, from_tty);
1395
1396   current_target.to_store_registers = store_registers_tmp;
1397   write_mem_command = OCD_WRITE_MEM;
1398
1399   ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
1400
1401 /*  discard_cleanups (old_chain);*/
1402 }
1403
1404 static void
1405 bdm_read_register_command (args, from_tty)
1406      char *args;
1407      int from_tty;
1408 {
1409   /* XXX repeat should go on to the next register */
1410
1411   if (!ocd_desc)
1412     error ("Not connected to OCD device.");
1413
1414   if (!args)
1415     error ("Must specify BDM register number.");
1416
1417 }
1418 \f
1419 void
1420 _initialize_remote_ocd ()
1421 {
1422   extern struct cmd_list_element *cmdlist;
1423   static struct cmd_list_element *ocd_cmd_list = NULL;
1424
1425   add_show_from_set (add_set_cmd ("remotetimeout", no_class,
1426                                   var_integer, (char *)&remote_timeout,
1427                                   "Set timeout value for remote read.\n", &setlist),
1428                      &showlist);
1429
1430   add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
1431                   0, &cmdlist);
1432
1433   add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
1434   add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
1435   add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
1436   /*  add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list);*/
1437 }