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