Sun Aug 1 22:58:18 1993 Stu Grossman (grossman at cygnus.com)
[deliverable/binutils-gdb.git] / gdb / remote-udi.c
index c2467cede9d6634c4a0a473d087d342a3c7d1743..b796e90003b85b87205847dfa684dacff9eb4518 100644 (file)
@@ -1,4 +1,4 @@
-/* Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
+/* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
    Copyright 1990, 1992 Free Software Foundation, Inc.
    Written by Daniel Mann.  Contributed by AMD.
 
    Copyright 1990, 1992 Free Software Foundation, Inc.
    Written by Daniel Mann.  Contributed by AMD.
 
@@ -18,18 +18,17 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* This is like remote.c but expects MiniMON to be running on the Am29000 
-   target hardware.
- - Originally written by Daniel Mann at AMD for gdb 3.91.6.
+/* This is like remote.c but uses the Universal Debug Interface (UDI) to 
+   talk to the target hardware (or simulator).  UDI is a TCP/IP based
+   protocol; for hardware that doesn't run TCP, an interface adapter 
+   daemon talks UDI on one side, and talks to the hardware (typically
+   over a serial port) on the other side.
+
+ - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
  - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
        file to gdb 3.95.  I was unable to get this working on sun3os4
  - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
        file to gdb 3.95.  I was unable to get this working on sun3os4
-       with termio, only with sgtty.  Because we are only attempting to
-       use this module to debug our kernel, which is already loaded when
-       gdb is started up, I did not code up the file downloading facilities.  
-       As a result this module has only the stubs to download files. 
-       You should get tagged at compile time if you need to make any 
-       changes/additions.
-*- Daniel Mann at AMD took the 3.95 adaptions above and replaced
+       with termio, only with sgtty.
+ - Daniel Mann at AMD took the 3.95 adaptions above and replaced
        MiniMON interface with UDI-p interface.   */
  
 #include "defs.h"
        MiniMON interface with UDI-p interface.   */
  
 #include "defs.h"
@@ -44,34 +43,29 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "terminal.h"
 #include "target.h"
 #include "29k-share/udi/udiproc.h"
 #include "terminal.h"
 #include "target.h"
 #include "29k-share/udi/udiproc.h"
+#include "gdbcmd.h"
+#include "bfd.h"
 
 /* access the register store directly, without going through
 
 /* access the register store directly, without going through
-   the normal handler functions. This avoids an extra data copy
-*/
-
-/* #define DEBUG 1             /* */
-#ifdef DEBUG 
-# define DENTER(NAME)  (printf("Entering %s\n",NAME), fflush(stdout)) 
-# define DEXIT(NAME)   (printf("Exiting  %s\n",NAME), fflush(stdout))
-#else
-# define DENTER(NAME)  
-# define DEXIT(NAME)   
-#endif 
-
+   the normal handler functions. This avoids an extra data copy.  */
 
 
+static int kiodebug;
 extern int stop_soon_quietly;           /* for wait_for_inferior */
 extern struct value *call_function_by_hand();
 extern int stop_soon_quietly;           /* for wait_for_inferior */
 extern struct value *call_function_by_hand();
-static void udi_resume();
-static void udi_fetch_registers ();
-static void udi_load();
-static int fetch_register ();
-static void udi_store_registers ();
-static int store_register ();
-static int regnum_to_srnum();
-static void  udi_close ();
-static CPUSpace udi_memory_space();
-static int udi_write_inferior_memory();
-static int udi_read_inferior_memory();
+static void udi_resume PARAMS ((int pid, int step, int sig));
+static void udi_fetch_registers PARAMS ((int regno));
+static void udi_load PARAMS ((char *args, int from_tty));
+static void fetch_register PARAMS ((int regno));
+static void udi_store_registers PARAMS ((int regno));
+static int store_register PARAMS ((int regno));
+static int regnum_to_srnum PARAMS ((int regno));
+static void udi_close PARAMS ((int quitting));
+static CPUSpace udi_memory_space PARAMS ((CORE_ADDR addr));
+static int udi_write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+                                             int len));
+static int udi_read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+                                            int len));
+static void download PARAMS ((char *load_arg_string, int from_tty));
 char   CoffFileName[100] = "";
 /*
  * Processor types. 
 char   CoffFileName[100] = "";
 /*
  * Processor types. 
@@ -82,7 +76,7 @@ char   CoffFileName[100] = "";
 #define TYPE_A29050     3
 static  char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
 static  int processor_type=TYPE_UNKNOWN;
 #define TYPE_A29050     3
 static  char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
 static  int processor_type=TYPE_UNKNOWN;
-#define FREEZE_MODE     (read_register(CPS_REGNUM) && 0x400)
+#define FREEZE_MODE     (read_register(CPS_REGNUM) & 0x400)
 #define USE_SHADOW_PC  ((processor_type == TYPE_A29050) && FREEZE_MODE) 
 
 #define LLOG_FILE "udi.log"
 #define USE_SHADOW_PC  ((processor_type == TYPE_A29050) && FREEZE_MODE) 
 
 #define LLOG_FILE "udi.log"
@@ -101,16 +95,21 @@ extern struct target_ops udi_ops;             /* Forward declaration */
 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
    udi_open knows that we don't have a file open when the program
    starts.  */
 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
    udi_open knows that we don't have a file open when the program
    starts.  */
-  UDISessionId udi_session_id = -1;
 
 
-  CPUOffset    IMemStart = 0;
-  CPUSizeT     IMemSize = 0;
-  CPUOffset    DMemStart = 0;
-  CPUSizeT     DMemSize = 0;
-  CPUOffset    RMemStart = 0;
-  CPUSizeT     RMemSize = 0;
-  UDIUInt32    CPUPRL;
-  UDIUInt32    CoProcPRL;
+UDISessionId udi_session_id = -1;
+
+CPUOffset IMemStart = 0;
+CPUSizeT IMemSize = 0;
+CPUOffset DMemStart = 0;
+CPUSizeT DMemSize = 0;
+CPUOffset RMemStart = 0;
+CPUSizeT RMemSize = 0;
+UDIUInt32 CPUPRL;
+UDIUInt32 CoProcPRL;
+
+UDIMemoryRange address_ranges[2]; /* Text and data */
+UDIResource entry = {0, 0};    /* Entry point */
+CPUSizeT stack_sizes[2];       /* Regular and memory stacks */
 
 #define        SBUF_MAX        1024    /* maximum size of string handling buffer */
 char sbuf[SBUF_MAX];
 
 #define        SBUF_MAX        1024    /* maximum size of string handling buffer */
 char sbuf[SBUF_MAX];
@@ -126,98 +125,76 @@ typedef   struct  bkpt_entry_str
 static bkpt_entry_t    bkpt_table[BKPT_TABLE_SIZE];
 extern char    dfe_errmsg[];           /* error string */
 
 static bkpt_entry_t    bkpt_table[BKPT_TABLE_SIZE];
 extern char    dfe_errmsg[];           /* error string */
 
