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