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