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