-/*********************************************************** SIGNAL SUPPORT */
-/* Called when SIGALRM signal sent due to alarm() timeout.  */
-#ifndef HAVE_TERMIO
-
-#ifndef __STDC__
-# ifndef volatile
-#  define volatile /**/
-# endif
-#endif
-volatile int n_alarms;
-
-static void
-udi_timer ()
-{
-#if 0
-  if (kiodebug)
-    printf ("udi_timer called\n");
-#endif
-  n_alarms++;
-}
-#endif /* HAVE_TERMIO */
-
 /* malloc'd name of the program on the remote system.  */
 static char *prog_name = NULL;
 
 /* malloc'd name of the program on the remote system.  */
 static char *prog_name = NULL;
 
-
 /* Number of SIGTRAPs we need to simulate.  That is, the next
    NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
    SIGTRAP without actually waiting for anything.  */
 
 /* Number of SIGTRAPs we need to simulate.  That is, the next
    NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
    SIGTRAP without actually waiting for anything.  */
 
-/******************************************************* UDI_CREATE_INFERIOR */
 /* This is called not only when we first attach, but also when the
    user types "run" after having attached.  */
 /* This is called not only when we first attach, but also when the
    user types "run" after having attached.  */
+
 static void
 udi_create_inferior (execfile, args, env)
      char *execfile;
      char *args;
      char **env;
 {
 static void
 udi_create_inferior (execfile, args, env)
      char *execfile;
      char *args;
      char **env;
 {
-  DENTER("udi_create_inferior()");
+  char *args1;
 
   if (execfile)
 
   if (execfile)
-  { if (prog_name != NULL)
-       free (prog_name);
-    prog_name = savestring (execfile, strlen (execfile));
-  }
-
-  if (prog_name == 0 /* || exec_bfd == 0 */ )
-    error ("No exec file specified");
+    {
+      if (prog_name != NULL)
+       free (prog_name);
+      prog_name = savestring (execfile, strlen (execfile));
+    }
+  else if (entry.Offset)
+    execfile = "";
+  else
+    error ("No image loaded into target.");
 
 
-  if (udi_session_id < 0){
-        printf("UDI connection not open yet.\n");
-       return;
-  }
+  if (udi_session_id < 0)
+    {
+      printf("UDI connection not open yet.\n");
+      return;
+    }
 
   inferior_pid = 40000;
 
 
   inferior_pid = 40000;
 
-#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
-   /* On ultra3 (NYU) we assume the kernel is already running so there is
-    *   no file to download
-    */
-#else
-  if(*args == '\0') args = prog_name;
-   udi_load(args, 0);
-#endif  /* !ULTRA3 */
-
-  /* We will get a task spawn event immediately.  */
-#ifdef NOTDEF          /* start_remote() now does a wait without a resume 
-                          so don't use it*/ 
-  start_remote ();
-#else
+  if (!entry.Offset)
+    download(execfile, 0);
+
+  args1 = alloca (strlen(execfile) + strlen(args) + 2);
+
+  strcpy (args1, execfile);
+  strcat (args1, " ");
+  strcat (args1, args);
+
+  UDIInitializeProcess (address_ranges,                /* ProcessMemory[] */
+                       (UDIInt)2,              /* NumberOfRanges */
+                       entry,                  /* EntryPoint */
+                       stack_sizes,            /* *StackSizes */
+                       (UDIInt)2,              /* NumberOfStacks */
+                       args1);                 /* ArgString */
+
   init_wait_for_inferior ();
   clear_proceed_status ();
   proceed(-1,-1,0);
   init_wait_for_inferior ();
   clear_proceed_status ();
   proceed(-1,-1,0);
-#endif
-  DEXIT("udi_create_inferior()");
 }
 }
