]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-udi.c
* printcmd.c (output_command): Thinko.
[thirdparty/binutils-gdb.git] / gdb / remote-udi.c
CommitLineData
9bddba9a
SG
1/*
2 - Remote debugging interface for Am290*0 running MiniMON monitor, for GDB.
3 This is like remote.c but expects MiniMON to be running on the Am29000
4 target hardware.
5 - Originally written by Daniel Mann at AMD for gdb 3.91.6.
6 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
7 file to gdb 3.95. I was unable to get this working on sun3os4
8 with termio, only with sgtty. Because we are only attempting to
9 use this module to debug our kernel, which is already loaded when
10 gdb is started up, I did not code up the file downloading facilities.
11 As a result this module has only the stubs to download files.
12 You should get tagged at compile time if you need to make any
13 changes/additions.
14*- Daniel Mann at AMD took the 3.95 adaptions above and replaced
15 MiniMON interface with UDI-p interface.
16
17 Copyright (C) 1990 Free Software Foundation, Inc.
18
19This file is part of GDB.
20
21This program is free software; you can redistribute it and/or modify
22it under the terms of the GNU General Public License as published by
23the Free Software Foundation; either version 1, or (at your option)
24any later version.
25
26This program is distributed in the hope that it will be useful,
27but WITHOUT ANY WARRANTY; without even the implied warranty of
28MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29GNU General Public License for more details.
30
31You should have received a copy of the GNU General Public License
32along with this program; see the file COPYING. If not, write to
33the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
34
35
36#include <stdio.h>
37#include "defs.h"
38#include "inferior.h"
39#include "wait.h"
40#include "value.h"
41#include <ctype.h>
42#include <fcntl.h>
43#include <signal.h>
44#include <errno.h>
45#include <string.h>
46#include "terminal.h"
47#include "target.h"
aa942355 48#include "29k-share/udi/udiproc.h"
9bddba9a
SG
49
50/* access the register store directly, without going through
51 the normal handler functions. This avoids an extra data copy
52*/
53
54/* #define DEBUG 1 /* */
55#ifdef DEBUG
56# define DENTER(NAME) (printf("Entering %s\n",NAME), fflush(stdout))
57# define DEXIT(NAME) (printf("Exiting %s\n",NAME), fflush(stdout))
58#else
59# define DENTER(NAME)
60# define DEXIT(NAME)
61#endif
62
63
9bddba9a
SG
64extern int stop_soon_quietly; /* for wait_for_inferior */
65extern struct value *call_function_by_hand();
66static void udi_resume();
67static void udi_fetch_registers ();
68static void udi_load();
69static int fetch_register ();
70static void udi_store_registers ();
71static int store_register ();
72static int regnum_to_srnum();
73static void udi_close ();
74static CPUSpace udi_memory_space();
75static int udi_write_inferior_memory();
76static int udi_read_inferior_memory();
77char CoffFileName[100] = "";
78/*
79 * Processor types.
80 */
81#define TYPE_UNKNOWN 0
82#define TYPE_A29000 1
83#define TYPE_A29030 2
84#define TYPE_A29050 3
85static char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
86static int processor_type=TYPE_UNKNOWN;
87#define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
88#define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
89
90#define LLOG_FILE "udi.log"
91#if defined (LOG_FILE)
92FILE *log_file;
93#endif
94
95static int timeout = 5;
96extern struct target_ops udi_ops; /* Forward declaration */
97
98/* Special register enumeration.
99*/
100
101/******************************************************************* UDI DATA*/
102#define MAXDATA 2*1024 /* max UDI[read/write] byte size */
103/* Descriptor for I/O to remote machine. Initialize it to -1 so that
104 udi_open knows that we don't have a file open when the program
105 starts. */
106 UDISessionId udi_session_id = -1;
107
108 CPUOffset IMemStart = 0;
109 CPUSizeT IMemSize = 0;
110 CPUOffset DMemStart = 0;
111 CPUSizeT DMemSize = 0;
112 CPUOffset RMemStart = 0;
113 CPUSizeT RMemSize = 0;
114 UDIUInt32 CPUPRL;
115 UDIUInt32 CoProcPRL;
116
117#define SBUF_MAX 1024 /* maximum size of string handling buffer */
118char sbuf[SBUF_MAX];
119
120typedef struct bkpt_entry_str
121{
122 UDIResource Addr;
123 UDIUInt32 PassCount;
124 UDIBreakType Type;
125 unsigned int BreakId;
126} bkpt_entry_t;
54847287
SG
127#define BKPT_TABLE_SIZE 40
128static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
9bddba9a
SG
129extern char dfe_errmsg[]; /* error string */
130
131/*********************************************************** SIGNAL SUPPORT */
132/* Called when SIGALRM signal sent due to alarm() timeout. */
133#ifndef HAVE_TERMIO
134
135#ifndef __STDC__
136# ifndef volatile
137# define volatile /**/
138# endif
139#endif
140volatile int n_alarms;
141
142static void
143udi_timer ()
144{
145#if 0
146 if (kiodebug)
147 printf ("udi_timer called\n");
148#endif
149 n_alarms++;
150}
151#endif /* HAVE_TERMIO */
152
153/* malloc'd name of the program on the remote system. */
154static char *prog_name = NULL;
155
156
157/* Number of SIGTRAPs we need to simulate. That is, the next
158 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
159 SIGTRAP without actually waiting for anything. */
160
161/******************************************************* UDI_CREATE_INFERIOR */
162/* This is called not only when we first attach, but also when the
163 user types "run" after having attached. */
164static void
165udi_create_inferior (execfile, args, env)
166 char *execfile;
167 char *args;
168 char **env;
169{
170 DENTER("udi_create_inferior()");
171
172 if (execfile)
173 { if (prog_name != NULL)
174 free (prog_name);
175 prog_name = savestring (execfile, strlen (execfile));
176 }
177
178 if (prog_name == 0 /* || exec_bfd == 0 */ )
179 error ("No exec file specified");
180
181 if (udi_session_id < 0){
182 printf("UDI connection not open yet.\n");
183 return;
184 }
185
d0b04c6a
SG
186 inferior_pid = 40000;
187
9bddba9a
SG
188#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
189 /* On ultra3 (NYU) we assume the kernel is already running so there is
190 * no file to download
191 */
192#else
193 if(*args == '\0') args = prog_name;
194 udi_load(args, 0);
195#endif /* !ULTRA3 */
196
197 /* We will get a task spawn event immediately. */
198#ifdef NOTDEF /* start_remote() now does a wait without a resume
199 so don't use it*/
200 start_remote ();
201#else
202 init_wait_for_inferior ();
203 clear_proceed_status ();
204 proceed(-1,-1,0);
205#endif
206 DEXIT("udi_create_inferior()");
207}
208/******************************************************* UDI_MOURN_INFERIOR */
209static void
210udi_mourn()
211{
212 DENTER("udi_mourn()");
213 pop_target (); /* Pop back to no-child state */
214 generic_mourn_inferior ();
215 DEXIT("udi_mourn()");
216}
217
218/******************************************************************** UDI_OPEN
219** Open a connection to remote TIP.
220 NAME is the socket domain used for communication with the TIP,
221 then a space and the socket name or TIP-host name.
222 '<udi_udi_config_id> [progname]' for example.
223 */
224
d0b04c6a
SG
225/* XXX - need cleanups for udiconnect for various failures!!! */
226
9bddba9a
SG
227static char *udi_config_id;
228static void
229udi_open (name, from_tty)
230 char *name;
231 int from_tty;
232{
233 unsigned int prl;
234 char *p;
235 int cnt;
236 UDIMemoryRange KnownMemory[10];
237 UDIUInt32 ChipVersions[10];
238 UDIInt NumberOfRanges = 10;
239 UDIInt NumberOfChips = 10;
240 UDIPId PId;
241 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
242
243 DENTER("udi_open()");
244
d0b04c6a
SG
245 target_preopen(from_tty);
246
9bddba9a
SG
247 /* Find the first whitespace character, it separates udi_config_id
248 from prog_name. */
249 if(!name) goto erroid;
250 for (p = name;
251 *p != '\0' && !isspace (*p); p++)
252 ;
253 if (*p == '\0')
254erroid:
255 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
d0b04c6a 256
9bddba9a
SG
257 udi_config_id = (char*)malloc (p - name + 1);
258 strncpy (udi_config_id, name, p - name);
259 udi_config_id[p - name] = '\0';
260
261 /* Skip over the whitespace after udi_config_id */
262 for (; isspace (*p); p++)
263 /*EMPTY*/;
264
265 if (prog_name != NULL)
266 free (prog_name);
267 prog_name = savestring (p, strlen (p));
268
d0b04c6a
SG
269 if (UDIConnect(udi_config_id, &udi_session_id))
270 error("UDIConnect() failed: %s\n", dfe_errmsg);
9bddba9a 271
9bddba9a
SG
272 push_target (&udi_ops);
273
274#ifndef HAVE_TERMIO
275#ifndef NO_SIGINTERRUPT
276 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
277 the read. */
278 if (siginterrupt (SIGALRM, 1) != 0)
d0b04c6a 279 error ("udi_open: siginterrupt() %s", safe_strerror(errno));
9bddba9a
SG
280#endif
281
282 /* Set up read timeout timer. */
283 if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
d0b04c6a 284 error ("udi_open: signal() %s", safe_strerror(errno));
9bddba9a
SG
285#endif
286
287#if defined (LOG_FILE)
288 log_file = fopen (LOG_FILE, "w");
289 if (log_file == NULL)
d0b04c6a 290 error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno));
9bddba9a
SG
291#endif
292 /*
293 ** Initialize target configuration structure (global)
294 */
295 if(UDIGetTargetConfig( KnownMemory, &NumberOfRanges,
296 ChipVersions, &NumberOfChips))
297 error ("UDIGetTargetConfig() failed");
298 if(NumberOfChips > 2)
299 fprintf(stderr,"Taret has more than one processor\n");
300 for(cnt=0; cnt<NumberOfRanges; cnt++)
301 { switch(KnownMemory[cnt].Space)
302 {
303 default: fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
304 break;
305 case UDI29KCP_S:
306 break;
307 case UDI29KIROMSpace:
308 RMemStart = KnownMemory[cnt].Offset;
309 RMemSize = KnownMemory[cnt].Size;
310 break;
311 case UDI29KIRAMSpace:
312 IMemStart = KnownMemory[cnt].Offset;
313 IMemSize = KnownMemory[cnt].Size;
314 break;
315 case UDI29KDRAMSpace:
316 DMemStart = KnownMemory[cnt].Offset;
317 DMemSize = KnownMemory[cnt].Size;
318 break;
319 }
320 }
321
322 /* Determine the processor revision level */
323 prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
324 if ((prl&0xe0) == 0)
325 { fprintf_filtered(stderr,
326 "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
327 processor_type = TYPE_A29000;
328 } else if ((prl&0xe0) == 0x40) /* 29030 = 0x4* */
329 { fprintf_filtered(stderr,
330 "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
331 processor_type = TYPE_A29030;
332 } else if ((prl&0xe0) == 0x20) /* 29050 = 0x2* */
333 { fprintf_filtered(stderr,
334 "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
335 processor_type = TYPE_A29050;
336 } else {
337 processor_type = TYPE_UNKNOWN;
338 fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
339 }
340 if(UDICreateProcess(&PId))
341 fprintf(stderr, "UDICreateProcess() failed\n");
342
343 /* Print out some stuff, letting the user now what's going on */
344 if(UDICapabilities( &TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
345 &TIPIPCId, sbuf))
346 error ("UDICapabilities() failed");
347 if (from_tty) {
348 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
349 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
350 processor_name[processor_type],
351 (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
352 (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
353 (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
354 sbuf);
355#ifdef ULTRA3
356 /* FIXME: can this restriction be removed? */
357 printf_filtered("Remote debugging using virtual addresses works only\n");
358 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
359#endif
360 }
361#ifdef ULTRA3
362 if (processor_type != TYPE_A29050) {
363 fprintf_filtered(stderr,
364 "Freeze-mode debugging can only be done on an Am29050,\n");
365 fprintf_filtered(stderr,
366 " unless GDB is being used with a 29K simulator.\n");
367 }
368#endif
369}
370
371/******************************************************************* UDI_CLOSE
372 Close the open connection to the TIP process.
373 Use this when you want to detach and do something else
374 with your gdb. */
375static void
376udi_close (quitting) /*FIXME: how is quitting used */
377 int quitting;
378{
379 int Terminate = -1;
380 DENTER("udi_close()");
381
382 if (udi_session_id < 0)
383 error ("Can't close udi connection: not debugging remotely.");
384
385 /* We should never get here if there isn't something valid in
386 udi_session_id.
387
388 if(UDIDisconnect(udi_stream, Terminate);)
389 error ("UDIDisconnect() failed in udi_close");
390
391 /* Do not try to close udi_session_id again, later in the program. */
392 udi_session_id = -1;
d0b04c6a 393 inferior_pid = 0;
9bddba9a
SG
394
395#if defined (LOG_FILE)
396 if (ferror (log_file))
397 printf ("Error writing log file.\n");
398 if (fclose (log_file) != 0)
399 printf ("Error closing log file.\n");
400#endif
401
d0b04c6a 402 printf_filtered (" Ending remote debugging\n");
9bddba9a
SG
403
404 DEXIT("udi_close()");
405}
406
407/**************************************************************** UDI_ATACH */
408/* Attach to a program that is already loaded and running
409 * Upon exiting the process's execution is stopped.
410 */
411static void
412udi_attach (args, from_tty)
413 char *args;
414 int from_tty;
415{
416 UDIResource From;
417 UDIInt32 PC_adds;
418 UDICount Count = 1;
419 UDISizeT Size = 4;
420 UDICount CountDone;
421 UDIBool HostEndian = 0;
422 DENTER("udi_attach()");
423
424 if (udi_session_id < 0)
425 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
426
427 if (from_tty)
428 printf ("Attaching to remote program %s...\n", prog_name);
429
430 mark_breakpoints_out ();
431 UDIStop();
432 From.Space = 11;
433 From.Offset = UDI29KSpecialRegs;
434 if(UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
435 error ("UDIRead failed in udi_attach");
436 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
437
438 DEXIT("udi_attach()");
439}
440/************************************************************* UDI_DETACH */
441/* Terminate the open connection to the TIP process.
442 Use this when you want to detach and do something else
443 with your gdb. Leave remote process running (with no breakpoints set). */
444static void
445udi_detach (args,from_tty)
446 char *args;
447 int from_tty;
448{
449 DENTER("udi_dettach()");
450 remove_breakpoints(); /* Just in case there were any left in */
451 if(UDIDisconnect(udi_session_id))
452 error ("UDIDisconnect() failed in udi_detach");
453 pop_target(); /* calls udi_close to do the real work */
454 if (from_tty)
455 printf ("Ending remote debugging\n");
456 DEXIT("udi_dettach()");
457}
458
459
460/****************************************************************** UDI_RESUME
461** Tell the remote machine to resume. */
462
463static void
464udi_resume (step, sig)
465 int step, sig;
466{
467 UDIError tip_error;
468 UDIUInt32 Steps = 1;
469 UDIStepType StepType = UDIStepNatural;
470 UDIRange Range;
471 DENTER("udi_resume()");
472 if (step) /* step 1 instruction */
473 { tip_error = tip_error = UDIStep(Steps, StepType, Range);
474 if(tip_error)fprintf(stderr, "UDIStep() error = %d\n", tip_error);
475 if(tip_error)error ("failed in udi_resume");
476
477 }
478 else
479 { if(UDIExecute())
480 error ("UDIExecute() failed in udi_resume");
481 }
482
483 DEXIT("udi_resume()");
484}
485
486/******************************************************************** UDI_WAIT
487** Wait until the remote machine stops, then return,
488 storing status in STATUS just as `wait' would. */
489
490static int
491udi_wait (status)
492 WAITTYPE *status;
493{
494 UDIInt32 MaxTime;
495 UDIPId PId;
496 UDIInt32 StopReason;
497 UDISizeT CountDone;
498 int old_timeout = timeout;
499 int old_immediate_quit = immediate_quit;
500 int i;
501
502 DENTER("udi_wait()");
503 WSETEXIT ((*status), 0);
504
505/* wait for message to arrive. It should be:
506 If the target stops executing, udi_wait() should return.
507*/
508 timeout = 0; /* Wait indefinetly for a message */
509 immediate_quit = 1; /* Helps ability to QUIT */
510 while(1)
511 {
512 i = 0;
513 MaxTime = UDIWaitForever;
514 UDIWait(MaxTime, &PId, &StopReason);
515 QUIT; /* Let user quit if they want */
516 switch (StopReason & 0xff)
517 {
518 default:
519 goto halted;
520 case UDIStdoutReady:
521 if(UDIGetStdout(sbuf, (UDISizeT)SBUF_MAX, &CountDone))
522 error("UDIGetStdin() failed in udi_wait");
523 while(CountDone--)putc(sbuf[i++], stdout);
524 fflush(stdout);
525 break;
526 case UDIStderrReady:
527 UDIGetStderr(sbuf, (UDISizeT)SBUF_MAX, &CountDone);
528 while(CountDone--)putc(sbuf[i++], stderr);
529 fflush(stderr);
530 fflush(stderr);
531 break;
532 case UDIStdinNeeded:
533 printf("DEBUG: stdin requested ... continue\n");
534/* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
535 break;
536 case UDIStdinModeX:
537 break;
538 }
539 continue;
540 }
541halted:
542 if (StopReason & 0xff == UDITrapped ) /* lower 8-bits == 0 */
543 {
544 if (StopReason >> 24 == 0)
545 { printf("Am290*0 received vector number 0 (break point)\n");
546 WSETSTOP ((*status), SIGTRAP);
547 }
548 else if (StopReason >> 24 == 1)
549 { printf("Am290*0 received vector 1\n");
550 WSETSTOP ((*status), SIGBUS);
551 }
552 else if (StopReason >> 24 == 3
553 || StopReason >> 24 == 4)
554 { printf("Am290*0 received vector number %d\n",
555 StopReason >> 24);
556 WSETSTOP ((*status), SIGFPE);
557 }
558 else if (StopReason >> 24 == 5)
559 { printf("Am290*0 received vector number %d\n",
560 StopReason >> 24);
561 WSETSTOP ((*status), SIGILL);
562 }
563 else if (StopReason >> 24 >= 6
564 && StopReason >> 24 <= 11)
565 { printf("Am290*0 received vector number %d\n",
566 StopReason >> 24);
567 WSETSTOP ((*status), SIGSEGV);
568 }
569 else if (StopReason >> 24 == 12
570 || StopReason >> 24 == 13)
571 { printf("Am290*0 received vector number %d\n",
572 StopReason >> 24);
573 WSETSTOP ((*status), SIGILL);
574 }
575 else if ((StopReason & 0xff) == 14)
576 { printf("Am290*0 received vector number %d\n",
577 StopReason >> 24);
578 WSETSTOP ((*status), SIGALRM);
579 }
580 else if ((StopReason & 0xff) == 15)
581 WSETSTOP ((*status), SIGTRAP);
582 else if ((StopReason >> 24) >= 16
583 && (StopReason >> 24) <= 21)
584 { printf("Am290*0 received vector number %d\n",
585 StopReason >> 24);
586 WSETSTOP ((*status), SIGINT);
587 }
588 else if ((StopReason & 0xff) == 22)
589 { printf("Am290*0 received vector number %d\n",
590 StopReason >> 24);
591 WSETSTOP ((*status), SIGILL);
592 }
593 else if ((StopReason & 0xff) == 77)
594 WSETSTOP ((*status), SIGTRAP);
595 else
596exit:
597 WSETEXIT ((*status), 0);
598 }
599 else if ((StopReason & 0xff) == UDIBreak)
600 WSETSTOP ((*status), SIGTRAP);
601 else if ((StopReason & 0xff) == UDINotExecuting)
602 WSETSTOP ((*status), SIGTERM);
603 else if ((StopReason & 0xff) == UDIRunning)
604 WSETSTOP ((*status), SIGILL);
605 else if ((StopReason & 0xff) == UDIStopped)
606 WSETSTOP ((*status), SIGTSTP);
607 else if ((StopReason & 0xff) == UDIWarned)
608 WSETSTOP ((*status), SIGLOST);
609 else if ((StopReason & 0xff) == UDIStepped)
610 WSETSTOP ((*status), SIGTRAP);
611 else if ((StopReason & 0xff) == UDIWaiting)
612 WSETSTOP ((*status), SIGSTOP);
613 else if ((StopReason & 0xff) == UDIHalted)
614 WSETSTOP ((*status), SIGKILL);
615 else
616 WSETEXIT ((*status), 0);
617
618 timeout = old_timeout; /* Restore original timeout value */
619 immediate_quit = old_immediate_quit;
620 DEXIT("udi_wait()");
621 return 0;
622}
623
624/********************************************************** UDI_FETCH_REGISTERS
625 * Read a remote register 'regno'.
626 * If regno==-1 then read all the registers.
627 */
628static void
629udi_fetch_registers (regno)
630int regno;
631{
632 UDIResource From;
633 UDIUInt32 *To;
634 UDICount Count;
635 UDISizeT Size = 4;
636 UDICount CountDone;
637 UDIBool HostEndian = 0;
638 int i;
639
640 if (regno >= 0) {
d0b04c6a
SG
641 fetch_register(regno);
642 return;
9bddba9a 643 }
9bddba9a
SG
644
645/* Gr1/rsp */
d0b04c6a 646
9bddba9a
SG
647 From.Space = UDI29KGlobalRegs;
648 From.Offset = 1;
d0b04c6a 649 To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a 650 Count = 1;
d0b04c6a 651 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 652 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
653
654 register_valid[GR1_REGNUM] = 1;
9bddba9a
SG
655
656#if defined(GR64_REGNUM) /* Read gr64-127 */
d0b04c6a 657
9bddba9a 658/* Global Registers gr64-gr95 */
d0b04c6a 659
9bddba9a
SG
660 From.Space = UDI29KGlobalRegs;
661 From.Offset = 64;
d0b04c6a 662 To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a 663 Count = 32;
d0b04c6a 664 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 665 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
666
667 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
668 register_valid[i] = 1;
669
9bddba9a
SG
670#endif /* GR64_REGNUM */
671
672/* Global Registers gr96-gr127 */
d0b04c6a 673
9bddba9a 674 From.Space = UDI29KGlobalRegs;
d0b04c6a
SG
675 From.Offset = 96;
676 To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a 677 Count = 32;
d0b04c6a 678 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 679 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 680
d0b04c6a
SG
681 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
682 register_valid[i] = 1;
683
684/* Local Registers */
685
9bddba9a
SG
686 From.Space = UDI29KLocalRegs;
687 From.Offset = 0;
d0b04c6a 688 To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a 689 Count = 128;
d0b04c6a 690 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 691 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 692
d0b04c6a
SG
693 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
694 register_valid[i] = 1;
695
696/* Protected Special Registers */
697
9bddba9a
SG
698 From.Space = UDI29KSpecialRegs;
699 From.Offset = 0;
d0b04c6a 700 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a 701 Count = 15;
d0b04c6a 702 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 703 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
704
705 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
706 register_valid[i] = 1;
9bddba9a
SG
707
708 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
d0b04c6a
SG
709 fetch_register(NPC_REGNUM);
710 fetch_register(PC_REGNUM);
711 fetch_register(PC2_REGNUM);
9bddba9a 712
d0b04c6a
SG
713/* Unprotected Special Registers sr128-sr135 */
714
715 From.Space = UDI29KSpecialRegs;
9bddba9a 716 From.Offset = 128;
d0b04c6a
SG
717 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
718 Count = 135-128 + 1;
719 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 720 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
721
722 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
723 register_valid[i] = 1;
9bddba9a
SG
724 }
725
726 /* There doesn't seem to be any way to get these. */
727 {
728 int val = -1;
729 supply_register (FPE_REGNUM, (char *) &val);
d0b04c6a 730 supply_register (INTE_REGNUM, (char *) &val);
9bddba9a
SG
731 supply_register (FPS_REGNUM, (char *) &val);
732 supply_register (EXO_REGNUM, (char *) &val);
733 }
9bddba9a
SG
734}
735
736
737/********************************************************* UDI_STORE_REGISTERS
738** Store register regno into the target.
739 * If regno==-1 then store all the registers.
740 */
741
742static void
743udi_store_registers (regno)
744int regno;
745{
746 UDIUInt32 *From;
747 UDIResource To;
748 UDICount Count;
749 UDISizeT Size = 4;
750 UDICount CountDone;
751 UDIBool HostEndian = 0;
752
753 if (regno >= 0)
754 {
755 store_register(regno);
756 return;
757 }
758
9bddba9a 759/* Gr1/rsp */
d0b04c6a
SG
760
761 From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a
SG
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)
d0b04c6a 769
9bddba9a 770/* Global registers gr64-gr95 */
d0b04c6a
SG
771
772 From = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a
SG
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");
d0b04c6a 778
9bddba9a
SG
779#endif /* GR64_REGNUM */
780
781/* Global registers gr96-gr127 */
d0b04c6a
SG
782
783 From = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a
SG
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 */
d0b04c6a
SG
791
792 From = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a
SG
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 */
d0b04c6a
SG
801
802 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a
SG
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
d0b04c6a
SG
809/* PC0, PC1, PC2 possibly as shadow registers */
810
811 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(10)];
9bddba9a
SG
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 */
d0b04c6a
SG
822
823 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(13)];
9bddba9a
SG
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 */
d0b04c6a
SG
831
832 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
9bddba9a
SG
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 ();
9bddba9a
SG
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
849static void
850udi_prepare_to_store ()
851{
852 /* Do nothing, since we can store individual regs */
853}
854
855/********************************************************** TRANSLATE_ADDR */
856static CORE_ADDR
857translate_addr(addr)
858CORE_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. */
877static int
878udi_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 */
894static void
895udi_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 */
902static int
903udi_insert_breakpoint (addr, contents_cache)
904 CORE_ADDR addr;
905 char *contents_cache;
906{
54847287
SG
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");
9bddba9a 916
9bddba9a
SG
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
54847287
SG
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);
9bddba9a
SG
931}
932
933/**************************************************** UDI_REMOVE_BREAKPOINT */
934static int
935udi_remove_breakpoint (addr, contents_cache)
936 CORE_ADDR addr;
937 char *contents_cache;
938{
54847287
SG
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
9bddba9a
SG
949 bkpt_table[cnt].Type = 0;
950
54847287
SG
951 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
952 if (err == 0) return 0; /* Success */
9bddba9a 953
54847287
SG
954 error("UDIClearBreakpoint returned error code %d\n", err);
955}
9bddba9a
SG
956
957/***************************************************************** UDI_KILL */
958static void
959udi_kill(arg,from_tty)
960char *arg;
961int from_tty;
962{
963 char buf[4];
964
965 DENTER("udi_kill()");
966#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
967 /* We don't ever kill the kernel */
968 if (from_tty) {
d0b04c6a
SG
969 printf_filtered("Kernel not killed, but left in current state.\n");
970 printf_filtered("Use detach to leave kernel running.\n");
9bddba9a
SG
971 }
972#else
973 UDIStop();
d0b04c6a 974 inferior_pid = 0;
9bddba9a
SG
975 if (from_tty) {
976 printf("Target has been stopped.");
977 }
978 pop_target();
979#endif
980 DEXIT("udi_kill()");
981}
982
983
984
985/***************************************************************** UDI_LOAD */
986/*
987 * Load a program into the target.
988 */
989static void
990udi_load(arg_string,from_tty)
991char *arg_string;
992int from_tty;
993{
994#define MAX_TOKENS 25
995#define BUFFER_SIZE 256
996 int token_count;
997 char *token[MAX_TOKENS];
998 char cmd_line[BUFFER_SIZE];
999
1000 dont_repeat ();
1001
1002#if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
1003 printf("The kernel had better be loaded already! Loading not done.\n");
1004#else
1005 if (arg_string == 0)
1006 error ("The load command takes a file name");
1007 arg_string = tilde_expand (arg_string);
1008 sprintf(cmd_line,"y %s %s", prog_name, arg_string);
1009
1010 token_count = 0;
1011 token[0] = cmd_line;
1012
1013 if (cmd_line[0] != '\0')
1014 { token[token_count] = strtok(cmd_line, " \t,;\n\r");
1015
1016 if (token[token_count] != NULL)
1017 { do {
1018 token_count = token_count + 1;
1019 token[token_count] = strtok((char *) NULL, " \t,;\n\r");
1020 } while ((token[token_count] != NULL) &&
1021 (token_count < MAX_TOKENS));
1022 }
1023 else
1024 *token[0] = '\0';
1025 }
1026 make_cleanup (free, arg_string);
1027 QUIT;
1028 immediate_quit++;
1029 if(yank_cmd(token, token_count))
1030 error("Failure when tring to load program");
1031 immediate_quit--;
1032 symbol_file_add (arg_string, from_tty, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1033#endif
1034
1035}
1036
1037/*************************************************** UDI_WRITE_INFERIOR_MEMORY
1038** Copy LEN bytes of data from debugger memory at MYADDR
1039 to inferior's memory at MEMADDR. Returns number of bytes written. */
1040static int
1041udi_write_inferior_memory (memaddr, myaddr, len)
1042 CORE_ADDR memaddr;
1043 char *myaddr;
1044 int len;
1045{
1046 int nwritten = 0;
1047 UDIUInt32 *From;
1048 UDIResource To;
1049 UDICount Count;
1050 UDISizeT Size = 1;
1051 UDICount CountDone = 0;
1052 UDIBool HostEndian = 0;
1053
1054
1055 /* DENTER("udi_write_inferior_memory()"); */
1056 To.Space = udi_memory_space(memaddr);
1057 From = (UDIUInt32*)myaddr;
1058
1059 while (nwritten < len)
1060 { Count = len - nwritten;
1061 if (Count > MAXDATA) Count = MAXDATA;
1062 To.Offset = memaddr + nwritten;
1063 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1064 { error("UDIWrite() failed in udi_write_inferrior_memory");
1065 break;
1066 }
1067 else
1068 { nwritten += CountDone;
1069 From += CountDone;
1070 }
1071 }
1072 /* DEXIT("udi_write_inferior_memory()"); */
1073 return(nwritten);
1074}
1075
1076/**************************************************** UDI_READ_INFERIOR_MEMORY
1077** Read LEN bytes from inferior memory at MEMADDR. Put the result
1078 at debugger address MYADDR. Returns number of bytes read. */
1079static int
1080udi_read_inferior_memory(memaddr, myaddr, len)
1081 CORE_ADDR memaddr;
1082 char *myaddr;
1083 int len;
1084{
1085 int nread = 0;
1086 UDIResource From;
1087 UDIUInt32 *To;
1088 UDICount Count;
1089 UDISizeT Size = 1;
1090 UDICount CountDone = 0;
1091 UDIBool HostEndian = 0;
1092
1093
1094 /* DENTER("udi_read_inferior_memory()"); */
1095 From.Space = udi_memory_space(memaddr);
1096 To = (UDIUInt32*)myaddr;
1097
1098 while (nread < len)
1099 { Count = len - nread;
1100 if (Count > MAXDATA) Count = MAXDATA;
1101 From.Offset = memaddr + nread;
1102 if(UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1103 { error("UDIWrite() failed in udi_read_inferrior_memory");
1104 break;
1105 }
1106 else
1107 { nread += CountDone;
1108 To += CountDone;
1109 }
1110 }
1111 return(nread);
1112}
1113
1114/********************************************************************* WARNING
1115*/
1116udi_warning(num)
1117int num;
1118{
1119 error ("ERROR while loading program into remote TIP: $d\n", num);
1120}
1121
1122
1123/*****************************************************************************/
1124/* Fetch a single register indicatated by 'regno'.
1125 * Returns 0/-1 on success/failure.
1126 */
1127static int
1128fetch_register (regno)
1129 int regno;
1130{
1131 UDIResource From;
1132 UDIUInt32 To;
1133 UDICount Count = 1;
1134 UDISizeT Size = 4;
1135 UDICount CountDone;
1136 UDIBool HostEndian = 0;
1137 int result;
1138
9bddba9a 1139 if (regno == GR1_REGNUM)
d0b04c6a
SG
1140 {
1141 From.Space = UDI29KGlobalRegs;
1142 From.Offset = 1;
1143 }
9bddba9a 1144 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
d0b04c6a
SG
1145 {
1146 From.Space = UDI29KGlobalRegs;
1147 From.Offset = (regno - GR96_REGNUM) + 96;;
1148 }
1149
9bddba9a 1150#if defined(GR64_REGNUM)
d0b04c6a 1151
9bddba9a 1152 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
d0b04c6a
SG
1153 {
1154 From.Space = UDI29KGlobalRegs;
1155 From.Offset = (regno - GR64_REGNUM) + 64;
1156 }
1157
9bddba9a 1158#endif /* GR64_REGNUM */
d0b04c6a 1159
9bddba9a 1160 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
d0b04c6a
SG
1161 {
1162 From.Space = UDI29KLocalRegs;
1163 From.Offset = (regno - LR0_REGNUM);
1164 }
9bddba9a 1165 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
d0b04c6a
SG
1166 {
1167 int val = -1;
1168 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
1169 return 0; /* Pretend Success */
1170 }
9bddba9a 1171 else
d0b04c6a
SG
1172 {
1173 From.Space = UDI29KSpecialRegs;
1174 From.Offset = regnum_to_srnum(regno);
1175 }
1176
1177 if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
9bddba9a 1178 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a 1179
9bddba9a
SG
1180 supply_register(regno, (char *) &To);
1181 return result;
1182}
1183/*****************************************************************************/
1184/* Store a single register indicated by 'regno'.
1185 * Returns 0/-1 on success/failure.
1186 */
1187static int
1188store_register (regno)
1189 int regno;
1190{
1191 int result;
1192 UDIUInt32 From;
1193 UDIResource To;
1194 UDICount Count = 1;
1195 UDISizeT Size = 4;
1196 UDICount CountDone;
1197 UDIBool HostEndian = 0;
1198
1199 DENTER("store_register()");
1200 From = read_register (regno); /* get data value */
1201
1202 if (regno == GR1_REGNUM)
1203 { To.Space = UDI29KGlobalRegs;
1204 To.Offset = 1;
1205 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1206 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1207 * register cache. Do this *after* calling read_register, because we want
1208 * read_register to return the value that write_register has just stuffed
1209 * into the registers array, not the value of the register fetched from
1210 * the inferior.
1211 */
1212 registers_changed ();
1213 }
1214#if defined(GR64_REGNUM)
1215 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1216 { To.Space = UDI29KGlobalRegs;
1217 To.Offset = (regno - GR64_REGNUM) + 64;
1218 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1219 }
1220#endif /* GR64_REGNUM */
1221 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1222 { To.Space = UDI29KGlobalRegs;
1223 To.Offset = (regno - GR96_REGNUM) + 96;
1224 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1225 }
1226 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1227 { To.Space = UDI29KLocalRegs;
1228 To.Offset = (regno - LR0_REGNUM);
1229 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1230 }
1231 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1232 {
1233 return 0; /* Pretend Success */
1234 }
1235 else /* An unprotected or protected special register */
1236 { To.Space = UDI29KSpecialRegs;
1237 To.Offset = regnum_to_srnum(regno);
1238 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1239 }
1240
1241 DEXIT("store_register()");
1242 if(result)
1243 { result = -1;
1244 error("UDIWrite() failed in store_registers");
1245 }
1246 return result;
1247}
1248/********************************************************** REGNUM_TO_SRNUM */
1249/*
1250 * Convert a gdb special register number to a 29000 special register number.
1251 */
1252static int
1253regnum_to_srnum(regno)
1254int regno;
1255{
1256 switch(regno) {
1257 case VAB_REGNUM: return(0);
1258 case OPS_REGNUM: return(1);
1259 case CPS_REGNUM: return(2);
1260 case CFG_REGNUM: return(3);
1261 case CHA_REGNUM: return(4);
1262 case CHD_REGNUM: return(5);
1263 case CHC_REGNUM: return(6);
1264 case RBP_REGNUM: return(7);
1265 case TMC_REGNUM: return(8);
1266 case TMR_REGNUM: return(9);
1267 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1268 case PC_REGNUM: return(USE_SHADOW_PC ? (21) : (11));
1269 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1270 case MMU_REGNUM: return(13);
1271 case LRU_REGNUM: return(14);
1272 case IPC_REGNUM: return(128);
1273 case IPA_REGNUM: return(129);
1274 case IPB_REGNUM: return(130);
1275 case Q_REGNUM: return(131);
1276 case ALU_REGNUM: return(132);
1277 case BP_REGNUM: return(133);
1278 case FC_REGNUM: return(134);
1279 case CR_REGNUM: return(135);
1280 case FPE_REGNUM: return(160);
d0b04c6a 1281 case INTE_REGNUM: return(161);
9bddba9a
SG
1282 case FPS_REGNUM: return(162);
1283 case EXO_REGNUM:return(164);
1284 default:
1285 return(255); /* Failure ? */
1286 }
1287}
1288/****************************************************************************/
1289/*
1290 * Determine the Target memory space qualifier based on the addr.
1291 * FIXME: Can't distinguis I_ROM/D_ROM.
1292 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1293 */
1294static CPUSpace
1295udi_memory_space(addr)
1296CORE_ADDR *addr;
1297{
1298 UDIUInt32 tstart = IMemStart;
1299 UDIUInt32 tend = tstart + IMemSize;
1300 UDIUInt32 dstart = DMemStart;
1301 UDIUInt32 dend = tstart + DMemSize;
1302 UDIUInt32 rstart = RMemStart;
1303 UDIUInt32 rend = tstart + RMemSize;
1304
1305 if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) {
1306 return UDI29KIRAMSpace;
1307 } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) {
1308 return UDI29KDRAMSpace;
1309 } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1310 /* FIXME: how do we determine between D_ROM and I_ROM */
1311 return UDI29KIROMSpace;
1312 } else /* FIXME: what do me do now? */
1313 return UDI29KDRAMSpace; /* Hmmm! */
1314}
1315/*********************************************************************** STUBS
1316*/
1317
1318void convert16() {;}
1319void convert32() {;}
1320FILE* EchoFile = 0; /* used for debugging */
1321int QuietMode = 0; /* used for debugging */
1322
1323/****************************************************************************/
1324/*
1325 * Define the target subroutine names
1326 */
1327static struct target_ops udi_ops = {
1328 "udi", "Remote UDI connected TIP",
1329 "Remote debug an Am290*0 using socket connection to TIP process ",
1330 udi_open, udi_close,
1331 udi_attach, udi_detach, udi_resume, udi_wait,
1332 udi_fetch_registers, udi_store_registers,
1333 udi_prepare_to_store, 0, 0, /* conv_to, conv_from */
1334 udi_xfer_inferior_memory,
1335 udi_files_info,
1336 udi_insert_breakpoint, udi_remove_breakpoint, /* Breakpoints */
1337 0, 0, 0, 0, 0, /* Terminal handling */
1338 udi_kill, /* FIXME, kill */
1339 udi_load,
1340 0, /* lookup_symbol */
1341 udi_create_inferior, /* create_inferior */
1342 udi_mourn, /* mourn_inferior FIXME */
1343 process_stratum, 0, /* next */
1344 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1345 0, 0, /* Section pointers */
1346 OPS_MAGIC, /* Always the last thing */
1347};
1348
1349void _initialize_remote_udi()
1350{
1351 add_target (&udi_ops);
1352}
1353
1354#ifdef NO_HIF_SUPPORT
1355service_HIF(msg)
1356union msg_t *msg;
1357{
1358 return(0); /* Emulate a failure */
1359}
1360#endif