146283Sdfr/* GDB interface to ARM RDI library.
246283Sdfr
398944Sobrien   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software
498944Sobrien   Foundation, Inc.
546283Sdfr
698944Sobrien   This file is part of GDB.
746283Sdfr
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1246283Sdfr
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1746283Sdfr
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2298944Sobrien
2346283Sdfr#include "defs.h"
2446283Sdfr#include "gdb_string.h"
2546283Sdfr#include <fcntl.h>
2646283Sdfr#include "frame.h"
2746283Sdfr#include "inferior.h"
2846283Sdfr#include "bfd.h"
2946283Sdfr#include "symfile.h"
3046283Sdfr#include "target.h"
3146283Sdfr#include "gdbcmd.h"
3246283Sdfr#include "objfiles.h"
3346283Sdfr#include "gdb-stabs.h"
3446283Sdfr#include "gdbthread.h"
3546283Sdfr#include "gdbcore.h"
3698944Sobrien#include "breakpoint.h"
3798944Sobrien#include "completer.h"
3898944Sobrien#include "regcache.h"
3998944Sobrien#include "arm-tdep.h"
4046283Sdfr
4146283Sdfr#ifdef USG
4246283Sdfr#include <sys/types.h>
4346283Sdfr#endif
4446283Sdfr
4546283Sdfr#include <signal.h>
4646283Sdfr
4746283Sdfr#include "rdi-share/ardi.h"
4846283Sdfr#include "rdi-share/adp.h"
4946283Sdfr#include "rdi-share/hsys.h"
5046283Sdfr
5198944Sobrienextern int isascii (int);
5246283Sdfr
5346283Sdfr/* Prototypes for local functions */
5446283Sdfr
5598944Sobrienstatic void arm_rdi_files_info (struct target_ops *ignore);
5646283Sdfr
5798944Sobrienstatic int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr,
5898944Sobrien				int len, int should_write,
5998944Sobrien				struct mem_attrib *attrib,
6098944Sobrien				struct target_ops *target);
6146283Sdfr
6298944Sobrienstatic void arm_rdi_prepare_to_store (void);
6346283Sdfr
6498944Sobrienstatic void arm_rdi_fetch_registers (int regno);
6546283Sdfr
6698944Sobrienstatic void arm_rdi_resume (ptid_t pid, int step,
6798944Sobrien                            enum target_signal siggnal);
6846283Sdfr
6998944Sobrienstatic void arm_rdi_open (char *name, int from_tty);
7046283Sdfr
7198944Sobrienstatic void arm_rdi_create_inferior (char *exec_file, char *args, char **env);
7246283Sdfr
7398944Sobrienstatic void arm_rdi_close (int quitting);
7446283Sdfr
7598944Sobrienstatic void arm_rdi_store_registers (int regno);
7646283Sdfr
7798944Sobrienstatic ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status);
7846283Sdfr
7998944Sobrienstatic void arm_rdi_kill (void);
8046283Sdfr
8198944Sobrienstatic void arm_rdi_detach (char *args, int from_tty);
8246283Sdfr
8398944Sobrienstatic int arm_rdi_insert_breakpoint (CORE_ADDR, char *);
8446283Sdfr
8598944Sobrienstatic int arm_rdi_remove_breakpoint (CORE_ADDR, char *);
8646283Sdfr
8798944Sobrienstatic char *rdi_error_message (int err);
8846283Sdfr
8998944Sobrienstatic enum target_signal rdi_error_signal (int err);
9046283Sdfr
9146283Sdfr/* Global variables.  */
9246283Sdfr
9346283Sdfrstruct target_ops arm_rdi_ops;
9446283Sdfr
9546283Sdfrstatic struct Dbg_ConfigBlock gdb_config;
9646283Sdfr
9746283Sdfrstatic struct Dbg_HostosInterface gdb_hostif;
9846283Sdfr
9946283Sdfrstatic int max_load_size;
10046283Sdfr
10146283Sdfrstatic int execute_status;
10246283Sdfr
10398944Sobrien/* Send heatbeat packets? */
10498944Sobrienstatic int rdi_heartbeat = 0;
10598944Sobrien
10698944Sobrien/* Target has ROM at address 0. */
10798944Sobrienstatic int rom_at_zero = 0;
10898944Sobrien
10998944Sobrien/* Enable logging? */
11098944Sobrienstatic int log_enable = 0;
11198944Sobrien
11298944Sobrien/* Name of the log file. Default is "rdi.log". */
11398944Sobrienstatic char *log_filename;
11498944Sobrien
11546283Sdfr/* A little list of breakpoints that have been set.  */
11646283Sdfr
11798944Sobrienstatic struct local_bp_list_entry
11898944Sobrien  {
11998944Sobrien    CORE_ADDR addr;
12098944Sobrien    PointHandle point;
12198944Sobrien    struct local_bp_list_entry *next;
12298944Sobrien  }
12398944Sobrien *local_bp_list;
12498944Sobrien
12546283Sdfr/* Helper callbacks for the "host interface" structure.  RDI functions call
12646283Sdfr   these to forward output from the target system and so forth.  */
12746283Sdfr
128130803Smarcelstatic void
12998944Sobrienvoiddummy (void *dummy)
13046283Sdfr{
13146283Sdfr  fprintf_unfiltered (gdb_stdout, "void dummy\n");
13246283Sdfr}
13346283Sdfr
13446283Sdfrstatic void
135130803Smarcelmyprint (void *arg, const char *format, va_list ap)
13646283Sdfr{
13746283Sdfr  vfprintf_unfiltered (gdb_stdout, format, ap);
13846283Sdfr}
13946283Sdfr
14046283Sdfrstatic void
141130803Smarcelmywritec (void *arg, int c)
14246283Sdfr{
14346283Sdfr  if (isascii (c))
14446283Sdfr    fputc_unfiltered (c, gdb_stdout);
14546283Sdfr}
14646283Sdfr
14746283Sdfrstatic int
148130803Smarcelmywrite (void *arg, char const *buffer, int len)
14946283Sdfr{
15046283Sdfr  int i;
15146283Sdfr  char *e;
15246283Sdfr
15346283Sdfr  e = (char *) buffer;
15446283Sdfr  for (i = 0; i < len; i++)
15598944Sobrien    {
15646283Sdfr      if (isascii ((int) *e))
15798944Sobrien	{
15898944Sobrien	  fputc_unfiltered ((int) *e, gdb_stdout);
15998944Sobrien	  e++;
16098944Sobrien	}
16198944Sobrien    }
16246283Sdfr
16346283Sdfr  return len;
16446283Sdfr}
16546283Sdfr
16646283Sdfrstatic void
167130803Smarcelmypause (void *arg)
16846283Sdfr{
16946283Sdfr}
17046283Sdfr
17146283Sdfr/* These last two are tricky as we have to handle the special case of
17246283Sdfr   being interrupted more carefully */
17346283Sdfr
17446283Sdfrstatic int
175130803Smarcelmyreadc (void *arg)
17698944Sobrien{
17746283Sdfr  return fgetc (stdin);
17846283Sdfr}
17946283Sdfr
18046283Sdfrstatic char *
181130803Smarcelmygets (void *arg, char *buffer, int len)
18246283Sdfr{
18398944Sobrien  return fgets (buffer, len, stdin);
18446283Sdfr}
18546283Sdfr
18646283Sdfr/* Prevent multiple calls to angel_RDI_close().  */
18746283Sdfrstatic int closed_already = 1;
18846283Sdfr
18946283Sdfr/* Open a connection to a remote debugger.  NAME is the filename used
19046283Sdfr   for communication.  */
19146283Sdfr
19246283Sdfrstatic void
19398944Sobrienarm_rdi_open (char *name, int from_tty)
19446283Sdfr{
19546283Sdfr  int rslt, i;
19646283Sdfr  unsigned long arg1, arg2;
19798944Sobrien  char *openArgs = NULL;
19898944Sobrien  char *devName = NULL;
19998944Sobrien  char *p;
20046283Sdfr
20146283Sdfr  if (name == NULL)
20246283Sdfr    error ("To open an RDI connection, you need to specify what serial\n\
20346283Sdfrdevice is attached to the remote system (e.g. /dev/ttya).");
20446283Sdfr
20598944Sobrien  /* split name after whitespace, pass tail as arg to open command */
20698944Sobrien
20798944Sobrien  devName = xstrdup (name);
20898944Sobrien  p = strchr (devName, ' ');
20998944Sobrien  if (p)
21098944Sobrien    {
21198944Sobrien      *p = '\0';
21298944Sobrien      ++p;
21398944Sobrien
21498944Sobrien      while (*p == ' ')
21598944Sobrien	++p;
21698944Sobrien
21798944Sobrien      openArgs = p;
21898944Sobrien    }
21998944Sobrien
22046283Sdfr  /* Make the basic low-level connection.  */
22146283Sdfr
22298944Sobrien  arm_rdi_close (0);
22398944Sobrien  rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat);
22446283Sdfr
22546283Sdfr  if (rslt != adp_ok)
22646283Sdfr    error ("Could not open device \"%s\"", name);
22746283Sdfr
22898944Sobrien  gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0);
22946283Sdfr  gdb_config.fpe = 1;
23046283Sdfr  gdb_config.rditype = 2;
23146283Sdfr  gdb_config.heartbeat_on = 1;
23246283Sdfr  gdb_config.flags = 2;
23346283Sdfr
23446283Sdfr  gdb_hostif.dbgprint = myprint;
23546283Sdfr  gdb_hostif.dbgpause = mypause;
23646283Sdfr  gdb_hostif.dbgarg = NULL;
23746283Sdfr  gdb_hostif.writec = mywritec;
23846283Sdfr  gdb_hostif.readc = myreadc;
23946283Sdfr  gdb_hostif.write = mywrite;
24046283Sdfr  gdb_hostif.gets = mygets;
24146283Sdfr  gdb_hostif.hostosarg = NULL;
24246283Sdfr  gdb_hostif.reset = voiddummy;
24346283Sdfr
24446283Sdfr  rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL);
24546283Sdfr  if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian)
24698944Sobrien    ;				/* do nothing, this is the expected return */
247130803Smarcel  else if (rslt != RDIError_NoError)
24846283Sdfr    {
24946283Sdfr      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
25098944Sobrien      Adp_CloseDevice ();
25198944Sobrien      error ("RDI_open failed\n");
25246283Sdfr    }
25346283Sdfr
25446283Sdfr  rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
255130803Smarcel  if (rslt != RDIError_NoError)
25646283Sdfr    {
25746283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
25846283Sdfr    }
25946283Sdfr  rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2);
260130803Smarcel  if (rslt != RDIError_NoError)
26146283Sdfr    {
26246283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
26346283Sdfr    }
26446283Sdfr  rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
265130803Smarcel  if (rslt != RDIError_NoError)
26646283Sdfr    {
26746283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
26846283Sdfr    }
26946283Sdfr  rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2);
270130803Smarcel  if (rslt != RDIError_NoError)
27146283Sdfr    {
27246283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
27346283Sdfr    }
27446283Sdfr  rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2);
275130803Smarcel  if (rslt != RDIError_NoError)
27646283Sdfr    {
27746283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
27846283Sdfr    }
27946283Sdfr
28046283Sdfr  rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2);
281130803Smarcel  if (rslt != RDIError_NoError)
28246283Sdfr    {
28346283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
28446283Sdfr    }
28546283Sdfr  max_load_size = arg1;
28646283Sdfr
28746283Sdfr  push_target (&arm_rdi_ops);
28846283Sdfr
28946283Sdfr  target_fetch_registers (-1);
29046283Sdfr
29146283Sdfr  rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
292130803Smarcel  if (rslt != RDIError_NoError)
29346283Sdfr    {
29446283Sdfr      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
29546283Sdfr    }
29646283Sdfr
29798944Sobrien  arg1 = rom_at_zero ? 0x0 : 0x13b;
29898944Sobrien
29946283Sdfr  rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2);
300130803Smarcel  if (rslt != RDIError_NoError)
30146283Sdfr    {
30246283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
30346283Sdfr    }
30446283Sdfr
30546283Sdfr  arg1 = (unsigned long) "";
30646283Sdfr  rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2);
307130803Smarcel  if (rslt != RDIError_NoError)
30846283Sdfr    {
30946283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
31046283Sdfr    }
31146283Sdfr
31246283Sdfr  /* Clear out any existing records of breakpoints.  */
31346283Sdfr  {
31446283Sdfr    struct local_bp_list_entry *entry, *preventry = NULL;
31546283Sdfr
31646283Sdfr    for (entry = local_bp_list; entry != NULL; entry = entry->next)
31746283Sdfr      {
31846283Sdfr	if (preventry)
31998944Sobrien	  xfree (preventry);
32046283Sdfr      }
32146283Sdfr  }
32246283Sdfr
32346283Sdfr  printf_filtered ("Connected to ARM RDI target.\n");
32446283Sdfr  closed_already = 0;
32598944Sobrien  inferior_ptid = pid_to_ptid (42);
32646283Sdfr}
32746283Sdfr
32898944Sobrien/* Start an inferior process and set inferior_ptid to its pid.
32946283Sdfr   EXEC_FILE is the file to run.
33046283Sdfr   ARGS is a string containing the arguments to the program.
33146283Sdfr   ENV is the environment vector to pass.  Errors reported with error().
33246283Sdfr   On VxWorks and various standalone systems, we ignore exec_file.  */
33346283Sdfr/* This is called not only when we first attach, but also when the
33446283Sdfr   user types "run" after having attached.  */
33546283Sdfr
33646283Sdfrstatic void
33798944Sobrienarm_rdi_create_inferior (char *exec_file, char *args, char **env)
33846283Sdfr{
33946283Sdfr  int len, rslt;
34046283Sdfr  unsigned long arg1, arg2;
34146283Sdfr  char *arg_buf;
34246283Sdfr  CORE_ADDR entry_point;
34346283Sdfr
34446283Sdfr  if (exec_file == 0 || exec_bfd == 0)
34598944Sobrien    error ("No executable file specified.");
34646283Sdfr
34746283Sdfr  entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd);
34846283Sdfr
34998944Sobrien  arm_rdi_kill ();
35046283Sdfr  remove_breakpoints ();
35146283Sdfr  init_wait_for_inferior ();
35246283Sdfr
35398944Sobrien  len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
35446283Sdfr  arg_buf = (char *) alloca (len);
35546283Sdfr  arg_buf[0] = '\0';
35646283Sdfr  strcat (arg_buf, exec_file);
35746283Sdfr  strcat (arg_buf, " ");
35846283Sdfr  strcat (arg_buf, args);
35946283Sdfr
36098944Sobrien  inferior_ptid = pid_to_ptid (42);
36198944Sobrien  insert_breakpoints ();	/* Needed to get correct instruction in cache */
36246283Sdfr
36346283Sdfr  if (env != NULL)
36446283Sdfr    {
36546283Sdfr      while (*env)
36646283Sdfr	{
36746283Sdfr	  if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
36846283Sdfr	    {
36946283Sdfr	      unsigned long top_of_memory;
37046283Sdfr	      char *end_of_num;
37146283Sdfr
37246283Sdfr	      /* Set up memory limit */
37346283Sdfr	      top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1,
37446283Sdfr				       &end_of_num, 0);
37598944Sobrien	      printf_filtered ("Setting top-of-memory to 0x%lx\n",
37646283Sdfr			       top_of_memory);
37798944Sobrien
37846283Sdfr	      rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2);
379130803Smarcel	      if (rslt != RDIError_NoError)
38046283Sdfr		{
38146283Sdfr		  printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
38246283Sdfr		}
38346283Sdfr	    }
38446283Sdfr	  env++;
38546283Sdfr	}
38646283Sdfr    }
38746283Sdfr
38846283Sdfr  arg1 = (unsigned long) arg_buf;
38998944Sobrien  rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2);
390130803Smarcel  if (rslt != RDIError_NoError)
39146283Sdfr    {
39246283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
39346283Sdfr    }
39446283Sdfr
39546283Sdfr  proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0);
39646283Sdfr}
39746283Sdfr
39846283Sdfr/* This takes a program previously attached to and detaches it.  After
39946283Sdfr   this is done, GDB can be used to debug some other program.  We
40046283Sdfr   better not have left any breakpoints in the target program or it'll
40146283Sdfr   die when it hits one.  */
40246283Sdfr
40346283Sdfrstatic void
40498944Sobrienarm_rdi_detach (char *args, int from_tty)
40546283Sdfr{
40646283Sdfr  pop_target ();
40746283Sdfr}
40846283Sdfr
40946283Sdfr/* Clean up connection to a remote debugger.  */
41046283Sdfr
41146283Sdfrstatic void
41298944Sobrienarm_rdi_close (int quitting)
41346283Sdfr{
41446283Sdfr  int rslt;
41546283Sdfr
41698944Sobrien  if (!closed_already)
41746283Sdfr    {
41846283Sdfr      rslt = angel_RDI_close ();
419130803Smarcel      if (rslt != RDIError_NoError)
42046283Sdfr	{
42146283Sdfr	  printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt));
42246283Sdfr	}
42346283Sdfr      closed_already = 1;
42498944Sobrien      inferior_ptid = null_ptid;
42598944Sobrien      Adp_CloseDevice ();
42698944Sobrien      generic_mourn_inferior ();
42746283Sdfr    }
42846283Sdfr}
42946283Sdfr
43046283Sdfr/* Tell the remote machine to resume.  */
43146283Sdfr
43246283Sdfrstatic void
43398944Sobrienarm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal)
43446283Sdfr{
43546283Sdfr  int rslt;
43646283Sdfr  PointHandle point;
43746283Sdfr
43898944Sobrien  if (0 /* turn on when hardware supports single-stepping */ )
43946283Sdfr    {
44046283Sdfr      rslt = angel_RDI_step (1, &point);
441130803Smarcel      if (rslt != RDIError_NoError)
442130803Smarcel	printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt));
44346283Sdfr    }
44446283Sdfr  else
44546283Sdfr    {
44646283Sdfr      char handle[4];
447130803Smarcel      CORE_ADDR pc = 0;
44846283Sdfr
44946283Sdfr      if (step)
45046283Sdfr	{
45198944Sobrien	  pc = read_register (ARM_PC_REGNUM);
45246283Sdfr	  pc = arm_get_next_pc (pc);
45346283Sdfr	  arm_rdi_insert_breakpoint (pc, handle);
45446283Sdfr	}
455130803Smarcel
45646283Sdfr      execute_status = rslt = angel_RDI_execute (&point);
457130803Smarcel      if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached)
458130803Smarcel	printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt));
459130803Smarcel
46046283Sdfr      if (step)
461130803Smarcel	arm_rdi_remove_breakpoint (pc, handle);
46246283Sdfr    }
46346283Sdfr}
46446283Sdfr
46546283Sdfr/* Wait until the remote machine stops, then return, storing status in
46646283Sdfr   STATUS just as `wait' would.  Returns "pid" (though it's not clear
46746283Sdfr   what, if anything, that means in the case of this target).  */
46846283Sdfr
46998944Sobrienstatic ptid_t
47098944Sobrienarm_rdi_wait (ptid_t ptid, struct target_waitstatus *status)
47146283Sdfr{
47246283Sdfr  status->kind = (execute_status == RDIError_NoError ?
47398944Sobrien		  TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED);
47446283Sdfr
47546283Sdfr  /* convert stopped code from target into right signal */
47646283Sdfr  status->value.sig = rdi_error_signal (execute_status);
47746283Sdfr
47898944Sobrien  return inferior_ptid;
47946283Sdfr}
48046283Sdfr
48146283Sdfr/* Read the remote registers into the block REGS.  */
48246283Sdfr
48346283Sdfrstatic void
48498944Sobrienarm_rdi_fetch_registers (int regno)
48546283Sdfr{
48646283Sdfr  int rslt, rdi_regmask;
48746283Sdfr  unsigned long rawreg, rawregs[32];
48846283Sdfr  char cookedreg[4];
48946283Sdfr
49098944Sobrien  if (regno == -1)
49146283Sdfr    {
49246283Sdfr      rslt = angel_RDI_CPUread (255, 0x27fff, rawregs);
493130803Smarcel      if (rslt != RDIError_NoError)
49446283Sdfr	{
49546283Sdfr	  printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
49646283Sdfr	}
49746283Sdfr
49846283Sdfr      for (regno = 0; regno < 15; regno++)
49946283Sdfr	{
50046283Sdfr	  store_unsigned_integer (cookedreg, 4, rawregs[regno]);
50146283Sdfr	  supply_register (regno, (char *) cookedreg);
50246283Sdfr	}
50346283Sdfr      store_unsigned_integer (cookedreg, 4, rawregs[15]);
50498944Sobrien      supply_register (ARM_PS_REGNUM, (char *) cookedreg);
50598944Sobrien      arm_rdi_fetch_registers (ARM_PC_REGNUM);
50646283Sdfr    }
50746283Sdfr  else
50846283Sdfr    {
50998944Sobrien      if (regno == ARM_PC_REGNUM)
51046283Sdfr	rdi_regmask = RDIReg_PC;
51198944Sobrien      else if (regno == ARM_PS_REGNUM)
51246283Sdfr	rdi_regmask = RDIReg_CPSR;
51346283Sdfr      else if (regno < 0 || regno > 15)
51446283Sdfr	{
51546283Sdfr	  rawreg = 0;
51646283Sdfr	  supply_register (regno, (char *) &rawreg);
51746283Sdfr	  return;
51846283Sdfr	}
51946283Sdfr      else
52046283Sdfr	rdi_regmask = 1 << regno;
52146283Sdfr
52246283Sdfr      rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg);
523130803Smarcel      if (rslt != RDIError_NoError)
52446283Sdfr	{
52546283Sdfr	  printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt));
52646283Sdfr	}
52746283Sdfr      store_unsigned_integer (cookedreg, 4, rawreg);
52846283Sdfr      supply_register (regno, (char *) cookedreg);
52946283Sdfr    }
53046283Sdfr}
53146283Sdfr
53298944Sobrienstatic void
53398944Sobrienarm_rdi_prepare_to_store (void)
53446283Sdfr{
53546283Sdfr  /* Nothing to do.  */
53646283Sdfr}
53746283Sdfr
53846283Sdfr/* Store register REGNO, or all registers if REGNO == -1, from the contents
53946283Sdfr   of REGISTERS.  FIXME: ignores errors.  */
54046283Sdfr
54146283Sdfrstatic void
54298944Sobrienarm_rdi_store_registers (int regno)
54346283Sdfr{
54446283Sdfr  int rslt, rdi_regmask;
54546283Sdfr
54646283Sdfr  /* These need to be able to take 'floating point register' contents */
54746283Sdfr  unsigned long rawreg[3], rawerreg[3];
54846283Sdfr
54998944Sobrien  if (regno == -1)
55046283Sdfr    {
55146283Sdfr      for (regno = 0; regno < NUM_REGS; regno++)
55246283Sdfr	arm_rdi_store_registers (regno);
55346283Sdfr    }
55446283Sdfr  else
55546283Sdfr    {
556130803Smarcel      deprecated_read_register_gen (regno, (char *) rawreg);
55746283Sdfr      /* RDI manipulates data in host byte order, so convert now. */
55846283Sdfr      store_unsigned_integer (rawerreg, 4, rawreg[0]);
55946283Sdfr
56098944Sobrien      if (regno == ARM_PC_REGNUM)
56146283Sdfr	rdi_regmask = RDIReg_PC;
56298944Sobrien      else if (regno == ARM_PS_REGNUM)
56346283Sdfr	rdi_regmask = RDIReg_CPSR;
56446283Sdfr      else if (regno < 0 || regno > 15)
56546283Sdfr	return;
56646283Sdfr      else
56746283Sdfr	rdi_regmask = 1 << regno;
56846283Sdfr
56946283Sdfr      rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg);
570130803Smarcel      if (rslt != RDIError_NoError)
57146283Sdfr	{
57246283Sdfr	  printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt));
57346283Sdfr	}
57446283Sdfr    }
57546283Sdfr}
57646283Sdfr
57746283Sdfr/* Read or write LEN bytes from inferior memory at MEMADDR,
57846283Sdfr   transferring to or from debugger address MYADDR.  Write to inferior
57946283Sdfr   if SHOULD_WRITE is nonzero.  Returns length of data written or
58098944Sobrien   read; 0 for error.  TARGET is unused.  */
58146283Sdfr
58246283Sdfrstatic int
58398944Sobrienarm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
58498944Sobrien		     int should_write, struct mem_attrib *attrib,
58598944Sobrien		     struct target_ops *target)
58646283Sdfr{
58746283Sdfr  int rslt, i;
58846283Sdfr
58946283Sdfr  if (should_write)
59046283Sdfr    {
59146283Sdfr      rslt = angel_RDI_write (myaddr, memaddr, &len);
592130803Smarcel      if (rslt != RDIError_NoError)
59346283Sdfr	{
59446283Sdfr	  printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt));
59546283Sdfr	}
59646283Sdfr    }
59798944Sobrien  else
59846283Sdfr    {
59946283Sdfr      rslt = angel_RDI_read (memaddr, myaddr, &len);
600130803Smarcel      if (rslt != RDIError_NoError)
60146283Sdfr	{
60246283Sdfr	  printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt));
60346283Sdfr	  len = 0;
60446283Sdfr	}
60546283Sdfr    }
60646283Sdfr  return len;
60746283Sdfr}
60846283Sdfr
60946283Sdfr/* Display random info collected from the target.  */
61046283Sdfr
61146283Sdfrstatic void
61298944Sobrienarm_rdi_files_info (struct target_ops *ignore)
61346283Sdfr{
61446283Sdfr  char *file = "nothing";
61546283Sdfr  int rslt;
61646283Sdfr  unsigned long arg1, arg2;
61746283Sdfr
61846283Sdfr  rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2);
619130803Smarcel  if (rslt != RDIError_NoError)
62046283Sdfr    {
62146283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
62246283Sdfr    }
62346283Sdfr  if (arg1 & (1 << 15))
62446283Sdfr    printf_filtered ("Target supports Thumb code.\n");
62546283Sdfr  if (arg1 & (1 << 14))
62646283Sdfr    printf_filtered ("Target can do profiling.\n");
62746283Sdfr  if (arg1 & (1 << 4))
62846283Sdfr    printf_filtered ("Target is real hardware.\n");
62998944Sobrien
63046283Sdfr  rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2);
631130803Smarcel  if (rslt != RDIError_NoError)
63246283Sdfr    {
63346283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
63446283Sdfr    }
63546283Sdfr  printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not"));
63646283Sdfr
63746283Sdfr  rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2);
638130803Smarcel  if (rslt != RDIError_NoError)
63946283Sdfr    {
64046283Sdfr      printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt));
64146283Sdfr    }
64246283Sdfr  else
64346283Sdfr    printf_filtered ("Target includes an EmbeddedICE.\n");
64446283Sdfr}
64546283Sdfr
64646283Sdfrstatic void
64798944Sobrienarm_rdi_kill (void)
64846283Sdfr{
64946283Sdfr  int rslt;
65046283Sdfr
65146283Sdfr  rslt = angel_RDI_open (1, &gdb_config, NULL, NULL);
652130803Smarcel  if (rslt != RDIError_NoError)
65346283Sdfr    {
65446283Sdfr      printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt));
65546283Sdfr    }
65646283Sdfr}
65746283Sdfr
65846283Sdfrstatic void
65998944Sobrienarm_rdi_mourn_inferior (void)
66046283Sdfr{
66198944Sobrien  /* We remove the inserted breakpoints in case the user wants to
66298944Sobrien     issue another target and load commands to rerun his application;
66398944Sobrien     This is something that wouldn't work on a native target, for instance,
66498944Sobrien     as the process goes away when the inferior exits, but it works with
66598944Sobrien     some remote targets like this one.  That is why this is done here. */
66698944Sobrien  remove_breakpoints();
66746283Sdfr  unpush_target (&arm_rdi_ops);
66846283Sdfr  generic_mourn_inferior ();
66946283Sdfr}
67046283Sdfr
67146283Sdfr/* While the RDI library keeps track of its own breakpoints, we need
67246283Sdfr   to remember "handles" so that we can delete them later.  Since
67346283Sdfr   breakpoints get used for stepping, be careful not to leak memory
67446283Sdfr   here.  */
67546283Sdfr
67646283Sdfrstatic int
67798944Sobrienarm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
67846283Sdfr{
67946283Sdfr  int rslt;
68046283Sdfr  PointHandle point;
68146283Sdfr  struct local_bp_list_entry *entry;
68246283Sdfr  int type = RDIPoint_EQ;
68346283Sdfr
68446283Sdfr  if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr))
68546283Sdfr    type |= RDIPoint_16Bit;
68646283Sdfr  rslt = angel_RDI_setbreak (addr, type, 0, &point);
687130803Smarcel  if (rslt != RDIError_NoError)
68846283Sdfr    {
68946283Sdfr      printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt));
69046283Sdfr    }
69146283Sdfr  entry =
69246283Sdfr    (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry));
69346283Sdfr  entry->addr = addr;
69446283Sdfr  entry->point = point;
69546283Sdfr  entry->next = local_bp_list;
69646283Sdfr  local_bp_list = entry;
69746283Sdfr  return rslt;
69846283Sdfr}
69946283Sdfr
70046283Sdfrstatic int
70198944Sobrienarm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
70246283Sdfr{
70346283Sdfr  int rslt;
70446283Sdfr  PointHandle point;
705130803Smarcel  struct local_bp_list_entry **entryp, *dead;
70646283Sdfr
707130803Smarcel  for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next)
708130803Smarcel    if ((*entryp)->addr == addr)
709130803Smarcel      break;
710130803Smarcel
711130803Smarcel  if (*entryp)
71246283Sdfr    {
713130803Smarcel      dead = *entryp;
714130803Smarcel      rslt = angel_RDI_clearbreak (dead->point);
715130803Smarcel      if (rslt != RDIError_NoError)
716130803Smarcel	printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt));
717130803Smarcel
71846283Sdfr      /* Delete the breakpoint entry locally.  */
719130803Smarcel      *entryp = dead->next;
720130803Smarcel      xfree (dead);
72146283Sdfr    }
722130803Smarcel
72346283Sdfr  return 0;
72446283Sdfr}
725130803Smarcel
72646283Sdfr
72746283Sdfrstatic char *
72898944Sobrienrdi_error_message (int err)
72946283Sdfr{
73046283Sdfr  switch (err)
73146283Sdfr    {
73298944Sobrien    case RDIError_NoError:
73346283Sdfr      return "no error";
73446283Sdfr    case RDIError_Reset:
73546283Sdfr      return "debuggee reset";
73646283Sdfr    case RDIError_UndefinedInstruction:
73746283Sdfr      return "undefined instruction";
73846283Sdfr    case RDIError_SoftwareInterrupt:
73946283Sdfr      return "SWI trapped";
74046283Sdfr    case RDIError_PrefetchAbort:
74146283Sdfr      return "prefetch abort, execution ran into unmapped memory?";
74246283Sdfr    case RDIError_DataAbort:
74346283Sdfr      return "data abort, no memory at specified address?";
74446283Sdfr    case RDIError_AddressException:
74546283Sdfr      return "address exception, access >26bit in 26bit mode";
74646283Sdfr    case RDIError_IRQ:
74746283Sdfr      return "IRQ, interrupt trapped";
74846283Sdfr    case RDIError_FIQ:
74946283Sdfr      return "FIQ, fast interrupt trapped";
75046283Sdfr    case RDIError_Error:
75146283Sdfr      return "a miscellaneous type of error";
75246283Sdfr    case RDIError_BranchThrough0:
75346283Sdfr      return "branch through location 0";
75446283Sdfr    case RDIError_NotInitialised:
75546283Sdfr      return "internal error, RDI_open not called first";
75646283Sdfr    case RDIError_UnableToInitialise:
75746283Sdfr      return "internal error, target world is broken";
75846283Sdfr    case RDIError_WrongByteSex:
75946283Sdfr      return "See Operator: WrongByteSex";
76046283Sdfr    case RDIError_UnableToTerminate:
76146283Sdfr      return "See Operator: Unable to Terminate";
76246283Sdfr    case RDIError_BadInstruction:
76346283Sdfr      return "bad instruction, illegal to execute this instruction";
76446283Sdfr    case RDIError_IllegalInstruction:
76546283Sdfr      return "illegal instruction, the effect of executing it is undefined";
76646283Sdfr    case RDIError_BadCPUStateSetting:
76746283Sdfr      return "internal error, tried to set SPSR of user mode";
76846283Sdfr    case RDIError_UnknownCoPro:
76946283Sdfr      return "unknown co-processor";
77046283Sdfr    case RDIError_UnknownCoProState:
77146283Sdfr      return "cannot execute co-processor request";
77246283Sdfr    case RDIError_BadCoProState:
77346283Sdfr      return "recognizably broken co-processor request";
77446283Sdfr    case RDIError_BadPointType:
77546283Sdfr      return "internal error, bad point yype";
77646283Sdfr    case RDIError_UnimplementedType:
77746283Sdfr      return "internal error, unimplemented type";
77846283Sdfr    case RDIError_BadPointSize:
77946283Sdfr      return "internal error, bad point size";
78046283Sdfr    case RDIError_UnimplementedSize:
78146283Sdfr      return "internal error, unimplemented size";
78246283Sdfr    case RDIError_NoMorePoints:
78346283Sdfr      return "last break/watch point was used";
78446283Sdfr    case RDIError_BreakpointReached:
78546283Sdfr      return "breakpoint reached";
78646283Sdfr    case RDIError_WatchpointAccessed:
78746283Sdfr      return "watchpoint accessed";
78846283Sdfr    case RDIError_NoSuchPoint:
78946283Sdfr      return "attempted to clear non-existent break/watch point";
79046283Sdfr    case RDIError_ProgramFinishedInStep:
79146283Sdfr      return "end of the program reached while stepping";
79246283Sdfr    case RDIError_UserInterrupt:
79346283Sdfr      return "you pressed Escape";
79446283Sdfr    case RDIError_CantSetPoint:
79546283Sdfr      return "no more break/watch points available";
79646283Sdfr    case RDIError_IncompatibleRDILevels:
79746283Sdfr      return "incompatible RDI levels";
79846283Sdfr    case RDIError_LittleEndian:
79946283Sdfr      return "debuggee is little endian";
80046283Sdfr    case RDIError_BigEndian:
80146283Sdfr      return "debuggee is big endian";
80246283Sdfr    case RDIError_SoftInitialiseError:
80346283Sdfr      return "recoverable error in RDI initialization";
80446283Sdfr    case RDIError_InsufficientPrivilege:
80546283Sdfr      return "internal error, supervisor state not accessible to monitor";
80646283Sdfr    case RDIError_UnimplementedMessage:
80746283Sdfr      return "internal error, unimplemented message";
80846283Sdfr    case RDIError_UndefinedMessage:
80946283Sdfr      return "internal error, undefined message";
81046283Sdfr    default:
81198944Sobrien      return "undefined error message, should reset target";
81246283Sdfr    }
81346283Sdfr}
81446283Sdfr
81546283Sdfr/* Convert the ARM error messages to signals that GDB knows about.  */
81646283Sdfr
81746283Sdfrstatic enum target_signal
81898944Sobrienrdi_error_signal (int err)
81946283Sdfr{
82046283Sdfr  switch (err)
82146283Sdfr    {
82246283Sdfr    case RDIError_NoError:
82346283Sdfr      return 0;
82446283Sdfr    case RDIError_Reset:
82598944Sobrien      return TARGET_SIGNAL_TERM;	/* ??? */
82646283Sdfr    case RDIError_UndefinedInstruction:
82746283Sdfr      return TARGET_SIGNAL_ILL;
82846283Sdfr    case RDIError_SoftwareInterrupt:
82946283Sdfr    case RDIError_PrefetchAbort:
83046283Sdfr    case RDIError_DataAbort:
83146283Sdfr      return TARGET_SIGNAL_TRAP;
83246283Sdfr    case RDIError_AddressException:
83346283Sdfr      return TARGET_SIGNAL_SEGV;
83446283Sdfr    case RDIError_IRQ:
83546283Sdfr    case RDIError_FIQ:
83646283Sdfr      return TARGET_SIGNAL_TRAP;
83746283Sdfr    case RDIError_Error:
83846283Sdfr      return TARGET_SIGNAL_TERM;
83946283Sdfr    case RDIError_BranchThrough0:
84046283Sdfr      return TARGET_SIGNAL_TRAP;
84146283Sdfr    case RDIError_NotInitialised:
84246283Sdfr    case RDIError_UnableToInitialise:
84346283Sdfr    case RDIError_WrongByteSex:
84446283Sdfr    case RDIError_UnableToTerminate:
84546283Sdfr      return TARGET_SIGNAL_UNKNOWN;
84646283Sdfr    case RDIError_BadInstruction:
84746283Sdfr    case RDIError_IllegalInstruction:
84846283Sdfr      return TARGET_SIGNAL_ILL;
84946283Sdfr    case RDIError_BadCPUStateSetting:
85046283Sdfr    case RDIError_UnknownCoPro:
85146283Sdfr    case RDIError_UnknownCoProState:
85246283Sdfr    case RDIError_BadCoProState:
85346283Sdfr    case RDIError_BadPointType:
85446283Sdfr    case RDIError_UnimplementedType:
85546283Sdfr    case RDIError_BadPointSize:
85646283Sdfr    case RDIError_UnimplementedSize:
85746283Sdfr    case RDIError_NoMorePoints:
85846283Sdfr      return TARGET_SIGNAL_UNKNOWN;
85946283Sdfr    case RDIError_BreakpointReached:
86046283Sdfr    case RDIError_WatchpointAccessed:
86146283Sdfr      return TARGET_SIGNAL_TRAP;
86246283Sdfr    case RDIError_NoSuchPoint:
86346283Sdfr    case RDIError_ProgramFinishedInStep:
86446283Sdfr      return TARGET_SIGNAL_UNKNOWN;
86546283Sdfr    case RDIError_UserInterrupt:
86646283Sdfr      return TARGET_SIGNAL_INT;
86746283Sdfr    case RDIError_IncompatibleRDILevels:
86846283Sdfr    case RDIError_LittleEndian:
86946283Sdfr    case RDIError_BigEndian:
87046283Sdfr    case RDIError_SoftInitialiseError:
87146283Sdfr    case RDIError_InsufficientPrivilege:
87246283Sdfr    case RDIError_UnimplementedMessage:
87346283Sdfr    case RDIError_UndefinedMessage:
87446283Sdfr    default:
87598944Sobrien      return TARGET_SIGNAL_UNKNOWN;
87646283Sdfr    }
87746283Sdfr}
87898944Sobrien
87998944Sobrienstatic void
88098944Sobrienarm_rdi_stop(void)
88198944Sobrien{
88298944Sobrien  angel_RDI_stop_request();
88398944Sobrien}
88498944Sobrien
88546283Sdfr
88646283Sdfr/* Define the target operations structure.  */
88746283Sdfr
88846283Sdfrstatic void
88998944Sobrieninit_rdi_ops (void)
89046283Sdfr{
89198944Sobrien  arm_rdi_ops.to_shortname = "rdi";
89246283Sdfr  arm_rdi_ops.to_longname = "ARM RDI";
89346283Sdfr  arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\
89498944SobrienSpecify the serial device it is connected to (e.g. /dev/ttya).";
89598944Sobrien  arm_rdi_ops.to_open = arm_rdi_open;
89698944Sobrien  arm_rdi_ops.to_close = arm_rdi_close;
89798944Sobrien  arm_rdi_ops.to_detach = arm_rdi_detach;
89898944Sobrien  arm_rdi_ops.to_resume = arm_rdi_resume;
89998944Sobrien  arm_rdi_ops.to_wait = arm_rdi_wait;
90098944Sobrien  arm_rdi_ops.to_stop = arm_rdi_stop;
90146283Sdfr  arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers;
90246283Sdfr  arm_rdi_ops.to_store_registers = arm_rdi_store_registers;
90346283Sdfr  arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store;
90446283Sdfr  arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory;
90546283Sdfr  arm_rdi_ops.to_files_info = arm_rdi_files_info;
90646283Sdfr  arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint;
90798944Sobrien  arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint;
90898944Sobrien  arm_rdi_ops.to_kill = arm_rdi_kill;
90998944Sobrien  arm_rdi_ops.to_load = generic_load;
91046283Sdfr  arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior;
91146283Sdfr  arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior;
91246283Sdfr  arm_rdi_ops.to_stratum = process_stratum;
91398944Sobrien  arm_rdi_ops.to_has_all_memory = 1;
91498944Sobrien  arm_rdi_ops.to_has_memory = 1;
91598944Sobrien  arm_rdi_ops.to_has_stack = 1;
91698944Sobrien  arm_rdi_ops.to_has_registers = 1;
91798944Sobrien  arm_rdi_ops.to_has_execution = 1;
91898944Sobrien  arm_rdi_ops.to_magic = OPS_MAGIC;
91946283Sdfr}
92046283Sdfr
92198944Sobrienstatic void
92298944Sobrienrdilogfile_command (char *arg, int from_tty)
92398944Sobrien{
92498944Sobrien  if (!arg || strlen (arg) == 0)
92598944Sobrien    {
92698944Sobrien      printf_filtered ("rdi log file is '%s'\n", log_filename);
92798944Sobrien      return;
92898944Sobrien    }
92998944Sobrien
93098944Sobrien  if (log_filename)
93198944Sobrien    xfree (log_filename);
93298944Sobrien
93398944Sobrien  log_filename = xstrdup (arg);
93498944Sobrien
93598944Sobrien  Adp_SetLogfile (log_filename);
93698944Sobrien}
93798944Sobrien
93898944Sobrienstatic void
93998944Sobrienrdilogenable_command (char *args, int from_tty)
94098944Sobrien{
94198944Sobrien  if (!args || strlen (args) == 0)
94298944Sobrien    {
94398944Sobrien      printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled");
94498944Sobrien      return;
94598944Sobrien    }
94698944Sobrien
94798944Sobrien  if (!strcasecmp (args, "1") ||
94898944Sobrien      !strcasecmp (args, "y") ||
94998944Sobrien      !strcasecmp (args, "yes") ||
95098944Sobrien      !strcasecmp (args, "on") ||
95198944Sobrien      !strcasecmp (args, "t") ||
95298944Sobrien      !strcasecmp (args, "true"))
95398944Sobrien    Adp_SetLogEnable (log_enable = 1);
95498944Sobrien  else if (!strcasecmp (args, "0") ||
95598944Sobrien	   !strcasecmp (args, "n") ||
95698944Sobrien	   !strcasecmp (args, "no") ||
95798944Sobrien	   !strcasecmp (args, "off") ||
95898944Sobrien	   !strcasecmp (args, "f") ||
95998944Sobrien	   !strcasecmp (args, "false"))
96098944Sobrien    Adp_SetLogEnable (log_enable = 0);
96198944Sobrien  else
96298944Sobrien    printf_filtered ("rdilogenable: unrecognized argument '%s'\n"
96398944Sobrien		     "              try y or n\n", args);
96498944Sobrien}
96598944Sobrien
966130803Smarcelextern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */
967130803Smarcel
96846283Sdfrvoid
96998944Sobrien_initialize_remote_rdi (void)
97046283Sdfr{
97198944Sobrien  struct cmd_list_element *c;
97298944Sobrien
97398944Sobrien  init_rdi_ops ();
97446283Sdfr  add_target (&arm_rdi_ops);
97598944Sobrien
97698944Sobrien  log_filename = xstrdup ("rdi.log");
97798944Sobrien  Adp_SetLogfile (log_filename);
97898944Sobrien  Adp_SetLogEnable (log_enable);
97998944Sobrien
98098944Sobrien  c = add_cmd ("rdilogfile", class_maintenance,
98198944Sobrien	       rdilogfile_command,
982130803Smarcel	       "Set filename for ADP packet log.\n"
983130803Smarcel	       "This file is used to log Angel Debugger Protocol packets.\n"
984130803Smarcel	       "With a single argument, sets the logfile name to that value.\n"
985130803Smarcel	       "Without an argument, shows the current logfile name.\n"
986130803Smarcel	       "See also: rdilogenable\n",
987130803Smarcel	       &maintenancelist);
988130803Smarcel  set_cmd_completer (c, filename_completer);
98998944Sobrien
99098944Sobrien  add_cmd ("rdilogenable", class_maintenance,
99198944Sobrien	   rdilogenable_command,
992130803Smarcel	   "Set enable logging of ADP packets.\n"
993130803Smarcel	   "This will log ADP packets exchanged between gdb and the\n"
994130803Smarcel	   "rdi target device.\n"
995130803Smarcel	   "An argument of 1, t, true, y or yes will enable.\n"
996130803Smarcel	   "An argument of 0, f, false, n or no will disabled.\n"
997130803Smarcel	   "Withough an argument, it will display current state.\n",
99898944Sobrien	   &maintenancelist);
99998944Sobrien
1000130803Smarcel  add_setshow_boolean_cmd
1001130803Smarcel    ("rdiromatzero", no_class, &rom_at_zero,
1002130803Smarcel     "Set target has ROM at addr 0.\n"
1003130803Smarcel     "A true value disables vector catching, false enables vector catching.\n"
1004130803Smarcel     "This is evaluated at the time the 'target rdi' command is executed\n",
1005130803Smarcel     "Show if target has ROM at addr 0.\n",
1006130803Smarcel     NULL, NULL,
1007130803Smarcel     &setlist, &showlist);
100898944Sobrien
1009130803Smarcel  add_setshow_boolean_cmd
1010130803Smarcel    ("rdiheartbeat", no_class, &rdi_heartbeat,
1011130803Smarcel     "Set enable for ADP heartbeat packets.\n"
1012130803Smarcel     "I don't know why you would want this. If you enable them,\n"
1013130803Smarcel     "it will confuse ARM and EPI JTAG interface boxes as well\n"
1014130803Smarcel     "as the Angel Monitor.\n",
1015130803Smarcel     "Show enable for ADP heartbeat packets.\n",
1016130803Smarcel     NULL, NULL,
1017130803Smarcel     &setlist, &showlist);
101846283Sdfr}
101946283Sdfr
102046283Sdfr/* A little dummy to make linking with the library succeed. */
102146283Sdfr
1022130803Smarcelvoid
1023130803SmarcelFail (const char *ignored, ...)
102498944Sobrien{
1025130803Smarcel
102698944Sobrien}
1027