-/******************************************************* UDI_MOURN_INFERIOR */
+
 static void
 udi_mourn()
 {
 static void
 udi_mourn()
 {
-  DENTER("udi_mourn()");
         pop_target ();                /* Pop back to no-child state */
         generic_mourn_inferior ();
         pop_target ();                /* Pop back to no-child state */
         generic_mourn_inferior ();
-  DEXIT("udi_mourn()");
 }
 
 /******************************************************************** UDI_OPEN
 ** Open a connection to remote TIP.
    NAME is the socket domain used for communication with the TIP,
    then a space and the socket name or TIP-host name.
 }
 
 /******************************************************************** UDI_OPEN
 ** Open a connection to remote TIP.
    NAME is the socket domain used for communication with the TIP,
    then a space and the socket name or TIP-host name.
-   '<udi_udi_config_id> [progname]' for example.
+   '<udi_udi_config_id>' for example.
  */
 
 /* XXX - need cleanups for udiconnect for various failures!!! */
  */
 
 /* XXX - need cleanups for udiconnect for various failures!!! */
@@ -228,59 +205,35 @@ udi_open (name, from_tty)
      char *name;
      int from_tty;
 {
      char *name;
      int from_tty;
 {
-  unsigned int prl;
-  char         *p;
-  int          cnt;
+  unsigned int prl;
+  char *p;
+  int cnt;
   UDIMemoryRange KnownMemory[10];
   UDIMemoryRange KnownMemory[10];
-  UDIUInt32    ChipVersions[10];
-  UDIInt       NumberOfRanges = 10;
-  UDIInt       NumberOfChips = 10;
-  UDIPId       PId;
-  UDIUInt32    TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
-
-  DENTER("udi_open()");
+  UDIUInt32 ChipVersions[10];
+  UDIInt NumberOfRanges = 10;
+  UDIInt NumberOfChips = 10;
+  UDIPId PId;
+  UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
 
   target_preopen(from_tty);
 
 
   target_preopen(from_tty);
 
-  /* Find the first whitespace character, it separates udi_config_id
-     from prog_name.  */
-  if(!name) goto erroid;
-    for (p = name;
-         *p != '\0' && !isspace (*p); p++)
-      ;
-  if (*p == '\0')
-erroid:
-    error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
-
-  udi_config_id = (char*)malloc (p - name + 1);
-  strncpy (udi_config_id, name, p - name);
-  udi_config_id[p - name] = '\0';
-
-  /* Skip over the whitespace after udi_config_id */
-  for (; isspace (*p); p++)
-    /*EMPTY*/;
-  
-  if (prog_name != NULL)
-    free (prog_name);
-  prog_name = savestring (p, strlen (p));
+  entry.Offset = 0;
 
 
-  if (UDIConnect(udi_config_id, &udi_session_id))
-    error("UDIConnect() failed: %s\n", dfe_errmsg);
+  for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
+    bkpt_table[cnt].Type = 0;
 
 
-  push_target (&udi_ops);
+  if (udi_config_id)
+    free (udi_config_id);
 
 
-#ifndef HAVE_TERMIO
-#ifndef NO_SIGINTERRUPT
-  /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
-     the read.  */
-  if (siginterrupt (SIGALRM, 1) != 0)
-    error ("udi_open: siginterrupt() %s", safe_strerror(errno));
-#endif
+  if (!name)
+    error("Usage: target udi config_id, where config_id appears in udi_soc file");
 
 
-  /* Set up read timeout timer.  */
-  if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
-    error ("udi_open: signal() %s", safe_strerror(errno));
-#endif
+  udi_config_id = strdup (strtok (name, " \t"));
+
+  if (UDIConnect (udi_config_id, &udi_session_id))
+    error("UDIConnect() failed: %s\n", dfe_errmsg);
+
+  push_target (&udi_ops);
 
 #if defined (LOG_FILE)
   log_file = fopen (LOG_FILE, "w");
 
 #if defined (LOG_FILE)
   log_file = fopen (LOG_FILE, "w");
@@ -290,80 +243,77 @@ erroid:
   /*
   ** Initialize target configuration structure (global)
   */
   /*
   ** Initialize target configuration structure (global)
   */
-  if(UDIGetTargetConfig( KnownMemory, &NumberOfRanges,
-               ChipVersions, &NumberOfChips))
+  if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
+                         ChipVersions, &NumberOfChips))
     error ("UDIGetTargetConfig() failed");
     error ("UDIGetTargetConfig() failed");
-  if(NumberOfChips > 2)
-    fprintf(stderr,"Taret has more than one processor\n");
-  for(cnt=0; cnt<NumberOfRanges; cnt++)
-  {     switch(KnownMemory[cnt].Space)
+  if (NumberOfChips > 2)
+    fprintf(stderr,"Target has more than one processor\n");
+  for (cnt=0; cnt < NumberOfRanges; cnt++)
+    {
+      switch(KnownMemory[cnt].Space)
        {
        {
-       default: fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
-               break;
+       default:
+         fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
+         break;
        case UDI29KCP_S:
        case UDI29KCP_S:
-               break;
+         break;
        case UDI29KIROMSpace:
        case UDI29KIROMSpace:
-               RMemStart = KnownMemory[cnt].Offset;
-               RMemSize = KnownMemory[cnt].Size;
-               break;
+         RMemStart = KnownMemory[cnt].Offset;
+         RMemSize = KnownMemory[cnt].Size;
+         break;
        case UDI29KIRAMSpace:
        case UDI29KIRAMSpace:
-               IMemStart = KnownMemory[cnt].Offset;
-               IMemSize = KnownMemory[cnt].Size;
-               break;
+         IMemStart = KnownMemory[cnt].Offset;
+         IMemSize = KnownMemory[cnt].Size;
+         break;
        case UDI29KDRAMSpace:
        case UDI29KDRAMSpace:
-               DMemStart = KnownMemory[cnt].Offset;
-               DMemSize = KnownMemory[cnt].Size;
-               break;
+         DMemStart = KnownMemory[cnt].Offset;
+         DMemSize = KnownMemory[cnt].Size;
+         break;
        }
        }
-  }
+    }
 
   /* Determine the processor revision level */
 
   /* Determine the processor revision level */
-  prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
+  prl = (unsigned int)read_register (CFG_REGNUM) >> 24;
   if ((prl&0xe0) == 0)
   if ((prl&0xe0) == 0)
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29000;
       processor_type = TYPE_A29000;
-  } else if ((prl&0xe0) == 0x40)       /* 29030 = 0x4* */
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
+    }
+  else if ((prl&0xe0) == 0x40)       /* 29030 = 0x4* */
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29030;
       processor_type = TYPE_A29030;
-  } else if ((prl&0xe0) == 0x20)       /* 29050 = 0x2* */
-  {   fprintf_filtered(stderr,
-               "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
+    }
+  else if ((prl&0xe0) == 0x20)       /* 29050 = 0x2* */
+    {
+      fprintf_filtered (stderr,
+                       "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
       processor_type = TYPE_A29050;
       processor_type = TYPE_A29050;
-  } else {
+    }
+  else
+    {
       processor_type = TYPE_UNKNOWN;
       processor_type = TYPE_UNKNOWN;
-      fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
-  }
-  if(UDICreateProcess(&PId))
+      fprintf_filtered (stderr,"WARNING: processor type unknown.\n");
+    }
+  if (UDICreateProcess (&PId))
      fprintf(stderr, "UDICreateProcess() failed\n");
 
   /* Print out some stuff, letting the user now what's going on */
      fprintf(stderr, "UDICreateProcess() failed\n");
 
   /* Print out some stuff, letting the user now what's going on */
-  if(UDICapabilities( &TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
-       &TIPIPCId, sbuf))
+  if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
+                      &TIPIPCId, sbuf))
     error ("UDICapabilities() failed");
     error ("UDICapabilities() failed");
