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