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