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