-  if (from_tty) {
-    printf_filtered("Remote debugging an %s connected via UDI socket,\n\
+  if (from_tty)
+    {
+      printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
  DFE-IPC version %x.%x.%x  TIP-IPC version %x.%x.%x  TIP version %x.%x.%x\n %s\n",
  DFE-IPC version %x.%x.%x  TIP-IPC version %x.%x.%x  TIP version %x.%x.%x\n %s\n",
-       processor_name[processor_type],
-       (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
-       (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
-       (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
-       sbuf);
-#ifdef ULTRA3
-    /* FIXME: can this restriction be removed? */
-    printf_filtered("Remote debugging using virtual addresses works only\n");
-    printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
-#endif
-  }
-#ifdef ULTRA3
-  if (processor_type != TYPE_A29050) {
-        fprintf_filtered(stderr,
-        "Freeze-mode debugging can only be done on an Am29050,\n");
-        fprintf_filtered(stderr,
-        " unless GDB is being used with a 29K simulator.\n");
-  }
-#endif
+                      processor_name[processor_type],
+                      (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
+                      (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
+                      (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
+                      sbuf);
+    }
 }
 
 /******************************************************************* UDI_CLOSE
 }
 
 /******************************************************************* UDI_CLOSE
@@ -374,16 +324,13 @@ static void
 udi_close (quitting)   /*FIXME: how is quitting used */
      int quitting;
 {
 udi_close (quitting)   /*FIXME: how is quitting used */
      int quitting;
 {
-  int  Terminate = -1;
-  DENTER("udi_close()");
-
   if (udi_session_id < 0)
   if (udi_session_id < 0)
-    error ("Can't close udi connection: not debugging remotely.");
+    return;
 
   /* We should never get here if there isn't something valid in
 
   /* We should never get here if there isn't something valid in
-     udi_session_id.
+     udi_session_id. */
 
 
-  if(UDIDisconnect(udi_stream, Terminate);)
+  if (UDIDisconnect (udi_session_id, UDITerminateSession))
     error ("UDIDisconnect() failed in udi_close");
 
   /* Do not try to close udi_session_id again, later in the program.  */
     error ("UDIDisconnect() failed in udi_close");
 
   /* Do not try to close udi_session_id again, later in the program.  */
@@ -398,8 +345,6 @@ udi_close (quitting)        /*FIXME: how is quitting used */
 #endif
 
   printf_filtered ("  Ending remote debugging\n");
 #endif
 
   printf_filtered ("  Ending remote debugging\n");
-
-  DEXIT("udi_close()");
 } 
 
 /**************************************************************** UDI_ATACH */
 } 
 
 /**************************************************************** UDI_ATACH */
@@ -417,23 +362,20 @@ udi_attach (args, from_tty)
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
-  DENTER("udi_attach()");
+  UDIError     err;
 
   if (udi_session_id < 0)
 
   if (udi_session_id < 0)
-      printf ("UDI connection not opened yet, use the 'target udi' command.\n");
+      error ("UDI connection not opened yet, use the 'target udi' command.\n");
        
   if (from_tty)
       printf ("Attaching to remote program %s...\n", prog_name);
 
        
   if (from_tty)
       printf ("Attaching to remote program %s...\n", prog_name);
 
-  mark_breakpoints_out ();
   UDIStop();
   UDIStop();
-  From.Space = 11;
-  From.Offset = UDI29KSpecialRegs;
-  if(UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
+  From.Space = UDI29KSpecialRegs;
+  From.Offset = 11;
+  if (err = UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
     error ("UDIRead failed in udi_attach");
   printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
     error ("UDIRead failed in udi_attach");
   printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
-
-  DEXIT("udi_attach()");
 }
 /************************************************************* UDI_DETACH */
 /* Terminate the open connection to the TIP process.
 }
 /************************************************************* UDI_DETACH */
 /* Terminate the open connection to the TIP process.
@@ -444,14 +386,16 @@ udi_detach (args,from_tty)
      char *args;
      int from_tty;
 {
      char *args;
      int from_tty;
 {
-  DENTER("udi_dettach()");
+
   remove_breakpoints();                /* Just in case there were any left in */
   remove_breakpoints();                /* Just in case there were any left in */
-  if(UDIDisconnect(udi_session_id))
+
+  if (UDIDisconnect (udi_session_id, UDIContinueSession))
     error ("UDIDisconnect() failed in udi_detach");
     error ("UDIDisconnect() failed in udi_detach");
+
   pop_target();                /* calls udi_close to do the real work */
   pop_target();                /* calls udi_close to do the real work */
+
   if (from_tty)
     printf ("Ending remote debugging\n");
   if (from_tty)
     printf ("Ending remote debugging\n");
-  DEXIT("udi_dettach()");
 }
 
 
 }
 
 
@@ -459,26 +403,26 @@ udi_detach (args,from_tty)
 ** Tell the remote machine to resume.  */
 
 static void
 ** Tell the remote machine to resume.  */
 
 static void
-udi_resume (step, sig)
-     int step, sig;
+udi_resume (pid, step, sig)
+     int pid, step, sig;
 {
 {
-  UDIError     tip_error;
-  UDIUInt32    Steps = 1;
-  UDIStepType   StepType = UDIStepNatural;
-  UDIRange      Range;
-  DENTER("udi_resume()");
+  UDIError tip_error;
+  UDIUInt32 Steps = 1;
+  UDIStepType StepType = UDIStepNatural;
+  UDIRange Range;
+
   if (step)                    /* step 1 instruction */
   if (step)                    /* step 1 instruction */
-  {  tip_error = tip_error = UDIStep(Steps, StepType, Range);
-      if(tip_error)fprintf(stderr,  "UDIStep() error = %d\n", tip_error);
-      if(tip_error)error ("failed in udi_resume");
+    {
+      tip_error = UDIStep (Steps, StepType, Range);
+      if (!tip_error)
+       return;
 
 
-  }
-  else 
-  { if(UDIExecute())
-      error ("UDIExecute() failed in udi_resume");
-  }
+      fprintf (stderr,  "UDIStep() error = %d\n", tip_error);
+      error ("failed in udi_resume");
+    }
 
 
-  DEXIT("udi_resume()");
+  if (UDIExecute())
+    error ("UDIExecute() failed in udi_resume");
 }
 
 /******************************************************************** UDI_WAIT
 }
 
 /******************************************************************** UDI_WAIT
@@ -497,7 +441,6 @@ udi_wait (status)
   int          old_immediate_quit = immediate_quit;
   int          i;
 
   int          old_immediate_quit = immediate_quit;
   int          i;
 
-  DENTER("udi_wait()");
   WSETEXIT ((*status), 0);
 
 /* wait for message to arrive. It should be:
   WSETEXIT ((*status), 0);
 
 /* wait for message to arrive. It should be:
@@ -505,117 +448,126 @@ udi_wait (status)
 */
   timeout = 0;                 /* Wait indefinetly for a message */
   immediate_quit = 1;          /* Helps ability to QUIT */
 */
   timeout = 0;                 /* Wait indefinetly for a message */
   immediate_quit = 1;          /* Helps ability to QUIT */
+
   while(1)
   while(1)
-  {
-    i = 0;
-    MaxTime = UDIWaitForever;
-    UDIWait(MaxTime, &PId, &StopReason);
-       QUIT;                   /* Let user quit if they want */
-    switch (StopReason & 0xff)
     {
     {
-    default:
-       goto halted;
-    case UDIStdoutReady:
-       if(UDIGetStdout(sbuf, (UDISizeT)SBUF_MAX, &CountDone))
-         error("UDIGetStdin() failed in udi_wait");
-       while(CountDone--)putc(sbuf[i++], stdout);
-       fflush(stdout);
-       break;
-    case UDIStderrReady:
-       UDIGetStderr(sbuf, (UDISizeT)SBUF_MAX, &CountDone);
-       while(CountDone--)putc(sbuf[i++], stderr);
-       fflush(stderr);
-       fflush(stderr);
-       break;
-    case UDIStdinNeeded:
-       printf("DEBUG: stdin requested ... continue\n");
-/*     UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
-       break;
-    case UDIStdinModeX:
-       break;
-    }
-  continue;
-  }
-halted:
-  if (StopReason & 0xff  == UDITrapped )  /* lower 8-bits == 0 */
-  {
-    if (StopReason >> 24  == 0)
-    { printf("Am290*0 received vector number 0 (break point)\n");
-      WSETSTOP ((*status), SIGTRAP);
-    }
-    else if (StopReason >> 24 == 1)
-    { printf("Am290*0 received vector 1\n");
-      WSETSTOP ((*status), SIGBUS);
-    }
-    else if (StopReason >> 24 == 3
-          || StopReason >> 24 == 4)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGFPE);
-    }
-    else if (StopReason >> 24 == 5)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGILL);
-    }
-    else if (StopReason >> 24 >= 6
-          && StopReason >> 24 <= 11)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGSEGV);
-    }
-    else if (StopReason >> 24 == 12
-          || StopReason >> 24 == 13)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGILL);
-    }
-    else if ((StopReason & 0xff) == 14)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGALRM);
-    }
-    else if ((StopReason & 0xff) == 15)
-      WSETSTOP ((*status), SIGTRAP);
-    else if ((StopReason >> 24) >= 16
-          && (StopReason >> 24) <= 21)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGINT);
-    }
-    else if ((StopReason & 0xff) == 22)
-    { printf("Am290*0 received vector number %d\n",
-         StopReason >> 24);
-      WSETSTOP ((*status), SIGILL);
+      i = 0;
+      MaxTime = UDIWaitForever;
+      UDIWait(MaxTime, &PId, &StopReason);
+      QUIT;                    /* Let user quit if they want */
+
+      switch (StopReason & UDIGrossState)
+       {
+       case UDIStdoutReady:
+         if (UDIGetStdout (sbuf, (UDISizeT)SBUF_MAX, &CountDone))
+           error ("UDIGetStdout() failed in udi_wait");
+         fwrite (sbuf, 1, CountDone, stdout);
+         fflush(stdout);
+         continue;
+       case UDIStderrReady:
+         UDIGetStderr (sbuf, (UDISizeT)SBUF_MAX, &CountDone);
+         fwrite (sbuf, 1, CountDone, stderr);
+         fflush(stderr);
+         continue;
+       case UDIStdinNeeded:
+         scanf ("%s", sbuf);
+         i = strlen (sbuf);
+         UDIPutStdin (sbuf, (UDISizeT)i, &CountDone);
+         continue;
+       case UDIRunning:
+         /* In spite of the fact that we told UDIWait to wait forever, it will
+            return spuriously sometimes.  */
+       case UDIStdinModeX:
+         continue;
+       default:
+         break;
+       }
+      break;
     }
     }
