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