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