-    else if ((StopReason & 0xff) == 77)
-      WSETSTOP ((*status), SIGTRAP);
-    else
-exit:
-    WSETEXIT ((*status), 0);
-  }
-  else if ((StopReason & 0xff)  == UDIBreak)
-      WSETSTOP ((*status), SIGTRAP);
-  else if ((StopReason & 0xff)  == UDINotExecuting)
+
+  switch (StopReason & UDIGrossState)
+    {
+    case UDITrapped:
+      printf("Am290*0 received vector number %d\n", StopReason >> 24);
+         
+      switch (StopReason >> 8)
+       {
+       case 0:                 /* Illegal opcode */
+         printf("      (break point)\n");
+         WSETSTOP ((*status), SIGTRAP);
+         break;
+       case 1:                 /* Unaligned Access */
+         WSETSTOP ((*status), SIGBUS);
+         break;
+       case 3:
+       case 4:
+         WSETSTOP ((*status), SIGFPE);
+         break;
+       case 5:                 /* Protection Violation */
+         WSETSTOP ((*status), SIGILL);
+         break;
+       case 6:
+       case 7:
+       case 8:                 /* User Instruction Mapping Miss */
+       case 9:                 /* User Data Mapping Miss */
+       case 10:                /* Supervisor Instruction Mapping Miss */
+       case 11:                /* Supervisor Data Mapping Miss */
+         WSETSTOP ((*status), SIGSEGV);
+         break;
+       case 12:
+       case 13:
+         WSETSTOP ((*status), SIGILL);
+         break;
+       case 14:                /* Timer */
+         WSETSTOP ((*status), SIGALRM);
+         break;
+       case 15:                /* Trace */
+         WSETSTOP ((*status), SIGTRAP);
+         break;
+       case 16:                /* INTR0 */
+       case 17:                /* INTR1 */
+       case 18:                /* INTR2 */
+       case 19:                /* INTR3/Internal */
+       case 20:                /* TRAP0 */
+       case 21:                /* TRAP1 */
+         WSETSTOP ((*status), SIGINT);
+         break;
+       case 22:                /* Floating-Point Exception */
+         WSETSTOP ((*status), SIGILL);
+         break;
+       case 77:                /* assert 77 */
+         WSETSTOP ((*status), SIGTRAP);
+         break;
+       default:
+         WSETEXIT ((*status), 0);
+       }
+      break;
+    case UDINotExecuting:
       WSETSTOP ((*status), SIGTERM);
       WSETSTOP ((*status), SIGTERM);
-  else if ((StopReason & 0xff)  == UDIRunning)
-      WSETSTOP ((*status), SIGILL);
-  else if ((StopReason & 0xff)  == UDIStopped)
+      break;
+    case UDIStopped:
       WSETSTOP ((*status), SIGTSTP);
       WSETSTOP ((*status), SIGTSTP);
-  else if ((StopReason & 0xff)  == UDIWarned)
-      WSETSTOP ((*status), SIGLOST);
-  else if ((StopReason & 0xff)  == UDIStepped)
+      break;
+    case UDIWarned:
+      WSETSTOP ((*status), SIGURG);
+      break;
+    case UDIStepped:
+    case UDIBreak:
       WSETSTOP ((*status), SIGTRAP);
       WSETSTOP ((*status), SIGTRAP);
-  else if ((StopReason & 0xff)  == UDIWaiting)
+      break;
+    case UDIWaiting:
       WSETSTOP ((*status), SIGSTOP);
       WSETSTOP ((*status), SIGSTOP);
-  else if ((StopReason & 0xff)  == UDIHalted)
+      break;
+    case UDIHalted:
       WSETSTOP ((*status), SIGKILL);
       WSETSTOP ((*status), SIGKILL);
-  else
-    WSETEXIT ((*status), 0);
+      break;
+    case UDIExited:
+    default:
+      WSETEXIT ((*status), 0);
+    }
 
   timeout = old_timeout;       /* Restore original timeout value */
   immediate_quit = old_immediate_quit;
 
   timeout = old_timeout;       /* Restore original timeout value */
   immediate_quit = old_immediate_quit;
-  DEXIT("udi_wait()");
   return 0;
 }
 
   return 0;
 }
 
