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, ¬_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