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