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