]> Git Repo - binutils.git/blob - gdb/remote-udi.c
* remote-udi.c (udi_wait): Don't stop if TIP says that remote is
[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 = 11;
409   From.Offset = UDI29KSpecialRegs;
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 ("UDIGetStdin() 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           printf("DEBUG: stdin requested ... continue\n");
508           /*    UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
509           continue;
510         case UDIRunning:
511           /* In spite of the fact that we told UDIWait to wait forever, it will
512              return spuriously sometimes.  */
513         case UDIStdinModeX:
514           continue;
515         default:
516           break;
517         }
518       break;
519     }
520
521   switch (StopReason & UDIGrossState)
522     {
523     case UDITrapped:
524       printf("Am290*0 received vector number %d\n", StopReason >> 24);
525           
526       switch (StopReason >> 8)
527         {
528         case 0:                 /* Illegal opcode */
529           printf("      (break point)\n");
530           WSETSTOP ((*status), SIGTRAP);
531           break;
532         case 1:                 /* Unaligned Access */
533           WSETSTOP ((*status), SIGBUS);
534           break;
535         case 3:
536         case 4:
537           WSETSTOP ((*status), SIGFPE);
538           break;
539         case 5:                 /* Protection Violation */
540           WSETSTOP ((*status), SIGILL);
541           break;
542         case 6:
543         case 7:
544         case 8:                 /* User Instruction Mapping Miss */
545         case 9:                 /* User Data Mapping Miss */
546         case 10:                /* Supervisor Instruction Mapping Miss */
547         case 11:                /* Supervisor Data Mapping Miss */
548           WSETSTOP ((*status), SIGSEGV);
549           break;
550         case 12:
551         case 13:
552           WSETSTOP ((*status), SIGILL);
553           break;
554         case 14:                /* Timer */
555           WSETSTOP ((*status), SIGALRM);
556           break;
557         case 15:                /* Trace */
558           WSETSTOP ((*status), SIGTRAP);
559           break;
560         case 16:                /* INTR0 */
561         case 17:                /* INTR1 */
562         case 18:                /* INTR2 */
563         case 19:                /* INTR3/Internal */
564         case 20:                /* TRAP0 */
565         case 21:                /* TRAP1 */
566           WSETSTOP ((*status), SIGINT);
567           break;
568         case 22:                /* Floating-Point Exception */
569           WSETSTOP ((*status), SIGILL);
570           break;
571         case 77:                /* assert 77 */
572           WSETSTOP ((*status), SIGTRAP);
573           break;
574         default:
575           WSETEXIT ((*status), 0);
576         }
577       break;
578     case UDINotExecuting:
579       WSETSTOP ((*status), SIGTERM);
580       break;
581     case UDIStopped:
582       WSETSTOP ((*status), SIGTSTP);
583       break;
584     case UDIWarned:
585       WSETSTOP ((*status), SIGLOST);
586       break;
587     case UDIStepped:
588     case UDIBreak:
589       WSETSTOP ((*status), SIGTRAP);
590       break;
591     case UDIWaiting:
592       WSETSTOP ((*status), SIGSTOP);
593       break;
594     case UDIHalted:
595       WSETSTOP ((*status), SIGKILL);
596       break;
597     case UDIExited:
598     default:
599       WSETEXIT ((*status), 0);
600     }
601
602   timeout = old_timeout;        /* Restore original timeout value */
603   immediate_quit = old_immediate_quit;
604   return 0;
605 }
606
607 /********************************************************** UDI_FETCH_REGISTERS
608  * Read a remote register 'regno'. 
609  * If regno==-1 then read all the registers.
610  */
611 static void 
612 udi_fetch_registers (regno)
613 int     regno;
614 {
615   UDIResource   From;
616   UDIUInt32     *To;
617   UDICount      Count;
618   UDISizeT      Size = 4;
619   UDICount      CountDone;
620   UDIBool       HostEndian = 0;
621   UDIError      err;
622   int           i;
623
624   if (regno >= 0)  {
625     fetch_register(regno);
626     return;
627   }
628
629 /* Gr1/rsp */
630
631   From.Space = UDI29KGlobalRegs;
632   From.Offset = 1;
633   To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
634   Count = 1;
635   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
636     error("UDIRead() failed in udi_fetch_registers");
637
638   register_valid[GR1_REGNUM] = 1;
639
640 #if defined(GR64_REGNUM)        /* Read gr64-127 */
641
642 /* Global Registers gr64-gr95 */ 
643
644   From.Space = UDI29KGlobalRegs;
645   From.Offset = 64;
646   To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
647   Count = 32;
648   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
649     error("UDIRead() failed in udi_fetch_registers");
650
651   for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
652     register_valid[i] = 1;
653
654 #endif  /*  GR64_REGNUM */
655
656 /* Global Registers gr96-gr127 */ 
657
658   From.Space = UDI29KGlobalRegs;
659   From.Offset = 96;
660   To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
661   Count = 32;
662   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
663     error("UDIRead() failed in udi_fetch_registers");
664
665   for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
666     register_valid[i] = 1;
667
668 /* Local Registers */
669
670   From.Space = UDI29KLocalRegs;
671   From.Offset = 0;
672   To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
673   Count = 128;
674   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
675     error("UDIRead() failed in udi_fetch_registers");
676
677   for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
678     register_valid[i] = 1;
679
680 /* Protected Special Registers */
681
682   From.Space = UDI29KSpecialRegs;
683   From.Offset = 0;
684   To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
685   Count = 15;
686   if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
687     error("UDIRead() failed in udi_fetch_registers");
688
689   for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
690     register_valid[i] = 1;
691
692   if (USE_SHADOW_PC) {  /* Let regno_to_srnum() handle the register number */
693     fetch_register(NPC_REGNUM);
694     fetch_register(PC_REGNUM);
695     fetch_register(PC2_REGNUM);
696
697 /* Unprotected Special Registers sr128-sr135 */
698
699     From.Space = UDI29KSpecialRegs;
700     From.Offset = 128;
701     To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
702     Count = 135-128 + 1;
703     if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
704       error("UDIRead() failed in udi_fetch_registers");
705
706     for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
707       register_valid[i] = 1;
708   }
709
710   if (kiodebug)
711     {
712       printf("Fetching all registers\n");
713       printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
714              read_register(NPC_REGNUM), read_register(PC_REGNUM),
715              read_register(PC2_REGNUM));
716     }
717
718   /* There doesn't seem to be any way to get these.  */
719   {
720     int val = -1;
721     supply_register (FPE_REGNUM, (char *) &val);
722     supply_register (INTE_REGNUM, (char *) &val);
723     supply_register (FPS_REGNUM, (char *) &val);
724     supply_register (EXO_REGNUM, (char *) &val);
725   }
726 }
727
728
729 /********************************************************* UDI_STORE_REGISTERS
730 ** Store register regno into the target.  
731  * If regno==-1 then store all the registers.
732  */
733
734 static void
735 udi_store_registers (regno)
736 int regno;
737 {
738   UDIUInt32     *From;
739   UDIResource   To;
740   UDICount      Count;
741   UDISizeT      Size = 4;
742   UDICount      CountDone;
743   UDIBool       HostEndian = 0;
744   
745   if (regno >= 0)
746     {
747       store_register(regno);
748       return;
749     }
750
751   if (kiodebug)
752     {
753       printf("Storing all registers\n");
754       printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM),
755              read_register(PC_REGNUM), read_register(PC2_REGNUM));
756     }
757
758 /* Gr1/rsp */
759
760   From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
761   To.Space = UDI29KGlobalRegs;
762   To.Offset = 1;
763   Count = 1;
764   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
765     error("UDIWrite() failed in udi_store_regisetrs");
766
767 #if defined(GR64_REGNUM)
768
769 /* Global registers gr64-gr95 */
770
771   From = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
772   To.Space = UDI29KGlobalRegs;
773   To.Offset = 64;
774   Count = 32;
775   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
776     error("UDIWrite() failed in udi_store_regisetrs");
777
778 #endif  /* GR64_REGNUM */
779
780 /* Global registers gr96-gr127 */
781
782   From = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
783   To.Space = UDI29KGlobalRegs;
784   To.Offset = 96;
785   Count = 32;
786   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
787     error("UDIWrite() failed in udi_store_regisetrs");
788
789 /* Local Registers */
790
791   From = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
792   To.Space = UDI29KLocalRegs;
793   To.Offset = 0;
794   Count = 128;
795   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
796     error("UDIWrite() failed in udi_store_regisetrs");
797
798
799 /* Protected Special Registers */ /* VAB through TMR */
800
801   From = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
802   To.Space = UDI29KSpecialRegs;
803   To.Offset = 0;
804   Count = 10;
805   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
806     error("UDIWrite() failed in udi_store_regisetrs");
807
808 /* PC0, PC1, PC2 possibly as shadow registers */
809
810   From = (UDIUInt32 *)&registers[4 * SR_REGNUM(10)];
811   To.Space = UDI29KSpecialRegs;
812   Count = 3;
813   if (USE_SHADOW_PC) 
814     To.Offset = 20;                             /* SPC0 */
815   else 
816     To.Offset = 10;                             /* PC0 */
817   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
818     error("UDIWrite() failed in udi_store_regisetrs");
819
820   /* LRU and MMU */
821
822   From = (UDIUInt32 *)&registers[4 * SR_REGNUM(13)];
823   To.Space = UDI29KSpecialRegs;
824   To.Offset = 13;
825   Count = 2;
826   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
827     error("UDIWrite() failed in udi_store_regisetrs");
828
829 /* Unprotected Special Registers */ 
830
831   From = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
832   To.Space = UDI29KSpecialRegs;
833   To.Offset = 128;
834   Count = 135-128 +1;
835   if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
836     error("UDIWrite() failed in udi_store_regisetrs");
837
838   registers_changed ();
839 }
840
841 /****************************************************** UDI_PREPARE_TO_STORE */
842 /* Get ready to modify the registers array.  On machines which store
843    individual registers, this doesn't need to do anything.  On machines
844    which store all the registers in one fell swoop, this makes sure
845    that registers contains all the registers from the program being
846    debugged.  */
847
848 static void
849 udi_prepare_to_store ()
850 {
851   /* Do nothing, since we can store individual regs */
852 }
853
854 /********************************************************** TRANSLATE_ADDR */
855 static CORE_ADDR
856 translate_addr(addr)
857 CORE_ADDR addr;
858 {
859 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
860         /* Check for a virtual address in the kernel */
861         /* Assume physical address of ublock is in  paddr_u register */
862         /* FIXME: doesn't work for user virtual addresses */
863         if (addr >= UVADDR) {
864                 /* PADDR_U register holds the physical address of the ublock */
865                 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
866                 return(i + addr - (CORE_ADDR)UVADDR);
867         } else {
868                 return(addr);
869         }
870 #else
871         return(addr);
872 #endif
873 }
874 /************************************************* UDI_XFER_INFERIOR_MEMORY */
875 /* FIXME!  Merge these two.  */
876 static int
877 udi_xfer_inferior_memory (memaddr, myaddr, len, write)
878      CORE_ADDR memaddr;
879      char *myaddr;
880      int len;
881      int write;
882 {
883
884   memaddr = translate_addr(memaddr);
885
886   if (write)
887     return udi_write_inferior_memory (memaddr, myaddr, len);
888   else
889     return udi_read_inferior_memory (memaddr, myaddr, len);
890 }
891
892 /********************************************************** UDI_FILES_INFO */
893 static void
894 udi_files_info ()
895 {
896   printf ("\tAttached to UDI socket to %s and running program %s.\n",
897           udi_config_id, prog_name);
898 }
899
900 /**************************************************** UDI_INSERT_BREAKPOINT */
901 static int
902 udi_insert_breakpoint (addr, contents_cache)
903      CORE_ADDR addr;
904      char *contents_cache;
905 {
906   int cnt;
907   UDIError err;
908
909   for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
910     if (bkpt_table[cnt].Type == 0) /* Find first free slot */
911       break;
912
913   if(cnt >= BKPT_TABLE_SIZE)
914     error("Too many breakpoints set");
915
916   bkpt_table[cnt].Addr.Offset = addr;
917   bkpt_table[cnt].Addr.Space  = UDI29KIRAMSpace;
918   bkpt_table[cnt].PassCount = 1;
919   bkpt_table[cnt].Type = UDIBreakFlagExecute;
920   
921   err = UDISetBreakpoint(bkpt_table[cnt].Addr,
922                          bkpt_table[cnt].PassCount,
923                          bkpt_table[cnt].Type,
924                          &bkpt_table[cnt].BreakId);
925
926   if (err == 0) return 0;               /* Success */
927
928   bkpt_table[cnt].Type = 0;
929   error("UDISetBreakpoint returned error code %d\n", err);
930 }
931
932 /**************************************************** UDI_REMOVE_BREAKPOINT */
933 static int
934 udi_remove_breakpoint (addr, contents_cache)
935      CORE_ADDR addr;
936      char *contents_cache;
937 {
938   int cnt;
939   UDIError err;
940
941   for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
942     if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
943       break;
944
945   if(cnt >= BKPT_TABLE_SIZE)
946     error("Can't find breakpoint in table");
947
948   bkpt_table[cnt].Type = 0;
949
950   err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
951   if (err == 0) return 0;       /* Success */
952
953   error("UDIClearBreakpoint returned error code %d\n", err);
954 }
955
956 static void
957 udi_kill(arg,from_tty)
958      char *arg;
959      int from_tty;
960 {
961
962 #if 0
963 /*
964 UDIStop does not really work as advertised.  It causes the TIP to close it's
965 connection, which usually results in GDB dying with a SIGPIPE.  For now, we
966 just invoke udi_close, which seems to get things right.
967 */
968   UDIStop();
969
970   udi_session_id = -1;
971   inferior_pid = 0;
972
973   if (from_tty)
974     printf("Target has been stopped.");
975 #else
976   udi_close(0);
977 #endif
978   pop_target();
979 }
980
981 /* 
982    Load a program into the target.  Args are: `program {options}'.  The options
983    are used to control loading of the program, and are NOT passed onto the
984    loaded code as arguments.  (You need to use the `run' command to do that.)
985
986    The options are:
987                 -ms %d  Set mem stack size to %d
988                 -rs %d  Set regular stack size to %d
989                 -i      send init info (default)
990                 -noi    don't send init info
991                 -[tT]   Load Text section
992                 -[dD]   Load Data section
993                 -[bB]   Load BSS section
994                 -[lL]   Load Lit section
995   */
996
997 static void
998 download(load_arg_string, from_tty)
999      char *load_arg_string;
1000      int from_tty;
1001 {
1002 #define DEFAULT_MEM_STACK_SIZE          0x6000
1003 #define DEFAULT_REG_STACK_SIZE          0x2000
1004
1005   char *token;
1006   char *filename;
1007   asection *section;
1008   bfd *pbfd;
1009   UDIError err;
1010   int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1011
1012   address_ranges[0].Space = UDI29KIRAMSpace;
1013   address_ranges[0].Offset = 0xffffffff;
1014   address_ranges[0].Size = 0;
1015
1016   address_ranges[1].Space = UDI29KDRAMSpace;
1017   address_ranges[1].Offset = 0xffffffff;
1018   address_ranges[1].Size = 0;
1019
1020   stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1021   stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1022
1023   dont_repeat ();
1024
1025   filename = strtok(load_arg_string, " \t");
1026   if (!filename)
1027     error ("Must specify at least a file name with the load command");
1028
1029   filename = tilde_expand (filename);
1030   make_cleanup (free, filename);
1031
1032   while (token = strtok (NULL, " \t"))
1033     {
1034       if (token[0] == '-')
1035         {
1036           token++;
1037
1038           if (strcmp (token, "ms") == 0)
1039             stack_sizes[1] = atol (strtok (NULL, " \t"));
1040           else if (strcmp (token, "rs") == 0)
1041             stack_sizes[0] = atol (strtok (NULL, " \t"));
1042           else
1043             {
1044               load_text = load_data = load_bss = load_lit = 0;
1045
1046               while (*token)
1047                 {
1048                   switch (*token++)
1049                     {
1050                     case 't':
1051                     case 'T':
1052                       load_text = 1;
1053                       break;
1054                     case 'd':
1055                     case 'D':
1056                       load_data = 1;
1057                       break;
1058                     case 'b':
1059                     case 'B':
1060                       load_bss = 1;
1061                       break;
1062                     case 'l':
1063                     case 'L':
1064                       load_lit = 1;
1065                       break;
1066                     default:
1067                       error ("Unknown UDI load option -%s", token-1);
1068                     }
1069                 }
1070             }
1071         }
1072     }
1073
1074   pbfd = bfd_openr (filename, 0);
1075
1076   if (!pbfd) 
1077     perror_with_name (filename);
1078   
1079   make_cleanup (bfd_close, pbfd);
1080
1081   QUIT;
1082   immediate_quit++;
1083
1084   if (!bfd_check_format (pbfd, bfd_object)) 
1085     error ("It doesn't seem to be an object file");
1086   
1087   for (section = pbfd->sections; section; section = section->next) 
1088     {
1089       if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1090         {
1091           UDIResource To;
1092           UDICount Count;
1093           unsigned long section_size, section_end;
1094           const char *section_name;
1095
1096           section_name = bfd_get_section_name (pbfd, section);
1097           if (strcmp (section_name, ".text") == 0 && !load_text)
1098             continue;
1099           else if (strcmp (section_name, ".data") == 0 && !load_data)
1100             continue;
1101           else if (strcmp (section_name, ".bss") == 0 && !load_bss)
1102             continue;
1103           else if (strcmp (section_name, ".lit") == 0 && !load_lit)
1104             continue;
1105
1106           To.Offset = bfd_get_section_vma (pbfd, section);
1107           section_size = bfd_section_size (pbfd, section);
1108           section_end = To.Offset + section_size;
1109
1110           printf("[Loading section %s at %x (%d bytes)]\n",
1111                  section_name,
1112                  To.Offset,
1113                  section_size);
1114
1115           if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1116             {
1117               To.Space = UDI29KIRAMSpace;
1118
1119               address_ranges[0].Offset = min (address_ranges[0].Offset,
1120                                               To.Offset);
1121               address_ranges[0].Size = max (address_ranges[0].Size,
1122                                             section_end
1123                                             - address_ranges[0].Offset);
1124             }
1125           else
1126             {
1127               To.Space = UDI29KDRAMSpace;
1128
1129               address_ranges[1].Offset = min (address_ranges[1].Offset,
1130                                               To.Offset);
1131               address_ranges[1].Size = max (address_ranges[1].Size,
1132                                             section_end
1133                                             - address_ranges[1].Offset);
1134             }
1135
1136           if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1137             {
1138               file_ptr fptr;
1139
1140               fptr = 0;
1141
1142               while (section_size > 0)
1143                 {
1144                   char buffer[1024];
1145
1146                   Count = min (section_size, 1024);
1147
1148                   bfd_get_section_contents (pbfd, section, buffer, fptr,
1149                                             Count);
1150
1151                   err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
1152                                   To,                   /* To */
1153                                   Count,                /* Count */
1154                                   (UDISizeT)1,          /* Size */
1155                                   &Count,               /* CountDone */
1156                                   (UDIBool)0);          /* HostEndian */
1157                   if (err)
1158                     error ("UDIWrite failed, error = %d", err);
1159
1160                   To.Offset += Count;
1161                   fptr += Count;
1162                   section_size -= Count;
1163                 }
1164             }
1165           else                  /* BSS */
1166             {
1167               UDIResource From;
1168               unsigned long zero = 0;
1169
1170               /* Write a zero byte at the vma */
1171               err = UDIWrite ((UDIHostMemPtr)&zero,     /* From */
1172                               To,                       /* To */
1173                               (UDICount)1,              /* Count */
1174                               (UDISizeT)4,              /* Size */
1175                               &Count,                   /* CountDone */
1176                               (UDIBool)0);              /* HostEndian */
1177               if (err)
1178                 error ("UDIWrite failed, error = %d", err);
1179
1180               From = To;
1181               To.Offset+=4;
1182
1183               /* Now, duplicate it for the length of the BSS */
1184               err = UDICopy (From,                      /* From */
1185                              To,                        /* To */
1186                              (UDICount)(section_size/4 - 1), /* Count */
1187                              (UDISizeT)4,               /* Size */
1188                              &Count,                    /* CountDone */
1189                              (UDIBool)1);               /* Direction */
1190               if (err)
1191                 {
1192                   char message[100];
1193                   int xerr;
1194
1195                   xerr = UDIGetErrorMsg(err, 100, message, &Count);
1196                   if (!xerr)
1197                     fprintf (stderr, "Error is %s\n", message);
1198                   else
1199                     fprintf (stderr, "xerr is %d\n", xerr);
1200                   error ("UDICopy failed, error = %d", err);
1201                 }
1202             }
1203
1204         }
1205     }
1206
1207   entry.Space = UDI29KIRAMSpace;
1208   entry.Offset = bfd_get_start_address (pbfd);
1209   
1210   immediate_quit--;
1211 }
1212
1213 /* User interface to download an image into the remote target.  See download()
1214  * for details on args.
1215  */
1216
1217 static void
1218 udi_load(args, from_tty)
1219      char *args;
1220      int from_tty;
1221 {
1222   download (args, from_tty);
1223
1224   symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
1225 }
1226
1227 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1228 ** Copy LEN bytes of data from debugger memory at MYADDR
1229    to inferior's memory at MEMADDR.  Returns number of bytes written.  */
1230 static int
1231 udi_write_inferior_memory (memaddr, myaddr, len)
1232      CORE_ADDR memaddr;
1233      char *myaddr;
1234      int len;
1235 {
1236   int           nwritten = 0;
1237   UDIUInt32     *From;
1238   UDIResource   To;
1239   UDICount      Count;
1240   UDISizeT      Size = 1;
1241   UDICount      CountDone = 0;
1242   UDIBool       HostEndian = 0;
1243   
1244   To.Space = udi_memory_space(memaddr);
1245   From = (UDIUInt32*)myaddr;
1246
1247   while (nwritten < len)
1248   {     Count = len - nwritten;
1249         if (Count > MAXDATA) Count = MAXDATA;
1250         To.Offset = memaddr + nwritten;
1251         if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1252         {  error("UDIWrite() failed in udi_write_inferrior_memory");
1253            break;       
1254         }
1255         else
1256         {  nwritten += CountDone;
1257            From += CountDone;
1258         }
1259   }
1260   return(nwritten);
1261 }
1262
1263 /**************************************************** UDI_READ_INFERIOR_MEMORY
1264 ** Read LEN bytes from inferior memory at MEMADDR.  Put the result
1265    at debugger address MYADDR.  Returns number of bytes read.  */
1266 static int
1267 udi_read_inferior_memory(memaddr, myaddr, len)
1268      CORE_ADDR memaddr;
1269      char *myaddr;
1270      int len;
1271 {
1272   int           nread = 0;
1273   UDIResource   From;
1274   UDIUInt32     *To;
1275   UDICount      Count;
1276   UDISizeT      Size = 1;
1277   UDICount      CountDone = 0;
1278   UDIBool       HostEndian = 0;
1279   UDIError      err;
1280   
1281   From.Space = udi_memory_space(memaddr);       
1282   To = (UDIUInt32*)myaddr;
1283
1284   while (nread < len)
1285   {     Count = len - nread;
1286         if (Count > MAXDATA) Count = MAXDATA;
1287         From.Offset = memaddr + nread;
1288         if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1289         {  error("UDIRead() failed in udi_read_inferrior_memory");
1290            break;       
1291         }
1292         else
1293         {  nread += CountDone;
1294            To += CountDone;
1295         }
1296   }
1297   return(nread);
1298 }
1299
1300 /********************************************************************* WARNING
1301 */
1302 udi_warning(num)
1303 int     num;
1304 {
1305     error ("ERROR while loading program into remote TIP: $d\n", num);
1306 }
1307
1308
1309 /*****************************************************************************/ 
1310 /* Fetch a single register indicatated by 'regno'. 
1311  * Returns 0/-1 on success/failure.  
1312  */
1313 static void
1314 fetch_register (regno)
1315      int regno;
1316 {
1317   UDIResource   From;
1318   UDIUInt32     To;
1319   UDICount      Count = 1;
1320   UDISizeT      Size = 4;
1321   UDICount      CountDone;
1322   UDIBool       HostEndian = 0;
1323   UDIError      err;
1324   int           result;
1325
1326   if (regno == GR1_REGNUM)
1327     {
1328       From.Space = UDI29KGlobalRegs;
1329       From.Offset = 1;
1330     }
1331   else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1332     {
1333       From.Space = UDI29KGlobalRegs;
1334       From.Offset = (regno - GR96_REGNUM) + 96;;
1335     }
1336
1337 #if defined(GR64_REGNUM)
1338
1339   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1340     {
1341       From.Space = UDI29KGlobalRegs;
1342       From.Offset = (regno - GR64_REGNUM) + 64;
1343     }
1344
1345 #endif  /* GR64_REGNUM */
1346
1347   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1348     {
1349       From.Space = UDI29KLocalRegs;
1350       From.Offset = (regno - LR0_REGNUM);
1351     }
1352   else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)  
1353     {
1354       int val = -1;
1355       supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
1356       return;           /* Pretend Success */
1357     }
1358   else 
1359     {
1360       From.Space = UDI29KSpecialRegs;
1361       From.Offset = regnum_to_srnum(regno); 
1362     }
1363
1364   if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
1365     error("UDIRead() failed in udi_fetch_registers");
1366
1367   supply_register(regno, (char *) &To);
1368
1369   if (kiodebug)
1370     printf("Fetching register %s = 0x%x\n", reg_names[regno], To);
1371 }
1372 /*****************************************************************************/ 
1373 /* Store a single register indicated by 'regno'. 
1374  * Returns 0/-1 on success/failure.  
1375  */
1376 static int
1377 store_register (regno)
1378      int regno;
1379 {
1380   int           result;
1381   UDIUInt32     From;
1382   UDIResource   To;
1383   UDICount      Count = 1;
1384   UDISizeT      Size = 4;
1385   UDICount      CountDone;
1386   UDIBool       HostEndian = 0;
1387
1388   From =  read_register (regno);        /* get data value */
1389
1390   if (kiodebug)
1391     printf("Storing register %s = 0x%x\n", reg_names[regno], From);
1392
1393   if (regno == GR1_REGNUM)
1394   { To.Space = UDI29KGlobalRegs;
1395     To.Offset = 1;
1396     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1397     /* Setting GR1 changes the numbers of all the locals, so invalidate the 
1398      * register cache.  Do this *after* calling read_register, because we want 
1399      * read_register to return the value that write_register has just stuffed 
1400      * into the registers array, not the value of the register fetched from 
1401      * the inferior.  
1402      */
1403     registers_changed ();
1404   }
1405 #if defined(GR64_REGNUM)
1406   else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1407   { To.Space = UDI29KGlobalRegs;
1408     To.Offset = (regno - GR64_REGNUM) + 64;
1409     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1410   }
1411 #endif  /* GR64_REGNUM */
1412   else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1413   { To.Space = UDI29KGlobalRegs;
1414     To.Offset = (regno - GR96_REGNUM) + 96;
1415     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1416   }
1417   else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1418   { To.Space = UDI29KLocalRegs;
1419     To.Offset = (regno - LR0_REGNUM);
1420     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1421   }
1422   else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)  
1423   { 
1424     return 0;           /* Pretend Success */
1425   }
1426   else  /* An unprotected or protected special register */
1427   { To.Space = UDI29KSpecialRegs;
1428     To.Offset = regnum_to_srnum(regno); 
1429     result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1430   }
1431
1432   if(result)
1433   { result = -1;
1434     error("UDIWrite() failed in store_registers");
1435   }
1436   return result;
1437 }
1438 /********************************************************** REGNUM_TO_SRNUM */
1439 /* 
1440  * Convert a gdb special register number to a 29000 special register number.
1441  */
1442 static int
1443 regnum_to_srnum(regno)
1444 int     regno;
1445 {
1446         switch(regno) {
1447                 case VAB_REGNUM: return(0); 
1448                 case OPS_REGNUM: return(1); 
1449                 case CPS_REGNUM: return(2); 
1450                 case CFG_REGNUM: return(3); 
1451                 case CHA_REGNUM: return(4); 
1452                 case CHD_REGNUM: return(5); 
1453                 case CHC_REGNUM: return(6); 
1454                 case RBP_REGNUM: return(7); 
1455                 case TMC_REGNUM: return(8); 
1456                 case TMR_REGNUM: return(9); 
1457                 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1458                 case PC_REGNUM:  return(USE_SHADOW_PC ? (21) : (11));
1459                 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1460                 case MMU_REGNUM: return(13); 
1461                 case LRU_REGNUM: return(14); 
1462                 case IPC_REGNUM: return(128); 
1463                 case IPA_REGNUM: return(129); 
1464                 case IPB_REGNUM: return(130); 
1465                 case Q_REGNUM:   return(131); 
1466                 case ALU_REGNUM: return(132); 
1467                 case BP_REGNUM:  return(133); 
1468                 case FC_REGNUM:  return(134); 
1469                 case CR_REGNUM:  return(135); 
1470                 case FPE_REGNUM: return(160); 
1471                 case INTE_REGNUM: return(161); 
1472                 case FPS_REGNUM: return(162); 
1473                 case EXO_REGNUM:return(164); 
1474                 default:
1475                         return(255);    /* Failure ? */
1476         }
1477 }
1478 /****************************************************************************/
1479 /*
1480  * Determine the Target memory space qualifier based on the addr. 
1481  * FIXME: Can't distinguis I_ROM/D_ROM.  
1482  * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1483  */
1484 static CPUSpace
1485 udi_memory_space(addr)
1486 CORE_ADDR       addr;
1487 {
1488         UDIUInt32 tstart = IMemStart;
1489         UDIUInt32 tend   = tstart + IMemSize;  
1490         UDIUInt32 dstart = DMemStart;
1491         UDIUInt32 dend   = tstart + DMemSize;  
1492         UDIUInt32 rstart = RMemStart;
1493         UDIUInt32 rend   = tstart + RMemSize;  
1494
1495         if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) { 
1496                 return UDI29KIRAMSpace;
1497         } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) { 
1498                 return UDI29KDRAMSpace;
1499         } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1500                 /* FIXME: how do we determine between D_ROM and I_ROM */
1501                 return UDI29KIROMSpace;
1502         } else  /* FIXME: what do me do now? */
1503                 return UDI29KDRAMSpace; /* Hmmm! */
1504 }
1505 /*********************************************************************** STUBS
1506 */
1507
1508 void  convert16() {;}
1509 void  convert32() {;}
1510 FILE* EchoFile = 0;             /* used for debugging */
1511 int   QuietMode = 0;            /* used for debugging */
1512
1513 /****************************************************************************/
1514 /* 
1515  *  Define the target subroutine names 
1516  */
1517 static struct target_ops udi_ops = {
1518         "udi",
1519         "Remote UDI connected TIP",
1520         "Remote debug an AMD 29k using UDI socket connection to TIP process",
1521         udi_open,
1522         udi_close,
1523         udi_attach,
1524         udi_detach,
1525         udi_resume,
1526         udi_wait,
1527         udi_fetch_registers,
1528         udi_store_registers,
1529         udi_prepare_to_store,
1530         udi_xfer_inferior_memory,
1531         udi_files_info,
1532         udi_insert_breakpoint,
1533         udi_remove_breakpoint,
1534         0,                      /* termial_init */
1535         0,                      /* terminal_inferior */
1536         0,                      /* terminal_ours_for_output */
1537         0,                      /* terminal_ours */
1538         0,                      /* terminal_info */
1539         udi_kill,               /* FIXME, kill */
1540         udi_load,
1541         0,                      /* lookup_symbol */
1542         udi_create_inferior,
1543         udi_mourn,              /* mourn_inferior FIXME */
1544         0,                      /* can_run */
1545         0,                      /* notice_signals */
1546         process_stratum,
1547         0,                      /* next */
1548         1,                      /* has_all_memory */
1549         1,                      /* has_memory */
1550         1,                      /* has_stack */
1551         1,                      /* has_registers */
1552         1,                      /* has_execution */
1553         0,                      /* sections */
1554         0,                      /* sections_end */
1555         OPS_MAGIC,              /* Always the last thing */
1556 };
1557
1558 void _initialize_remote_udi()
1559 {
1560   add_target (&udi_ops);
1561   add_show_from_set (
1562                      add_set_cmd ("remotedebug", no_class, var_boolean,
1563                                   (char *)&kiodebug,
1564                                   "Set debugging of UDI I/O.\n\
1565 When enabled, debugging info is displayed.",
1566                                   &setlist),
1567                      &showlist);
1568 }
1569
1570 #ifdef NO_HIF_SUPPORT
1571 service_HIF(msg)
1572 union msg_t     *msg;
1573 {
1574         return(0);      /* Emulate a failure */
1575 }
1576 #endif
This page took 0.111864 seconds and 4 git commands to generate.