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