home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gdb-4.9 / gdb / remote-udi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-12  |  41.6 KB  |  1,578 lines

  1. /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
  2.    Copyright 1990, 1992 Free Software Foundation, Inc.
  3.    Written by Daniel Mann.  Contributed by AMD.
  4.  
  5. This file is part of GDB.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* This is like remote.c but uses the Universal Debug Interface (UDI) to 
  22.    talk to the target hardware (or simulator).  UDI is a TCP/IP based
  23.    protocol; for hardware that doesn't run TCP, an interface adapter 
  24.    daemon talks UDI on one side, and talks to the hardware (typically
  25.    over a serial port) on the other side.
  26.  
  27.  - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
  28.  - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
  29.     file to gdb 3.95.  I was unable to get this working on sun3os4
  30.     with termio, only with sgtty.  Because we are only attempting to
  31.     use this module to debug our kernel, which is already loaded when
  32.     gdb is started up, I did not code up the file downloading facilities.  
  33.     As a result this module has only the stubs to download files. 
  34.     You should get tagged at compile time if you need to make any 
  35.     changes/additions.
  36.  - Daniel Mann at AMD took the 3.95 adaptions above and replaced
  37.        MiniMON interface with UDI-p interface.      */
  38.  
  39. #include "defs.h"
  40. #include "inferior.h"
  41. #include "wait.h"
  42. #include "value.h"
  43. #include <ctype.h>
  44. #include <fcntl.h>
  45. #include <signal.h>
  46. #include <errno.h>
  47. #include <string.h>
  48. #include "terminal.h"
  49. #include "target.h"
  50. #include "29k-share/udi/udiproc.h"
  51. #include "gdbcmd.h"
  52. #include "bfd.h"
  53.  
  54. /* access the register store directly, without going through
  55.    the normal handler functions. This avoids an extra data copy.  */
  56.  
  57. static int kiodebug;
  58. extern int stop_soon_quietly;           /* for wait_for_inferior */
  59. extern struct value *call_function_by_hand();
  60. static void udi_resume PARAMS ((int step, int sig));
  61. static void udi_fetch_registers PARAMS ((int regno));
  62. static void udi_load PARAMS ((char *args, int from_tty));
  63. static void fetch_register PARAMS ((int regno));
  64. static void udi_store_registers PARAMS ((int regno));
  65. static int store_register PARAMS ((int regno));
  66. static int regnum_to_srnum PARAMS ((int regno));
  67. static void udi_close PARAMS ((int quitting));
  68. static CPUSpace udi_memory_space PARAMS ((CORE_ADDR addr));
  69. static int udi_write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
  70.                           int len));
  71. static int udi_read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
  72.                          int len));
  73. static void download PARAMS ((char *load_arg_string, int from_tty));
  74. char   CoffFileName[100] = "";
  75. /*
  76.  * Processor types. 
  77.  */
  78. #define TYPE_UNKNOWN    0
  79. #define TYPE_A29000     1
  80. #define TYPE_A29030     2
  81. #define TYPE_A29050     3
  82. static  char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
  83. static  int processor_type=TYPE_UNKNOWN;
  84. #define FREEZE_MODE     (read_register(CPS_REGNUM) & 0x400)
  85. #define USE_SHADOW_PC    ((processor_type == TYPE_A29050) && FREEZE_MODE) 
  86.  
  87. #define LLOG_FILE "udi.log"
  88. #if defined (LOG_FILE)
  89. FILE *log_file;
  90. #endif
  91.  
  92. static int timeout = 5;
  93. extern struct target_ops udi_ops;             /* Forward declaration */
  94.  
  95. /* Special register enumeration.
  96. */
  97.  
  98. /******************************************************************* UDI DATA*/
  99. #define    MAXDATA        2*1024        /* max UDI[read/write] byte size */
  100. /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
  101.    udi_open knows that we don't have a file open when the program
  102.    starts.  */
  103.  
  104. UDISessionId udi_session_id = -1;
  105.  
  106. CPUOffset IMemStart = 0;
  107. CPUSizeT IMemSize = 0;
  108. CPUOffset DMemStart = 0;
  109. CPUSizeT DMemSize = 0;
  110. CPUOffset RMemStart = 0;
  111. CPUSizeT RMemSize = 0;
  112. UDIUInt32 CPUPRL;
  113. UDIUInt32 CoProcPRL;
  114.  
  115. UDIMemoryRange address_ranges[2]; /* Text and data */
  116. UDIResource entry = {0, 0};    /* Entry point */
  117. CPUSizeT stack_sizes[2];    /* Regular and memory stacks */
  118.  
  119. #define    SBUF_MAX    1024    /* maximum size of string handling buffer */
  120. char sbuf[SBUF_MAX];
  121.  
  122. typedef    struct     bkpt_entry_str
  123. {
  124.     UDIResource     Addr;
  125.     UDIUInt32     PassCount;
  126.     UDIBreakType Type;
  127.     unsigned int BreakId;
  128. } bkpt_entry_t;
  129. #define        BKPT_TABLE_SIZE 40
  130. static bkpt_entry_t    bkpt_table[BKPT_TABLE_SIZE];
  131. extern    char    dfe_errmsg[];        /* error string */
  132.  
  133. /* Called when SIGALRM signal sent due to alarm() timeout.  */
  134. #ifndef HAVE_TERMIO
  135.  
  136. volatile int n_alarms;
  137.  
  138. static void
  139. udi_timer ()
  140. {
  141. #if 0
  142.   if (kiodebug)
  143.     printf ("udi_timer called\n");
  144. #endif
  145.   n_alarms++;
  146. }
  147. #endif    /* HAVE_TERMIO */
  148.  
  149. /* malloc'd name of the program on the remote system.  */
  150. static char *prog_name = NULL;
  151.  
  152. /* Number of SIGTRAPs we need to simulate.  That is, the next
  153.    NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
  154.    SIGTRAP without actually waiting for anything.  */
  155.  
  156. /* This is called not only when we first attach, but also when the
  157.    user types "run" after having attached.  */
  158.  
  159. static void
  160. udi_create_inferior (execfile, args, env)
  161.      char *execfile;
  162.      char *args;
  163.      char **env;
  164. {
  165.   char *args1;
  166.  
  167.   if (execfile)
  168.     {
  169.       if (prog_name != NULL)
  170.     free (prog_name);
  171.       prog_name = savestring (execfile, strlen (execfile));
  172.     }
  173.   else if (entry.Offset)
  174.     execfile = "";
  175.   else
  176.     error ("No image loaded into target.");
  177.  
  178.   if (udi_session_id < 0)
  179.     {
  180.       printf("UDI connection not open yet.\n");
  181.       return;
  182.     }
  183.  
  184.   inferior_pid = 40000;
  185.  
  186.   if (!entry.Offset)
  187.     download(execfile, 0);
  188.  
  189.   args1 = alloca (strlen(execfile) + strlen(args) + 2);
  190.  
  191.   strcpy (args1, execfile);
  192.   strcat (args1, " ");
  193.   strcat (args1, args);
  194.  
  195.   UDIInitializeProcess (address_ranges,        /* ProcessMemory[] */
  196.             (UDIInt)2,        /* NumberOfRanges */
  197.             entry,            /* EntryPoint */
  198.             stack_sizes,        /* *StackSizes */
  199.             (UDIInt)2,        /* NumberOfStacks */
  200.             args1);            /* ArgString */
  201.  
  202.   init_wait_for_inferior ();
  203.   clear_proceed_status ();
  204.   proceed(-1,-1,0);
  205. }
  206.  
  207. static void
  208. udi_mourn()
  209. {
  210.         pop_target ();                /* Pop back to no-child state */
  211.         generic_mourn_inferior ();
  212. }
  213.  
  214. /******************************************************************** UDI_OPEN
  215. ** Open a connection to remote TIP.
  216.    NAME is the socket domain used for communication with the TIP,
  217.    then a space and the socket name or TIP-host name.
  218.    '<udi_udi_config_id>' for example.
  219.  */
  220.  
  221. /* XXX - need cleanups for udiconnect for various failures!!! */
  222.  
  223. static char *udi_config_id;
  224. static void
  225. udi_open (name, from_tty)
  226.      char *name;
  227.      int from_tty;
  228. {
  229.   unsigned int prl;
  230.   char *p;
  231.   int cnt;
  232.   UDIMemoryRange KnownMemory[10];
  233.   UDIUInt32 ChipVersions[10];
  234.   UDIInt NumberOfRanges = 10;
  235.   UDIInt NumberOfChips = 10;
  236.   UDIPId PId;
  237.   UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
  238.  
  239.   target_preopen(from_tty);
  240.  
  241.   entry.Offset = 0;
  242.  
  243.   for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
  244.     bkpt_table[cnt].Type = 0;
  245.  
  246.   if (udi_config_id)
  247.     free (udi_config_id);
  248.  
  249.   if (!name)
  250.     error("Usage: target udi config_id, where config_id appears in udi_soc file");
  251.  
  252.   udi_config_id = strdup (strtok (name, " \t"));
  253.  
  254.   if (UDIConnect (udi_config_id, &udi_session_id))
  255.     error("UDIConnect() failed: %s\n", dfe_errmsg);
  256.  
  257.   push_target (&udi_ops);
  258.  
  259. #ifndef HAVE_TERMIO
  260. #ifndef NO_SIGINTERRUPT
  261.   /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
  262.      the read.  */
  263.   if (siginterrupt (SIGALRM, 1) != 0)
  264.     error ("udi_open: siginterrupt() %s", safe_strerror(errno));
  265. #endif
  266.  
  267.   /* Set up read timeout timer.  */
  268.   if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
  269.     error ("udi_open: signal() %s", safe_strerror(errno));
  270. #endif
  271.  
  272. #if defined (LOG_FILE)
  273.   log_file = fopen (LOG_FILE, "w");
  274.   if (log_file == NULL)
  275.     error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno));
  276. #endif
  277.   /*
  278.   ** Initialize target configuration structure (global)
  279.   */
  280.   if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
  281.               ChipVersions, &NumberOfChips))
  282.     error ("UDIGetTargetConfig() failed");
  283.   if (NumberOfChips > 2)
  284.     fprintf(stderr,"Target has more than one processor\n");
  285.   for (cnt=0; cnt < NumberOfRanges; cnt++)
  286.     {
  287.       switch(KnownMemory[cnt].Space)
  288.     {
  289.     default:
  290.       fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
  291.       break;
  292.     case UDI29KCP_S:
  293.       break;
  294.     case UDI29KIROMSpace:
  295.       RMemStart = KnownMemory[cnt].Offset;
  296.       RMemSize = KnownMemory[cnt].Size;
  297.       break;
  298.     case UDI29KIRAMSpace:
  299.       IMemStart = KnownMemory[cnt].Offset;
  300.       IMemSize = KnownMemory[cnt].Size;
  301.       break;
  302.     case UDI29KDRAMSpace:
  303.       DMemStart = KnownMemory[cnt].Offset;
  304.       DMemSize = KnownMemory[cnt].Size;
  305.       break;
  306.     }
  307.     }
  308.  
  309.   /* Determine the processor revision level */
  310.   prl = (unsigned int)read_register (CFG_REGNUM) >> 24;
  311.   if ((prl&0xe0) == 0)
  312.     {
  313.       fprintf_filtered (stderr,
  314.             "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
  315.       processor_type = TYPE_A29000;
  316.     }
  317.   else if ((prl&0xe0) == 0x40)       /* 29030 = 0x4* */
  318.     {
  319.       fprintf_filtered (stderr,
  320.             "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
  321.       processor_type = TYPE_A29030;
  322.     }
  323.   else if ((prl&0xe0) == 0x20)       /* 29050 = 0x2* */
  324.     {
  325.       fprintf_filtered (stderr,
  326.             "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
  327.       processor_type = TYPE_A29050;
  328.     }
  329.   else
  330.     {
  331.       processor_type = TYPE_UNKNOWN;
  332.       fprintf_filtered (stderr,"WARNING: processor type unknown.\n");
  333.     }
  334.   if (UDICreateProcess (&PId))
  335.      fprintf(stderr, "UDICreateProcess() failed\n");
  336.  
  337.   /* Print out some stuff, letting the user now what's going on */
  338.   if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
  339.                &TIPIPCId, sbuf))
  340.     error ("UDICapabilities() failed");
  341.   if (from_tty)
  342.     {
  343.       printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
  344.  DFE-IPC version %x.%x.%x  TIP-IPC version %x.%x.%x  TIP version %x.%x.%x\n %s\n",
  345.                processor_name[processor_type],
  346.                (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
  347.                (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
  348.                (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
  349.                sbuf);
  350.     }
  351. }
  352.  
  353. /******************************************************************* UDI_CLOSE
  354.    Close the open connection to the TIP process.
  355.    Use this when you want to detach and do something else
  356.    with your gdb.  */
  357. static void
  358. udi_close (quitting)    /*FIXME: how is quitting used */
  359.      int quitting;
  360. {
  361.   if (udi_session_id < 0)
  362.     return;
  363.  
  364.   /* We should never get here if there isn't something valid in
  365.      udi_session_id. */
  366.  
  367.   if (UDIDisconnect (udi_session_id, UDITerminateSession))
  368.     error ("UDIDisconnect() failed in udi_close");
  369.  
  370.   /* Do not try to close udi_session_id again, later in the program.  */
  371.   udi_session_id = -1;
  372.   inferior_pid = 0;
  373.  
  374. #if defined (LOG_FILE)
  375.   if (ferror (log_file))
  376.     printf ("Error writing log file.\n");
  377.   if (fclose (log_file) != 0)
  378.     printf ("Error closing log file.\n");
  379. #endif
  380.  
  381.   printf_filtered ("  Ending remote debugging\n");
  382.  
  383. /**************************************************************** UDI_ATACH */
  384. /* Attach to a program that is already loaded and running 
  385.  * Upon exiting the process's execution is stopped.
  386.  */
  387. static void
  388. udi_attach (args, from_tty)
  389.      char *args;
  390.      int from_tty;
  391. {
  392.   UDIResource    From;
  393.   UDIInt32    PC_adds;
  394.   UDICount    Count = 1;
  395.   UDISizeT    Size = 4;
  396.   UDICount    CountDone;
  397.   UDIBool    HostEndian = 0;
  398.   UDIError    err;
  399.  
  400.   if (udi_session_id < 0)
  401.       error ("UDI connection not opened yet, use the 'target udi' command.\n");
  402.     
  403.   if (from_tty)
  404.       printf ("Attaching to remote program %s...\n", prog_name);
  405.  
  406.   UDIStop();
  407.   From.Space = UDI29KSpecialRegs;
  408.   From.Offset = 11;
  409.   if (err = UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
  410.     error ("UDIRead failed in udi_attach");
  411.   printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
  412. }
  413. /************************************************************* UDI_DETACH */
  414. /* Terminate the open connection to the TIP process.
  415.    Use this when you want to detach and do something else
  416.    with your gdb.  Leave remote process running (with no breakpoints set). */
  417. static void
  418. udi_detach (args,from_tty)
  419.      char *args;
  420.      int from_tty;
  421. {
  422.  
  423.   remove_breakpoints();        /* Just in case there were any left in */
  424.  
  425.   if (UDIDisconnect (udi_session_id, UDIContinueSession))
  426.     error ("UDIDisconnect() failed in udi_detach");
  427.  
  428.   pop_target();             /* calls udi_close to do the real work */
  429.  
  430.   if (from_tty)
  431.     printf ("Ending remote debugging\n");
  432. }
  433.  
  434.  
  435. /****************************************************************** UDI_RESUME
  436. ** Tell the remote machine to resume.  */
  437.  
  438. static void
  439. udi_resume (step, sig)
  440.      int step, sig;
  441. {
  442.   UDIError tip_error;
  443.   UDIUInt32 Steps = 1;
  444.   UDIStepType StepType = UDIStepNatural;
  445.   UDIRange Range;
  446.  
  447.   if (step)             /* step 1 instruction */
  448.     {
  449.       tip_error = UDIStep (Steps, StepType, Range);
  450.       if (!tip_error)
  451.     return;
  452.  
  453.       fprintf (stderr,  "UDIStep() error = %d\n", tip_error);
  454.       error ("failed in udi_resume");
  455.     }
  456.  
  457.   if (UDIExecute())
  458.     error ("UDIExecute() failed in udi_resume");
  459. }
  460.  
  461. /******************************************************************** UDI_WAIT
  462. ** Wait until the remote machine stops, then return,
  463.    storing status in STATUS just as `wait' would.  */
  464.  
  465. static int
  466. udi_wait (status)
  467.      WAITTYPE *status;
  468. {
  469.   UDIInt32    MaxTime;
  470.   UDIPId    PId;
  471.   UDIInt32    StopReason;
  472.   UDISizeT    CountDone;
  473.   int         old_timeout = timeout;
  474.   int         old_immediate_quit = immediate_quit;
  475.   int        i;
  476.  
  477.   WSETEXIT ((*status), 0);
  478.  
  479. /* wait for message to arrive. It should be:
  480.   If the target stops executing, udi_wait() should return.
  481. */
  482.   timeout = 0;            /* Wait indefinetly for a message */
  483.   immediate_quit = 1;       /* Helps ability to QUIT */
  484.  
  485.   while(1)
  486.     {
  487.       i = 0;
  488.       MaxTime = UDIWaitForever;
  489.       UDIWait(MaxTime, &PId, &StopReason);
  490.       QUIT;            /* Let user quit if they want */
  491.  
  492.       switch (StopReason & UDIGrossState)
  493.     {
  494.     case UDIStdoutReady:
  495.       if (UDIGetStdout (sbuf, (UDISizeT)SBUF_MAX, &CountDone))
  496.         error ("UDIGetStdout() failed in udi_wait");
  497.       fwrite (sbuf, 1, CountDone, stdout);
  498.       fflush(stdout);
  499.       continue;
  500.     case UDIStderrReady:
  501.       UDIGetStderr (sbuf, (UDISizeT)SBUF_MAX, &CountDone);
  502.       fwrite (sbuf, 1, CountDone, stderr);
  503.       fflush(stderr);
  504.       continue;
  505.     case UDIStdinNeeded:
  506.       scanf ("%s", sbuf);
  507.       i = strlen (sbuf);
  508.       UDIPutStdin (sbuf, (UDISizeT)i, &CountDone);
  509.       continue;
  510.     case UDIRunning:
  511.       /* In spite of the fact that we told UDIWait to wait forever, it will
  512.          return spuriously sometimes.  */
  513.     case UDIStdinModeX:
  514.       continue;
  515.     default:
  516.       break;
  517.     }
  518.       break;
  519.     }
  520.  
  521.   switch (StopReason & UDIGrossState)
  522.     {
  523.     case UDITrapped:
  524.       printf("Am290*0 received vector number %d\n", StopReason >> 24);
  525.       
  526.       switch (StopReason >> 8)
  527.     {
  528.     case 0:            /* Illegal opcode */
  529.       printf("    (break point)\n");
  530.       WSETSTOP ((*status), SIGTRAP);
  531.       break;
  532.     case 1:            /* Unaligned Access */
  533.       WSETSTOP ((*status), SIGBUS);
  534.       break;
  535.     case 3:
  536.     case 4:
  537.       WSETSTOP ((*status), SIGFPE);
  538.       break;
  539.     case 5:            /* Protection Violation */
  540.       WSETSTOP ((*status), SIGILL);
  541.       break;
  542.     case 6:
  543.     case 7:
  544.     case 8:            /* User Instruction Mapping Miss */
  545.     case 9:            /* User Data Mapping Miss */
  546.     case 10:        /* Supervisor Instruction Mapping Miss */
  547.     case 11:        /* Supervisor Data Mapping Miss */
  548.       WSETSTOP ((*status), SIGSEGV);
  549.       break;
  550.     case 12:
  551.     case 13:
  552.       WSETSTOP ((*status), SIGILL);
  553.       break;
  554.     case 14:        /* Timer */
  555.       WSETSTOP ((*status), SIGALRM);
  556.       break;
  557.     case 15:        /* Trace */
  558.       WSETSTOP ((*status), SIGTRAP);
  559.       break;
  560.     case 16:        /* INTR0 */
  561.     case 17:        /* INTR1 */
  562.     case 18:        /* INTR2 */
  563.     case 19:        /* INTR3/Internal */
  564.     case 20:        /* TRAP0 */
  565.     case 21:        /* TRAP1 */
  566.       WSETSTOP ((*status), SIGINT);
  567.       break;
  568.     case 22:        /* Floating-Point Exception */
  569.       WSETSTOP ((*status), SIGILL);
  570.       break;
  571.     case 77:        /* assert 77 */
  572.       WSETSTOP ((*status), SIGTRAP);
  573.       break;
  574.     default:
  575.       WSETEXIT ((*status), 0);
  576.     }
  577.       break;
  578.     case UDINotExecuting:
  579.       WSETSTOP ((*status), SIGTERM);
  580.       break;
  581.     case UDIStopped:
  582.       WSETSTOP ((*status), SIGTSTP);
  583.       break;
  584.     case UDIWarned:
  585.       WSETSTOP ((*status), SIGURG);
  586.       break;
  587.     case UDIStepped:
  588.     case UDIBreak:
  589.       WSETSTOP ((*status), SIGTRAP);
  590.       break;
  591.     case UDIWaiting:
  592.       WSETSTOP ((*status), SIGSTOP);
  593.       break;
  594.     case UDIHalted:
  595.       WSETSTOP ((*status), SIGKILL);
  596.       break;
  597.     case UDIExited:
  598.     default:
  599.       WSETEXIT ((*status), 0);
  600.     }
  601.  
  602.   timeout = old_timeout;    /* Restore original timeout value */
  603.   immediate_quit = old_immediate_quit;
  604.   return 0;
  605. }
  606.  
  607. /********************************************************** UDI_FETCH_REGISTERS
  608.  * Read a remote register 'regno'. 
  609.  * If regno==-1 then read all the registers.
  610.  */
  611. static void 
  612. udi_fetch_registers (regno)
  613. int    regno;
  614. {
  615.   UDIResource    From;
  616.   UDIUInt32    *To;
  617.   UDICount    Count;
  618.   UDISizeT    Size = 4;
  619.   UDICount    CountDone;
  620.   UDIBool    HostEndian = 0;
  621.   UDIError    err;
  622.   int        i;
  623.  
  624.   if (regno >= 0)  {
  625.     fetch_register(regno);
  626.     return;
  627.   }
  628.  
  629. /* Gr1/rsp */
  630.  
  631.   From.Space = UDI29KGlobalRegs;
  632.   From.Offset = 1;
  633.   To = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
  634.   Count = 1;
  635.   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  636.     error("UDIRead() failed in udi_fetch_registers");
  637.  
  638.   register_valid[GR1_REGNUM] = 1;
  639.  
  640. #if defined(GR64_REGNUM)    /* Read gr64-127 */
  641.  
  642. /* Global Registers gr64-gr95 */ 
  643.  
  644.   From.Space = UDI29KGlobalRegs;
  645.   From.Offset = 64;
  646.   To = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
  647.   Count = 32;
  648.   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  649.     error("UDIRead() failed in udi_fetch_registers");
  650.  
  651.   for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
  652.     register_valid[i] = 1;
  653.  
  654. #endif    /*  GR64_REGNUM */
  655.  
  656. /* Global Registers gr96-gr127 */ 
  657.  
  658.   From.Space = UDI29KGlobalRegs;
  659.   From.Offset = 96;
  660.   To = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
  661.   Count = 32;
  662.   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  663.     error("UDIRead() failed in udi_fetch_registers");
  664.  
  665.   for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
  666.     register_valid[i] = 1;
  667.  
  668. /* Local Registers */
  669.  
  670.   From.Space = UDI29KLocalRegs;
  671.   From.Offset = 0;
  672.   To = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
  673.   Count = 128;
  674.   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  675.     error("UDIRead() failed in udi_fetch_registers");
  676.  
  677.   for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
  678.     register_valid[i] = 1;
  679.  
  680. /* Protected Special Registers */
  681.  
  682.   From.Space = UDI29KSpecialRegs;
  683.   From.Offset = 0;
  684.   To = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
  685.   Count = 15;
  686.   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  687.     error("UDIRead() failed in udi_fetch_registers");
  688.  
  689.   for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
  690.     register_valid[i] = 1;
  691.  
  692.   if (USE_SHADOW_PC) {    /* Let regno_to_srnum() handle the register number */
  693.     fetch_register(NPC_REGNUM);
  694.     fetch_register(PC_REGNUM);
  695.     fetch_register(PC2_REGNUM);
  696.  
  697. /* Unprotected Special Registers sr128-sr135 */
  698.  
  699.     From.Space = UDI29KSpecialRegs;
  700.     From.Offset = 128;
  701.     To = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
  702.     Count = 135-128 + 1;
  703.     if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  704.       error("UDIRead() failed in udi_fetch_registers");
  705.  
  706.     for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
  707.       register_valid[i] = 1;
  708.   }
  709.  
  710.   if (kiodebug)
  711.     {
  712.       printf("Fetching all registers\n");
  713.       printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
  714.          read_register(NPC_REGNUM), read_register(PC_REGNUM),
  715.          read_register(PC2_REGNUM));
  716.     }
  717.  
  718.   /* There doesn't seem to be any way to get these.  */
  719.   {
  720.     int val = -1;
  721.     supply_register (FPE_REGNUM, (char *) &val);
  722.     supply_register (INTE_REGNUM, (char *) &val);
  723.     supply_register (FPS_REGNUM, (char *) &val);
  724.     supply_register (EXO_REGNUM, (char *) &val);
  725.   }
  726. }
  727.  
  728.  
  729. /********************************************************* UDI_STORE_REGISTERS
  730. ** Store register regno into the target.  
  731.  * If regno==-1 then store all the registers.
  732.  */
  733.  
  734. static void
  735. udi_store_registers (regno)
  736. int regno;
  737. {
  738.   UDIUInt32    *From;
  739.   UDIResource    To;
  740.   UDICount    Count;
  741.   UDISizeT    Size = 4;
  742.   UDICount    CountDone;
  743.   UDIBool    HostEndian = 0;
  744.   
  745.   if (regno >= 0)
  746.     {
  747.       store_register(regno);
  748.       return;
  749.     }
  750.  
  751.   if (kiodebug)
  752.     {
  753.       printf("Storing all registers\n");
  754.       printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM),
  755.          read_register(PC_REGNUM), read_register(PC2_REGNUM));
  756.     }
  757.  
  758. /* Gr1/rsp */
  759.  
  760.   From = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
  761.   To.Space = UDI29KGlobalRegs;
  762.   To.Offset = 1;
  763.   Count = 1;
  764.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  765.     error("UDIWrite() failed in udi_store_regisetrs");
  766.  
  767. #if defined(GR64_REGNUM)
  768.  
  769. /* Global registers gr64-gr95 */
  770.  
  771.   From = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
  772.   To.Space = UDI29KGlobalRegs;
  773.   To.Offset = 64;
  774.   Count = 32;
  775.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  776.     error("UDIWrite() failed in udi_store_regisetrs");
  777.  
  778. #endif    /* GR64_REGNUM */
  779.  
  780. /* Global registers gr96-gr127 */
  781.  
  782.   From = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
  783.   To.Space = UDI29KGlobalRegs;
  784.   To.Offset = 96;
  785.   Count = 32;
  786.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  787.     error("UDIWrite() failed in udi_store_regisetrs");
  788.  
  789. /* Local Registers */
  790.  
  791.   From = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
  792.   To.Space = UDI29KLocalRegs;
  793.   To.Offset = 0;
  794.   Count = 128;
  795.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  796.     error("UDIWrite() failed in udi_store_regisetrs");
  797.  
  798.  
  799. /* Protected Special Registers */ /* VAB through TMR */
  800.  
  801.   From = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
  802.   To.Space = UDI29KSpecialRegs;
  803.   To.Offset = 0;
  804.   Count = 10;
  805.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  806.     error("UDIWrite() failed in udi_store_regisetrs");
  807.  
  808. /* PC0, PC1, PC2 possibly as shadow registers */
  809.  
  810.   From = (UDIUInt32 *)®isters[4 * SR_REGNUM(10)];
  811.   To.Space = UDI29KSpecialRegs;
  812.   Count = 3;
  813.   if (USE_SHADOW_PC) 
  814.     To.Offset = 20;                /* SPC0 */
  815.   else 
  816.     To.Offset = 10;                /* PC0 */
  817.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  818.     error("UDIWrite() failed in udi_store_regisetrs");
  819.  
  820.   /* LRU and MMU */
  821.  
  822.   From = (UDIUInt32 *)®isters[4 * SR_REGNUM(13)];
  823.   To.Space = UDI29KSpecialRegs;
  824.   To.Offset = 13;
  825.   Count = 2;
  826.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  827.     error("UDIWrite() failed in udi_store_regisetrs");
  828.  
  829. /* Unprotected Special Registers */ 
  830.  
  831.   From = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
  832.   To.Space = UDI29KSpecialRegs;
  833.   To.Offset = 128;
  834.   Count = 135-128 +1;
  835.   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  836.     error("UDIWrite() failed in udi_store_regisetrs");
  837.  
  838.   registers_changed ();
  839. }
  840.  
  841. /****************************************************** UDI_PREPARE_TO_STORE */
  842. /* Get ready to modify the registers array.  On machines which store
  843.    individual registers, this doesn't need to do anything.  On machines
  844.    which store all the registers in one fell swoop, this makes sure
  845.    that registers contains all the registers from the program being
  846.    debugged.  */
  847.  
  848. static void
  849. udi_prepare_to_store ()
  850. {
  851.   /* Do nothing, since we can store individual regs */
  852. }
  853.  
  854. /********************************************************** TRANSLATE_ADDR */
  855. static CORE_ADDR
  856. translate_addr(addr)
  857. CORE_ADDR addr;
  858. {
  859. #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
  860.         /* Check for a virtual address in the kernel */
  861.         /* Assume physical address of ublock is in  paddr_u register */
  862.     /* FIXME: doesn't work for user virtual addresses */
  863.         if (addr >= UVADDR) {
  864.                 /* PADDR_U register holds the physical address of the ublock */
  865.                 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
  866.                 return(i + addr - (CORE_ADDR)UVADDR);
  867.         } else {
  868.             return(addr);
  869.         }
  870. #else
  871.         return(addr);
  872. #endif
  873. }
  874. /************************************************* UDI_XFER_INFERIOR_MEMORY */
  875. /* FIXME!  Merge these two.  */
  876. static int
  877. udi_xfer_inferior_memory (memaddr, myaddr, len, write)
  878.      CORE_ADDR memaddr;
  879.      char *myaddr;
  880.      int len;
  881.      int write;
  882. {
  883.  
  884.   memaddr = translate_addr(memaddr);
  885.  
  886.   if (write)
  887.     return udi_write_inferior_memory (memaddr, myaddr, len);
  888.   else
  889.     return udi_read_inferior_memory (memaddr, myaddr, len);
  890. }
  891.  
  892. /********************************************************** UDI_FILES_INFO */
  893. static void
  894. udi_files_info ()
  895. {
  896.   printf ("\tAttached to UDI socket to %s and running program %s.\n",
  897.           udi_config_id, prog_name);
  898. }
  899.  
  900. /**************************************************** UDI_INSERT_BREAKPOINT */
  901. static int
  902. udi_insert_breakpoint (addr, contents_cache)
  903.      CORE_ADDR addr;
  904.      char *contents_cache;
  905. {
  906.   int cnt;
  907.   UDIError err;
  908.  
  909.   for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
  910.     if (bkpt_table[cnt].Type == 0) /* Find first free slot */
  911.       break;
  912.  
  913.   if(cnt >= BKPT_TABLE_SIZE)
  914.     error("Too many breakpoints set");
  915.  
  916.   bkpt_table[cnt].Addr.Offset = addr;
  917.   bkpt_table[cnt].Addr.Space  = UDI29KIRAMSpace;
  918.   bkpt_table[cnt].PassCount = 1;
  919.   bkpt_table[cnt].Type = UDIBreakFlagExecute;
  920.   
  921.   err = UDISetBreakpoint(bkpt_table[cnt].Addr,
  922.              bkpt_table[cnt].PassCount,
  923.              bkpt_table[cnt].Type,
  924.              &bkpt_table[cnt].BreakId);
  925.  
  926.   if (err == 0) return 0;        /* Success */
  927.  
  928.   bkpt_table[cnt].Type = 0;
  929.   error("UDISetBreakpoint returned error code %d\n", err);
  930. }
  931.  
  932. /**************************************************** UDI_REMOVE_BREAKPOINT */
  933. static int
  934. udi_remove_breakpoint (addr, contents_cache)
  935.      CORE_ADDR addr;
  936.      char *contents_cache;
  937. {
  938.   int cnt;
  939.   UDIError err;
  940.  
  941.   for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
  942.     if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
  943.       break;
  944.  
  945.   if(cnt >= BKPT_TABLE_SIZE)
  946.     error("Can't find breakpoint in table");
  947.  
  948.   bkpt_table[cnt].Type = 0;
  949.  
  950.   err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
  951.   if (err == 0) return 0;    /* Success */
  952.  
  953.   error("UDIClearBreakpoint returned error code %d\n", err);
  954. }
  955.  
  956. static void
  957. udi_kill(arg,from_tty)
  958.      char *arg;
  959.      int from_tty;
  960. {
  961.  
  962. #if 0
  963. /*
  964. UDIStop does not really work as advertised.  It causes the TIP to close it's
  965. connection, which usually results in GDB dying with a SIGPIPE.  For now, we
  966. just invoke udi_close, which seems to get things right.
  967. */
  968.   UDIStop();
  969.  
  970.   udi_session_id = -1;
  971.   inferior_pid = 0;
  972.  
  973.   if (from_tty)
  974.     printf("Target has been stopped.");
  975. #else
  976.   udi_close(0);
  977. #endif
  978.   pop_target();
  979. }
  980.  
  981. /* 
  982.    Load a program into the target.  Args are: `program {options}'.  The options
  983.    are used to control loading of the program, and are NOT passed onto the
  984.    loaded code as arguments.  (You need to use the `run' command to do that.)
  985.  
  986.    The options are:
  987.          -ms %d    Set mem stack size to %d
  988.         -rs %d    Set regular stack size to %d
  989.         -i    send init info (default)
  990.         -noi    don't send init info
  991.         -[tT]      Load Text section
  992.         -[dD]    Load Data section
  993.         -[bB]    Load BSS section
  994.         -[lL]    Load Lit section
  995.   */
  996.  
  997. static void
  998. download(load_arg_string, from_tty)
  999.      char *load_arg_string;
  1000.      int from_tty;
  1001. {
  1002. #define DEFAULT_MEM_STACK_SIZE         0x6000
  1003. #define DEFAULT_REG_STACK_SIZE         0x2000
  1004.  
  1005.   char *token;
  1006.   char *filename;
  1007.   asection *section;
  1008.   bfd *pbfd;
  1009.   UDIError err;
  1010.   int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
  1011.  
  1012.   address_ranges[0].Space = UDI29KIRAMSpace;
  1013.   address_ranges[0].Offset = 0xffffffff;
  1014.   address_ranges[0].Size = 0;
  1015.  
  1016.   address_ranges[1].Space = UDI29KDRAMSpace;
  1017.   address_ranges[1].Offset = 0xffffffff;
  1018.   address_ranges[1].Size = 0;
  1019.  
  1020.   stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
  1021.   stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
  1022.  
  1023.   dont_repeat ();
  1024.  
  1025.   filename = strtok(load_arg_string, " \t");
  1026.   if (!filename)
  1027.     error ("Must specify at least a file name with the load command");
  1028.  
  1029.   filename = tilde_expand (filename);
  1030.   make_cleanup (free, filename);
  1031.  
  1032.   while (token = strtok (NULL, " \t"))
  1033.     {
  1034.       if (token[0] == '-')
  1035.     {
  1036.       token++;
  1037.  
  1038.       if (STREQ (token, "ms"))
  1039.         stack_sizes[1] = atol (strtok (NULL, " \t"));
  1040.       else if (STREQ (token, "rs"))
  1041.         stack_sizes[0] = atol (strtok (NULL, " \t"));
  1042.       else
  1043.         {
  1044.           load_text = load_data = load_bss = load_lit = 0;
  1045.  
  1046.           while (*token)
  1047.         {
  1048.           switch (*token++)
  1049.             {
  1050.             case 't':
  1051.             case 'T':
  1052.               load_text = 1;
  1053.               break;
  1054.             case 'd':
  1055.             case 'D':
  1056.               load_data = 1;
  1057.               break;
  1058.             case 'b':
  1059.             case 'B':
  1060.               load_bss = 1;
  1061.               break;
  1062.             case 'l':
  1063.             case 'L':
  1064.               load_lit = 1;
  1065.               break;
  1066.             default:
  1067.               error ("Unknown UDI load option -%s", token-1);
  1068.             }
  1069.         }
  1070.         }
  1071.     }
  1072.     }
  1073.  
  1074.   pbfd = bfd_openr (filename, 0);
  1075.  
  1076.   if (!pbfd) 
  1077.     perror_with_name (filename);
  1078.   
  1079.   make_cleanup (bfd_close, pbfd);
  1080.  
  1081.   QUIT;
  1082.   immediate_quit++;
  1083.  
  1084.   if (!bfd_check_format (pbfd, bfd_object)) 
  1085.     error ("It doesn't seem to be an object file");
  1086.   
  1087.   for (section = pbfd->sections; section; section = section->next) 
  1088.     {
  1089.       if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
  1090.     {
  1091.       UDIResource To;
  1092.       UDICount Count;
  1093.       unsigned long section_size, section_end;
  1094.       const char *section_name;
  1095.  
  1096.       section_name = bfd_get_section_name (pbfd, section);
  1097.       if (STREQ (section_name, ".text") && !load_text)
  1098.         continue;
  1099.       else if (STREQ (section_name, ".data") && !load_data)
  1100.         continue;
  1101.       else if (STREQ (section_name, ".bss") && !load_bss)
  1102.         continue;
  1103.       else if (STREQ (section_name, ".lit") && !load_lit)
  1104.         continue;
  1105.  
  1106.       To.Offset = bfd_get_section_vma (pbfd, section);
  1107.       section_size = bfd_section_size (pbfd, section);
  1108.       section_end = To.Offset + section_size;
  1109.  
  1110.       printf("[Loading section %s at %x (%d bytes)]\n",
  1111.          section_name,
  1112.          To.Offset,
  1113.          section_size);
  1114.  
  1115.       if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
  1116.         {
  1117.           To.Space = UDI29KIRAMSpace;
  1118.  
  1119.           address_ranges[0].Offset = min (address_ranges[0].Offset,
  1120.                           To.Offset);
  1121.           address_ranges[0].Size = max (address_ranges[0].Size,
  1122.                         section_end
  1123.                         - address_ranges[0].Offset);
  1124.         }
  1125.       else
  1126.         {
  1127.           To.Space = UDI29KDRAMSpace;
  1128.  
  1129.           address_ranges[1].Offset = min (address_ranges[1].Offset,
  1130.                           To.Offset);
  1131.           address_ranges[1].Size = max (address_ranges[1].Size,
  1132.                         section_end
  1133.                         - address_ranges[1].Offset);
  1134.         }
  1135.  
  1136.       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
  1137.         {
  1138.           file_ptr fptr;
  1139.  
  1140.           fptr = 0;
  1141.  
  1142.           while (section_size > 0)
  1143.         {
  1144.           char buffer[1024];
  1145.  
  1146.           Count = min (section_size, 1024);
  1147.  
  1148.           bfd_get_section_contents (pbfd, section, buffer, fptr,
  1149.                         Count);
  1150.  
  1151.           err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
  1152.                   To,            /* To */
  1153.                   Count,        /* Count */
  1154.                   (UDISizeT)1,        /* Size */
  1155.                   &Count,        /* CountDone */
  1156.                   (UDIBool)0);        /* HostEndian */
  1157.           if (err)
  1158.             error ("UDIWrite failed, error = %d", err);
  1159.  
  1160.           To.Offset += Count;
  1161.           fptr += Count;
  1162.           section_size -= Count;
  1163.         }
  1164.         }
  1165.       else            /* BSS */
  1166.         {
  1167.           UDIResource From;
  1168.           unsigned long zero = 0;
  1169.  
  1170.           /* Write a zero byte at the vma */
  1171.           err = UDIWrite ((UDIHostMemPtr)&zero,    /* From */
  1172.                   To,            /* To */
  1173.                   (UDICount)1,        /* Count */
  1174.                   (UDISizeT)4,        /* Size */
  1175.                   &Count,            /* CountDone */
  1176.                   (UDIBool)0);        /* HostEndian */
  1177.           if (err)
  1178.         error ("UDIWrite failed, error = %d", err);
  1179.  
  1180.           From = To;
  1181.           To.Offset+=4;
  1182.  
  1183.           /* Now, duplicate it for the length of the BSS */
  1184.           err = UDICopy (From,            /* From */
  1185.                  To,            /* To */
  1186.                  (UDICount)(section_size/4 - 1), /* Count */
  1187.                  (UDISizeT)4,        /* Size */
  1188.                  &Count,            /* CountDone */
  1189.                  (UDIBool)1);        /* Direction */
  1190.           if (err)
  1191.         {
  1192.           char message[100];
  1193.           int xerr;
  1194.  
  1195.           xerr = UDIGetErrorMsg(err, 100, message, &Count);
  1196.           if (!xerr)
  1197.             fprintf (stderr, "Error is %s\n", message);
  1198.           else
  1199.             fprintf (stderr, "xerr is %d\n", xerr);
  1200.           error ("UDICopy failed, error = %d", err);
  1201.         }
  1202.         }
  1203.  
  1204.     }
  1205.     }
  1206.  
  1207.   entry.Space = UDI29KIRAMSpace;
  1208.   entry.Offset = bfd_get_start_address (pbfd);
  1209.   
  1210.   immediate_quit--;
  1211. }
  1212.  
  1213. /* User interface to download an image into the remote target.  See download()
  1214.  * for details on args.
  1215.  */
  1216.  
  1217. static void
  1218. udi_load(args, from_tty)
  1219.      char *args;
  1220.      int from_tty;
  1221. {
  1222.   download (args, from_tty);
  1223.  
  1224.   symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
  1225. }
  1226.  
  1227. /*************************************************** UDI_WRITE_INFERIOR_MEMORY
  1228. ** Copy LEN bytes of data from debugger memory at MYADDR
  1229.    to inferior's memory at MEMADDR.  Returns number of bytes written.  */
  1230. static int
  1231. udi_write_inferior_memory (memaddr, myaddr, len)
  1232.      CORE_ADDR memaddr;
  1233.      char *myaddr;
  1234.      int len;
  1235. {
  1236.   int        nwritten = 0;
  1237.   UDIUInt32    *From;
  1238.   UDIResource    To;
  1239.   UDICount    Count;
  1240.   UDISizeT    Size = 1;
  1241.   UDICount    CountDone = 0;
  1242.   UDIBool    HostEndian = 0;
  1243.   
  1244.   To.Space = udi_memory_space(memaddr);
  1245.   From = (UDIUInt32*)myaddr;
  1246.  
  1247.   while (nwritten < len)
  1248.   {    Count = len - nwritten;
  1249.     if (Count > MAXDATA) Count = MAXDATA;
  1250.       To.Offset = memaddr + nwritten;
  1251.         if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
  1252.         {  error("UDIWrite() failed in udi_write_inferrior_memory");
  1253.        break;    
  1254.     }
  1255.     else
  1256.       {  nwritten += CountDone;
  1257.        From += CountDone;
  1258.     }
  1259.   }
  1260.   return(nwritten);
  1261. }
  1262.  
  1263. /**************************************************** UDI_READ_INFERIOR_MEMORY
  1264. ** Read LEN bytes from inferior memory at MEMADDR.  Put the result
  1265.    at debugger address MYADDR.  Returns number of bytes read.  */
  1266. static int
  1267. udi_read_inferior_memory(memaddr, myaddr, len)
  1268.      CORE_ADDR memaddr;
  1269.      char *myaddr;
  1270.      int len;
  1271. {
  1272.   int        nread = 0;
  1273.   UDIResource    From;
  1274.   UDIUInt32    *To;
  1275.   UDICount    Count;
  1276.   UDISizeT    Size = 1;
  1277.   UDICount    CountDone = 0;
  1278.   UDIBool    HostEndian = 0;
  1279.   UDIError    err;
  1280.   
  1281.   From.Space = udi_memory_space(memaddr);    
  1282.   To = (UDIUInt32*)myaddr;
  1283.  
  1284.   while (nread < len)
  1285.   {    Count = len - nread;
  1286.     if (Count > MAXDATA) Count = MAXDATA;
  1287.       From.Offset = memaddr + nread;
  1288.         if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
  1289.         {  error("UDIRead() failed in udi_read_inferrior_memory");
  1290.        break;    
  1291.     }
  1292.     else
  1293.       {  nread += CountDone;
  1294.        To += CountDone;
  1295.     }
  1296.   }
  1297.   return(nread);
  1298. }
  1299.  
  1300. /********************************************************************* WARNING
  1301. */
  1302. udi_warning(num)
  1303. int    num;
  1304. {
  1305.     error ("ERROR while loading program into remote TIP: $d\n", num);
  1306. }
  1307.  
  1308.  
  1309. /*****************************************************************************/ 
  1310. /* Fetch a single register indicatated by 'regno'. 
  1311.  * Returns 0/-1 on success/failure.  
  1312.  */
  1313. static void
  1314. fetch_register (regno)
  1315.      int regno;
  1316. {
  1317.   UDIResource    From;
  1318.   UDIUInt32    To;
  1319.   UDICount    Count = 1;
  1320.   UDISizeT    Size = 4;
  1321.   UDICount    CountDone;
  1322.   UDIBool    HostEndian = 0;
  1323.   UDIError    err;
  1324.   int          result;
  1325.  
  1326.   if (regno == GR1_REGNUM)
  1327.     {
  1328.       From.Space = UDI29KGlobalRegs;
  1329.       From.Offset = 1;
  1330.     }
  1331.   else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
  1332.     {
  1333.       From.Space = UDI29KGlobalRegs;
  1334.       From.Offset = (regno - GR96_REGNUM) + 96;;
  1335.     }
  1336.  
  1337. #if defined(GR64_REGNUM)
  1338.  
  1339.   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
  1340.     {
  1341.       From.Space = UDI29KGlobalRegs;
  1342.       From.Offset = (regno - GR64_REGNUM) + 64;
  1343.     }
  1344.  
  1345. #endif    /* GR64_REGNUM */
  1346.  
  1347.   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
  1348.     {
  1349.       From.Space = UDI29KLocalRegs;
  1350.       From.Offset = (regno - LR0_REGNUM);
  1351.     }
  1352.   else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)  
  1353.     {
  1354.       int val = -1;
  1355.       supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
  1356.       return;        /* Pretend Success */
  1357.     }
  1358.   else 
  1359.     {
  1360.       From.Space = UDI29KSpecialRegs;
  1361.       From.Offset = regnum_to_srnum(regno); 
  1362.     }
  1363.  
  1364.   if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
  1365.     error("UDIRead() failed in udi_fetch_registers");
  1366.  
  1367.   supply_register(regno, (char *) &To);
  1368.  
  1369.   if (kiodebug)
  1370.     printf("Fetching register %s = 0x%x\n", reg_names[regno], To);
  1371. }
  1372. /*****************************************************************************/ 
  1373. /* Store a single register indicated by 'regno'. 
  1374.  * Returns 0/-1 on success/failure.  
  1375.  */
  1376. static int
  1377. store_register (regno)
  1378.      int regno;
  1379. {
  1380.   int          result;
  1381.   UDIUInt32    From;
  1382.   UDIResource    To;
  1383.   UDICount    Count = 1;
  1384.   UDISizeT    Size = 4;
  1385.   UDICount    CountDone;
  1386.   UDIBool    HostEndian = 0;
  1387.  
  1388.   From =  read_register (regno);    /* get data value */
  1389.  
  1390.   if (kiodebug)
  1391.     printf("Storing register %s = 0x%x\n", reg_names[regno], From);
  1392.  
  1393.   if (regno == GR1_REGNUM)
  1394.   { To.Space = UDI29KGlobalRegs;
  1395.     To.Offset = 1;
  1396.     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
  1397.     /* Setting GR1 changes the numbers of all the locals, so invalidate the 
  1398.      * register cache.  Do this *after* calling read_register, because we want 
  1399.      * read_register to return the value that write_register has just stuffed 
  1400.      * into the registers array, not the value of the register fetched from 
  1401.      * the inferior.  
  1402.      */
  1403.     registers_changed ();
  1404.   }
  1405. #if defined(GR64_REGNUM)
  1406.   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
  1407.   { To.Space = UDI29KGlobalRegs;
  1408.     To.Offset = (regno - GR64_REGNUM) + 64;
  1409.     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
  1410.   }
  1411. #endif    /* GR64_REGNUM */
  1412.   else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
  1413.   { To.Space = UDI29KGlobalRegs;
  1414.     To.Offset = (regno - GR96_REGNUM) + 96;
  1415.     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
  1416.   }
  1417.   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
  1418.   { To.Space = UDI29KLocalRegs;
  1419.     To.Offset = (regno - LR0_REGNUM);
  1420.     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
  1421.   }
  1422.   else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)  
  1423.   { 
  1424.     return 0;        /* Pretend Success */
  1425.   }
  1426.   else     /* An unprotected or protected special register */
  1427.   { To.Space = UDI29KSpecialRegs;
  1428.     To.Offset = regnum_to_srnum(regno); 
  1429.     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
  1430.   }
  1431.  
  1432.   if(result)
  1433.   { result = -1;
  1434.     error("UDIWrite() failed in store_registers");
  1435.   }
  1436.   return result;
  1437. }
  1438. /********************************************************** REGNUM_TO_SRNUM */
  1439. /* 
  1440.  * Convert a gdb special register number to a 29000 special register number.
  1441.  */
  1442. static int
  1443. regnum_to_srnum(regno)
  1444. int    regno;
  1445. {
  1446.     switch(regno) {
  1447.         case VAB_REGNUM: return(0); 
  1448.         case OPS_REGNUM: return(1); 
  1449.         case CPS_REGNUM: return(2); 
  1450.         case CFG_REGNUM: return(3); 
  1451.         case CHA_REGNUM: return(4); 
  1452.         case CHD_REGNUM: return(5); 
  1453.         case CHC_REGNUM: return(6); 
  1454.         case RBP_REGNUM: return(7); 
  1455.         case TMC_REGNUM: return(8); 
  1456.         case TMR_REGNUM: return(9); 
  1457.         case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
  1458.         case PC_REGNUM:  return(USE_SHADOW_PC ? (21) : (11));
  1459.         case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
  1460.         case MMU_REGNUM: return(13); 
  1461.         case LRU_REGNUM: return(14); 
  1462.         case IPC_REGNUM: return(128); 
  1463.         case IPA_REGNUM: return(129); 
  1464.         case IPB_REGNUM: return(130); 
  1465.         case Q_REGNUM:   return(131); 
  1466.         case ALU_REGNUM: return(132); 
  1467.         case BP_REGNUM:  return(133); 
  1468.         case FC_REGNUM:  return(134); 
  1469.         case CR_REGNUM:  return(135); 
  1470.         case FPE_REGNUM: return(160); 
  1471.         case INTE_REGNUM: return(161); 
  1472.         case FPS_REGNUM: return(162); 
  1473.         case EXO_REGNUM:return(164); 
  1474.         default:
  1475.             return(255);    /* Failure ? */
  1476.     }
  1477. }
  1478. /****************************************************************************/
  1479. /*
  1480.  * Determine the Target memory space qualifier based on the addr. 
  1481.  * FIXME: Can't distinguis I_ROM/D_ROM.  
  1482.  * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
  1483.  */
  1484. static CPUSpace
  1485. udi_memory_space(addr)
  1486. CORE_ADDR    addr;
  1487. {
  1488.     UDIUInt32 tstart = IMemStart;
  1489.     UDIUInt32 tend   = tstart + IMemSize;  
  1490.     UDIUInt32 dstart = DMemStart;
  1491.     UDIUInt32 dend   = tstart + DMemSize;  
  1492.     UDIUInt32 rstart = RMemStart;
  1493.     UDIUInt32 rend   = tstart + RMemSize;  
  1494.  
  1495.     if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) { 
  1496.         return UDI29KIRAMSpace;
  1497.     } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) { 
  1498.         return UDI29KDRAMSpace;
  1499.     } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
  1500.         /* FIXME: how do we determine between D_ROM and I_ROM */
  1501.         return UDI29KIROMSpace;
  1502.     } else    /* FIXME: what do me do now? */
  1503.         return UDI29KDRAMSpace;    /* Hmmm! */
  1504. }
  1505. /*********************************************************************** STUBS
  1506. */
  1507.  
  1508. void  convert16() {;}
  1509. void  convert32() {;}
  1510. FILE* EchoFile = 0;        /* used for debugging */
  1511. int   QuietMode = 0;        /* used for debugging */
  1512.  
  1513. /****************************************************************************/
  1514. /* 
  1515.  *  Define the target subroutine names 
  1516.  */
  1517. static struct target_ops udi_ops = {
  1518.         "udi",
  1519.     "Remote UDI connected TIP",
  1520.     "Remote debug an AMD 29k using UDI socket connection to TIP process",
  1521.         udi_open,
  1522.     udi_close,
  1523.         udi_attach,
  1524.     udi_detach,
  1525.     udi_resume,
  1526.     udi_wait,
  1527.         udi_fetch_registers,
  1528.     udi_store_registers,
  1529.         udi_prepare_to_store,
  1530.         udi_xfer_inferior_memory,
  1531.         udi_files_info,
  1532.         udi_insert_breakpoint,
  1533.     udi_remove_breakpoint,
  1534.         0,            /* termial_init */
  1535.     0,            /* terminal_inferior */
  1536.     0,            /* terminal_ours_for_output */
  1537.     0,            /* terminal_ours */
  1538.     0,            /* terminal_info */
  1539.         udi_kill,                 /* FIXME, kill */
  1540.         udi_load,
  1541.         0,                      /* lookup_symbol */
  1542.         udi_create_inferior,
  1543.         udi_mourn,        /* mourn_inferior FIXME */
  1544.     0,            /* can_run */
  1545.     0,            /* notice_signals */
  1546.         process_stratum,
  1547.     0,            /* next */
  1548.         1,            /* has_all_memory */
  1549.     1,            /* has_memory */
  1550.     1,            /* has_stack */
  1551.     1,            /* has_registers */
  1552.     1,            /* has_execution */
  1553.     0,            /* sections */
  1554.     0,            /* sections_end */
  1555.     OPS_MAGIC,        /* Always the last thing */
  1556. };
  1557.  
  1558. void _initialize_remote_udi()
  1559. {
  1560.   add_target (&udi_ops);
  1561.   add_show_from_set (
  1562.              add_set_cmd ("remotedebug", no_class, var_boolean,
  1563.                   (char *)&kiodebug,
  1564.                   "Set debugging of UDI I/O.\n\
  1565. When enabled, debugging info is displayed.",
  1566.                   &setlist),
  1567.              &showlist);
  1568. }
  1569.  
  1570. #ifdef NO_HIF_SUPPORT
  1571. service_HIF(msg)
  1572. union msg_t    *msg;
  1573. {
  1574.     return(0);    /* Emulate a failure */
  1575. }
  1576. #endif
  1577.