1130812Smarcel/* Remote debugging for the ARM RDP interface.
2130812Smarcel
3130812Smarcel   Copyright 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003 Free
4130812Smarcel   Software Foundation, Inc.
5130812Smarcel
6130812Smarcel   This file is part of GDB.
7130812Smarcel
8130812Smarcel   This program is free software; you can redistribute it and/or modify
9130812Smarcel   it under the terms of the GNU General Public License as published by
10130812Smarcel   the Free Software Foundation; either version 2 of the License, or
11130812Smarcel   (at your option) any later version.
12130812Smarcel
13130812Smarcel   This program is distributed in the hope that it will be useful,
14130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
15130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16130812Smarcel   GNU General Public License for more details.
17130812Smarcel
18130812Smarcel   You should have received a copy of the GNU General Public License
19130812Smarcel   along with this program; if not, write to the Free Software
20130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
21130812Smarcel   Boston, MA 02111-1307, USA.
22130812Smarcel
23130812Smarcel
24130812Smarcel */
25130812Smarcel
26130812Smarcel
27130812Smarcel/*
28130812Smarcel   Much of this file (in particular the SWI stuff) is based on code by
29130812Smarcel   David Taylor (djt1000@uk.ac.cam.hermes).
30130812Smarcel
31130812Smarcel   I hacked on and simplified it by removing a lot of sexy features he
32130812Smarcel   had added, and some of the (unix specific) workarounds he'd done
33130812Smarcel   for other GDB problems - which if they still exist should be fixed
34130812Smarcel   in GDB, not in a remote-foo thing .  I also made it conform more to
35130812Smarcel   the doc I have; which may be wrong.
36130812Smarcel
37130812Smarcel   Steve Chamberlain (sac@cygnus.com).
38130812Smarcel */
39130812Smarcel
40130812Smarcel
41130812Smarcel#include "defs.h"
42130812Smarcel#include "inferior.h"
43130812Smarcel#include "value.h"
44130812Smarcel#include "gdb/callback.h"
45130812Smarcel#include "command.h"
46130812Smarcel#include <ctype.h>
47130812Smarcel#include <fcntl.h>
48130812Smarcel#include "symfile.h"
49130812Smarcel#include "remote-utils.h"
50130812Smarcel#include "gdb_string.h"
51130812Smarcel#include "gdbcore.h"
52130812Smarcel#include "regcache.h"
53130812Smarcel#include "serial.h"
54130812Smarcel
55130812Smarcel#include "arm-tdep.h"
56130812Smarcel
57130812Smarcel#ifdef HAVE_TIME_H
58130812Smarcel#include <time.h>
59130812Smarcel#endif
60130812Smarcel
61130812Smarcelextern struct target_ops remote_rdp_ops;
62130812Smarcelstatic struct serial *io;
63130812Smarcelstatic host_callback *callback = &default_callback;
64130812Smarcel
65130812Smarcelstruct
66130812Smarcel  {
67130812Smarcel    int step_info;
68130812Smarcel    int break_info;
69130812Smarcel    int model_info;
70130812Smarcel    int target_info;
71130812Smarcel    int can_step;
72130812Smarcel    char command_line[10];
73130812Smarcel    int rdi_level;
74130812Smarcel    int rdi_stopped_status;
75130812Smarcel  }
76130812Smarcelds;
77130812Smarcel
78130812Smarcel
79130812Smarcel
80130812Smarcel/* Definitions for the RDP protocol. */
81130812Smarcel
82130812Smarcel#define RDP_MOUTHFULL   		(1<<6)
83130812Smarcel#define FPU_COPRO_NUMBER 		1
84130812Smarcel
85130812Smarcel#define RDP_OPEN 	 		0
86130812Smarcel#define RDP_OPEN_TYPE_COLD 		0
87130812Smarcel#define RDP_OPEN_TYPE_WARM 		1
88130812Smarcel#define RDP_OPEN_TYPE_BAUDRATE          2
89130812Smarcel
90130812Smarcel#define RDP_OPEN_BAUDRATE_9600       	1
91130812Smarcel#define RDP_OPEN_BAUDRATE_19200        	2
92130812Smarcel#define RDP_OPEN_BAUDRATE_38400        	3
93130812Smarcel
94130812Smarcel#define RDP_OPEN_TYPE_RETURN_SEX	(1<<3)
95130812Smarcel
96130812Smarcel#define RDP_CLOSE 			1
97130812Smarcel
98130812Smarcel#define RDP_MEM_READ 			2
99130812Smarcel
100130812Smarcel#define RDP_MEM_WRITE 			3
101130812Smarcel
102130812Smarcel#define RDP_CPU_READ 			4
103130812Smarcel#define RDP_CPU_WRITE 			5
104130812Smarcel#define RDP_CPU_READWRITE_MODE_CURRENT 255
105130812Smarcel#define RDP_CPU_READWRITE_MASK_PC 	(1<<16)
106130812Smarcel#define RDP_CPU_READWRITE_MASK_CPSR 	(1<<17)
107130812Smarcel#define RDP_CPU_READWRITE_MASK_SPSR 	(1<<18)
108130812Smarcel
109130812Smarcel#define RDP_COPRO_READ   		6
110130812Smarcel#define RDP_COPRO_WRITE 		7
111130812Smarcel#define RDP_FPU_READWRITE_MASK_FPS 	(1<<8)
112130812Smarcel
113130812Smarcel#define RDP_SET_BREAK			0xa
114130812Smarcel#define RDP_SET_BREAK_TYPE_PC_EQUAL     0
115130812Smarcel#define RDP_SET_BREAK_TYPE_GET_HANDLE   (0x10)
116130812Smarcel
117130812Smarcel#define RDP_CLEAR_BREAK 		0xb
118130812Smarcel
119130812Smarcel#define RDP_EXEC 			0x10
120130812Smarcel#define RDP_EXEC_TYPE_SYNC 		0
121130812Smarcel
122130812Smarcel#define RDP_STEP 			0x11
123130812Smarcel
124130812Smarcel#define RDP_INFO  			0x12
125130812Smarcel#define RDP_INFO_ABOUT_STEP 		2
126130812Smarcel#define RDP_INFO_ABOUT_STEP_GT_1	1
127130812Smarcel#define RDP_INFO_ABOUT_STEP_TO_JMP 	2
128130812Smarcel#define RDP_INFO_ABOUT_STEP_1		4
129130812Smarcel#define RDP_INFO_ABOUT_TARGET 		0
130130812Smarcel#define RDP_INFO_ABOUT_BREAK 		1
131130812Smarcel#define RDP_INFO_ABOUT_BREAK_COMP	1
132130812Smarcel#define RDP_INFO_ABOUT_BREAK_RANGE 	2
133130812Smarcel#define RDP_INFO_ABOUT_BREAK_BYTE_READ 	4
134130812Smarcel#define RDP_INFO_ABOUT_BREAK_HALFWORD_READ 8
135130812Smarcel#define RDP_INFO_ABOUT_BREAK_WORD_READ (1<<4)
136130812Smarcel#define RDP_INFO_ABOUT_BREAK_BYTE_WRITE (1<<5)
137130812Smarcel#define RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE (1<<6)
138130812Smarcel#define RDP_INFO_ABOUT_BREAK_WORD_WRITE (1<<7)
139130812Smarcel#define RDP_INFO_ABOUT_BREAK_MASK 	(1<<8)
140130812Smarcel#define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9)
141130812Smarcel#define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10)
142130812Smarcel#define RDP_INFO_ABOUT_BREAK_COND 	(1<<11)
143130812Smarcel#define RDP_INFO_VECTOR_CATCH		(0x180)
144130812Smarcel#define RDP_INFO_ICEBREAKER		(7)
145130812Smarcel#define RDP_INFO_SET_CMDLINE            (0x300)
146130812Smarcel
147130812Smarcel#define RDP_SELECT_CONFIG		(0x16)
148130812Smarcel#define RDI_ConfigCPU			0
149130812Smarcel#define RDI_ConfigSystem		1
150130812Smarcel#define RDI_MatchAny			0
151130812Smarcel#define RDI_MatchExactly		1
152130812Smarcel#define RDI_MatchNoEarlier		2
153130812Smarcel
154130812Smarcel#define RDP_RESET 			0x7f
155130812Smarcel
156130812Smarcel/* Returns from RDP */
157130812Smarcel#define RDP_RES_STOPPED 		0x20
158130812Smarcel#define RDP_RES_SWI 			0x21
159130812Smarcel#define RDP_RES_FATAL 			0x5e
160130812Smarcel#define RDP_RES_VALUE 			0x5f
161130812Smarcel#define RDP_RES_VALUE_LITTLE_ENDIAN     240
162130812Smarcel#define RDP_RES_VALUE_BIG_ENDIAN 	241
163130812Smarcel#define RDP_RES_RESET			0x7f
164130812Smarcel#define RDP_RES_AT_BREAKPOINT    	143
165130812Smarcel#define RDP_RES_IDUNNO			0xe6
166130812Smarcel#define RDP_OSOpReply           	0x13
167130812Smarcel#define RDP_OSOpWord            	2
168130812Smarcel#define RDP_OSOpNothing         	0
169130812Smarcel
170130812Smarcelstatic int timeout = 2;
171130812Smarcel
172130812Smarcelstatic char *commandline = NULL;
173130812Smarcel
174130812Smarcelstatic int
175130812Smarcelremote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
176130812Smarcel				 int write,
177130812Smarcel				 struct mem_attrib *attrib,
178130812Smarcel				 struct target_ops *target);
179130812Smarcel
180130812Smarcel
181130812Smarcel/* Stuff for talking to the serial layer. */
182130812Smarcel
183130812Smarcelstatic unsigned char
184130812Smarcelget_byte (void)
185130812Smarcel{
186130812Smarcel  int c = serial_readchar (io, timeout);
187130812Smarcel
188130812Smarcel  if (remote_debug)
189130812Smarcel    fprintf_unfiltered (gdb_stdlog, "[%02x]\n", c);
190130812Smarcel
191130812Smarcel  if (c == SERIAL_TIMEOUT)
192130812Smarcel    {
193130812Smarcel      if (timeout == 0)
194130812Smarcel	return (unsigned char) c;
195130812Smarcel
196130812Smarcel      error ("Timeout reading from remote_system");
197130812Smarcel    }
198130812Smarcel
199130812Smarcel  return c;
200130812Smarcel}
201130812Smarcel
202130812Smarcel/* Note that the target always speaks little-endian to us,
203130812Smarcel   even if it's a big endian machine. */
204130812Smarcelstatic unsigned int
205130812Smarcelget_word (void)
206130812Smarcel{
207130812Smarcel  unsigned int val = 0;
208130812Smarcel  unsigned int c;
209130812Smarcel  int n;
210130812Smarcel  for (n = 0; n < 4; n++)
211130812Smarcel    {
212130812Smarcel      c = get_byte ();
213130812Smarcel      val |= c << (n * 8);
214130812Smarcel    }
215130812Smarcel  return val;
216130812Smarcel}
217130812Smarcel
218130812Smarcelstatic void
219130812Smarcelput_byte (char val)
220130812Smarcel{
221130812Smarcel  if (remote_debug)
222130812Smarcel    fprintf_unfiltered (gdb_stdlog, "(%02x)\n", val);
223130812Smarcel  serial_write (io, &val, 1);
224130812Smarcel}
225130812Smarcel
226130812Smarcelstatic void
227130812Smarcelput_word (int val)
228130812Smarcel{
229130812Smarcel  /* We always send in little endian */
230130812Smarcel  unsigned char b[4];
231130812Smarcel  b[0] = val;
232130812Smarcel  b[1] = val >> 8;
233130812Smarcel  b[2] = val >> 16;
234130812Smarcel  b[3] = val >> 24;
235130812Smarcel
236130812Smarcel  if (remote_debug)
237130812Smarcel    fprintf_unfiltered (gdb_stdlog, "(%04x)", val);
238130812Smarcel
239130812Smarcel  serial_write (io, b, 4);
240130812Smarcel}
241130812Smarcel
242130812Smarcel
243130812Smarcel
244130812Smarcel/* Stuff for talking to the RDP layer. */
245130812Smarcel
246130812Smarcel/* This is a bit more fancy that need be so that it syncs even in nasty cases.
247130812Smarcel
248130812Smarcel   I'be been unable to make it reliably sync up with the change
249130812Smarcel   baudrate open command.  It likes to sit and say it's been reset,
250130812Smarcel   with no more action.  So I took all that code out.  I'd rather sync
251130812Smarcel   reliably at 9600 than wait forever for a possible 19200 connection.
252130812Smarcel
253130812Smarcel */
254130812Smarcelstatic void
255130812Smarcelrdp_init (int cold, int tty)
256130812Smarcel{
257130812Smarcel  int sync = 0;
258130812Smarcel  int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM;
259130812Smarcel  int baudtry = 9600;
260130812Smarcel
261130812Smarcel  time_t now = time (0);
262130812Smarcel  time_t stop_time = now + 10;	/* Try and sync for 10 seconds, then give up */
263130812Smarcel
264130812Smarcel
265130812Smarcel  while (time (0) < stop_time && !sync)
266130812Smarcel    {
267130812Smarcel      int restype;
268130812Smarcel      QUIT;
269130812Smarcel
270130812Smarcel      serial_flush_input (io);
271130812Smarcel      serial_flush_output (io);
272130812Smarcel
273130812Smarcel      if (tty)
274130812Smarcel	printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);
275130812Smarcel
276130812Smarcel      /*
277130812Smarcel         ** It seems necessary to reset an EmbeddedICE to get it going.
278130812Smarcel         ** This has the side benefit of displaying the startup banner.
279130812Smarcel       */
280130812Smarcel      if (cold)
281130812Smarcel	{
282130812Smarcel	  put_byte (RDP_RESET);
283130812Smarcel	  while ((restype = serial_readchar (io, 1)) > 0)
284130812Smarcel	    {
285130812Smarcel	      switch (restype)
286130812Smarcel		{
287130812Smarcel		case SERIAL_TIMEOUT:
288130812Smarcel		  break;
289130812Smarcel		case RDP_RESET:
290130812Smarcel		  /* Sent at start of reset process: ignore */
291130812Smarcel		  break;
292130812Smarcel		default:
293130812Smarcel		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
294130812Smarcel		  break;
295130812Smarcel		}
296130812Smarcel	    }
297130812Smarcel
298130812Smarcel	  if (restype == 0)
299130812Smarcel	    {
300130812Smarcel	      /* Got end-of-banner mark */
301130812Smarcel	      printf_filtered ("\n");
302130812Smarcel	    }
303130812Smarcel	}
304130812Smarcel
305130812Smarcel      put_byte (RDP_OPEN);
306130812Smarcel
307130812Smarcel      put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
308130812Smarcel      put_word (0);
309130812Smarcel
310130812Smarcel      while (!sync && (restype = serial_readchar (io, 1)) > 0)
311130812Smarcel	{
312130812Smarcel	  if (remote_debug)
313130812Smarcel	    fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype);
314130812Smarcel
315130812Smarcel	  switch (restype)
316130812Smarcel	    {
317130812Smarcel	    case SERIAL_TIMEOUT:
318130812Smarcel	      break;
319130812Smarcel
320130812Smarcel	    case RDP_RESET:
321130812Smarcel	      while ((restype = serial_readchar (io, 1)) == RDP_RESET)
322130812Smarcel		;
323130812Smarcel	      do
324130812Smarcel		{
325130812Smarcel		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
326130812Smarcel		}
327130812Smarcel	      while ((restype = serial_readchar (io, 1)) > 0);
328130812Smarcel
329130812Smarcel	      if (tty)
330130812Smarcel		{
331130812Smarcel		  printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
332130812Smarcel		  printf_unfiltered ("Waiting for it to settle down...\n");
333130812Smarcel		}
334130812Smarcel	      sleep (3);
335130812Smarcel	      if (tty)
336130812Smarcel		printf_unfiltered ("\nTrying again.\n");
337130812Smarcel	      cold = 0;
338130812Smarcel	      break;
339130812Smarcel
340130812Smarcel	    default:
341130812Smarcel	      break;
342130812Smarcel
343130812Smarcel	    case RDP_RES_VALUE:
344130812Smarcel	      {
345130812Smarcel		int resval = serial_readchar (io, 1);
346130812Smarcel
347130812Smarcel		if (remote_debug)
348130812Smarcel		  fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval);
349130812Smarcel
350130812Smarcel		switch (resval)
351130812Smarcel		  {
352130812Smarcel		  case SERIAL_TIMEOUT:
353130812Smarcel		    break;
354130812Smarcel		  case RDP_RES_VALUE_LITTLE_ENDIAN:
355130812Smarcel#if 0
356130812Smarcel		    /* FIXME: cagney/2003-11-22: Ever since the ARM
357130812Smarcel                       was multi-arched (in 2002-02-08), this
358130812Smarcel                       assignment has had no effect.  There needs to
359130812Smarcel                       be some sort of check/decision based on the
360130812Smarcel                       current architecture's byte-order vs the remote
361130812Smarcel                       target's byte order.  For the moment disable
362130812Smarcel                       the assignment to keep things building.  */
363130812Smarcel		    target_byte_order = BFD_ENDIAN_LITTLE;
364130812Smarcel#endif
365130812Smarcel		    sync = 1;
366130812Smarcel		    break;
367130812Smarcel		  case RDP_RES_VALUE_BIG_ENDIAN:
368130812Smarcel#if 0
369130812Smarcel		    /* FIXME: cagney/2003-11-22: Ever since the ARM
370130812Smarcel                       was multi-arched (in 2002-02-08), this
371130812Smarcel                       assignment has had no effect.  There needs to
372130812Smarcel                       be some sort of check/decision based on the
373130812Smarcel                       current architecture's byte-order vs the remote
374130812Smarcel                       target's byte order.  For the moment disable
375130812Smarcel                       the assignment to keep things building.  */
376130812Smarcel		    target_byte_order = BFD_ENDIAN_BIG;
377130812Smarcel#endif
378130812Smarcel		    sync = 1;
379130812Smarcel		    break;
380130812Smarcel		  default:
381130812Smarcel		    break;
382130812Smarcel		  }
383130812Smarcel	      }
384130812Smarcel	    }
385130812Smarcel	}
386130812Smarcel    }
387130812Smarcel
388130812Smarcel  if (!sync)
389130812Smarcel    {
390130812Smarcel      error ("Couldn't reset the board, try pressing the reset button");
391130812Smarcel    }
392130812Smarcel}
393130812Smarcel
394130812Smarcel
395130812Smarcelstatic void
396130812Smarcelsend_rdp (char *template,...)
397130812Smarcel{
398130812Smarcel  char buf[200];
399130812Smarcel  char *dst = buf;
400130812Smarcel  va_list alist;
401130812Smarcel  va_start (alist, template);
402130812Smarcel
403130812Smarcel  while (*template)
404130812Smarcel    {
405130812Smarcel      unsigned int val;
406130812Smarcel      int *pi;
407130812Smarcel      int *pstat;
408130812Smarcel      char *pc;
409130812Smarcel      int i;
410130812Smarcel      switch (*template++)
411130812Smarcel	{
412130812Smarcel	case 'b':
413130812Smarcel	  val = va_arg (alist, int);
414130812Smarcel	  *dst++ = val;
415130812Smarcel	  break;
416130812Smarcel	case 'w':
417130812Smarcel	  val = va_arg (alist, int);
418130812Smarcel	  *dst++ = val;
419130812Smarcel	  *dst++ = val >> 8;
420130812Smarcel	  *dst++ = val >> 16;
421130812Smarcel	  *dst++ = val >> 24;
422130812Smarcel	  break;
423130812Smarcel	case 'S':
424130812Smarcel	  val = get_byte ();
425130812Smarcel	  if (val != RDP_RES_VALUE)
426130812Smarcel	    {
427130812Smarcel	      printf_unfiltered ("got bad res value of %d, %x\n", val, val);
428130812Smarcel	    }
429130812Smarcel	  break;
430130812Smarcel	case 'V':
431130812Smarcel	  pstat = va_arg (alist, int *);
432130812Smarcel	  pi = va_arg (alist, int *);
433130812Smarcel
434130812Smarcel	  *pstat = get_byte ();
435130812Smarcel	  /* Check the result was zero, if not read the syndrome */
436130812Smarcel	  if (*pstat)
437130812Smarcel	    {
438130812Smarcel	      *pi = get_word ();
439130812Smarcel	    }
440130812Smarcel	  break;
441130812Smarcel	case 'Z':
442130812Smarcel	  /* Check the result code */
443130812Smarcel	  switch (get_byte ())
444130812Smarcel	    {
445130812Smarcel	    case 0:
446130812Smarcel	      /* Success */
447130812Smarcel	      break;
448130812Smarcel	    case 253:
449130812Smarcel	      /* Target can't do it; never mind */
450130812Smarcel	      printf_unfiltered ("RDP: Insufficient privilege\n");
451130812Smarcel	      return;
452130812Smarcel	    case 254:
453130812Smarcel	      /* Target can't do it; never mind */
454130812Smarcel	      printf_unfiltered ("RDP: Unimplemented message\n");
455130812Smarcel	      return;
456130812Smarcel	    case 255:
457130812Smarcel	      error ("Command garbled");
458130812Smarcel	      break;
459130812Smarcel	    default:
460130812Smarcel	      error ("Corrupt reply from target");
461130812Smarcel	      break;
462130812Smarcel	    }
463130812Smarcel	  break;
464130812Smarcel	case 'W':
465130812Smarcel	  /* Read a word from the target */
466130812Smarcel	  pi = va_arg (alist, int *);
467130812Smarcel	  *pi = get_word ();
468130812Smarcel	  break;
469130812Smarcel	case 'P':
470130812Smarcel	  /* Read in some bytes from the target. */
471130812Smarcel	  pc = va_arg (alist, char *);
472130812Smarcel	  val = va_arg (alist, int);
473130812Smarcel	  for (i = 0; i < val; i++)
474130812Smarcel	    {
475130812Smarcel	      pc[i] = get_byte ();
476130812Smarcel	    }
477130812Smarcel	  break;
478130812Smarcel	case 'p':
479130812Smarcel	  /* send what's being pointed at */
480130812Smarcel	  pc = va_arg (alist, char *);
481130812Smarcel	  val = va_arg (alist, int);
482130812Smarcel	  dst = buf;
483130812Smarcel	  serial_write (io, pc, val);
484130812Smarcel	  break;
485130812Smarcel	case '-':
486130812Smarcel	  /* Send whats in the queue */
487130812Smarcel	  if (dst != buf)
488130812Smarcel	    {
489130812Smarcel	      serial_write (io, buf, dst - buf);
490130812Smarcel	      dst = buf;
491130812Smarcel	    }
492130812Smarcel	  break;
493130812Smarcel	case 'B':
494130812Smarcel	  pi = va_arg (alist, int *);
495130812Smarcel	  *pi = get_byte ();
496130812Smarcel	  break;
497130812Smarcel	default:
498130812Smarcel	  internal_error (__FILE__, __LINE__, "failed internal consistency check");
499130812Smarcel	}
500130812Smarcel    }
501130812Smarcel  va_end (alist);
502130812Smarcel
503130812Smarcel  if (dst != buf)
504130812Smarcel    internal_error (__FILE__, __LINE__, "failed internal consistency check");
505130812Smarcel}
506130812Smarcel
507130812Smarcel
508130812Smarcelstatic int
509130812Smarcelrdp_write (CORE_ADDR memaddr, char *buf, int len)
510130812Smarcel{
511130812Smarcel  int res;
512130812Smarcel  int val;
513130812Smarcel
514130812Smarcel  send_rdp ("bww-p-SV", RDP_MEM_WRITE, memaddr, len, buf, len, &res, &val);
515130812Smarcel
516130812Smarcel  if (res)
517130812Smarcel    {
518130812Smarcel      return val;
519130812Smarcel    }
520130812Smarcel  return len;
521130812Smarcel}
522130812Smarcel
523130812Smarcel
524130812Smarcelstatic int
525130812Smarcelrdp_read (CORE_ADDR memaddr, char *buf, int len)
526130812Smarcel{
527130812Smarcel  int res;
528130812Smarcel  int val;
529130812Smarcel  send_rdp ("bww-S-P-V",
530130812Smarcel	    RDP_MEM_READ, memaddr, len,
531130812Smarcel	    buf, len,
532130812Smarcel	    &res, &val);
533130812Smarcel  if (res)
534130812Smarcel    {
535130812Smarcel      return val;
536130812Smarcel    }
537130812Smarcel  return len;
538130812Smarcel}
539130812Smarcel
540130812Smarcelstatic void
541130812Smarcelrdp_fetch_one_register (int mask, char *buf)
542130812Smarcel{
543130812Smarcel  int val;
544130812Smarcel  send_rdp ("bbw-SWZ", RDP_CPU_READ, RDP_CPU_READWRITE_MODE_CURRENT, mask, &val);
545130812Smarcel  store_signed_integer (buf, 4, val);
546130812Smarcel}
547130812Smarcel
548130812Smarcelstatic void
549130812Smarcelrdp_fetch_one_fpu_register (int mask, char *buf)
550130812Smarcel{
551130812Smarcel#if 0
552130812Smarcel  /* !!! Since the PIE board doesn't work as documented,
553130812Smarcel     and it doesn't have FPU hardware anyway and since it
554130812Smarcel     slows everything down, I've disabled this. */
555130812Smarcel  int val;
556130812Smarcel  if (mask == RDP_FPU_READWRITE_MASK_FPS)
557130812Smarcel    {
558130812Smarcel      /* this guy is only a word */
559130812Smarcel      send_rdp ("bbw-SWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, &val);
560130812Smarcel      store_signed_integer (buf, 4, val);
561130812Smarcel    }
562130812Smarcel  else
563130812Smarcel    {
564130812Smarcel      /* There are 12 bytes long
565130812Smarcel         !! fixme about endianness
566130812Smarcel       */
567130812Smarcel      int dummy;		/* I've seen these come back as four words !! */
568130812Smarcel      send_rdp ("bbw-SWWWWZ", RDP_COPRO_READ, FPU_COPRO_NUMBER, mask, buf + 0, buf + 4, buf + 8, &dummy);
569130812Smarcel    }
570130812Smarcel#endif
571130812Smarcel  memset (buf, 0, MAX_REGISTER_SIZE);
572130812Smarcel}
573130812Smarcel
574130812Smarcel
575130812Smarcelstatic void
576130812Smarcelrdp_store_one_register (int mask, char *buf)
577130812Smarcel{
578130812Smarcel  int val = extract_unsigned_integer (buf, 4);
579130812Smarcel
580130812Smarcel  send_rdp ("bbww-SZ",
581130812Smarcel	    RDP_CPU_WRITE, RDP_CPU_READWRITE_MODE_CURRENT, mask, val);
582130812Smarcel}
583130812Smarcel
584130812Smarcel
585130812Smarcelstatic void
586130812Smarcelrdp_store_one_fpu_register (int mask, char *buf)
587130812Smarcel{
588130812Smarcel#if 0
589130812Smarcel  /* See comment in fetch_one_fpu_register */
590130812Smarcel  if (mask == RDP_FPU_READWRITE_MASK_FPS)
591130812Smarcel    {
592130812Smarcel      int val = extract_unsigned_integer (buf, 4);
593130812Smarcel      /* this guy is only a word */
594130812Smarcel      send_rdp ("bbww-SZ", RDP_COPRO_WRITE,
595130812Smarcel		FPU_COPRO_NUMBER,
596130812Smarcel		mask, val);
597130812Smarcel    }
598130812Smarcel  else
599130812Smarcel    {
600130812Smarcel      /* There are 12 bytes long
601130812Smarcel         !! fixme about endianness
602130812Smarcel       */
603130812Smarcel      int dummy = 0;
604130812Smarcel      /* I've seen these come as four words, not the three advertized !! */
605130812Smarcel      printf ("Sending mask %x\n", mask);
606130812Smarcel      send_rdp ("bbwwwww-SZ",
607130812Smarcel		RDP_COPRO_WRITE,
608130812Smarcel		FPU_COPRO_NUMBER,
609130812Smarcel		mask,
610130812Smarcel		*(int *) (buf + 0),
611130812Smarcel		*(int *) (buf + 4),
612130812Smarcel		*(int *) (buf + 8),
613130812Smarcel		0);
614130812Smarcel
615130812Smarcel      printf ("done mask %x\n", mask);
616130812Smarcel    }
617130812Smarcel#endif
618130812Smarcel}
619130812Smarcel
620130812Smarcel
621130812Smarcel/* Convert between GDB requests and the RDP layer. */
622130812Smarcel
623130812Smarcelstatic void
624130812Smarcelremote_rdp_fetch_register (int regno)
625130812Smarcel{
626130812Smarcel  if (regno == -1)
627130812Smarcel    {
628130812Smarcel      for (regno = 0; regno < NUM_REGS; regno++)
629130812Smarcel	remote_rdp_fetch_register (regno);
630130812Smarcel    }
631130812Smarcel  else
632130812Smarcel    {
633130812Smarcel      char buf[MAX_REGISTER_SIZE];
634130812Smarcel      if (regno < 15)
635130812Smarcel	rdp_fetch_one_register (1 << regno, buf);
636130812Smarcel      else if (regno == ARM_PC_REGNUM)
637130812Smarcel	rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_PC, buf);
638130812Smarcel      else if (regno == ARM_PS_REGNUM)
639130812Smarcel	rdp_fetch_one_register (RDP_CPU_READWRITE_MASK_CPSR, buf);
640130812Smarcel      else if (regno == ARM_FPS_REGNUM)
641130812Smarcel	rdp_fetch_one_fpu_register (RDP_FPU_READWRITE_MASK_FPS, buf);
642130812Smarcel      else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
643130812Smarcel	rdp_fetch_one_fpu_register (1 << (regno - ARM_F0_REGNUM), buf);
644130812Smarcel      else
645130812Smarcel	{
646130812Smarcel	  printf ("Help me with fetch reg %d\n", regno);
647130812Smarcel	}
648130812Smarcel      supply_register (regno, buf);
649130812Smarcel    }
650130812Smarcel}
651130812Smarcel
652130812Smarcel
653130812Smarcelstatic void
654130812Smarcelremote_rdp_store_register (int regno)
655130812Smarcel{
656130812Smarcel  if (regno == -1)
657130812Smarcel    {
658130812Smarcel      for (regno = 0; regno < NUM_REGS; regno++)
659130812Smarcel	remote_rdp_store_register (regno);
660130812Smarcel    }
661130812Smarcel  else
662130812Smarcel    {
663130812Smarcel      char tmp[MAX_REGISTER_SIZE];
664130812Smarcel      deprecated_read_register_gen (regno, tmp);
665130812Smarcel      if (regno < 15)
666130812Smarcel	rdp_store_one_register (1 << regno, tmp);
667130812Smarcel      else if (regno == ARM_PC_REGNUM)
668130812Smarcel	rdp_store_one_register (RDP_CPU_READWRITE_MASK_PC, tmp);
669130812Smarcel      else if (regno == ARM_PS_REGNUM)
670130812Smarcel	rdp_store_one_register (RDP_CPU_READWRITE_MASK_CPSR, tmp);
671130812Smarcel      else if (regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
672130812Smarcel	rdp_store_one_fpu_register (1 << (regno - ARM_F0_REGNUM), tmp);
673130812Smarcel      else
674130812Smarcel	{
675130812Smarcel	  printf ("Help me with reg %d\n", regno);
676130812Smarcel	}
677130812Smarcel    }
678130812Smarcel}
679130812Smarcel
680130812Smarcelstatic void
681130812Smarcelremote_rdp_kill (void)
682130812Smarcel{
683130812Smarcel  callback->shutdown (callback);
684130812Smarcel}
685130812Smarcel
686130812Smarcel
687130812Smarcelstatic void
688130812Smarcelrdp_info (void)
689130812Smarcel{
690130812Smarcel  send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_STEP,
691130812Smarcel	    &ds.step_info);
692130812Smarcel  send_rdp ("bw-S-W-Z", RDP_INFO, RDP_INFO_ABOUT_BREAK,
693130812Smarcel	    &ds.break_info);
694130812Smarcel  send_rdp ("bw-S-WW-Z", RDP_INFO, RDP_INFO_ABOUT_TARGET,
695130812Smarcel	    &ds.target_info,
696130812Smarcel	    &ds.model_info);
697130812Smarcel
698130812Smarcel  ds.can_step = ds.step_info & RDP_INFO_ABOUT_STEP_1;
699130812Smarcel
700130812Smarcel  ds.rdi_level = (ds.target_info >> 5) & 3;
701130812Smarcel}
702130812Smarcel
703130812Smarcel
704130812Smarcelstatic void
705130812Smarcelrdp_execute_start (void)
706130812Smarcel{
707130812Smarcel  /* Start it off, but don't wait for it */
708130812Smarcel  send_rdp ("bb-", RDP_EXEC, RDP_EXEC_TYPE_SYNC);
709130812Smarcel}
710130812Smarcel
711130812Smarcel
712130812Smarcelstatic void
713130812Smarcelrdp_set_command_line (char *command, char *args)
714130812Smarcel{
715130812Smarcel  /*
716130812Smarcel     ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems
717130812Smarcel     ** don't implement that, and get all confused at the unexpected text.
718130812Smarcel     ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv
719130812Smarcel   */
720130812Smarcel
721130812Smarcel  if (commandline != NULL)
722130812Smarcel    xfree (commandline);
723130812Smarcel
724130812Smarcel  xasprintf (&commandline, "%s %s", command, args);
725130812Smarcel}
726130812Smarcel
727130812Smarcelstatic void
728130812Smarcelrdp_catch_vectors (void)
729130812Smarcel{
730130812Smarcel  /*
731130812Smarcel     ** We want the target monitor to intercept the abort vectors
732130812Smarcel     ** i.e. stop the program if any of these are used.
733130812Smarcel   */
734130812Smarcel  send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH,
735130812Smarcel  /*
736130812Smarcel     ** Specify a bitmask including
737130812Smarcel     **  the reset vector
738130812Smarcel     **  the undefined instruction vector
739130812Smarcel     **  the prefetch abort vector
740130812Smarcel     **  the data abort vector
741130812Smarcel     **  the address exception vector
742130812Smarcel   */
743130812Smarcel	    (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4) | (1 << 5)
744130812Smarcel    );
745130812Smarcel}
746130812Smarcel
747130812Smarcel
748130812Smarcel
749130812Smarcel#define a_byte 1
750130812Smarcel#define a_word 2
751130812Smarcel#define a_string 3
752130812Smarcel
753130812Smarcel
754130812Smarceltypedef struct
755130812Smarcel{
756130812Smarcel  CORE_ADDR n;
757130812Smarcel  const char *s;
758130812Smarcel}
759130812Smarcelargsin;
760130812Smarcel
761130812Smarcel#define ABYTE 1
762130812Smarcel#define AWORD 2
763130812Smarcel#define ASTRING 3
764130812Smarcel#define ADDRLEN 4
765130812Smarcel
766130812Smarcel#define SWI_WriteC                      0x0
767130812Smarcel#define SWI_Write0                      0x2
768130812Smarcel#define SWI_ReadC                       0x4
769130812Smarcel#define SWI_CLI                         0x5
770130812Smarcel#define SWI_GetEnv                      0x10
771130812Smarcel#define SWI_Exit                        0x11
772130812Smarcel#define SWI_EnterOS                     0x16
773130812Smarcel
774130812Smarcel#define SWI_GetErrno                    0x60
775130812Smarcel#define SWI_Clock                       0x61
776130812Smarcel
777130812Smarcel#define SWI_Time                        0x63
778130812Smarcel#define SWI_Remove                      0x64
779130812Smarcel#define SWI_Rename                      0x65
780130812Smarcel#define SWI_Open                        0x66
781130812Smarcel
782130812Smarcel#define SWI_Close                       0x68
783130812Smarcel#define SWI_Write                       0x69
784130812Smarcel#define SWI_Read                        0x6a
785130812Smarcel#define SWI_Seek                        0x6b
786130812Smarcel#define SWI_Flen                        0x6c
787130812Smarcel
788130812Smarcel#define SWI_IsTTY                       0x6e
789130812Smarcel#define SWI_TmpNam                      0x6f
790130812Smarcel#define SWI_InstallHandler              0x70
791130812Smarcel#define SWI_GenerateError               0x71
792130812Smarcel
793130812Smarcel
794130812Smarcel#ifndef O_BINARY
795130812Smarcel#define O_BINARY 0
796130812Smarcel#endif
797130812Smarcel
798130812Smarcelstatic int translate_open_mode[] =
799130812Smarcel{
800130812Smarcel  O_RDONLY,			/* "r"   */
801130812Smarcel  O_RDONLY + O_BINARY,		/* "rb"  */
802130812Smarcel  O_RDWR,			/* "r+"  */
803130812Smarcel  O_RDWR + O_BINARY,		/* "r+b" */
804130812Smarcel  O_WRONLY + O_CREAT + O_TRUNC,	/* "w"   */
805130812Smarcel  O_WRONLY + O_BINARY + O_CREAT + O_TRUNC,	/* "wb"  */
806130812Smarcel  O_RDWR + O_CREAT + O_TRUNC,	/* "w+"  */
807130812Smarcel  O_RDWR + O_BINARY + O_CREAT + O_TRUNC,	/* "w+b" */
808130812Smarcel  O_WRONLY + O_APPEND + O_CREAT,	/* "a"   */
809130812Smarcel  O_WRONLY + O_BINARY + O_APPEND + O_CREAT,	/* "ab"  */
810130812Smarcel  O_RDWR + O_APPEND + O_CREAT,	/* "a+"  */
811130812Smarcel  O_RDWR + O_BINARY + O_APPEND + O_CREAT	/* "a+b" */
812130812Smarcel};
813130812Smarcel
814130812Smarcelstatic int
815130812Smarcelexec_swi (int swi, argsin *args)
816130812Smarcel{
817130812Smarcel  int i;
818130812Smarcel  char c;
819130812Smarcel  switch (swi)
820130812Smarcel    {
821130812Smarcel    case SWI_WriteC:
822130812Smarcel      callback->write_stdout (callback, &c, 1);
823130812Smarcel      return 0;
824130812Smarcel    case SWI_Write0:
825130812Smarcel      for (i = 0; i < args->n; i++)
826130812Smarcel	callback->write_stdout (callback, args->s, strlen (args->s));
827130812Smarcel      return 0;
828130812Smarcel    case SWI_ReadC:
829130812Smarcel      callback->read_stdin (callback, &c, 1);
830130812Smarcel      args->n = c;
831130812Smarcel      return 1;
832130812Smarcel    case SWI_CLI:
833130812Smarcel      args->n = callback->system (callback, args->s);
834130812Smarcel      return 1;
835130812Smarcel    case SWI_GetErrno:
836130812Smarcel      args->n = callback->get_errno (callback);
837130812Smarcel      return 1;
838130812Smarcel    case SWI_Time:
839130812Smarcel      args->n = callback->time (callback, NULL);
840130812Smarcel      return 1;
841130812Smarcel
842130812Smarcel    case SWI_Clock:
843130812Smarcel      /* return number of centi-seconds... */
844130812Smarcel      args->n =
845130812Smarcel#ifdef CLOCKS_PER_SEC
846130812Smarcel	(CLOCKS_PER_SEC >= 100)
847130812Smarcel	? (clock () / (CLOCKS_PER_SEC / 100))
848130812Smarcel	: ((clock () * 100) / CLOCKS_PER_SEC);
849130812Smarcel#else
850130812Smarcel      /* presume unix... clock() returns microseconds */
851130812Smarcel	clock () / 10000;
852130812Smarcel#endif
853130812Smarcel      return 1;
854130812Smarcel
855130812Smarcel    case SWI_Remove:
856130812Smarcel      args->n = callback->unlink (callback, args->s);
857130812Smarcel      return 1;
858130812Smarcel    case SWI_Rename:
859130812Smarcel      args->n = callback->rename (callback, args[0].s, args[1].s);
860130812Smarcel      return 1;
861130812Smarcel
862130812Smarcel    case SWI_Open:
863130812Smarcel      /* Now we need to decode the Demon open mode */
864130812Smarcel      i = translate_open_mode[args[1].n];
865130812Smarcel
866130812Smarcel      /* Filename ":tt" is special: it denotes stdin/out */
867130812Smarcel      if (strcmp (args->s, ":tt") == 0)
868130812Smarcel	{
869130812Smarcel	  if (i == O_RDONLY)	/* opening tty "r" */
870130812Smarcel	    args->n = 0 /* stdin */ ;
871130812Smarcel	  else
872130812Smarcel	    args->n = 1 /* stdout */ ;
873130812Smarcel	}
874130812Smarcel      else
875130812Smarcel	args->n = callback->open (callback, args->s, i);
876130812Smarcel      return 1;
877130812Smarcel
878130812Smarcel    case SWI_Close:
879130812Smarcel      args->n = callback->close (callback, args->n);
880130812Smarcel      return 1;
881130812Smarcel
882130812Smarcel    case SWI_Write:
883130812Smarcel      /* Return the number of bytes *not* written */
884130812Smarcel      args->n = args[1].n -
885130812Smarcel	callback->write (callback, args[0].n, args[1].s, args[1].n);
886130812Smarcel      return 1;
887130812Smarcel
888130812Smarcel    case SWI_Read:
889130812Smarcel      {
890130812Smarcel	char *copy = alloca (args[2].n);
891130812Smarcel	int done = callback->read (callback, args[0].n, copy, args[2].n);
892130812Smarcel	if (done > 0)
893130812Smarcel	  remote_rdp_xfer_inferior_memory (args[1].n, copy, done, 1, 0, 0);
894130812Smarcel	args->n = args[2].n - done;
895130812Smarcel	return 1;
896130812Smarcel      }
897130812Smarcel
898130812Smarcel    case SWI_Seek:
899130812Smarcel      /* Return non-zero on failure */
900130812Smarcel      args->n = callback->lseek (callback, args[0].n, args[1].n, 0) < 0;
901130812Smarcel      return 1;
902130812Smarcel
903130812Smarcel    case SWI_Flen:
904130812Smarcel      {
905130812Smarcel	long old = callback->lseek (callback, args->n, 0, SEEK_CUR);
906130812Smarcel	args->n = callback->lseek (callback, args->n, 0, SEEK_END);
907130812Smarcel	callback->lseek (callback, args->n, old, 0);
908130812Smarcel	return 1;
909130812Smarcel      }
910130812Smarcel
911130812Smarcel    case SWI_IsTTY:
912130812Smarcel      args->n = callback->isatty (callback, args->n);
913130812Smarcel      return 1;
914130812Smarcel
915130812Smarcel    case SWI_GetEnv:
916130812Smarcel      if (commandline != NULL)
917130812Smarcel	{
918130812Smarcel	  int len = strlen (commandline);
919130812Smarcel	  if (len > 255)
920130812Smarcel	    {
921130812Smarcel	      len = 255;
922130812Smarcel	      commandline[255] = '\0';
923130812Smarcel	    }
924130812Smarcel	  remote_rdp_xfer_inferior_memory (args[0].n,
925130812Smarcel					   commandline, len + 1, 1, 0, 0);
926130812Smarcel	}
927130812Smarcel      else
928130812Smarcel	remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0, 0);
929130812Smarcel      return 1;
930130812Smarcel
931130812Smarcel    default:
932130812Smarcel      return 0;
933130812Smarcel    }
934130812Smarcel}
935130812Smarcel
936130812Smarcel
937130812Smarcelstatic void
938130812Smarcelhandle_swi (void)
939130812Smarcel{
940130812Smarcel  argsin args[3];
941130812Smarcel  char *buf;
942130812Smarcel  int len;
943130812Smarcel  int count = 0;
944130812Smarcel
945130812Smarcel  int swino = get_word ();
946130812Smarcel  int type = get_byte ();
947130812Smarcel  while (type != 0)
948130812Smarcel    {
949130812Smarcel      switch (type & 0x3)
950130812Smarcel	{
951130812Smarcel	case ABYTE:
952130812Smarcel	  args[count].n = get_byte ();
953130812Smarcel	  break;
954130812Smarcel
955130812Smarcel	case AWORD:
956130812Smarcel	  args[count].n = get_word ();
957130812Smarcel	  break;
958130812Smarcel
959130812Smarcel	case ASTRING:
960130812Smarcel	  /* If the word is under 32 bytes it will be sent otherwise
961130812Smarcel	     an address to it is passed. Also: Special case of 255 */
962130812Smarcel
963130812Smarcel	  len = get_byte ();
964130812Smarcel	  if (len > 32)
965130812Smarcel	    {
966130812Smarcel	      if (len == 255)
967130812Smarcel		{
968130812Smarcel		  len = get_word ();
969130812Smarcel		}
970130812Smarcel	      buf = alloca (len);
971130812Smarcel	      remote_rdp_xfer_inferior_memory (get_word (),
972130812Smarcel					       buf,
973130812Smarcel					       len,
974130812Smarcel					       0,
975130812Smarcel					       0,
976130812Smarcel					       0);
977130812Smarcel	    }
978130812Smarcel	  else
979130812Smarcel	    {
980130812Smarcel	      int i;
981130812Smarcel	      buf = alloca (len + 1);
982130812Smarcel	      for (i = 0; i < len; i++)
983130812Smarcel		buf[i] = get_byte ();
984130812Smarcel	      buf[i] = 0;
985130812Smarcel	    }
986130812Smarcel	  args[count].n = len;
987130812Smarcel	  args[count].s = buf;
988130812Smarcel	  break;
989130812Smarcel
990130812Smarcel	default:
991130812Smarcel	  error ("Unimplemented SWI argument");
992130812Smarcel	}
993130812Smarcel
994130812Smarcel      type = type >> 2;
995130812Smarcel      count++;
996130812Smarcel    }
997130812Smarcel
998130812Smarcel  if (exec_swi (swino, args))
999130812Smarcel    {
1000130812Smarcel      /* We have two options here reply with either a byte or a word
1001130812Smarcel         which is stored in args[0].n. There is no harm in replying with
1002130812Smarcel         a word all the time, so thats what I do! */
1003130812Smarcel      send_rdp ("bbw-", RDP_OSOpReply, RDP_OSOpWord, args[0].n);
1004130812Smarcel    }
1005130812Smarcel  else
1006130812Smarcel    {
1007130812Smarcel      send_rdp ("bb-", RDP_OSOpReply, RDP_OSOpNothing);
1008130812Smarcel    }
1009130812Smarcel}
1010130812Smarcel
1011130812Smarcelstatic void
1012130812Smarcelrdp_execute_finish (void)
1013130812Smarcel{
1014130812Smarcel  int running = 1;
1015130812Smarcel
1016130812Smarcel  while (running)
1017130812Smarcel    {
1018130812Smarcel      int res;
1019130812Smarcel      res = serial_readchar (io, 1);
1020130812Smarcel      while (res == SERIAL_TIMEOUT)
1021130812Smarcel	{
1022130812Smarcel	  QUIT;
1023130812Smarcel	  printf_filtered ("Waiting for target..\n");
1024130812Smarcel	  res = serial_readchar (io, 1);
1025130812Smarcel	}
1026130812Smarcel
1027130812Smarcel      switch (res)
1028130812Smarcel	{
1029130812Smarcel	case RDP_RES_SWI:
1030130812Smarcel	  handle_swi ();
1031130812Smarcel	  break;
1032130812Smarcel	case RDP_RES_VALUE:
1033130812Smarcel	  send_rdp ("B", &ds.rdi_stopped_status);
1034130812Smarcel	  running = 0;
1035130812Smarcel	  break;
1036130812Smarcel	case RDP_RESET:
1037130812Smarcel	  printf_filtered ("Target reset\n");
1038130812Smarcel	  running = 0;
1039130812Smarcel	  break;
1040130812Smarcel	default:
1041130812Smarcel	  printf_filtered ("Ignoring %x\n", res);
1042130812Smarcel	  break;
1043130812Smarcel	}
1044130812Smarcel    }
1045130812Smarcel}
1046130812Smarcel
1047130812Smarcel
1048130812Smarcelstatic void
1049130812Smarcelrdp_execute (void)
1050130812Smarcel{
1051130812Smarcel  rdp_execute_start ();
1052130812Smarcel  rdp_execute_finish ();
1053130812Smarcel}
1054130812Smarcel
1055130812Smarcelstatic int
1056130812Smarcelremote_rdp_insert_breakpoint (CORE_ADDR addr, char *save)
1057130812Smarcel{
1058130812Smarcel  int res;
1059130812Smarcel  if (ds.rdi_level > 0)
1060130812Smarcel    {
1061130812Smarcel      send_rdp ("bwb-SWB",
1062130812Smarcel		RDP_SET_BREAK,
1063130812Smarcel		addr,
1064130812Smarcel		RDP_SET_BREAK_TYPE_PC_EQUAL | RDP_SET_BREAK_TYPE_GET_HANDLE,
1065130812Smarcel		save,
1066130812Smarcel		&res);
1067130812Smarcel    }
1068130812Smarcel  else
1069130812Smarcel    {
1070130812Smarcel      send_rdp ("bwb-SB",
1071130812Smarcel		RDP_SET_BREAK,
1072130812Smarcel		addr,
1073130812Smarcel		RDP_SET_BREAK_TYPE_PC_EQUAL,
1074130812Smarcel		&res);
1075130812Smarcel    }
1076130812Smarcel  return res;
1077130812Smarcel}
1078130812Smarcel
1079130812Smarcelstatic int
1080130812Smarcelremote_rdp_remove_breakpoint (CORE_ADDR addr, char *save)
1081130812Smarcel{
1082130812Smarcel  int res;
1083130812Smarcel  if (ds.rdi_level > 0)
1084130812Smarcel    {
1085130812Smarcel      send_rdp ("b-p-S-B",
1086130812Smarcel		RDP_CLEAR_BREAK,
1087130812Smarcel		save, 4,
1088130812Smarcel		&res);
1089130812Smarcel    }
1090130812Smarcel  else
1091130812Smarcel    {
1092130812Smarcel      send_rdp ("bw-S-B",
1093130812Smarcel		RDP_CLEAR_BREAK,
1094130812Smarcel		addr,
1095130812Smarcel		&res);
1096130812Smarcel    }
1097130812Smarcel  return res;
1098130812Smarcel}
1099130812Smarcel
1100130812Smarcelstatic void
1101130812Smarcelrdp_step (void)
1102130812Smarcel{
1103130812Smarcel  if (ds.can_step && 0)
1104130812Smarcel    {
1105130812Smarcel      /* The pie board can't do steps so I can't test this, and
1106130812Smarcel         the other code will always work. */
1107130812Smarcel      int status;
1108130812Smarcel      send_rdp ("bbw-S-B",
1109130812Smarcel		RDP_STEP, 0, 1,
1110130812Smarcel		&status);
1111130812Smarcel    }
1112130812Smarcel  else
1113130812Smarcel    {
1114130812Smarcel      char handle[4];
1115130812Smarcel      CORE_ADDR pc = read_register (ARM_PC_REGNUM);
1116130812Smarcel      pc = arm_get_next_pc (pc);
1117130812Smarcel      remote_rdp_insert_breakpoint (pc, handle);
1118130812Smarcel      rdp_execute ();
1119130812Smarcel      remote_rdp_remove_breakpoint (pc, handle);
1120130812Smarcel    }
1121130812Smarcel}
1122130812Smarcel
1123130812Smarcelstatic void
1124130812Smarcelremote_rdp_open (char *args, int from_tty)
1125130812Smarcel{
1126130812Smarcel  int not_icebreaker;
1127130812Smarcel
1128130812Smarcel  if (!args)
1129130812Smarcel    error_no_arg ("serial port device name");
1130130812Smarcel
1131130812Smarcel  baud_rate = 9600;
1132130812Smarcel
1133130812Smarcel  target_preopen (from_tty);
1134130812Smarcel
1135130812Smarcel  io = serial_open (args);
1136130812Smarcel
1137130812Smarcel  if (!io)
1138130812Smarcel    perror_with_name (args);
1139130812Smarcel
1140130812Smarcel  serial_raw (io);
1141130812Smarcel
1142130812Smarcel  rdp_init (1, from_tty);
1143130812Smarcel
1144130812Smarcel
1145130812Smarcel  if (from_tty)
1146130812Smarcel    {
1147130812Smarcel      printf_unfiltered ("Remote RDP debugging using %s at %d baud\n", args, baud_rate);
1148130812Smarcel    }
1149130812Smarcel
1150130812Smarcel  rdp_info ();
1151130812Smarcel
1152130812Smarcel  /* Need to set up the vector interception state */
1153130812Smarcel  rdp_catch_vectors ();
1154130812Smarcel
1155130812Smarcel  /*
1156130812Smarcel     ** If it's an EmbeddedICE, we need to set the processor config.
1157130812Smarcel     ** Assume we can always have ARM7TDI...
1158130812Smarcel   */
1159130812Smarcel  send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, &not_icebreaker);
1160130812Smarcel  if (!not_icebreaker)
1161130812Smarcel    {
1162130812Smarcel      const char *CPU = "ARM7TDI";
1163130812Smarcel      int ICEversion;
1164130812Smarcel      int len = strlen (CPU);
1165130812Smarcel
1166130812Smarcel      send_rdp ("bbbbw-p-SWZ",
1167130812Smarcel		RDP_SELECT_CONFIG,
1168130812Smarcel		RDI_ConfigCPU,	/* Aspect: set the CPU */
1169130812Smarcel		len,		/* The number of bytes in the name */
1170130812Smarcel		RDI_MatchAny,	/* We'll take whatever we get */
1171130812Smarcel		0,		/* We'll take whatever version's there */
1172130812Smarcel		CPU, len,
1173130812Smarcel		&ICEversion);
1174130812Smarcel    }
1175130812Smarcel
1176130812Smarcel  /* command line initialised on 'run' */
1177130812Smarcel
1178130812Smarcel  push_target (&remote_rdp_ops);
1179130812Smarcel
1180130812Smarcel  callback->init (callback);
1181130812Smarcel  flush_cached_frames ();
1182130812Smarcel  registers_changed ();
1183130812Smarcel  stop_pc = read_pc ();
1184130812Smarcel  print_stack_frame (get_selected_frame (), -1, 1);
1185130812Smarcel}
1186130812Smarcel
1187130812Smarcel
1188130812Smarcel
1189130812Smarcel/* Close out all files and local state before this target loses control. */
1190130812Smarcel
1191130812Smarcelstatic void
1192130812Smarcelremote_rdp_close (int quitting)
1193130812Smarcel{
1194130812Smarcel  callback->shutdown (callback);
1195130812Smarcel  if (io)
1196130812Smarcel    serial_close (io);
1197130812Smarcel  io = 0;
1198130812Smarcel}
1199130812Smarcel
1200130812Smarcel
1201130812Smarcel/* Resume execution of the target process.  STEP says whether to single-step
1202130812Smarcel   or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
1203130812Smarcel   to the target, or zero for no signal.  */
1204130812Smarcel
1205130812Smarcelstatic void
1206130812Smarcelremote_rdp_resume (ptid_t ptid, int step, enum target_signal siggnal)
1207130812Smarcel{
1208130812Smarcel  if (step)
1209130812Smarcel    rdp_step ();
1210130812Smarcel  else
1211130812Smarcel    rdp_execute ();
1212130812Smarcel}
1213130812Smarcel
1214130812Smarcel/* Wait for inferior process to do something.  Return pid of child,
1215130812Smarcel   or -1 in case of error; store status through argument pointer STATUS,
1216130812Smarcel   just as `wait' would.  */
1217130812Smarcel
1218130812Smarcelstatic ptid_t
1219130812Smarcelremote_rdp_wait (ptid_t ptid, struct target_waitstatus *status)
1220130812Smarcel{
1221130812Smarcel  switch (ds.rdi_stopped_status)
1222130812Smarcel    {
1223130812Smarcel    default:
1224130812Smarcel    case RDP_RES_RESET:
1225130812Smarcel    case RDP_RES_SWI:
1226130812Smarcel      status->kind = TARGET_WAITKIND_EXITED;
1227130812Smarcel      status->value.integer = read_register (0);
1228130812Smarcel      break;
1229130812Smarcel    case RDP_RES_AT_BREAKPOINT:
1230130812Smarcel      status->kind = TARGET_WAITKIND_STOPPED;
1231130812Smarcel      /* The signal in sigrc is a host signal.  That probably
1232130812Smarcel         should be fixed.  */
1233130812Smarcel      status->value.sig = TARGET_SIGNAL_TRAP;
1234130812Smarcel      break;
1235130812Smarcel#if 0
1236130812Smarcel    case rdp_signalled:
1237130812Smarcel      status->kind = TARGET_WAITKIND_SIGNALLED;
1238130812Smarcel      /* The signal in sigrc is a host signal.  That probably
1239130812Smarcel         should be fixed.  */
1240130812Smarcel      status->value.sig = target_signal_from_host (sigrc);
1241130812Smarcel      break;
1242130812Smarcel#endif
1243130812Smarcel    }
1244130812Smarcel
1245130812Smarcel  return inferior_ptid;
1246130812Smarcel}
1247130812Smarcel
1248130812Smarcel/* Get ready to modify the registers array.  On machines which store
1249130812Smarcel   individual registers, this doesn't need to do anything.  On machines
1250130812Smarcel   which store all the registers in one fell swoop, this makes sure
1251130812Smarcel   that registers contains all the registers from the program being
1252130812Smarcel   debugged.  */
1253130812Smarcel
1254130812Smarcelstatic void
1255130812Smarcelremote_rdp_prepare_to_store (void)
1256130812Smarcel{
1257130812Smarcel  /* Do nothing, since we can store individual regs */
1258130812Smarcel}
1259130812Smarcel
1260130812Smarcel/* Transfer LEN bytes between GDB address MYADDR and target address
1261130812Smarcel   MEMADDR.  If WRITE is non-zero, transfer them to the target,
1262130812Smarcel   otherwise transfer them from the target.  TARGET is unused.
1263130812Smarcel
1264130812Smarcel   Returns the number of bytes transferred. */
1265130812Smarcel
1266130812Smarcelstatic int
1267130812Smarcelremote_rdp_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
1268130812Smarcel				 int write, struct mem_attrib *attrib,
1269130812Smarcel				 struct target_ops *target)
1270130812Smarcel{
1271130812Smarcel  /* I infer from D Taylor's code that there's a limit on the amount
1272130812Smarcel     we can transfer in one chunk.. */
1273130812Smarcel  int done = 0;
1274130812Smarcel  while (done < len)
1275130812Smarcel    {
1276130812Smarcel      int justdone;
1277130812Smarcel      int thisbite = len - done;
1278130812Smarcel      if (thisbite > RDP_MOUTHFULL)
1279130812Smarcel	thisbite = RDP_MOUTHFULL;
1280130812Smarcel
1281130812Smarcel      QUIT;
1282130812Smarcel
1283130812Smarcel      if (write)
1284130812Smarcel	{
1285130812Smarcel	  justdone = rdp_write (memaddr + done, myaddr + done, thisbite);
1286130812Smarcel	}
1287130812Smarcel      else
1288130812Smarcel	{
1289130812Smarcel	  justdone = rdp_read (memaddr + done, myaddr + done, thisbite);
1290130812Smarcel	}
1291130812Smarcel
1292130812Smarcel      done += justdone;
1293130812Smarcel
1294130812Smarcel      if (justdone != thisbite)
1295130812Smarcel	break;
1296130812Smarcel    }
1297130812Smarcel  return done;
1298130812Smarcel}
1299130812Smarcel
1300130812Smarcel
1301130812Smarcel
1302130812Smarcelstruct yn
1303130812Smarcel{
1304130812Smarcel  const char *name;
1305130812Smarcel  int bit;
1306130812Smarcel};
1307130812Smarcelstatic struct yn stepinfo[] =
1308130812Smarcel{
1309130812Smarcel  {"Step more than one instruction", RDP_INFO_ABOUT_STEP_GT_1},
1310130812Smarcel  {"Step to jump", RDP_INFO_ABOUT_STEP_TO_JMP},
1311130812Smarcel  {"Step one instruction", RDP_INFO_ABOUT_STEP_1},
1312130812Smarcel  {0}
1313130812Smarcel};
1314130812Smarcel
1315130812Smarcelstatic struct yn breakinfo[] =
1316130812Smarcel{
1317130812Smarcel  {"comparison breakpoints supported", RDP_INFO_ABOUT_BREAK_COMP},
1318130812Smarcel  {"range breakpoints supported", RDP_INFO_ABOUT_BREAK_RANGE},
1319130812Smarcel  {"watchpoints for byte reads supported", RDP_INFO_ABOUT_BREAK_BYTE_READ},
1320130812Smarcel  {"watchpoints for half-word reads supported", RDP_INFO_ABOUT_BREAK_HALFWORD_READ},
1321130812Smarcel  {"watchpoints for word reads supported", RDP_INFO_ABOUT_BREAK_WORD_READ},
1322130812Smarcel  {"watchpoints for byte writes supported", RDP_INFO_ABOUT_BREAK_BYTE_WRITE},
1323130812Smarcel  {"watchpoints for half-word writes supported", RDP_INFO_ABOUT_BREAK_HALFWORD_WRITE},
1324130812Smarcel  {"watchpoints for word writes supported", RDP_INFO_ABOUT_BREAK_WORD_WRITE},
1325130812Smarcel  {"mask break/watch-points supported", RDP_INFO_ABOUT_BREAK_MASK},
1326130812Smarcel{"thread-specific breakpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_BREAK},
1327130812Smarcel{"thread-specific watchpoints supported", RDP_INFO_ABOUT_BREAK_THREAD_WATCH},
1328130812Smarcel  {"conditional breakpoints supported", RDP_INFO_ABOUT_BREAK_COND},
1329130812Smarcel  {0}
1330130812Smarcel};
1331130812Smarcel
1332130812Smarcel
1333130812Smarcelstatic void
1334130812Smarceldump_bits (struct yn *t, int info)
1335130812Smarcel{
1336130812Smarcel  while (t->name)
1337130812Smarcel    {
1338130812Smarcel      printf_unfiltered ("  %-45s : %s\n", t->name, (info & t->bit) ? "Yes" : "No");
1339130812Smarcel      t++;
1340130812Smarcel    }
1341130812Smarcel}
1342130812Smarcel
1343130812Smarcelstatic void
1344130812Smarcelremote_rdp_files_info (struct target_ops *target)
1345130812Smarcel{
1346130812Smarcel  printf_filtered ("Target capabilities:\n");
1347130812Smarcel  dump_bits (stepinfo, ds.step_info);
1348130812Smarcel  dump_bits (breakinfo, ds.break_info);
1349130812Smarcel  printf_unfiltered ("target level RDI %x\n", (ds.target_info >> 5) & 3);
1350130812Smarcel}
1351130812Smarcel
1352130812Smarcel
1353130812Smarcelstatic void
1354130812Smarcelremote_rdp_create_inferior (char *exec_file, char *allargs, char **env)
1355130812Smarcel{
1356130812Smarcel  CORE_ADDR entry_point;
1357130812Smarcel
1358130812Smarcel  if (exec_file == 0 || exec_bfd == 0)
1359130812Smarcel    error ("No executable file specified.");
1360130812Smarcel
1361130812Smarcel  entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
1362130812Smarcel
1363130812Smarcel  remote_rdp_kill ();
1364130812Smarcel  remove_breakpoints ();
1365130812Smarcel  init_wait_for_inferior ();
1366130812Smarcel
1367130812Smarcel  /* This gives us a chance to set up the command line */
1368130812Smarcel  rdp_set_command_line (exec_file, allargs);
1369130812Smarcel
1370130812Smarcel  inferior_ptid = pid_to_ptid (42);
1371130812Smarcel  insert_breakpoints ();	/* Needed to get correct instruction in cache */
1372130812Smarcel
1373130812Smarcel  /*
1374130812Smarcel     ** RDP targets don't provide any facility to set the top of memory,
1375130812Smarcel     ** so we don't bother to look for MEMSIZE in the environment.
1376130812Smarcel   */
1377130812Smarcel
1378130812Smarcel  /* Let's go! */
1379130812Smarcel  proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
1380130812Smarcel}
1381130812Smarcel
1382130812Smarcel/* Attach doesn't need to do anything */
1383130812Smarcelstatic void
1384130812Smarcelremote_rdp_attach (char *args, int from_tty)
1385130812Smarcel{
1386130812Smarcel  return;
1387130812Smarcel}
1388130812Smarcel
1389130812Smarcel/* Define the target subroutine names */
1390130812Smarcel
1391130812Smarcelstruct target_ops remote_rdp_ops;
1392130812Smarcel
1393130812Smarcelstatic void
1394130812Smarcelinit_remote_rdp_ops (void)
1395130812Smarcel{
1396130812Smarcel  remote_rdp_ops.to_shortname = "rdp";
1397130812Smarcel  remote_rdp_ops.to_longname = "Remote Target using the RDProtocol";
1398130812Smarcel  remote_rdp_ops.to_doc = "Use a remote ARM system which uses the ARM Remote Debugging Protocol";
1399130812Smarcel  remote_rdp_ops.to_open = remote_rdp_open;
1400130812Smarcel  remote_rdp_ops.to_close = remote_rdp_close;
1401130812Smarcel  remote_rdp_ops.to_attach = remote_rdp_attach;
1402130812Smarcel  remote_rdp_ops.to_resume = remote_rdp_resume;
1403130812Smarcel  remote_rdp_ops.to_wait = remote_rdp_wait;
1404130812Smarcel  remote_rdp_ops.to_fetch_registers = remote_rdp_fetch_register;
1405130812Smarcel  remote_rdp_ops.to_store_registers = remote_rdp_store_register;
1406130812Smarcel  remote_rdp_ops.to_prepare_to_store = remote_rdp_prepare_to_store;
1407130812Smarcel  remote_rdp_ops.to_xfer_memory = remote_rdp_xfer_inferior_memory;
1408130812Smarcel  remote_rdp_ops.to_files_info = remote_rdp_files_info;
1409130812Smarcel  remote_rdp_ops.to_insert_breakpoint = remote_rdp_insert_breakpoint;
1410130812Smarcel  remote_rdp_ops.to_remove_breakpoint = remote_rdp_remove_breakpoint;
1411130812Smarcel  remote_rdp_ops.to_kill = remote_rdp_kill;
1412130812Smarcel  remote_rdp_ops.to_load = generic_load;
1413130812Smarcel  remote_rdp_ops.to_create_inferior = remote_rdp_create_inferior;
1414130812Smarcel  remote_rdp_ops.to_mourn_inferior = generic_mourn_inferior;
1415130812Smarcel  remote_rdp_ops.to_stratum = process_stratum;
1416130812Smarcel  remote_rdp_ops.to_has_all_memory = 1;
1417130812Smarcel  remote_rdp_ops.to_has_memory = 1;
1418130812Smarcel  remote_rdp_ops.to_has_stack = 1;
1419130812Smarcel  remote_rdp_ops.to_has_registers = 1;
1420130812Smarcel  remote_rdp_ops.to_has_execution = 1;
1421130812Smarcel  remote_rdp_ops.to_magic = OPS_MAGIC;
1422130812Smarcel}
1423130812Smarcel
1424130812Smarcelextern initialize_file_ftype _initialize_remote_rdp; /* -Wmissing-prototypes */
1425130812Smarcel
1426130812Smarcelvoid
1427130812Smarcel_initialize_remote_rdp (void)
1428130812Smarcel{
1429130812Smarcel  init_remote_rdp_ops ();
1430130812Smarcel  add_target (&remote_rdp_ops);
1431130812Smarcel}
1432