@@ -633,6 +585,7 @@ int regno;
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   int          i;
 
   if (regno >= 0)  {
   int          i;
 
   if (regno >= 0)  {
@@ -646,7 +599,7 @@ int regno;
   From.Offset = 1;
   To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
   Count = 1;
   From.Offset = 1;
   To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
   Count = 1;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   register_valid[GR1_REGNUM] = 1;
     error("UDIRead() failed in udi_fetch_registers");
 
   register_valid[GR1_REGNUM] = 1;
@@ -659,7 +612,7 @@ int regno;
   From.Offset = 64;
   To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
   Count = 32;
   From.Offset = 64;
   To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
   Count = 32;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
@@ -673,7 +626,7 @@ int regno;
   From.Offset = 96;
   To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
   Count = 32;
   From.Offset = 96;
   To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
   Count = 32;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
@@ -685,7 +638,7 @@ int regno;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
   Count = 128;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
   Count = 128;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
@@ -697,7 +650,7 @@ int regno;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
   Count = 15;
   From.Offset = 0;
   To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
   Count = 15;
-  if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
     error("UDIRead() failed in udi_fetch_registers");
 
   for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
@@ -714,13 +667,21 @@ int       regno;
     From.Offset = 128;
     To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
     Count = 135-128 + 1;
     From.Offset = 128;
     To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
     Count = 135-128 + 1;
-    if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+    if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
       error("UDIRead() failed in udi_fetch_registers");
 
     for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
       register_valid[i] = 1;
   }
 
       error("UDIRead() failed in udi_fetch_registers");
 
     for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
       register_valid[i] = 1;
   }
 
+  if (kiodebug)
+    {
+      printf("Fetching all registers\n");
+      printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
+            read_register(NPC_REGNUM), read_register(PC_REGNUM),
+            read_register(PC2_REGNUM));
+    }
+
   /* There doesn't seem to be any way to get these.  */
   {
     int val = -1;
   /* There doesn't seem to be any way to get these.  */
   {
     int val = -1;
@@ -754,6 +715,13 @@ int regno;
       return;
     }
 
       return;
     }
 
+  if (kiodebug)
+    {
+      printf("Storing all registers\n");
+      printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM),
+            read_register(PC_REGNUM), read_register(PC2_REGNUM));
+    }
+
 /* Gr1/rsp */
 
   From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
 /* Gr1/rsp */
 
   From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
@@ -952,84 +920,275 @@ udi_remove_breakpoint (addr, contents_cache)
   error("UDIClearBreakpoint returned error code %d\n", err);
 }
 
   error("UDIClearBreakpoint returned error code %d\n", err);
 }
 
-/***************************************************************** UDI_KILL */
 static void
 udi_kill(arg,from_tty)
 static void
 udi_kill(arg,from_tty)
-char    *arg;
-int     from_tty;
+     char *arg;
+     int from_tty;
 {
 {
-       char    buf[4];
 
 
-       DENTER("udi_kill()");
-#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
-       /* We don't ever kill the kernel */
-       if (from_tty) {
-               printf_filtered("Kernel not killed, but left in current state.\n");
-               printf_filtered("Use detach to leave kernel running.\n");
-       }
-#else
-       UDIStop();
-       inferior_pid = 0;
-       if (from_tty) {
-               printf("Target has been stopped.");
-       }
-       pop_target();
-#endif 
-       DEXIT("udi_kill()");
-}
+#if 0
+/*
+UDIStop does not really work as advertised.  It causes the TIP to close it's
+connection, which usually results in GDB dying with a SIGPIPE.  For now, we
+just invoke udi_close, which seems to get things right.
+*/
+  UDIStop();
 
 
+  udi_session_id = -1;
+  inferior_pid = 0;
 
 
+  if (from_tty)
+    printf("Target has been stopped.");
+#else
+  udi_close(0);
+#endif
+  pop_target();
+}
 
 
-/***************************************************************** UDI_LOAD */
 /* 
 /* 
- * Load a program into the target.
- */
+   Load a program into the target.  Args are: `program {options}'.  The options
+   are used to control loading of the program, and are NOT passed onto the
+   loaded code as arguments.  (You need to use the `run' command to do that.)
+
+   The options are:
+               -ms %d  Set mem stack size to %d
+               -rs %d  Set regular stack size to %d
+               -i      send init info (default)
+               -noi    don't send init info
+               -[tT]   Load Text section
+               -[dD]   Load Data section
+               -[bB]   Load BSS section
+               -[lL]   Load Lit section
+  */
+
 static void
 static void
