OSDN Git Service

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