OSDN Git Service

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