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