-udi_load(arg_string,from_tty)
-char   *arg_string;
-int    from_tty;
+download(load_arg_string, from_tty)
+     char *load_arg_string;
+     int from_tty;
 {
 {
-#define MAX_TOKENS 25
-#define BUFFER_SIZE 256
-   int token_count;
-   char        *token[MAX_TOKENS];
-   char        cmd_line[BUFFER_SIZE];
+#define DEFAULT_MEM_STACK_SIZE                 0x6000
+#define DEFAULT_REG_STACK_SIZE                 0x2000
+
+  char *token;
+  char *filename;
+  asection *section;
+  bfd *pbfd;
+  UDIError err;
+  int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
+
+  address_ranges[0].Space = UDI29KIRAMSpace;
+  address_ranges[0].Offset = 0xffffffff;
+  address_ranges[0].Size = 0;
+
+  address_ranges[1].Space = UDI29KDRAMSpace;
+  address_ranges[1].Offset = 0xffffffff;
+  address_ranges[1].Size = 0;
+
+  stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
+  stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
 
   dont_repeat ();
 
 
   dont_repeat ();
 
-#if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
-  printf("The kernel had better be loaded already!  Loading not done.\n");
-#else
-  if (arg_string == 0)
-    error ("The load command takes a file name");
-  arg_string = tilde_expand (arg_string);
-  sprintf(cmd_line,"y %s %s", prog_name, arg_string);
-
-  token_count = 0;
-  token[0] = cmd_line;
-
-  if (cmd_line[0] != '\0')
-  { token[token_count] = strtok(cmd_line, " \t,;\n\r");
-
-    if (token[token_count] != NULL)
-    { do {
-            token_count = token_count + 1;
-            token[token_count] = strtok((char *) NULL, " \t,;\n\r");
-         } while ((token[token_count] != NULL) &&
-                     (token_count < MAX_TOKENS));
+  filename = strtok(load_arg_string, " \t");
+  if (!filename)
+    error ("Must specify at least a file name with the load command");
+
+  filename = tilde_expand (filename);
+  make_cleanup (free, filename);
+
+  while (token = strtok (NULL, " \t"))
+    {
+      if (token[0] == '-')
+       {
+         token++;
+
+         if (STREQ (token, "ms"))
+           stack_sizes[1] = atol (strtok (NULL, " \t"));
+         else if (STREQ (token, "rs"))
+           stack_sizes[0] = atol (strtok (NULL, " \t"));
+         else
+           {
+             load_text = load_data = load_bss = load_lit = 0;
+
+             while (*token)
+               {
+                 switch (*token++)
+                   {
+                   case 't':
+                   case 'T':
+                     load_text = 1;
+                     break;
+                   case 'd':
+                   case 'D':
+                     load_data = 1;
+                     break;
+                   case 'b':
+                   case 'B':
+                     load_bss = 1;
+                     break;
+                   case 'l':
+                   case 'L':
+                     load_lit = 1;
+                     break;
+                   default:
+                     error ("Unknown UDI load option -%s", token-1);
+                   }
+               }
+           }
+       }
     }
     }
-    else
-         *token[0] = '\0';
-  }
-  make_cleanup (free, arg_string);
+
+  pbfd = bfd_openr (filename, 0);
+
+  if (!pbfd) 
+    perror_with_name (filename);
+  
+  make_cleanup (bfd_close, pbfd);
+
   QUIT;
   immediate_quit++;
   QUIT;
   immediate_quit++;
-  if(yank_cmd(token, token_count))
-       error("Failure when tring to load program");
+
+  if (!bfd_check_format (pbfd, bfd_object)) 
+    error ("It doesn't seem to be an object file");
+  
+  for (section = pbfd->sections; section; section = section->next) 
+    {
+      if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
+       {
+         UDIResource To;
+         UDICount Count;
+         unsigned long section_size, section_end;
+         const char *section_name;
+
+         section_name = bfd_get_section_name (pbfd, section);
+         if (STREQ (section_name, ".text") && !load_text)
+           continue;
+         else if (STREQ (section_name, ".data") && !load_data)
+           continue;
+         else if (STREQ (section_name, ".bss") && !load_bss)
+           continue;
+         else if (STREQ (section_name, ".lit") && !load_lit)
+           continue;
+
+         To.Offset = bfd_get_section_vma (pbfd, section);
+         section_size = bfd_section_size (pbfd, section);
+         section_end = To.Offset + section_size;
+
+         printf("[Loading section %s at %x (%d bytes)]\n",
+                section_name,
+                To.Offset,
+                section_size);
+
+         if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
+           {
+             To.Space = UDI29KIRAMSpace;
+
+             address_ranges[0].Offset = min (address_ranges[0].Offset,
+                                             To.Offset);
+             address_ranges[0].Size = max (address_ranges[0].Size,
+                                           section_end
+                                           - address_ranges[0].Offset);
+           }
+         else
+           {
+             To.Space = UDI29KDRAMSpace;
+
+             address_ranges[1].Offset = min (address_ranges[1].Offset,
+                                             To.Offset);
+             address_ranges[1].Size = max (address_ranges[1].Size,
+                                           section_end
+                                           - address_ranges[1].Offset);
+           }
+
+         if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
+           {
+             file_ptr fptr;
+
+             fptr = 0;
+
+             while (section_size > 0)
+               {
+                 char buffer[1024];
+
+                 Count = min (section_size, 1024);
+
+                 bfd_get_section_contents (pbfd, section, buffer, fptr,
+                                           Count);
+
+                 err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
+                                 To,                   /* To */
+                                 Count,                /* Count */
+                                 (UDISizeT)1,          /* Size */
+                                 &Count,               /* CountDone */
+                                 (UDIBool)0);          /* HostEndian */
+                 if (err)
+                   error ("UDIWrite failed, error = %d", err);
+
+                 To.Offset += Count;
+                 fptr += Count;
+                 section_size -= Count;
+               }
+           }
+         else                  /* BSS */
+           {
+             UDIResource From;
+             unsigned long zero = 0;
+
+             /* Write a zero byte at the vma */
+             err = UDIWrite ((UDIHostMemPtr)&zero,     /* From */
+                             To,                       /* To */
+                             (UDICount)1,              /* Count */
+                             (UDISizeT)4,              /* Size */
+                             &Count,                   /* CountDone */
+                             (UDIBool)0);              /* HostEndian */
+             if (err)
+               error ("UDIWrite failed, error = %d", err);
+
+             From = To;
+             To.Offset+=4;
+
+             /* Now, duplicate it for the length of the BSS */
+             err = UDICopy (From,                      /* From */
+                            To,                        /* To */
+                            (UDICount)(section_size/4 - 1), /* Count */
+                            (UDISizeT)4,               /* Size */
+                            &Count,                    /* CountDone */
+                            (UDIBool)1);               /* Direction */
+             if (err)
+               {
+                 char message[100];
+                 int xerr;
+
+                 xerr = UDIGetErrorMsg(err, 100, message, &Count);
+                 if (!xerr)
+                   fprintf (stderr, "Error is %s\n", message);
+                 else
+                   fprintf (stderr, "xerr is %d\n", xerr);
+                 error ("UDICopy failed, error = %d", err);
+               }
+           }
+
+       }
+    }
+
+  entry.Space = UDI29KIRAMSpace;
+  entry.Offset = bfd_get_start_address (pbfd);
+  
   immediate_quit--;
   immediate_quit--;
-  symbol_file_add (arg_string, from_tty, 0, 0, 0, 0);/*DEBUG need to add text_addr */
-#endif
+}
+
+/* User interface to download an image into the remote target.  See download()
+ * for details on args.
+ */
+
+static void
+udi_load(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  download (args, from_tty);
 
 
+  symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
 }
 
 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
 }
 
 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
@@ -1049,9 +1208,7 @@ udi_write_inferior_memory (memaddr, myaddr, len)
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
   
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
   
-
-  /* DENTER("udi_write_inferior_memory()"); */
-  To.Space = udi_memory_space(memaddr);        
+  To.Space = udi_memory_space(memaddr);
   From = (UDIUInt32*)myaddr;
 
   while (nwritten < len)
   From = (UDIUInt32*)myaddr;
 
   while (nwritten < len)
@@ -1067,7 +1224,6 @@ udi_write_inferior_memory (memaddr, myaddr, len)
           From += CountDone;
        }
   }
           From += CountDone;
        }
   }
-  /* DEXIT("udi_write_inferior_memory()"); */
   return(nwritten);
 }
 
   return(nwritten);
 }
 
@@ -1087,9 +1243,8 @@ udi_read_inferior_memory(memaddr, myaddr, len)
   UDISizeT     Size = 1;
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
   UDISizeT     Size = 1;
   UDICount     CountDone = 0;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   
   
-
-  /* DENTER("udi_read_inferior_memory()"); */
   From.Space = udi_memory_space(memaddr);      
   To = (UDIUInt32*)myaddr;
 
   From.Space = udi_memory_space(memaddr);      
   To = (UDIUInt32*)myaddr;
 
