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