* osabi.c (gdb_osabi_name): Add entry for GDB_OSABI_INTERIX.
[deliverable/binutils-gdb.git] / gdb / ocd.c
CommitLineData
c906108c 1/* Target communications support for Macraigor Systems' On-Chip Debugging
b5a2688f
AC
2
3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
4 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
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, 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"
c906108c
SS
32#include "gdbcmd.h"
33#include "objfiles.h"
34#include "gdb-stabs.h"
c906108c
SS
35#include <sys/types.h>
36#include <signal.h>
37#include "serial.h"
38#include "ocd.h"
4e052eda 39#include "regcache.h"
c906108c
SS
40
41/* Prototypes for local functions */
42
a14ed312 43static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
c906108c 44
a14ed312 45static int ocd_start_remote (PTR dummy);
c906108c 46
a14ed312 47static int readchar (int timeout);
c906108c 48
a14ed312 49static void reset_packet (void);
c906108c 50
a14ed312 51static void output_packet (void);
c906108c 52
a14ed312 53static int get_quoted_char (int timeout);
c906108c 54
a14ed312 55static void put_quoted_char (int c);
c906108c 56
a14ed312 57static void ocd_interrupt (int signo);
c906108c 58
a14ed312 59static void ocd_interrupt_twice (int signo);
c906108c 60
a14ed312 61static void interrupt_query (void);
c906108c 62
a14ed312 63static unsigned char *ocd_do_command (int cmd, int *statusp, int *lenp);
c906108c 64
a14ed312 65static void ocd_put_packet (unsigned char *packet, int pktlen);
c906108c 66
a14ed312 67static unsigned char *ocd_get_packet (int cmd, int *pktlen, int timeout);
c906108c
SS
68
69static struct target_ops *current_ops = NULL;
70
71static 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. */
81static 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. */
819cc324 87static struct serial *ocd_desc = NULL;
c906108c
SS
88\f
89void
fba45db2 90ocd_error (char *s, int error_code)
c906108c
SS
91{
92 char buf[100];
93
94 fputs_filtered (s, gdb_stderr);
95 fputs_filtered (" ", gdb_stderr);
96
97 switch (error_code)
98 {
c5aa993b
JM
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;
c906108c
SS
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
154int
39f77062 155ocd_thread_alive (ptid_t th)
c906108c
SS
156{
157 return 1;
158}
159\f
160/* Clean up connection to a remote debugger. */
161
162/* ARGSUSED */
163void
fba45db2 164ocd_close (int quitting)
c906108c
SS
165{
166 if (ocd_desc)
2cd58942 167 serial_close (ocd_desc);
c906108c
SS
168 ocd_desc = NULL;
169}
170
171/* Stub for catch_errors. */
172
173static int
fba45db2 174ocd_start_remote (PTR dummy)
c906108c
SS
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
c5aa993b 183 target_type = *(enum ocd_target_type *) dummy;
c906108c 184
8edbea78 185 immediate_quit++; /* Allow user to interrupt it */
c906108c 186
2cd58942 187 serial_send_break (ocd_desc); /* Wake up the wiggler */
c906108c
SS
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);
c5aa993b 218/* ocd_do_command (OCD_RESET, &status, &pktlen); */
c906108c
SS
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
8edbea78 247 immediate_quit--;
c906108c
SS
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));
0f7d239c 258 select_frame (get_current_frame ());
c906108c
SS
259 print_stack_frame (selected_frame, -1, 1);
260
261 buf[0] = OCD_LOG_FILE;
c5aa993b 262 buf[1] = 3; /* close existing WIGGLERS.LOG */
c906108c
SS
263 ocd_put_packet (buf, 2);
264 p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
265
266 buf[0] = OCD_LOG_FILE;
c5aa993b 267 buf[1] = 2; /* append to existing WIGGLERS.LOG */
c906108c
SS
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
c906108c 277void
fba45db2
KB
278ocd_open (char *name, int from_tty, enum ocd_target_type target_type,
279 struct target_ops *ops)
c906108c
SS
280{
281 unsigned char buf[10], *p;
c906108c
SS
282 int pktlen;
283
284 if (name == 0)
285 error ("To open an OCD connection, you need to specify the\n\
286device 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
50a9e2f1
AC
294 ocd_desc = serial_open (name);
295 if (!ocd_desc)
296 perror_with_name (name);
c906108c
SS
297
298 if (baud_rate != -1)
299 {
2cd58942 300 if (serial_setbaudrate (ocd_desc, baud_rate))
c906108c 301 {
2cd58942 302 serial_close (ocd_desc);
c906108c
SS
303 perror_with_name (name);
304 }
305 }
306
2cd58942 307 serial_raw (ocd_desc);
c906108c
SS
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. */
2cd58942 311 serial_flush_input (ocd_desc);
c906108c
SS
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
39f77062 328 inferior_ptid = pid_to_ptid (42000);
c906108c
SS
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 {
c5aa993b 336 pop_target ();
c906108c
SS
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
346void
fba45db2 347ocd_detach (char *args, int from_tty)
c906108c
SS
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
359void
39f77062 360ocd_resume (ptid_t ptid, int step, enum target_signal siggnal)
c906108c
SS
361{
362 int pktlen;
363
c906108c
SS
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
370void
fba45db2 371ocd_stop (void)
c906108c
SS
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
382static volatile int ocd_interrupt_flag;
383
384/* Send ^C to target to halt it. Target will respond, and send us a
385 packet. */
386
387static void
fba45db2 388ocd_interrupt (int signo)
c906108c
SS
389{
390 /* If this doesn't work, try more severe steps. */
391 signal (signo, ocd_interrupt_twice);
c5aa993b 392
c906108c
SS
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
c5aa993b 406static void (*ofunc) ();
c906108c
SS
407
408/* The user typed ^C twice. */
409static void
fba45db2 410ocd_interrupt_twice (int signo)
c906108c
SS
411{
412 signal (signo, ofunc);
c5aa993b 413
c906108c
SS
414 interrupt_query ();
415
416 signal (signo, ocd_interrupt);
417}
418
419/* Ask the user what to do when an interrupt is received. */
420
421static void
fba45db2 422interrupt_query (void)
c906108c
SS
423{
424 target_terminal_ours ();
425
426 if (query ("Interrupted while waiting for the program.\n\
427Give up (and stop debugging it)? "))
428 {
429 target_mourn_inferior ();
b5a2688f 430 throw_exception (RETURN_QUIT);
c906108c
SS
431 }
432
433 target_terminal_inferior ();
434}
435
436/* If nonzero, ignore the next kill. */
437static 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
444int
fba45db2 445ocd_wait (void)
c906108c
SS
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
492unsigned char *
fba45db2 493ocd_read_bdm_registers (int first_bdm_regno, int last_bdm_regno, int *reglen)
c906108c
SS
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
534CORE_ADDR
fba45db2 535ocd_read_bdm_register (int bdm_regno)
c906108c
SS
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
547void
fba45db2 548ocd_write_bdm_registers (int first_bdm_regno, unsigned char *regptr, int reglen)
c906108c
SS
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
576void
fba45db2 577ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg)
c906108c
SS
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
c5aa993b 586void
fba45db2 587ocd_prepare_to_store (void)
c906108c
SS
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
599static int write_mem_command = OCD_WRITE_MEM;
600
601int
fba45db2 602ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
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
673static int
fba45db2 674ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
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
697ec6c4
KB
739 nonzero. Returns length of data written or read; 0 for error. TARGET
740 is ignored. */
c906108c
SS
741
742/* ARGSUSED */
743int
697ec6c4 744ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
58841d58 745 struct mem_attrib *attrib, struct target_ops *target)
c906108c 746{
4930751a
C
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;
c906108c
SS
755}
756\f
757void
fba45db2 758ocd_files_info (struct target_ops *ignore)
c906108c
SS
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
768static int
fba45db2 769readchar (int timeout)
c906108c
SS
770{
771 int ch;
772
2cd58942 773 ch = serial_readchar (ocd_desc, timeout);
c906108c
SS
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
793static int
fba45db2 794get_quoted_char (int timeout)
c906108c
SS
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
c5aa993b 816static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
c906108c
SS
817
818static void
fba45db2 819reset_packet (void)
c906108c
SS
820{
821 pktp = pkt;
822}
823
824static void
fba45db2 825output_packet (void)
c906108c 826{
2cd58942 827 if (serial_write (ocd_desc, pkt, pktp - pkt))
c906108c
SS
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
836static void
fba45db2 837put_quoted_char (int c)
c906108c
SS
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
859static void
fba45db2 860stu_put_packet (unsigned char *buf, int len)
c906108c
SS
861{
862 unsigned char checksum;
863 unsigned char c;
864
865 if (len == 0 || len > 256)
e1e9e218 866 internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Can't represent 0 length packet */
c906108c
SS
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
902static void
fba45db2 903ocd_put_packet (unsigned char *buf, int len)
c906108c
SS
904{
905 unsigned char checksum;
906 unsigned char c;
907 unsigned char *packet, *packet_ptr;
908
c5aa993b 909 packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
c906108c
SS
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;
2cd58942 925 if (serial_write (ocd_desc, packet, packet_ptr - packet))
c906108c
SS
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.
c5aa993b 935 */
c906108c
SS
936
937static unsigned char *
fba45db2 938stu_get_packet (unsigned char cmd, int *lenp, int timeout)
c906108c
SS
939{
940 int ch;
941 int len;
942 static unsigned char buf[256 + 10], *p;
943 unsigned char checksum;
944
c5aa993b 945find_packet:
c906108c
SS
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
c5aa993b 955found_syn: /* Found the start of a packet */
c906108c
SS
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.
c5aa993b 998 */
c906108c
SS
999
1000static unsigned char *
fba45db2 1001ocd_get_packet (int cmd, int *lenp, int timeout)
c906108c
SS
1002{
1003 int ch;
1004 int len;
c906108c
SS
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? */
c5aa993b 1056 /* write address, read flag */
c906108c
SS
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 {
c5aa993b
JM
1066 case OCD_AYT: /* Are You There? */
1067 case OCD_SET_BAUD_RATE: /* Set Baud Rate */
1068 case OCD_INIT: /* Initialize OCD device */
c906108c 1069 case OCD_SET_SPEED: /* Set Speed */
c5aa993b
JM
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 */
c906108c 1074 case OCD_RUN_ADDR: /* Run Target from Specified Address */
c5aa993b 1075 case OCD_STOP: /* Stop Target */
c906108c
SS
1076 case OCD_RESET_RUN: /* Reset Target and Run */
1077 case OCD_RESET: /* Reset Target and Halt */
c5aa993b
JM
1078 case OCD_STEP: /* Single Step */
1079 case OCD_WRITE_REGS: /* Write Register */
c906108c
SS
1080 case OCD_WRITE_MEM: /* Write Memory */
1081 case OCD_FILL_MEM: /* Fill Memory */
1082 case OCD_MOVE_MEM: /* Move Memory */
c5aa993b
JM
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 */
c906108c
SS
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 */
c5aa993b 1090 case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */
c906108c
SS
1091 len = 0;
1092 break;
c5aa993b 1093 case OCD_GET_VERSION: /* Get Version */
c906108c
SS
1094 len = 10;
1095 break;
c5aa993b 1096 case OCD_GET_STATUS_MASK: /* Get Status Mask */
c906108c
SS
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 */
c5aa993b 1102 case OCD_READ_INT_MEM: /* Read Internal Memory */
c906108c
SS
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
c5aa993b 1139 *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
c906108c
SS
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
1147static unsigned char *
fba45db2 1148ocd_do_command (int cmd, int *statusp, int *lenp)
c906108c
SS
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;
c5aa993b 1158 ocd_put_packet (buf, 1); /* Send command */
c906108c
SS
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;
c5aa993b 1181 logbuf[1] = 3; /* close existing WIGGLERS.LOG */
c906108c
SS
1182 ocd_put_packet (logbuf, 2);
1183 ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1184
1185 logbuf[0] = OCD_LOG_FILE;
c5aa993b 1186 logbuf[1] = 2; /* append to existing WIGGLERS.LOG */
c906108c
SS
1187 ocd_put_packet (logbuf, 2);
1188 ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1189
1190 return p + 3;
1191}
1192\f
1193void
fba45db2 1194ocd_kill (void)
c906108c
SS
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
1210void
fba45db2 1211ocd_mourn (void)
c906108c
SS
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
1220void
fba45db2 1221ocd_create_inferior (char *exec_file, char *args, char **env)
c906108c
SS
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
1230void
fba45db2 1231ocd_load (char *args, int from_tty)
c906108c
SS
1232{
1233 generic_load (args, from_tty);
1234
39f77062 1235 inferior_ptid = null_ptid;
c906108c
SS
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 */
c5aa993b
JM
1249
1250#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */
c906108c 1251#if 0
c5aa993b 1252#define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */
c906108c
SS
1253#endif
1254
1255/* BDM (at least on CPU32) uses a different breakpoint */
1256
1257int
fba45db2 1258ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
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
1271int
fba45db2 1272ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
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
1282static void
fba45db2 1283bdm_command (char *args, int from_tty)
c906108c
SS
1284{
1285 error ("bdm command must be followed by `reset'");
1286}
1287
1288static void
fba45db2 1289bdm_reset_command (char *args, int from_tty)
c906108c
SS
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);
4930751a 1297 dcache_invalidate (target_dcache);
c906108c
SS
1298 registers_changed ();
1299}
1300
1301static void
fba45db2 1302bdm_restart_command (char *args, int from_tty)
c906108c
SS
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
1319static void
fba45db2 1320noop_store_registers (int regno)
c906108c
SS
1321{
1322}
1323
1324static void
fba45db2 1325bdm_update_flash_command (char *args, int from_tty)
c906108c
SS
1326{
1327 int status, pktlen;
d4f3574e 1328 struct cleanup *old_chain;
507f3c78 1329 void (*store_registers_tmp) (int);
c906108c
SS
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
c5aa993b 1337/* old_chain = make_cleanup (flash_cleanup, 0); */
c906108c
SS
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
c5aa993b 1354/* discard_cleanups (old_chain); */
c906108c
SS
1355}
1356
1357static void
fba45db2 1358bdm_read_register_command (char *args, int from_tty)
c906108c
SS
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
1370void
fba45db2 1371_initialize_remote_ocd (void)
c906108c
SS
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,
c5aa993b
JM
1377 var_integer, (char *) &remote_timeout,
1378 "Set timeout value for remote read.\n", &setlist),
c906108c
SS
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);
c5aa993b 1387 /* add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */
c906108c 1388}
This page took 0.271571 seconds and 4 git commands to generate.