@@ -1097,8 +1252,8 @@ udi_read_inferior_memory(memaddr, myaddr, len)
   {    Count = len - nread;
        if (Count > MAXDATA) Count = MAXDATA;
        From.Offset = memaddr + nread;
   {    Count = len - nread;
        if (Count > MAXDATA) Count = MAXDATA;
        From.Offset = memaddr + nread;
-        if(UDIRead(From, To, Count, Size, &CountDone, HostEndian))
-       {  error("UDIWrite() failed in udi_read_inferrior_memory");
+        if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
+       {  error("UDIRead() failed in udi_read_inferrior_memory");
           break;       
        }
        else
           break;       
        }
        else
@@ -1122,7 +1277,7 @@ int       num;
 /* Fetch a single register indicatated by 'regno'. 
  * Returns 0/-1 on success/failure.  
  */
 /* Fetch a single register indicatated by 'regno'. 
  * Returns 0/-1 on success/failure.  
  */
-static int
+static void
 fetch_register (regno)
      int regno;
 {
 fetch_register (regno)
      int regno;
 {
@@ -1132,6 +1287,7 @@ fetch_register (regno)
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
   UDISizeT     Size = 4;
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
+  UDIError     err;
   int                  result;
 
   if (regno == GR1_REGNUM)
   int                  result;
 
   if (regno == GR1_REGNUM)
@@ -1164,7 +1320,7 @@ fetch_register (regno)
     {
       int val = -1;
       supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
     {
       int val = -1;
       supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
-      return 0;                /* Pretend Success */
+      return;          /* Pretend Success */
     }
   else 
     {
     }
   else 
     {
@@ -1172,11 +1328,13 @@ fetch_register (regno)
       From.Offset = regnum_to_srnum(regno); 
     }
 
       From.Offset = regnum_to_srnum(regno); 
     }
 
-  if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
+  if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
     error("UDIRead() failed in udi_fetch_registers");
 
   supply_register(regno, (char *) &To);
     error("UDIRead() failed in udi_fetch_registers");
 
   supply_register(regno, (char *) &To);
-  return result;
+
+  if (kiodebug)
+    printf("Fetching register %s = 0x%x\n", reg_names[regno], To);
 }
 /*****************************************************************************/ 
 /* Store a single register indicated by 'regno'. 
 }
 /*****************************************************************************/ 
 /* Store a single register indicated by 'regno'. 
@@ -1194,9 +1352,11 @@ store_register (regno)
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
 
   UDICount     CountDone;
   UDIBool      HostEndian = 0;
 
-  DENTER("store_register()");
   From =  read_register (regno);       /* get data value */
 
   From =  read_register (regno);       /* get data value */
 
+  if (kiodebug)
+    printf("Storing register %s = 0x%x\n", reg_names[regno], From);
+
   if (regno == GR1_REGNUM)
   { To.Space = UDI29KGlobalRegs;
     To.Offset = 1;
   if (regno == GR1_REGNUM)
   { To.Space = UDI29KGlobalRegs;
     To.Offset = 1;
@@ -1236,7 +1396,6 @@ store_register (regno)
     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
   }
 
     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
   }
 
-  DEXIT("store_register()");
   if(result)
   { result = -1;
     error("UDIWrite() failed in store_registers");
   if(result)
   { result = -1;
     error("UDIWrite() failed in store_registers");
@@ -1291,7 +1450,7 @@ int       regno;
  */
 static CPUSpace
 udi_memory_space(addr)
  */
 static CPUSpace
 udi_memory_space(addr)
-CORE_ADDR      *addr;
+CORE_ADDR      addr;
 {
        UDIUInt32 tstart = IMemStart;
        UDIUInt32 tend   = tstart + IMemSize;  
 {
        UDIUInt32 tstart = IMemStart;
        UDIUInt32 tend   = tstart + IMemSize;  
@@ -1323,30 +1482,74 @@ int   QuietMode = 0;            /* used for debugging */
  *  Define the target subroutine names 
  */
 static struct target_ops udi_ops = {
  *  Define the target subroutine names 
  */
 static struct target_ops udi_ops = {
-        "udi", "Remote UDI connected TIP",
-       "Remote debug an Am290*0 using socket connection to TIP process ",
-        udi_open, udi_close,
-        udi_attach, udi_detach, udi_resume, udi_wait,
-        udi_fetch_registers, udi_store_registers,
-        udi_prepare_to_store, 0, 0,   /* conv_to, conv_from */
+        "udi",
+       "Remote UDI connected TIP",
+       "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
+Arguments are\n\
+`configuration-id AF_INET hostname port-number'\n\
+    To connect via the network, where hostname and port-number specify the\n\
+    host and port where you can connect via UDI.\n\
+    configuration-id is unused.\n\
+\n\
+`configuration-id AF_UNIX socket-name tip-program'\n\
+    To connect using a local connection to the \"tip.exe\" program which is\n\
+    supplied by AMD.  If socket-name specifies an AF_UNIX socket then the\n\
+    tip program must already be started; connect to it using that socket.\n\
+    If not, start up tip-program, which should be the name of the tip\n\
+    program.  If appropriate, the PATH environment variable is searched.\n\
+    configuration-id is unused.\n\
+\n\
+`configuration-id'\n\
+    Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
+    are files containing lines in the above formats.  configuration-id is\n\
+    used to pick which line of the file to use.",
+        udi_open,
+       udi_close,
+        udi_attach,
+       udi_detach,
+       udi_resume,
+       udi_wait,
+        udi_fetch_registers,
+       udi_store_registers,
+        udi_prepare_to_store,
         udi_xfer_inferior_memory,
         udi_files_info,
         udi_xfer_inferior_memory,
         udi_files_info,
-        udi_insert_breakpoint, udi_remove_breakpoint, /* Breakpoints */
-        0, 0, 0, 0, 0,          /* Terminal handling */
+        udi_insert_breakpoint,
+       udi_remove_breakpoint,
+        0,                     /* termial_init */
+       0,                      /* terminal_inferior */
+       0,                      /* terminal_ours_for_output */
+       0,                      /* terminal_ours */
+       0,                      /* terminal_info */
         udi_kill,              /* FIXME, kill */
         udi_load,
         0,                      /* lookup_symbol */
         udi_kill,              /* FIXME, kill */
         udi_load,
         0,                      /* lookup_symbol */
-        udi_create_inferior,  /* create_inferior */
-        udi_mourn,            /* mourn_inferior FIXME */
-        process_stratum, 0, /* next */
-        1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
-       0, 0,                   /* Section pointers */
+        udi_create_inferior,
+        udi_mourn,             /* mourn_inferior FIXME */
+       0,                      /* can_run */
+       0,                      /* notice_signals */
+        process_stratum,
+       0,                      /* next */
+        1,                     /* has_all_memory */
+       1,                      /* has_memory */
+       1,                      /* has_stack */
+       1,                      /* has_registers */
+       1,                      /* has_execution */
+       0,                      /* sections */
+       0,                      /* sections_end */
        OPS_MAGIC,              /* Always the last thing */
 };
 
 void _initialize_remote_udi()
 {
   add_target (&udi_ops);
        OPS_MAGIC,              /* Always the last thing */
 };
 
 void _initialize_remote_udi()
 {
   add_target (&udi_ops);
+  add_show_from_set (
+                    add_set_cmd ("remotedebug", no_class, var_boolean,
+                                 (char *)&kiodebug,
+                                 "Set debugging of UDI I/O.\n\
+When enabled, debugging info is displayed.",
+                                 &setlist),
+                    &showlist);
 }
 
 #ifdef NO_HIF_SUPPORT
 }
 
 #ifdef NO_HIF_SUPPORT
This page took 0.039306 seconds and 4 git commands to generate.