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