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