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