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