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