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