]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/remote-rdp.c
b531047118a74617c1639df309e8d6e17a973666
[thirdparty/binutils-gdb.git] / gdb / remote-rdp.c
1 /* Remote debugging for the ARM RDP interface.
2 Copyright 1994, 1995, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
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.
11
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.
16
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.
21
22
23 */
24
25
26 /*
27 Much of this file (in particular the SWI stuff) is based on code by
28 David Taylor (djt1000@uk.ac.cam.hermes).
29
30 I hacked on and simplified it by removing a lot of sexy features he
31 had added, and some of the (unix specific) workarounds he'd done
32 for other GDB problems - which if they still exist should be fixed
33 in GDB, not in a remote-foo thing . I also made it conform more to
34 the doc I have; which may be wrong.
35
36 Steve Chamberlain (sac@cygnus.com).
37 */
38
39
40 #include "defs.h"
41 #include "inferior.h"
42 #include "value.h"
43 #include "callback.h"
44 #include "command.h"
45 #include <ctype.h>
46 #include <fcntl.h>
47 #include "symfile.h"
48 #include "remote-utils.h"
49 #include "gdb_string.h"
50 #include "gdbcore.h"
51 #include "regcache.h"
52 #include "serial.h"
53
54 #ifdef HAVE_TIME_H
55 #include <time.h>
56 #endif
57
58 extern struct target_ops remote_rdp_ops;
59 static struct serial *io;
60 static host_callback *callback = &default_callback;
61
62 struct
63 {
64 int step_info;
65 int break_info;
66 int model_info;
67 int target_info;
68 int can_step;
69 char command_line[10];
70 int rdi_level;
71 int rdi_stopped_status;
72 }
73 ds;
74
75
76
77 /* Definitions for the RDP protocol. */
78
79 #define RDP_MOUTHFULL (1<<6)
80 #define FPU_COPRO_NUMBER 1
81
82 #define RDP_OPEN 0
83 #define RDP_OPEN_TYPE_COLD 0
84 #define RDP_OPEN_TYPE_WARM 1
85 #define RDP_OPEN_TYPE_BAUDRATE 2
86
87 #define RDP_OPEN_BAUDRATE_9600 1
88 #define RDP_OPEN_BAUDRATE_19200 2
89 #define RDP_OPEN_BAUDRATE_38400 3
90
91 #define RDP_OPEN_TYPE_RETURN_SEX (1<<3)
92
93 #define RDP_CLOSE 1
94
95 #define RDP_MEM_READ 2
96
97 #define RDP_MEM_WRITE 3
98
99 #define RDP_CPU_READ 4
100 #define RDP_CPU_WRITE 5
101 #define RDP_CPU_READWRITE_MODE_CURRENT 255
102 #define RDP_CPU_READWRITE_MASK_PC (1<<16)
103 #define RDP_CPU_READWRITE_MASK_CPSR (1<<17)
104 #define RDP_CPU_READWRITE_MASK_SPSR (1<<18)
105
106 #define RDP_COPRO_READ 6
107 #define RDP_COPRO_WRITE 7
108 #define RDP_FPU_READWRITE_MASK_FPS (1<<8)
109
110 #define RDP_SET_BREAK 0xa
111 #define RDP_SET_BREAK_TYPE_PC_EQUAL 0
112 #define RDP_SET_BREAK_TYPE_GET_HANDLE (0x10)
113
114 #define RDP_CLEAR_BREAK 0xb
115
116 #define RDP_EXEC 0x10
117 #define RDP_EXEC_TYPE_SYNC 0
118
119 #define RDP_STEP 0x11
120
121 #define RDP_INFO 0x12
122 #define RDP_INFO_ABOUT_STEP 2
123 #define RDP_INFO_ABOUT_STEP_GT_1 1
124 #define RDP_INFO_ABOUT_STEP_TO_JMP 2
125 #define RDP_INFO_ABOUT_STEP_1 4
126 #define RDP_INFO_ABOUT_TARGET 0
127 #define RDP_INFO_ABOUT_BREAK 1
128 #define RDP_INFO_ABOUT_BREAK_COMP 1
129 #define RDP_INFO_ABOUT_BREAK_RANGE 2
130 #define RDP_INFO_ABOUT_BREAK_BYTE_READ 4
131 #define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8
132 #define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4)
133 #define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5)
134 #define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6)
135 #define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7)
136 #define RDP_INFO_ABOUT_BREAK_MASK (1<<8)
137 #define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
138 #define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
139 #define RDP_INFO_ABOUT_BREAK_COND (1<<11)
140 #define RDP_INFO_VECTOR_CATCH (0x180)
141 #define RDP_INFO_ICEBREAKER (7)
142 #define RDP_INFO_SET_CMDLINE (0x300)
143
144 #define RDP_SELECT_CONFIG (0x16)
145 #define RDI_ConfigCPU 0
146 #define RDI_ConfigSystem 1
147 #define RDI_MatchAny 0
148 #define RDI_MatchExactly 1
149 #define RDI_MatchNoEarlier 2
150
151 #define RDP_RESET 0x7f
152
153 /* Returns from RDP */
154 #define RDP_RES_STOPPED 0x20
155 #define RDP_RES_SWI 0x21
156 #define RDP_RES_FATAL 0x5e
157 #define RDP_RES_VALUE 0x5f
158 #define RDP_RES_VALUE_LITTLE_ENDIAN 240
159 #define RDP_RES_VALUE_BIG_ENDIAN 241
160 #define RDP_RES_RESET 0x7f
161 #define RDP_RES_AT_BREAKPOINT 143
162 #define RDP_RES_IDUNNO 0xe6
163 #define RDP_OSOpReply 0x13
164 #define RDP_OSOpWord 2
165 #define RDP_OSOpNothing 0
166
167 static int timeout = 2;
168
169 static char *commandline = NULL;
170
171 static int
172 remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
173 int write,
174 struct mem_attrib *attrib,
175 struct target_ops *target);
176
177
178 /* Stuff for talking to the serial layer. */
179
180 static unsigned char
181 get_byte (void)
182 {
183 int c = serial_readchar (io, timeout);
184
185 if (remote_debug)
186 fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c);
187
188 if (c == SERIAL_TIMEOUT)
189 {
190 if (timeout == 0)
191 return (unsigned char) c;
192
193 error ("Timeout reading from remote_system");
194 }
195
196 return c;
197 }
198
199 /* Note that the target always speaks little-endian to us,
200 even if it's a big endian machine. */
201 static unsigned int
202 get_word (void)
203 {
204 unsigned int val = 0;
205 unsigned int c;
206 int n;
207 for (n = 0; n < 4; n++)
208 {
209 c = get_byte ();
210 val |= c << (n * 8);
211 }
212 return val;
213 }
214
215 static void
216 put_byte (char val)
217 {
218 if (remote_debug)
219 fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val);
220 serial_write (io, &val, 1);
221 }
222
223 static void
224 put_word (int val)
225 {
226 /* We always send in little endian */
227 unsigned char b[4];
228 b[0] = val;
229 b[1] = val >> 8;
230 b[2] = val >> 16;
231 b[3] = val >> 24;
232
233 if (remote_debug)
234 fprintf_unfiltered (gdb_stdlog, "(%04x)", val);
235
236 serial_write (io, b, 4);
237 }
238
239
240
241 /* Stuff for talking to the RDP layer. */
242
243 /* This is a bit more fancy that need be so that it syncs even in nasty cases.
244
245 I'be been unable to make it reliably sync up with the change
246 baudrate open command. It likes to sit and say it's been reset,
247 with no more action. So I took all that code out. I'd rather sync
248 reliably at 9600 than wait forever for a possible 19200 connection.
249
250 */
251 static void
252 rdp_init (int cold, int tty)
253 {
254 int sync = 0;
255 int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM;
256 int baudtry = 9600;
257
258 time_t now = time (0);
259 time_t stop_time = now + 10; /* Try and sync for 10 seconds, then give up */
260
261
262 while (time (0) < stop_time && !sync)
263 {
264 int restype;
265 QUIT;
266
267 serial_flush_input (io);
268 serial_flush_output (io);
269
270 if (tty)
271 printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
272
273 /*
274 ** It seems necessary to reset an EmbeddedICE to get it going.
275 ** This has the side benefit of displaying the startup banner.
276 */
277 if (cold)
278 {
279 put_byte (RDP_RESET);
280 while ((restype = serial_readchar (io, 1)) > 0)
281 {
282 switch (restype)
283 {
284 case SERIAL_TIMEOUT:
285 break;
286 case RDP_RESET:
287 /* Sent at start of reset process: ignore */
288 break;
289 default:
290 printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
291 break;
292 }
293 }
294
295 if (restype == 0)
296 {
297 /* Got end-of-banner mark */
298 printf_filtered ("\n");
299 }
300 }
301
302 put_byte (RDP_OPEN);
303
304 put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
305 put_word (0);
306
307 while (!sync && (restype = serial_readchar (io, 1)) > 0)
308 {
309 if (remote_debug)
310 fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype);
311
312 switch (restype)
313 {
314 case SERIAL_TIMEOUT:
315 break;
316
317 case RDP_RESET:
318 while ((restype = serial_readchar (io, 1)) == RDP_RESET)
319 ;
320 do
321 {
322 printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
323 }
324 while ((restype = serial_readchar (io, 1)) > 0);
325
326 if (tty)
327 {
328 printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
329 printf_unfiltered ("Waiting for it to settle down...\n");
330 }
331 sleep (3);
332 if (tty)
333 printf_unfiltered ("\nTrying again.\n");
334 cold = 0;
335 break;
336
337 default:
338 break;
339
340 case RDP_RES_VALUE:
341 {
342 int resval = serial_readchar (io, 1);
343
344 if (remote_debug)
345 fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval);
346
347 switch (resval)
348 {
349 case SERIAL_TIMEOUT:
350 break;
351 case RDP_RES_VALUE_LITTLE_ENDIAN:
352 target_byte_order = BFD_ENDIAN_LITTLE;
353 sync = 1;
354 break;
355 case RDP_RES_VALUE_BIG_ENDIAN:
356 target_byte_order = BIG_ENDIAN;
357 sync = 1;
358 break;
359 default:
360 break;
361 }
362 }
363 }
364 }
365 }
366
367 if (!sync)
368 {
369 error ("Couldn't reset the board, try pressing the reset button");
370 }
371 }
372
373
374 void
375 send_rdp (char *template,...)
376 {
377 char buf[200];
378 char *dst = buf;
379 va_list alist;
380 va_start (alist, template);
381
382 while (*template)
383 {
384 unsigned int val;
385 int *pi;
386 int *pstat;
387 char *pc;
388 int i;
389 switch (*template++)
390 {
391 case 'b':
392 val = va_arg (alist, int);
393 *dst++ = val;
394 break;
395 case 'w':
396 val = va_arg (alist, int);
397 *dst++ = val;
398 *dst++ = val >> 8;
399 *dst++ = val >> 16;
400 *dst++ = val >> 24;
401 break;
402 case 'S':
403 val = get_byte ();
404 if (val != RDP_RES_VALUE)
405 {
406 printf_unfiltered ("got bad res value of %d, %x\n", val, val);
407 }
408 break;
409 case 'V':
410 pstat = va_arg (alist, int *);
411 pi = va_arg (alist, int *);
412
413 *pstat = get_byte ();
414 /* Check the result was zero, if not read the syndrome */
415 if (*pstat)
416 {
417 *pi = get_word ();
418 }
419 break;
420 case 'Z':
421 /* Check the result code */
422 switch (get_byte ())
423 {
424 case 0:
425 /* Success */
426 break;
427 case 253:
428 /* Target can't do it; never mind */
429 printf_unfiltered ("RDP: Insufficient privilege\n");
430 return;
431 case 254:
432 /* Target can't do it; never mind */
433 printf_unfiltered ("RDP: Unimplemented message\n");
434 return;
435 case 255:
436 error ("Command garbled");
437 break;
438 default:
439 error ("Corrupt reply from target");
440 break;
441 }
442 break;
443 case 'W':
444 /* Read a word from the target */
445 pi = va_arg (alist, int *);
446 *pi = get_word ();
447 break;
448 case 'P':
449 /* Read in some bytes from the target. */
450 pc = va_arg (alist, char *);
451 val = va_arg (alist, int);
452 for (i = 0; i < val; i++)
453 {
454 pc[i] = get_byte ();
455 }
456 break;
457 case 'p':
458 /* send what's being pointed at */
459 pc = va_arg (alist, char *);
460 val = va_arg (alist, int);
461 dst = buf;
462 serial_write (io, pc, val);
463 break;
464 case '-':
465 /* Send whats in the queue */
466 if (dst != buf)
467 {
468 serial_write (io, buf, dst - buf);
469 dst = buf;
470 }
471 break;
472 case 'B':
473 pi = va_arg (alist, int *);
474 *pi = get_byte ();
475 break;
476 default:
477 internal_error (__FILE__, __LINE__, "failed internal consistency check");
478 }
479 }
480 va_end (alist);
481
482 if (dst != buf)
483 internal_error (__FILE__, __LINE__, "failed internal consistency check");
484 }
485
486
487 static int
488 rdp_write (CORE_ADDR memaddr, char *buf, int len)
489 {
490 int res;
491 int val;
492
493 send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val);
494
495 if (res)
496 {
497 return val;
498 }
499 return len;
500 }
501
502
503 static int
504 rdp_read (CORE_ADDR memaddr, char *buf, int len)
505 {
506 int res;
507 int val;
508 send_rdp ("bww-S-P-V",
509 RDP_MEM_READ, memaddr, len,
510 buf, len,
511 &res, &val);
512 if (res)
513 {
514 return val;
515 }
516 return len;
517 }
518
519 static void
520 rdp_fetch_one_register (int mask, char *buf)
521 {
522 int val;
523 send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val);
524 store_signed_integer (buf, 4, val);
525 }
526
527 static void
528 rdp_fetch_one_fpu_register (int mask, char *buf)
529 {
530 #if 0
531 /* !!! Since the PIE board doesn't work as documented,
532 and it doesn't have FPU hardware anyway and since it
533 slows everything down, I've disabled this. */
534 int val;
535 if (mask == RDP_FPU_READWRITE_MASK_FPS)
536 {
537 /* this guy is only a word */
538 send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val);
539 store_signed_integer (buf, 4, val);
540 }
541 else
542 {
543 /* There are 12 bytes long
544 !! fixme about endianness
545 */
546 int dummy; /* I've seen these come back as four words !! */
547 send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy);
548 }
549 #endif
550 memset (buf, 0, MAX_REGISTER_RAW_SIZE);
551 }
552
553
554 static void
555 rdp_store_one_register (int mask, char *buf)
556 {
557 int val = extract_unsigned_integer (buf, 4);
558
559 send_rdp ("bbww-SZ",
560 RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val);
561 }
562
563
564 static void
565 rdp_store_one_fpu_register (int mask, char *buf)
566 {
567 #if 0
568 /* See comment in fetch_one_fpu_register */
569 if (mask == RDP_FPU_READWRITE_MASK_FPS)
570 {
571 int val = extract_unsigned_integer (buf, 4);
572 /* this guy is only a word */
573 send_rdp ("bbww-SZ", RDP_COPRO_WRITE,
574 FPU_COPRO_NUMBER,
575 mask, val);
576 }
577 else
578 {
579 /* There are 12 bytes long
580 !! fixme about endianness
581 */
582 int dummy = 0;
583 /* I've seen these come as four words, not the three advertized !! */
584 printf ("Sending mask %x\n", mask);
585 send_rdp ("bbwwwww-SZ",
586 RDP_COPRO_WRITE,
587 FPU_COPRO_NUMBER,
588 mask,
589 *(int *) (buf + 0),
590 *(int *) (buf + 4),
591 *(int *) (buf + 8),
592 0);
593
594 printf ("done mask %x\n", mask);
595 }
596 #endif
597 }
598 \f
599
600 /* Convert between GDB requests and the RDP layer. */
601
602 static void
603 remote_rdp_fetch_register (int regno)
604 {
605 if (regno == -1)
606 {
607 for (regno = 0; regno < NUM_REGS; regno++)
608 remote_rdp_fetch_register (regno);
609 }
610 else
611 {
612 char buf[MAX_REGISTER_RAW_SIZE];
613 if (regno < 15)
614 rdp_fetch_one_register (1 << regno, buf);
615 else if (regno == PC_REGNUM)
616 rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf);
617 else if (regno == PS_REGNUM)
618 rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf);
619 else if (regno == FPS_REGNUM)
620 rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf);
621 else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
622 rdp_fetch_one_fpu_register (1 << (regno - F0_REGNUM), buf);
623 else
624 {
625 printf ("Help me with fetch reg %d\n", regno);
626 }
627 supply_register (regno, buf);
628 }
629 }
630
631
632 static void
633 remote_rdp_store_register (int regno)
634 {
635 if (regno == -1)
636 {
637 for (regno = 0; regno < NUM_REGS; regno++)
638 remote_rdp_store_register (regno);
639 }
640 else
641 {
642 char tmp[MAX_REGISTER_RAW_SIZE];
643 read_register_gen (regno, tmp);
644 if (regno < 15)
645 rdp_store_one_register (1 << regno, tmp);
646 else if (regno == PC_REGNUM)
647 rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp);
648 else if (regno == PS_REGNUM)
649 rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp);
650 else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
651 rdp_store_one_fpu_register (1 << (regno - F0_REGNUM), tmp);
652 else
653 {
654 printf ("Help me with reg %d\n", regno);
655 }
656 }
657 }
658
659 static void
660 remote_rdp_kill (void)
661 {
662 callback->shutdown (callback);
663 }
664
665
666 static void
667 rdp_info (void)
668 {
669 send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP,
670 &ds.step_info);
671 send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK,
672 &ds.break_info);
673 send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET,
674 &ds.target_info,
675 &ds.model_info);
676
677 ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1;
678
679 ds.rdi_level = (ds.target_info >> 5) & 3;
680 }
681
682
683 static void
684 rdp_execute_start (void)
685 {
686 /* Start it off, but don't wait for it */
687 send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC);
688 }
689
690
691 static void
692 rdp_set_command_line (char *command, char *args)
693 {
694 /*
695 ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
696 ** don't implement that, and get all confused at the unexpected text.
697 ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
698 */
699
700 if (commandline != NULL)
701 xfree (commandline);
702
703 xasprintf (&commandline, "%s %s", command, args);
704 }
705
706 static void
707 rdp_catch_vectors (void)
708 {
709 /*
710 ** We want the target monitor to intercept the abort vectors
711 ** i.e. stop the program if any of these are used.
712 */
713 send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
714 /*
715 ** Specify a bitmask including
716 ** the reset vector
717 ** the undefined instruction vector
718 ** the prefetch abort vector
719 ** the data abort vector
720 ** the address exception vector
721 */
722 (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5)
723 );
724 }
725
726
727
728 #define a_byte 1
729 #define a_word 2
730 #define a_string 3
731
732
733 typedef struct
734 {
735 CORE_ADDR n;
736 const char *s;
737 }
738 argsin;
739
740 #define ABYTE 1
741 #define AWORD 2
742 #define ASTRING 3
743 #define ADDRLEN 4
744
745 #define SWI_WriteC 0x0
746 #define SWI_Write0 0x2
747 #define SWI_ReadC 0x4
748 #define SWI_CLI 0x5
749 #define SWI_GetEnv 0x10
750 #define SWI_Exit 0x11
751 #define SWI_EnterOS 0x16
752
753 #define SWI_GetErrno 0x60
754 #define SWI_Clock 0x61
755
756 #define SWI_Time 0x63
757 #define SWI_Remove 0x64
758 #define SWI_Rename 0x65
759 #define SWI_Open 0x66
760
761 #define SWI_Close 0x68
762 #define SWI_Write 0x69
763 #define SWI_Read 0x6a
764 #define SWI_Seek 0x6b
765 #define SWI_Flen 0x6c
766
767 #define SWI_IsTTY 0x6e
768 #define SWI_TmpNam 0x6f
769 #define SWI_InstallHandler 0x70
770 #define SWI_GenerateError 0x71
771
772
773 #ifndef O_BINARY
774 #define O_BINARY 0
775 #endif
776
777 static int translate_open_mode[] =
778 {
779 O_RDONLY, /* "r" */
780 O_RDONLY + O_BINARY, /* "rb" */
781 O_RDWR, /* "r+" */
782 O_RDWR + O_BINARY, /* "r+b" */
783 O_WRONLY + O_CREAT + O_TRUNC, /* "w" */
784 O_WRONLY + O_BINARY + O_CREAT + O_TRUNC, /* "wb" */
785 O_RDWR + O_CREAT + O_TRUNC, /* "w+" */
786 O_RDWR + O_BINARY + O_CREAT + O_TRUNC, /* "w+b" */
787 O_WRONLY + O_APPEND + O_CREAT, /* "a" */
788 O_WRONLY + O_BINARY + O_APPEND + O_CREAT, /* "ab" */
789 O_RDWR + O_APPEND + O_CREAT, /* "a+" */
790 O_RDWR + O_BINARY + O_APPEND + O_CREAT /* "a+b" */
791 };
792
793 static int
794 exec_swi (int swi, argsin *args)
795 {
796 int i;
797 char c;
798 switch (swi)
799 {
800 case SWI_WriteC:
801 callback->write_stdout (callback, &c, 1);
802 return 0;
803 case SWI_Write0:
804 for (i = 0; i < args->n; i++)
805 callback->write_stdout (callback, args->s, strlen (args->s));
806 return 0;
807 case SWI_ReadC:
808 callback->read_stdin (callback, &c, 1);
809 args->n = c;
810 return 1;
811 case SWI_CLI:
812 args->n = callback->system (callback, args->s);
813 return 1;
814 case SWI_GetErrno:
815 args->n = callback->get_errno (callback);
816 return 1;
817 case SWI_Time:
818 args->n = callback->time (callback, NULL);
819 return 1;
820
821 case SWI_Clock:
822 /* return number of centi-seconds... */
823 args->n =
824 #ifdef CLOCKS_PER_SEC
825 (CLOCKS_PER_SEC >= 100)
826 ? (clock () / (CLOCKS_PER_SEC / 100))
827 : ((clock () * 100) / CLOCKS_PER_SEC);
828 #else
829 /* presume unix... clock() returns microseconds */
830 clock () / 10000;
831 #endif
832 return 1;
833
834 case SWI_Remove:
835 args->n = callback->unlink (callback, args->s);
836 return 1;
837 case SWI_Rename:
838 args->n = callback->rename (callback, args[0].s, args[1].s);
839 return 1;
840
841 case SWI_Open:
842 /* Now we need to decode the Demon open mode */
843 i = translate_open_mode[args[1].n];
844
845 /* Filename ":tt" is special: it denotes stdin/out */
846 if (strcmp (args->s, ":tt") == 0)
847 {
848 if (i == O_RDONLY) /* opening tty "r" */
849 args->n = 0 /* stdin */ ;
850 else
851 args->n = 1 /* stdout */ ;
852 }
853 else
854 args->n = callback->open (callback, args->s, i);
855 return 1;
856
857 case SWI_Close:
858 args->n = callback->close (callback, args->n);
859 return 1;
860
861 case SWI_Write:
862 /* Return the number of bytes *not* written */
863 args->n = args[1].n -
864 callback->write (callback, args[0].n, args[1].s, args[1].n);
865 return 1;
866
867 case SWI_Read:
868 {
869 char *copy = alloca (args[2].n);
870 int done = callback->read (callback, args[0].n, copy, args[2].n);
871 if (done > 0)
872 remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
873 args->n = args[2].n - done;
874 return 1;
875 }
876
877 case SWI_Seek:
878 /* Return non-zero on failure */
879 args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0;
880 return 1;
881
882 case SWI_Flen:
883 {
884 long old = callback->lseek (callback, args->n, 0, SEEK_CUR);
885 args->n = callback->lseek (callback, args->n, 0, SEEK_END);
886 callback->lseek (callback, args->n, old, 0);
887 return 1;
888 }
889
890 case SWI_IsTTY:
891 args->n = callback->isatty (callback, args->n);
892 return 1;
893
894 case SWI_GetEnv:
895 if (commandline != NULL)
896 {
897 int len = strlen (commandline);
898 if (len > 255)
899 {
900 len = 255;
901 commandline[255] = '\0';
902 }
903 remote_rdp_xfer_inferior_memory (args[0].n,
904 commandline, len + 1, 1, 0, 0);
905 }
906 else
907 remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
908 return 1;
909
910 default:
911 return 0;
912 }
913 }
914
915
916 static void
917 handle_swi (void)
918 {
919 argsin args[3];
920 char *buf;
921 int len;
922 int count = 0;
923
924 int swino = get_word ();
925 int type = get_byte ();
926 while (type != 0)
927 {
928 switch (type & 0x3)
929 {
930 case ABYTE:
931 args[count].n = get_byte ();
932 break;
933
934 case AWORD:
935 args[count].n = get_word ();
936 break;
937
938 case ASTRING:
939 /* If the word is under 32 bytes it will be sent otherwise
940 an address to it is passed. Also: Special case of 255 */
941
942 len = get_byte ();
943 if (len > 32)
944 {
945 if (len == 255)
946 {
947 len = get_word ();
948 }
949 buf = alloca (len);
950 remote_rdp_xfer_inferior_memory (get_word (),
951 buf,
952 len,
953 0,
954 0,
955 0);
956 }
957 else
958 {
959 int i;
960 buf = alloca (len + 1);
961 for (i = 0; i < len; i++)
962 buf[i] = get_byte ();
963 buf[i] = 0;
964 }
965 args[count].n = len;
966 args[count].s = buf;
967 break;
968
969 default:
970 error ("Unimplemented SWI argument");
971 }
972
973 type = type >> 2;
974 count++;
975 }
976
977 if (exec_swi (swino, args))
978 {
979 /* We have two options here reply with either a byte or a word
980 which is stored in args[0].n. There is no harm in replying with
981 a word all the time, so thats what I do! */
982 send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n);
983 }
984 else
985 {
986 send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing);
987 }
988 }
989
990 static void
991 rdp_execute_finish (void)
992 {
993 int running = 1;
994
995 while (running)
996 {
997 int res;
998 res = serial_readchar (io, 1);
999 while (res == SERIAL_TIMEOUT)
1000 {
1001 QUIT;
1002 printf_filtered ("Waiting for target..\n");
1003 res = serial_readchar (io, 1);
1004 }
1005
1006 switch (res)
1007 {
1008 case RDP_RES_SWI:
1009 handle_swi ();
1010 break;
1011 case RDP_RES_VALUE:
1012 send_rdp ("B", &ds.rdi_stopped_status);
1013 running = 0;
1014 break;
1015 case RDP_RESET:
1016 printf_filtered ("Target reset\n");
1017 running = 0;
1018 break;
1019 default:
1020 printf_filtered ("Ignoring %x\n", res);
1021 break;
1022 }
1023 }
1024 }
1025
1026
1027 static void
1028 rdp_execute (void)
1029 {
1030 rdp_execute_start ();
1031 rdp_execute_finish ();
1032 }
1033
1034 static int
1035 remote_rdp_insert_breakpoint (CORE_ADDR addr, char *save)
1036 {
1037 int res;
1038 if (ds.rdi_level > 0)
1039 {
1040 send_rdp ("bwb-SWB",
1041 RDP_SET_BREAK,
1042 addr,
1043 RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE,
1044 save,
1045 &res);
1046 }
1047 else
1048 {
1049 send_rdp ("bwb-SB",
1050 RDP_SET_BREAK,
1051 addr,
1052 RDP_SET_BREAK_TYPE_PC_EQUAL,
1053 &res);
1054 }
1055 return res;
1056 }
1057
1058 static int
1059 remote_rdp_remove_breakpoint (CORE_ADDR addr, char *save)
1060 {
1061 int res;
1062 if (ds.rdi_level > 0)
1063 {
1064 send_rdp ("b-p-S-B",
1065 RDP_CLEAR_BREAK,
1066 save, 4,
1067 &res);
1068 }
1069 else
1070 {
1071 send_rdp ("bw-S-B",
1072 RDP_CLEAR_BREAK,
1073 addr,
1074 &res);
1075 }
1076 return res;
1077 }
1078
1079 static void
1080 rdp_step (void)
1081 {
1082 if (ds.can_step && 0)
1083 {
1084 /* The pie board can't do steps so I can't test this, and
1085 the other code will always work. */
1086 int status;
1087 send_rdp ("bbw-S-B",
1088 RDP_STEP, 0, 1,
1089 &status);
1090 }
1091 else
1092 {
1093 char handle[4];
1094 CORE_ADDR pc = read_register (PC_REGNUM);
1095 pc = arm_get_next_pc (pc);
1096 remote_rdp_insert_breakpoint (pc, handle);
1097 rdp_execute ();
1098 remote_rdp_remove_breakpoint (pc, handle);
1099 }
1100 }
1101
1102 static void
1103 remote_rdp_open (char *args, int from_tty)
1104 {
1105 int not_icebreaker;
1106
1107 if (!args)
1108 error_no_arg ("serial port device name");
1109
1110 baud_rate = 9600;
1111
1112 target_preopen (from_tty);
1113
1114 io = serial_open (args);
1115
1116 if (!io)
1117 perror_with_name (args);
1118
1119 serial_raw (io);
1120
1121 rdp_init (1, from_tty);
1122
1123
1124 if (from_tty)
1125 {
1126 printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate);
1127 }
1128
1129 rdp_info ();
1130
1131 /* Need to set up the vector interception state */
1132 rdp_catch_vectors ();
1133
1134 /*
1135 ** If it's an EmbeddedICE, we need to set the processor config.
1136 ** Assume we can always have ARM7TDI...
1137 */
1138 send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, &not_icebreaker);
1139 if (!not_icebreaker)
1140 {
1141 const char *CPU = "ARM7TDI";
1142 int ICEversion;
1143 int len = strlen (CPU);
1144
1145 send_rdp ("bbbbw-p-SWZ",
1146 RDP_SELECT_CONFIG,
1147 RDI_ConfigCPU, /* Aspect: set the CPU */
1148 len, /* The number of bytes in the name */
1149 RDI_MatchAny, /* We'll take whatever we get */
1150 0, /* We'll take whatever version's there */
1151 CPU, len,
1152 &ICEversion);
1153 }
1154
1155 /* command line initialised on 'run' */
1156
1157 push_target (&remote_rdp_ops);
1158
1159 callback->init (callback);
1160 flush_cached_frames ();
1161 registers_changed ();
1162 stop_pc = read_pc ();
1163 set_current_frame (create_new_frame (read_fp (), stop_pc));
1164 select_frame (get_current_frame (), 0);
1165 print_stack_frame (selected_frame, -1, 1);
1166 }
1167
1168
1169
1170 /* Close out all files and local state before this target loses control. */
1171
1172 static void
1173 remote_rdp_close (int quitting)
1174 {
1175 callback->shutdown (callback);
1176 if (io)
1177 serial_close (io);
1178 io = 0;
1179 }
1180
1181
1182 /* Resume execution of the target process. STEP says whether to single-step
1183 or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
1184 to the target, or zero for no signal. */
1185
1186 static void
1187 remote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal)
1188 {
1189 if (step)
1190 rdp_step ();
1191 else
1192 rdp_execute ();
1193 }
1194
1195 /* Wait for inferior process to do something. Return pid of child,
1196 or -1 in case of error; store status through argument pointer STATUS,
1197 just as `wait' would. */
1198
1199 static ptid_t
1200 remote_rdp_wait (ptid_t ptid, struct target_waitstatus *status)
1201 {
1202 switch (ds.rdi_stopped_status)
1203 {
1204 default:
1205 case RDP_RES_RESET:
1206 case RDP_RES_SWI:
1207 status->kind = TARGET_WAITKIND_EXITED;
1208 status->value.integer = read_register (0);
1209 break;
1210 case RDP_RES_AT_BREAKPOINT:
1211 status->kind = TARGET_WAITKIND_STOPPED;
1212 /* The signal in sigrc is a host signal. That probably
1213 should be fixed. */
1214 status->value.sig = TARGET_SIGNAL_TRAP;
1215 break;
1216 #if 0
1217 case rdp_signalled:
1218 status->kind = TARGET_WAITKIND_SIGNALLED;
1219 /* The signal in sigrc is a host signal. That probably
1220 should be fixed. */
1221 status->value.sig = target_signal_from_host (sigrc);
1222 break;
1223 #endif
1224 }
1225
1226 return inferior_ptid;
1227 }
1228
1229 /* Get ready to modify the registers array. On machines which store
1230 individual registers, this doesn't need to do anything. On machines
1231 which store all the registers in one fell swoop, this makes sure
1232 that registers contains all the registers from the program being
1233 debugged. */
1234
1235 static void
1236 remote_rdp_prepare_to_store (void)
1237 {
1238 /* Do nothing, since we can store individual regs */
1239 }
1240
1241 /* Transfer LEN bytes between GDB address MYADDR and target address
1242 MEMADDR. If WRITE is non-zero, transfer them to the target,
1243 otherwise transfer them from the target. TARGET is unused.
1244
1245 Returns the number of bytes transferred. */
1246
1247 static int
1248 remote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
1249 int write,
1250 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
1251 struct target_ops *target ATTRIBUTE_UNUSED)
1252 {
1253 /* I infer from D Taylor's code that there's a limit on the amount
1254 we can transfer in one chunk.. */
1255 int done = 0;
1256 while (done < len)
1257 {
1258 int justdone;
1259 int thisbite = len - done;
1260 if (thisbite > RDP_MOUTHFULL)
1261 thisbite = RDP_MOUTHFULL;
1262
1263 QUIT;
1264
1265 if (write)
1266 {
1267 justdone = rdp_write (memaddr + done, myaddr + done, thisbite);
1268 }
1269 else
1270 {
1271 justdone = rdp_read (memaddr + done, myaddr + done, thisbite);
1272 }
1273
1274 done += justdone;
1275
1276 if (justdone != thisbite)
1277 break;
1278 }
1279 return done;
1280 }
1281
1282
1283
1284 struct yn
1285 {
1286 const char *name;
1287 int bit;
1288 };
1289 static struct yn stepinfo[] =
1290 {
1291 {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1},
1292 {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP},
1293 {"Step one instruction", RDP_INFO_ABOUT_STEP_1},
1294 {0}
1295 };
1296
1297 static struct yn breakinfo[] =
1298 {
1299 {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP},
1300 {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE},
1301 {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ},
1302 {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ},
1303 {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ},
1304 {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE},
1305 {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE},
1306 {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE},
1307 {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK},
1308 {"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK},
1309 {"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH},
1310 {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND},
1311 {0}
1312 };
1313
1314
1315 static void
1316 dump_bits (struct yn *t, int info)
1317 {
1318 while (t->name)
1319 {
1320 printf_unfiltered (" %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No");
1321 t++;
1322 }
1323 }
1324
1325 static void
1326 remote_rdp_files_info (struct target_ops *target)
1327 {
1328 printf_filtered ("Target capabilities:\n");
1329 dump_bits (stepinfo, ds.step_info);
1330 dump_bits (breakinfo, ds.break_info);
1331 printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3);
1332 }
1333
1334
1335 static void
1336 remote_rdp_create_inferior (char *exec_file, char *allargs, char **env)
1337 {
1338 CORE_ADDR entry_point;
1339
1340 if (exec_file == 0 || exec_bfd == 0)
1341 error ("No executable file specified.");
1342
1343 entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
1344
1345 remote_rdp_kill ();
1346 remove_breakpoints ();
1347 init_wait_for_inferior ();
1348
1349 /* This gives us a chance to set up the command line */
1350 rdp_set_command_line (exec_file, allargs);
1351
1352 inferior_ptid = pid_to_ptid (42);
1353 insert_breakpoints (); /* Needed to get correct instruction in cache */
1354
1355 /*
1356 ** RDP targets don't provide any facility to set the top of memory,
1357 ** so we don't bother to look for MEMSIZE in the environment.
1358 */
1359
1360 /* Let's go! */
1361 proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
1362 }
1363
1364 /* Accept any stray run/attach commands */
1365 static int
1366 remote_rdp_can_run (void)
1367 {
1368 return 1;
1369 }
1370
1371 /* Attach doesn't need to do anything */
1372 static void
1373 remote_rdp_attach (char *args, int from_tty)
1374 {
1375 return;
1376 }
1377
1378 /* Define the target subroutine names */
1379
1380 struct target_ops remote_rdp_ops;
1381
1382 static void
1383 init_remote_rdp_ops (void)
1384 {
1385 remote_rdp_ops.to_shortname = "rdp";
1386 remote_rdp_ops.to_longname = "Remote Target using the RDProtocol";
1387 remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol";
1388 remote_rdp_ops.to_open = remote_rdp_open;
1389 remote_rdp_ops.to_close = remote_rdp_close;
1390 remote_rdp_ops.to_attach = remote_rdp_attach;
1391 remote_rdp_ops.to_post_attach = NULL;
1392 remote_rdp_ops.to_require_attach = NULL;
1393 remote_rdp_ops.to_detach = NULL;
1394 remote_rdp_ops.to_require_detach = NULL;
1395 remote_rdp_ops.to_resume = remote_rdp_resume;
1396 remote_rdp_ops.to_wait = remote_rdp_wait;
1397 remote_rdp_ops.to_post_wait = NULL;
1398 remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register;
1399 remote_rdp_ops.to_store_registers = remote_rdp_store_register;
1400 remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store;
1401 remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory;
1402 remote_rdp_ops.to_files_info = remote_rdp_files_info;
1403 remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
1404 remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
1405 remote_rdp_ops.to_terminal_init = NULL;
1406 remote_rdp_ops.to_terminal_inferior = NULL;
1407 remote_rdp_ops.to_terminal_ours_for_output = NULL;
1408 remote_rdp_ops.to_terminal_ours = NULL;
1409 remote_rdp_ops.to_terminal_info = NULL;
1410 remote_rdp_ops.to_kill = remote_rdp_kill;
1411 remote_rdp_ops.to_load = generic_load;
1412 remote_rdp_ops.to_lookup_symbol = NULL;
1413 remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
1414 remote_rdp_ops.to_post_startup_inferior = NULL;
1415 remote_rdp_ops.to_acknowledge_created_inferior = NULL;
1416 remote_rdp_ops.to_clone_and_follow_inferior = NULL;
1417 remote_rdp_ops.to_post_follow_inferior_by_clone = NULL;
1418 remote_rdp_ops.to_insert_fork_catchpoint = NULL;
1419 remote_rdp_ops.to_remove_fork_catchpoint = NULL;
1420 remote_rdp_ops.to_insert_vfork_catchpoint = NULL;
1421 remote_rdp_ops.to_remove_vfork_catchpoint = NULL;
1422 remote_rdp_ops.to_has_forked = NULL;
1423 remote_rdp_ops.to_has_vforked = NULL;
1424 remote_rdp_ops.to_can_follow_vfork_prior_to_exec = NULL;
1425 remote_rdp_ops.to_post_follow_vfork = NULL;
1426 remote_rdp_ops.to_insert_exec_catchpoint = NULL;
1427 remote_rdp_ops.to_remove_exec_catchpoint = NULL;
1428 remote_rdp_ops.to_has_execd = NULL;
1429 remote_rdp_ops.to_reported_exec_events_per_exec_call = NULL;
1430 remote_rdp_ops.to_has_exited = NULL;
1431 remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior;
1432 remote_rdp_ops.to_can_run = remote_rdp_can_run;
1433 remote_rdp_ops.to_notice_signals = 0;
1434 remote_rdp_ops.to_thread_alive = 0;
1435 remote_rdp_ops.to_stop = 0;
1436 remote_rdp_ops.to_pid_to_exec_file = NULL;
1437 remote_rdp_ops.to_stratum = process_stratum;
1438 remote_rdp_ops.DONT_USE = NULL;
1439 remote_rdp_ops.to_has_all_memory = 1;
1440 remote_rdp_ops.to_has_memory = 1;
1441 remote_rdp_ops.to_has_stack = 1;
1442 remote_rdp_ops.to_has_registers = 1;
1443 remote_rdp_ops.to_has_execution = 1;
1444 remote_rdp_ops.to_sections = NULL;
1445 remote_rdp_ops.to_sections_end = NULL;
1446 remote_rdp_ops.to_magic = OPS_MAGIC;
1447 }
1448
1449 void
1450 _initialize_remote_rdp (void)
1451 {
1452 init_remote_rdp_ops ();
1453 add_target (&remote_rdp_ops);
1454 }