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