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