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