OSDN Git Service

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