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