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