1/* GDB interface to ARM RDI library.
2
3   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software
4   Foundation, Inc.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330,
21   Boston, MA 02111-1307, USA.  */
22
23#include "defs.h"
24#include "gdb_string.h"
25#include <fcntl.h>
26#include "frame.h"
27#include "inferior.h"
28#include "bfd.h"
29#include "symfile.h"
30#include "target.h"
31#include "gdbcmd.h"
32#include "objfiles.h"
33#include "gdb-stabs.h"
34#include "gdbthread.h"
35#include "gdbcore.h"
36#include "breakpoint.h"
37#include "completer.h"
38#include "regcache.h"
39#include "arm-tdep.h"
40
41#ifdef USG
42#include <sys/types.h>
43#endif
44
45#include <signal.h>
46
47#include "rdi-share/ardi.h"
48#include "rdi-share/adp.h"
49#include "rdi-share/hsys.h"
50
51extern int isascii (int);
52
53/* Prototypes for local functions */
54
55static void arm_rdi_files_info (struct target_ops *ignore);
56
57static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
58				int len, int should_write,
59				struct mem_attrib *attrib,
60				struct target_ops *target);
61
62static void arm_rdi_prepare_to_store (void);
63
64static void arm_rdi_fetch_registers (int regno);
65
66static void arm_rdi_resume (ptid_t pid, int step,
67                            enum target_signal siggnal);
68
69static void arm_rdi_open (char *name, int from_tty);
70
71static void arm_rdi_create_inferior (char *exec_file, char *args, char **env);
72
73static void arm_rdi_close (int quitting);
74
75static void arm_rdi_store_registers (int regno);
76
77static ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status);
78
79static void arm_rdi_kill (void);
80
81static void arm_rdi_detach (char *args, int from_tty);
82
83static int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
84
85static int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
86
87static char *rdi_error_message (int err);
88
89static enum target_signal rdi_error_signal (int err);
90
91/* Global variables.  */
92
93struct target_ops arm_rdi_ops;
94
95static struct Dbg_ConfigBlock gdb_config;
96
97static struct Dbg_HostosInterface gdb_hostif;
98
99static int max_load_size;
100
101static int execute_status;
102
103/* Send heatbeat packets? */
104static int rdi_heartbeat = 0;
105
106/* Target has ROM at address 0. */
107static int rom_at_zero = 0;
108
109/* Enable logging? */
110static int log_enable = 0;
111
112/* Name of the log file. Default is "rdi.log". */
113static char *log_filename;
114
115/* A little list of breakpoints that have been set.  */
116
117static struct local_bp_list_entry
118  {
119    CORE_ADDR addr;
120    PointHandle point;
121    struct local_bp_list_entry *next;
122  }
123 *local_bp_list;
124
125/* Helper callbacks for the "host interface" structure.  RDI functions call
126   these to forward output from the target system and so forth.  */
127
128static void
129voiddummy (void *dummy)
130{
131  fprintf_unfiltered (gdb_stdout, "void dummy\n");
132}
133
134static void
135myprint (void *arg, const char *format, va_list ap)
136{
137  vfprintf_unfiltered (gdb_stdout, format, ap);
138}
139
140static void
141mywritec (void *arg, int c)
142{
143  if (isascii (c))
144    fputc_unfiltered (c, gdb_stdout);
145}
146
147static int
148mywrite (void *arg, char const *buffer, int len)
149{
150  int i;
151  char *e;
152
153  e = (char *) buffer;
154  for (i = 0; i < len; i++)
155    {
156      if (isascii ((int) *e))
157	{
158	  fputc_unfiltered ((int) *e, gdb_stdout);
159	  e++;
160	}
161    }
162
163  return len;
164}
165
166static void
167mypause (void *arg)
168{
169}
170
171/* These last two are tricky as we have to handle the special case of
172   being interrupted more carefully */
173
174static int
175myreadc (void *arg)
176{
177  return fgetc (stdin);
178}
179
180static char *
181mygets (void *arg, char *buffer, int len)
182{
183  return fgets (buffer, len, stdin);
184}
185
186/* Prevent multiple calls to angel_RDI_close().  */
187static int closed_already = 1;
188
189/* Open a connection to a remote debugger.  NAME is the filename used
190   for communication.  */
191
192static void
193arm_rdi_open (char *name, int from_tty)
194{
195  int rslt, i;
196  unsigned long arg1, arg2;
197  char *openArgs = NULL;
198  char *devName = NULL;
199  char *p;
200
201  if (name == NULL)
202    error ("To open an RDI connection, you need to specify what serial\n\
203device is attached to the remote system (e.g. /dev/ttya).");
204
205  /* split name after whitespace, pass tail as arg to open command */
206
207  devName = xstrdup (name);
208  p = strchr (devName, ' ');
209  if (p)
210    {
211      *p = '\0';
212      ++p;
213
214      while (*p == ' ')
215	++p;
216
217      openArgs = p;
218    }
219
220  /* Make the basic low-level connection.  */
221
222  arm_rdi_close (0);
223  rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
224
225  if (rslt != adp_ok)
226    error ("Could not open device \"%s\"", name);
227
228  gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0);
229  gdb_config.fpe = 1;
230  gdb_config.rditype = 2;
231  gdb_config.heartbeat_on = 1;
232  gdb_config.flags = 2;
233
234  gdb_hostif.dbgprint = myprint;
235  gdb_hostif.dbgpause = mypause;
236  gdb_hostif.dbgarg = NULL;
237  gdb_hostif.writec = mywritec;
238  gdb_hostif.readc = myreadc;
239  gdb_hostif.write = mywrite;
240  gdb_hostif.gets = mygets;
241  gdb_hostif.hostosarg = NULL;
242  gdb_hostif.reset = voiddummy;
243
244  rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
245  if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
246    ;				/* do nothing, this is the expected return */
247  else if (rslt != RDIError_NoError)
248    {
249      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
250      Adp_CloseDevice ();
251      error ("RDI_open failed\n");
252    }
253
254  rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
255  if (rslt != RDIError_NoError)
256    {
257      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
258    }
259  rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
260  if (rslt != RDIError_NoError)
261    {
262      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
263    }
264  rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
265  if (rslt != RDIError_NoError)
266    {
267      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
268    }
269  rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
270  if (rslt != RDIError_NoError)
271    {
272      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
273    }
274  rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
275  if (rslt != RDIError_NoError)
276    {
277      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
278    }
279
280  rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
281  if (rslt != RDIError_NoError)
282    {
283      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
284    }
285  max_load_size = arg1;
286
287  push_target (&arm_rdi_ops);
288
289  target_fetch_registers (-1);
290
291  rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
292  if (rslt != RDIError_NoError)
293    {
294      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
295    }
296
297  arg1 = rom_at_zero ? 0x0 : 0x13b;
298
299  rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
300  if (rslt != RDIError_NoError)
301    {
302      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
303    }
304
305  arg1 = (unsigned long) "";
306  rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
307  if (rslt != RDIError_NoError)
308    {
309      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
310    }
311
312  /* Clear out any existing records of breakpoints.  */
313  {
314    struct local_bp_list_entry *entry, *preventry = NULL;
315
316    for (entry = local_bp_list; entry != NULL; entry = entry->next)
317      {
318	if (preventry)
319	  xfree (preventry);
320      }
321  }
322
323  printf_filtered ("Connected to ARM RDI target.\n");
324  closed_already = 0;
325  inferior_ptid = pid_to_ptid (42);
326}
327
328/* Start an inferior process and set inferior_ptid to its pid.
329   EXEC_FILE is the file to run.
330   ARGS is a string containing the arguments to the program.
331   ENV is the environment vector to pass.  Errors reported with error().
332   On VxWorks and various standalone systems, we ignore exec_file.  */
333/* This is called not only when we first attach, but also when the
334   user types "run" after having attached.  */
335
336static void
337arm_rdi_create_inferior (char *exec_file, char *args, char **env)
338{
339  int len, rslt;
340  unsigned long arg1, arg2;
341  char *arg_buf;
342  CORE_ADDR entry_point;
343
344  if (exec_file == 0 || exec_bfd == 0)
345    error ("No executable file specified.");
346
347  entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
348
349  arm_rdi_kill ();
350  remove_breakpoints ();
351  init_wait_for_inferior ();
352
353  len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
354  arg_buf = (char *) alloca (len);
355  arg_buf[0] = '\0';
356  strcat (arg_buf, exec_file);
357  strcat (arg_buf, " ");
358  strcat (arg_buf, args);
359
360  inferior_ptid = pid_to_ptid (42);
361  insert_breakpoints ();	/* Needed to get correct instruction in cache */
362
363  if (env != NULL)
364    {
365      while (*env)
366	{
367	  if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
368	    {
369	      unsigned long top_of_memory;
370	      char *end_of_num;
371
372	      /* Set up memory limit */
373	      top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
374				       &end_of_num, 0);
375	      printf_filtered ("Setting top-of-memory to 0x%lx\n",
376			       top_of_memory);
377
378	      rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
379	      if (rslt != RDIError_NoError)
380		{
381		  printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
382		}
383	    }
384	  env++;
385	}
386    }
387
388  arg1 = (unsigned long) arg_buf;
389  rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
390  if (rslt != RDIError_NoError)
391    {
392      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
393    }
394
395  proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
396}
397
398/* This takes a program previously attached to and detaches it.  After
399   this is done, GDB can be used to debug some other program.  We
400   better not have left any breakpoints in the target program or it'll
401   die when it hits one.  */
402
403static void
404arm_rdi_detach (char *args, int from_tty)
405{
406  pop_target ();
407}
408
409/* Clean up connection to a remote debugger.  */
410
411static void
412arm_rdi_close (int quitting)
413{
414  int rslt;
415
416  if (!closed_already)
417    {
418      rslt = angel_RDI_close ();
419      if (rslt != RDIError_NoError)
420	{
421	  printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
422	}
423      closed_already = 1;
424      inferior_ptid = null_ptid;
425      Adp_CloseDevice ();
426      generic_mourn_inferior ();
427    }
428}
429
430/* Tell the remote machine to resume.  */
431
432static void
433arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal)
434{
435  int rslt;
436  PointHandle point;
437
438  if (0 /* turn on when hardware supports single-stepping */ )
439    {
440      rslt = angel_RDI_step (1, &point);
441      if (rslt != RDIError_NoError)
442	printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
443    }
444  else
445    {
446      char handle[4];
447      CORE_ADDR pc = 0;
448
449      if (step)
450	{
451	  pc = read_register (ARM_PC_REGNUM);
452	  pc = arm_get_next_pc (pc);
453	  arm_rdi_insert_breakpoint (pc, handle);
454	}
455
456      execute_status = rslt = angel_RDI_execute (&point);
457      if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached)
458	printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
459
460      if (step)
461	arm_rdi_remove_breakpoint (pc, handle);
462    }
463}
464
465/* Wait until the remote machine stops, then return, storing status in
466   STATUS just as `wait' would.  Returns "pid" (though it's not clear
467   what, if anything, that means in the case of this target).  */
468
469static ptid_t
470arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status)
471{
472  status->kind = (execute_status == RDIError_NoError ?
473		  TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
474
475  /* convert stopped code from target into right signal */
476  status->value.sig = rdi_error_signal (execute_status);
477
478  return inferior_ptid;
479}
480
481/* Read the remote registers into the block REGS.  */
482
483static void
484arm_rdi_fetch_registers (int regno)
485{
486  int rslt, rdi_regmask;
487  unsigned long rawreg, rawregs[32];
488  char cookedreg[4];
489
490  if (regno == -1)
491    {
492      rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
493      if (rslt != RDIError_NoError)
494	{
495	  printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
496	}
497
498      for (regno = 0; regno < 15; regno++)
499	{
500	  store_unsigned_integer (cookedreg, 4, rawregs[regno]);
501	  supply_register (regno, (char *) cookedreg);
502	}
503      store_unsigned_integer (cookedreg, 4, rawregs[15]);
504      supply_register (ARM_PS_REGNUM, (char *) cookedreg);
505      arm_rdi_fetch_registers (ARM_PC_REGNUM);
506    }
507  else
508    {
509      if (regno == ARM_PC_REGNUM)
510	rdi_regmask = RDIReg_PC;
511      else if (regno == ARM_PS_REGNUM)
512	rdi_regmask = RDIReg_CPSR;
513      else if (regno < 0 || regno > 15)
514	{
515	  rawreg = 0;
516	  supply_register (regno, (char *) &rawreg);
517	  return;
518	}
519      else
520	rdi_regmask = 1 << regno;
521
522      rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
523      if (rslt != RDIError_NoError)
524	{
525	  printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
526	}
527      store_unsigned_integer (cookedreg, 4, rawreg);
528      supply_register (regno, (char *) cookedreg);
529    }
530}
531
532static void
533arm_rdi_prepare_to_store (void)
534{
535  /* Nothing to do.  */
536}
537
538/* Store register REGNO, or all registers if REGNO == -1, from the contents
539   of REGISTERS.  FIXME: ignores errors.  */
540
541static void
542arm_rdi_store_registers (int regno)
543{
544  int rslt, rdi_regmask;
545
546  /* These need to be able to take 'floating point register' contents */
547  unsigned long rawreg[3], rawerreg[3];
548
549  if (regno == -1)
550    {
551      for (regno = 0; regno < NUM_REGS; regno++)
552	arm_rdi_store_registers (regno);
553    }
554  else
555    {
556      deprecated_read_register_gen (regno, (char *) rawreg);
557      /* RDI manipulates data in host byte order, so convert now. */
558      store_unsigned_integer (rawerreg, 4, rawreg[0]);
559
560      if (regno == ARM_PC_REGNUM)
561	rdi_regmask = RDIReg_PC;
562      else if (regno == ARM_PS_REGNUM)
563	rdi_regmask = RDIReg_CPSR;
564      else if (regno < 0 || regno > 15)
565	return;
566      else
567	rdi_regmask = 1 << regno;
568
569      rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
570      if (rslt != RDIError_NoError)
571	{
572	  printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
573	}
574    }
575}
576
577/* Read or write LEN bytes from inferior memory at MEMADDR,
578   transferring to or from debugger address MYADDR.  Write to inferior
579   if SHOULD_WRITE is nonzero.  Returns length of data written or
580   read; 0 for error.  TARGET is unused.  */
581
582static int
583arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
584		     int should_write, struct mem_attrib *attrib,
585		     struct target_ops *target)
586{
587  int rslt, i;
588
589  if (should_write)
590    {
591      rslt = angel_RDI_write (myaddr, memaddr, &len);
592      if (rslt != RDIError_NoError)
593	{
594	  printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
595	}
596    }
597  else
598    {
599      rslt = angel_RDI_read (memaddr, myaddr, &len);
600      if (rslt != RDIError_NoError)
601	{
602	  printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
603	  len = 0;
604	}
605    }
606  return len;
607}
608
609/* Display random info collected from the target.  */
610
611static void
612arm_rdi_files_info (struct target_ops *ignore)
613{
614  char *file = "nothing";
615  int rslt;
616  unsigned long arg1, arg2;
617
618  rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
619  if (rslt != RDIError_NoError)
620    {
621      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
622    }
623  if (arg1 & (1 << 15))
624    printf_filtered ("Target supports Thumb code.\n");
625  if (arg1 & (1 << 14))
626    printf_filtered ("Target can do profiling.\n");
627  if (arg1 & (1 << 4))
628    printf_filtered ("Target is real hardware.\n");
629
630  rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
631  if (rslt != RDIError_NoError)
632    {
633      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
634    }
635  printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
636
637  rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
638  if (rslt != RDIError_NoError)
639    {
640      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
641    }
642  else
643    printf_filtered ("Target includes an EmbeddedICE.\n");
644}
645
646static void
647arm_rdi_kill (void)
648{
649  int rslt;
650
651  rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
652  if (rslt != RDIError_NoError)
653    {
654      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
655    }
656}
657
658static void
659arm_rdi_mourn_inferior (void)
660{
661  /* We remove the inserted breakpoints in case the user wants to
662     issue another target and load commands to rerun his application;
663     This is something that wouldn't work on a native target, for instance,
664     as the process goes away when the inferior exits, but it works with
665     some remote targets like this one.  That is why this is done here. */
666  remove_breakpoints();
667  unpush_target (&arm_rdi_ops);
668  generic_mourn_inferior ();
669}
670
671/* While the RDI library keeps track of its own breakpoints, we need
672   to remember "handles" so that we can delete them later.  Since
673   breakpoints get used for stepping, be careful not to leak memory
674   here.  */
675
676static int
677arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
678{
679  int rslt;
680  PointHandle point;
681  struct local_bp_list_entry *entry;
682  int type = RDIPoint_EQ;
683
684  if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
685    type |= RDIPoint_16Bit;
686  rslt = angel_RDI_setbreak (addr, type, 0, &point);
687  if (rslt != RDIError_NoError)
688    {
689      printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
690    }
691  entry =
692    (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
693  entry->addr = addr;
694  entry->point = point;
695  entry->next = local_bp_list;
696  local_bp_list = entry;
697  return rslt;
698}
699
700static int
701arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
702{
703  int rslt;
704  PointHandle point;
705  struct local_bp_list_entry **entryp, *dead;
706
707  for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next)
708    if ((*entryp)->addr == addr)
709      break;
710
711  if (*entryp)
712    {
713      dead = *entryp;
714      rslt = angel_RDI_clearbreak (dead->point);
715      if (rslt != RDIError_NoError)
716	printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
717
718      /* Delete the breakpoint entry locally.  */
719      *entryp = dead->next;
720      xfree (dead);
721    }
722
723  return 0;
724}
725
726
727static char *
728rdi_error_message (int err)
729{
730  switch (err)
731    {
732    case RDIError_NoError:
733      return "no error";
734    case RDIError_Reset:
735      return "debuggee reset";
736    case RDIError_UndefinedInstruction:
737      return "undefined instruction";
738    case RDIError_SoftwareInterrupt:
739      return "SWI trapped";
740    case RDIError_PrefetchAbort:
741      return "prefetch abort, execution ran into unmapped memory?";
742    case RDIError_DataAbort:
743      return "data abort, no memory at specified address?";
744    case RDIError_AddressException:
745      return "address exception, access >26bit in 26bit mode";
746    case RDIError_IRQ:
747      return "IRQ, interrupt trapped";
748    case RDIError_FIQ:
749      return "FIQ, fast interrupt trapped";
750    case RDIError_Error:
751      return "a miscellaneous type of error";
752    case RDIError_BranchThrough0:
753      return "branch through location 0";
754    case RDIError_NotInitialised:
755      return "internal error, RDI_open not called first";
756    case RDIError_UnableToInitialise:
757      return "internal error, target world is broken";
758    case RDIError_WrongByteSex:
759      return "See Operator: WrongByteSex";
760    case RDIError_UnableToTerminate:
761      return "See Operator: Unable to Terminate";
762    case RDIError_BadInstruction:
763      return "bad instruction, illegal to execute this instruction";
764    case RDIError_IllegalInstruction:
765      return "illegal instruction, the effect of executing it is undefined";
766    case RDIError_BadCPUStateSetting:
767      return "internal error, tried to set SPSR of user mode";
768    case RDIError_UnknownCoPro:
769      return "unknown co-processor";
770    case RDIError_UnknownCoProState:
771      return "cannot execute co-processor request";
772    case RDIError_BadCoProState:
773      return "recognizably broken co-processor request";
774    case RDIError_BadPointType:
775      return "internal error, bad point yype";
776    case RDIError_UnimplementedType:
777      return "internal error, unimplemented type";
778    case RDIError_BadPointSize:
779      return "internal error, bad point size";
780    case RDIError_UnimplementedSize:
781      return "internal error, unimplemented size";
782    case RDIError_NoMorePoints:
783      return "last break/watch point was used";
784    case RDIError_BreakpointReached:
785      return "breakpoint reached";
786    case RDIError_WatchpointAccessed:
787      return "watchpoint accessed";
788    case RDIError_NoSuchPoint:
789      return "attempted to clear non-existent break/watch point";
790    case RDIError_ProgramFinishedInStep:
791      return "end of the program reached while stepping";
792    case RDIError_UserInterrupt:
793      return "you pressed Escape";
794    case RDIError_CantSetPoint:
795      return "no more break/watch points available";
796    case RDIError_IncompatibleRDILevels:
797      return "incompatible RDI levels";
798    case RDIError_LittleEndian:
799      return "debuggee is little endian";
800    case RDIError_BigEndian:
801      return "debuggee is big endian";
802    case RDIError_SoftInitialiseError:
803      return "recoverable error in RDI initialization";
804    case RDIError_InsufficientPrivilege:
805      return "internal error, supervisor state not accessible to monitor";
806    case RDIError_UnimplementedMessage:
807      return "internal error, unimplemented message";
808    case RDIError_UndefinedMessage:
809      return "internal error, undefined message";
810    default:
811      return "undefined error message, should reset target";
812    }
813}
814
815/* Convert the ARM error messages to signals that GDB knows about.  */
816
817static enum target_signal
818rdi_error_signal (int err)
819{
820  switch (err)
821    {
822    case RDIError_NoError:
823      return 0;
824    case RDIError_Reset:
825      return TARGET_SIGNAL_TERM;	/* ??? */
826    case RDIError_UndefinedInstruction:
827      return TARGET_SIGNAL_ILL;
828    case RDIError_SoftwareInterrupt:
829    case RDIError_PrefetchAbort:
830    case RDIError_DataAbort:
831      return TARGET_SIGNAL_TRAP;
832    case RDIError_AddressException:
833      return TARGET_SIGNAL_SEGV;
834    case RDIError_IRQ:
835    case RDIError_FIQ:
836      return TARGET_SIGNAL_TRAP;
837    case RDIError_Error:
838      return TARGET_SIGNAL_TERM;
839    case RDIError_BranchThrough0:
840      return TARGET_SIGNAL_TRAP;
841    case RDIError_NotInitialised:
842    case RDIError_UnableToInitialise:
843    case RDIError_WrongByteSex:
844    case RDIError_UnableToTerminate:
845      return TARGET_SIGNAL_UNKNOWN;
846    case RDIError_BadInstruction:
847    case RDIError_IllegalInstruction:
848      return TARGET_SIGNAL_ILL;
849    case RDIError_BadCPUStateSetting:
850    case RDIError_UnknownCoPro:
851    case RDIError_UnknownCoProState:
852    case RDIError_BadCoProState:
853    case RDIError_BadPointType:
854    case RDIError_UnimplementedType:
855    case RDIError_BadPointSize:
856    case RDIError_UnimplementedSize:
857    case RDIError_NoMorePoints:
858      return TARGET_SIGNAL_UNKNOWN;
859    case RDIError_BreakpointReached:
860    case RDIError_WatchpointAccessed:
861      return TARGET_SIGNAL_TRAP;
862    case RDIError_NoSuchPoint:
863    case RDIError_ProgramFinishedInStep:
864      return TARGET_SIGNAL_UNKNOWN;
865    case RDIError_UserInterrupt:
866      return TARGET_SIGNAL_INT;
867    case RDIError_IncompatibleRDILevels:
868    case RDIError_LittleEndian:
869    case RDIError_BigEndian:
870    case RDIError_SoftInitialiseError:
871    case RDIError_InsufficientPrivilege:
872    case RDIError_UnimplementedMessage:
873    case RDIError_UndefinedMessage:
874    default:
875      return TARGET_SIGNAL_UNKNOWN;
876    }
877}
878
879static void
880arm_rdi_stop(void)
881{
882  angel_RDI_stop_request();
883}
884
885
886/* Define the target operations structure.  */
887
888static void
889init_rdi_ops (void)
890{
891  arm_rdi_ops.to_shortname = "rdi";
892  arm_rdi_ops.to_longname = "ARM RDI";
893  arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
894Specify the serial device it is connected to (e.g. /dev/ttya).";
895  arm_rdi_ops.to_open = arm_rdi_open;
896  arm_rdi_ops.to_close = arm_rdi_close;
897  arm_rdi_ops.to_detach = arm_rdi_detach;
898  arm_rdi_ops.to_resume = arm_rdi_resume;
899  arm_rdi_ops.to_wait = arm_rdi_wait;
900  arm_rdi_ops.to_stop = arm_rdi_stop;
901  arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
902  arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
903  arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
904  arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
905  arm_rdi_ops.to_files_info = arm_rdi_files_info;
906  arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
907  arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
908  arm_rdi_ops.to_kill = arm_rdi_kill;
909  arm_rdi_ops.to_load = generic_load;
910  arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
911  arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
912  arm_rdi_ops.to_stratum = process_stratum;
913  arm_rdi_ops.to_has_all_memory = 1;
914  arm_rdi_ops.to_has_memory = 1;
915  arm_rdi_ops.to_has_stack = 1;
916  arm_rdi_ops.to_has_registers = 1;
917  arm_rdi_ops.to_has_execution = 1;
918  arm_rdi_ops.to_magic = OPS_MAGIC;
919}
920
921static void
922rdilogfile_command (char *arg, int from_tty)
923{
924  if (!arg || strlen (arg) == 0)
925    {
926      printf_filtered ("rdi log file is '%s'\n", log_filename);
927      return;
928    }
929
930  if (log_filename)
931    xfree (log_filename);
932
933  log_filename = xstrdup (arg);
934
935  Adp_SetLogfile (log_filename);
936}
937
938static void
939rdilogenable_command (char *args, int from_tty)
940{
941  if (!args || strlen (args) == 0)
942    {
943      printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled");
944      return;
945    }
946
947  if (!strcasecmp (args, "1") ||
948      !strcasecmp (args, "y") ||
949      !strcasecmp (args, "yes") ||
950      !strcasecmp (args, "on") ||
951      !strcasecmp (args, "t") ||
952      !strcasecmp (args, "true"))
953    Adp_SetLogEnable (log_enable = 1);
954  else if (!strcasecmp (args, "0") ||
955	   !strcasecmp (args, "n") ||
956	   !strcasecmp (args, "no") ||
957	   !strcasecmp (args, "off") ||
958	   !strcasecmp (args, "f") ||
959	   !strcasecmp (args, "false"))
960    Adp_SetLogEnable (log_enable = 0);
961  else
962    printf_filtered ("rdilogenable: unrecognized argument '%s'\n"
963		     "              try y or n\n", args);
964}
965
966extern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */
967
968void
969_initialize_remote_rdi (void)
970{
971  struct cmd_list_element *c;
972
973  init_rdi_ops ();
974  add_target (&arm_rdi_ops);
975
976  log_filename = xstrdup ("rdi.log");
977  Adp_SetLogfile (log_filename);
978  Adp_SetLogEnable (log_enable);
979
980  c = add_cmd ("rdilogfile", class_maintenance,
981	       rdilogfile_command,
982	       "Set filename for ADP packet log.\n"
983	       "This file is used to log Angel Debugger Protocol packets.\n"
984	       "With a single argument, sets the logfile name to that value.\n"
985	       "Without an argument, shows the current logfile name.\n"
986	       "See also: rdilogenable\n",
987	       &maintenancelist);
988  set_cmd_completer (c, filename_completer);
989
990  add_cmd ("rdilogenable", class_maintenance,
991	   rdilogenable_command,
992	   "Set enable logging of ADP packets.\n"
993	   "This will log ADP packets exchanged between gdb and the\n"
994	   "rdi target device.\n"
995	   "An argument of 1, t, true, y or yes will enable.\n"
996	   "An argument of 0, f, false, n or no will disabled.\n"
997	   "Withough an argument, it will display current state.\n",
998	   &maintenancelist);
999
1000  add_setshow_boolean_cmd
1001    ("rdiromatzero", no_class, &rom_at_zero,
1002     "Set target has ROM at addr 0.\n"
1003     "A true value disables vector catching, false enables vector catching.\n"
1004     "This is evaluated at the time the 'target rdi' command is executed\n",
1005     "Show if target has ROM at addr 0.\n",
1006     NULL, NULL,
1007     &setlist, &showlist);
1008
1009  add_setshow_boolean_cmd
1010    ("rdiheartbeat", no_class, &rdi_heartbeat,
1011     "Set enable for ADP heartbeat packets.\n"
1012     "I don't know why you would want this. If you enable them,\n"
1013     "it will confuse ARM and EPI JTAG interface boxes as well\n"
1014     "as the Angel Monitor.\n",
1015     "Show enable for ADP heartbeat packets.\n",
1016     NULL, NULL,
1017     &setlist, &showlist);
1018}
1019
1020/* A little dummy to make linking with the library succeed. */
1021
1022void
1023Fail (const char *ignored, ...)
1024{
1025
1026}
1027