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