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