* Makefile.in: Remove dependancies for 29k-share/dfe/yank.o and
[deliverable/binutils-gdb.git] / gdb / remote-udi.c
CommitLineData
15ee4caa 1/* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
5140562f
JG
2 Copyright 1990, 1992 Free Software Foundation, Inc.
3 Written by Daniel Mann. Contributed by AMD.
9bddba9a
SG
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
5140562f
JG
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
9bddba9a
SG
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
5140562f
JG
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
9bddba9a 20
15ee4caa
JG
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.
5140562f
JG
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.
15ee4caa 36 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
5140562f
JG
37 MiniMON interface with UDI-p interface. */
38
9bddba9a
SG
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"
aa942355 50#include "29k-share/udi/udiproc.h"
aa1dea48 51#include "gdbcmd.h"
b6113cc4 52#include "bfd.h"
9bddba9a
SG
53
54/* access the register store directly, without going through
836e343b 55 the normal handler functions. This avoids an extra data copy. */
9bddba9a 56
aa1dea48 57static int kiodebug;
9bddba9a
SG
58extern int stop_soon_quietly; /* for wait_for_inferior */
59extern struct value *call_function_by_hand();
b6113cc4
SG
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));
9bddba9a
SG
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. */
9bddba9a 103
b6113cc4
SG
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 */
9bddba9a
SG
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;
54847287
SG
129#define BKPT_TABLE_SIZE 40
130static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
9bddba9a
SG
131extern char dfe_errmsg[]; /* error string */
132
9bddba9a
SG
133/* Called when SIGALRM signal sent due to alarm() timeout. */
134#ifndef HAVE_TERMIO
135
9bddba9a
SG
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
9bddba9a
SG
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
9bddba9a
SG
156/* This is called not only when we first attach, but also when the
157 user types "run" after having attached. */
b6113cc4 158
9bddba9a
SG
159static void
160udi_create_inferior (execfile, args, env)
161 char *execfile;
162 char *args;
163 char **env;
164{
b6113cc4 165 char *args1;
9bddba9a
SG
166
167 if (execfile)
b6113cc4
SG
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.");
9bddba9a 177
b6113cc4
SG
178 if (udi_session_id < 0)
179 {
180 printf("UDI connection not open yet.\n");
181 return;
182 }
9bddba9a 183
d0b04c6a
SG
184 inferior_pid = 40000;
185
b6113cc4
SG
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 */
9bddba9a 201
9bddba9a
SG
202 init_wait_for_inferior ();
203 clear_proceed_status ();
204 proceed(-1,-1,0);
9bddba9a 205}
b6113cc4 206
9bddba9a
SG
207static void
208udi_mourn()
209{
9bddba9a
SG
210 pop_target (); /* Pop back to no-child state */
211 generic_mourn_inferior ();
9bddba9a
SG
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.
b6113cc4 218 '<udi_udi_config_id>' for example.
9bddba9a
SG
219 */
220
d0b04c6a
SG
221/* XXX - need cleanups for udiconnect for various failures!!! */
222
9bddba9a
SG
223static char *udi_config_id;
224static void
225udi_open (name, from_tty)
226 char *name;
227 int from_tty;
228{
b6113cc4
SG
229 unsigned int prl;
230 char *p;
231 int cnt;
9bddba9a 232 UDIMemoryRange KnownMemory[10];
b6113cc4
SG
233 UDIUInt32 ChipVersions[10];
234 UDIInt NumberOfRanges = 10;
235 UDIInt NumberOfChips = 10;
236 UDIPId PId;
237 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
9bddba9a 238
d0b04c6a
SG
239 target_preopen(from_tty);
240
b6113cc4
SG
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");
9bddba9a 246
b6113cc4
SG
247 udi_config_id = strdup (strtok (name, " \t"));
248
249 if (UDIConnect (udi_config_id, &udi_session_id))
d0b04c6a 250 error("UDIConnect() failed: %s\n", dfe_errmsg);
9bddba9a 251
9bddba9a
SG
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)
d0b04c6a 259 error ("udi_open: siginterrupt() %s", safe_strerror(errno));
9bddba9a
SG
260#endif
261
262 /* Set up read timeout timer. */
263 if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
d0b04c6a 264 error ("udi_open: signal() %s", safe_strerror(errno));
9bddba9a
SG
265#endif
266
267#if defined (LOG_FILE)
268 log_file = fopen (LOG_FILE, "w");
269 if (log_file == NULL)
d0b04c6a 270 error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno));
9bddba9a
SG
271#endif
272 /*
273 ** Initialize target configuration structure (global)
274 */
b6113cc4
SG
275 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
276 ChipVersions, &NumberOfChips))
9bddba9a 277 error ("UDIGetTargetConfig() failed");
b6113cc4
SG
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)
9bddba9a 283 {
b6113cc4
SG
284 default:
285 fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
286 break;
9bddba9a 287 case UDI29KCP_S:
b6113cc4 288 break;
9bddba9a 289 case UDI29KIROMSpace:
b6113cc4
SG
290 RMemStart = KnownMemory[cnt].Offset;
291 RMemSize = KnownMemory[cnt].Size;
292 break;
9bddba9a 293 case UDI29KIRAMSpace:
b6113cc4
SG
294 IMemStart = KnownMemory[cnt].Offset;
295 IMemSize = KnownMemory[cnt].Size;
296 break;
9bddba9a 297 case UDI29KDRAMSpace:
b6113cc4
SG
298 DMemStart = KnownMemory[cnt].Offset;
299 DMemSize = KnownMemory[cnt].Size;
300 break;
9bddba9a 301 }
b6113cc4 302 }
9bddba9a
SG
303
304 /* Determine the processor revision level */
b6113cc4 305 prl = (unsigned int)read_register (CFG_REGNUM) >> 24;
9bddba9a 306 if ((prl&0xe0) == 0)
b6113cc4
SG
307 {
308 fprintf_filtered (stderr,
309 "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
9bddba9a 310 processor_type = TYPE_A29000;
b6113cc4
SG
311 }
312 else if ((prl&0xe0) == 0x40) /* 29030 = 0x4* */
313 {
314 fprintf_filtered (stderr,
315 "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
9bddba9a 316 processor_type = TYPE_A29030;
b6113cc4
SG
317 }
318 else if ((prl&0xe0) == 0x20) /* 29050 = 0x2* */
319 {
320 fprintf_filtered (stderr,
321 "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
9bddba9a 322 processor_type = TYPE_A29050;
b6113cc4
SG
323 }
324 else
325 {
9bddba9a 326 processor_type = TYPE_UNKNOWN;
b6113cc4
SG
327 fprintf_filtered (stderr,"WARNING: processor type unknown.\n");
328 }
329 if (UDICreateProcess (&PId))
9bddba9a
SG
330 fprintf(stderr, "UDICreateProcess() failed\n");
331
332 /* Print out some stuff, letting the user now what's going on */
b6113cc4
SG
333 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
334 &TIPIPCId, sbuf))
9bddba9a 335 error ("UDICapabilities() failed");
b6113cc4
SG
336 if (from_tty)
337 {
338 printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
9bddba9a 339 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
b6113cc4
SG
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 }
9bddba9a
SG
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{
9bddba9a 356 if (udi_session_id < 0)
b6113cc4 357 return;
9bddba9a
SG
358
359 /* We should never get here if there isn't something valid in
b6113cc4 360 udi_session_id. */
9bddba9a 361
b6113cc4 362 if (UDIDisconnect (udi_session_id, UDITerminateSession))
9bddba9a
SG
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;
d0b04c6a 367 inferior_pid = 0;
9bddba9a
SG
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
d0b04c6a 376 printf_filtered (" Ending remote debugging\n");
9bddba9a
SG
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;
9bddba9a
SG
394
395 if (udi_session_id < 0)
f7fe7196 396 error ("UDI connection not opened yet, use the 'target udi' command.\n");
9bddba9a
SG
397
398 if (from_tty)
399 printf ("Attaching to remote program %s...\n", prog_name);
400
9bddba9a
SG
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);
9bddba9a
SG
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{
b6113cc4 417
9bddba9a 418 remove_breakpoints(); /* Just in case there were any left in */
b6113cc4
SG
419
420 if (UDIDisconnect (udi_session_id, UDIContinueSession))
9bddba9a 421 error ("UDIDisconnect() failed in udi_detach");
b6113cc4 422
9bddba9a 423 pop_target(); /* calls udi_close to do the real work */
b6113cc4 424
9bddba9a
SG
425 if (from_tty)
426 printf ("Ending remote debugging\n");
9bddba9a
SG
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{
aa1dea48
SG
437 UDIError tip_error;
438 UDIUInt32 Steps = 1;
439 UDIStepType StepType = UDIStepNatural;
440 UDIRange Range;
836e343b 441
9bddba9a 442 if (step) /* step 1 instruction */
aa1dea48
SG
443 {
444 tip_error = UDIStep (Steps, StepType, Range);
445 if (!tip_error)
446 return;
9bddba9a 447
aa1dea48
SG
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");
9bddba9a
SG
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
9bddba9a
SG
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 */
aa1dea48 479
9bddba9a 480 while(1)
9bddba9a 481 {
aa1dea48
SG
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;
9bddba9a 510 }
aa1dea48
SG
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:
9bddba9a 570 WSETSTOP ((*status), SIGTERM);
aa1dea48
SG
571 break;
572 case UDIRunning:
9bddba9a 573 WSETSTOP ((*status), SIGILL);
aa1dea48
SG
574 break;
575 case UDIStopped:
9bddba9a 576 WSETSTOP ((*status), SIGTSTP);
aa1dea48
SG
577 break;
578 case UDIWarned:
9bddba9a 579 WSETSTOP ((*status), SIGLOST);
aa1dea48
SG
580 break;
581 case UDIStepped:
582 case UDIBreak:
9bddba9a 583 WSETSTOP ((*status), SIGTRAP);
aa1dea48
SG
584 break;
585 case UDIWaiting:
9bddba9a 586 WSETSTOP ((*status), SIGSTOP);
aa1dea48
SG
587 break;
588 case UDIHalted:
9bddba9a 589 WSETSTOP ((*status), SIGKILL);
aa1dea48
SG
590 break;
591 case UDIExited:
592 default:
593 WSETEXIT ((*status), 0);
594 }
9bddba9a
SG
595
596 timeout = old_timeout; /* Restore original timeout value */
597 immediate_quit = old_immediate_quit;
9bddba9a
SG
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) {
d0b04c6a
SG
618 fetch_register(regno);
619 return;
9bddba9a 620 }
9bddba9a
SG
621
622/* Gr1/rsp */
d0b04c6a 623
9bddba9a
SG
624 From.Space = UDI29KGlobalRegs;
625 From.Offset = 1;
d0b04c6a 626 To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a 627 Count = 1;
d0b04c6a 628 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 629 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
630
631 register_valid[GR1_REGNUM] = 1;
9bddba9a
SG
632
633#if defined(GR64_REGNUM) /* Read gr64-127 */
d0b04c6a 634
9bddba9a 635/* Global Registers gr64-gr95 */
d0b04c6a 636
9bddba9a
SG
637 From.Space = UDI29KGlobalRegs;
638 From.Offset = 64;
d0b04c6a 639 To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a 640 Count = 32;
d0b04c6a 641 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 642 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
643
644 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
645 register_valid[i] = 1;
646
9bddba9a
SG
647#endif /* GR64_REGNUM */
648
649/* Global Registers gr96-gr127 */
d0b04c6a 650
9bddba9a 651 From.Space = UDI29KGlobalRegs;
d0b04c6a
SG
652 From.Offset = 96;
653 To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a 654 Count = 32;
d0b04c6a 655 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 656 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 657
d0b04c6a
SG
658 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
659 register_valid[i] = 1;
660
661/* Local Registers */
662
9bddba9a
SG
663 From.Space = UDI29KLocalRegs;
664 From.Offset = 0;
d0b04c6a 665 To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a 666 Count = 128;
d0b04c6a 667 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 668 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 669
d0b04c6a
SG
670 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
671 register_valid[i] = 1;
672
673/* Protected Special Registers */
674
9bddba9a
SG
675 From.Space = UDI29KSpecialRegs;
676 From.Offset = 0;
d0b04c6a 677 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a 678 Count = 15;
d0b04c6a 679 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 680 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
681
682 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
683 register_valid[i] = 1;
9bddba9a
SG
684
685 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
d0b04c6a
SG
686 fetch_register(NPC_REGNUM);
687 fetch_register(PC_REGNUM);
688 fetch_register(PC2_REGNUM);
9bddba9a 689
d0b04c6a
SG
690/* Unprotected Special Registers sr128-sr135 */
691
692 From.Space = UDI29KSpecialRegs;
9bddba9a 693 From.Offset = 128;
d0b04c6a
SG
694 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
695 Count = 135-128 + 1;
696 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 697 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
698
699 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
700 register_valid[i] = 1;
9bddba9a
SG
701 }
702
aa1dea48
SG
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
9bddba9a
SG
711 /* There doesn't seem to be any way to get these. */
712 {
713 int val = -1;
714 supply_register (FPE_REGNUM, (char *) &val);
d0b04c6a 715 supply_register (INTE_REGNUM, (char *) &val);
9bddba9a
SG
716 supply_register (FPS_REGNUM, (char *) &val);
717 supply_register (EXO_REGNUM, (char *) &val);
718 }
9bddba9a
SG
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
aa1dea48
SG
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
9bddba9a 751/* Gr1/rsp */
d0b04c6a
SG
752
753 From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a
SG
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)
d0b04c6a 761
9bddba9a 762/* Global registers gr64-gr95 */
d0b04c6a
SG
763
764 From = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a
SG
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");
d0b04c6a 770
9bddba9a
SG
771#endif /* GR64_REGNUM */
772
773/* Global registers gr96-gr127 */
d0b04c6a
SG
774
775 From = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a
SG
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 */
d0b04c6a
SG
783
784 From = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a
SG
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 */
d0b04c6a
SG
793
794 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a
SG
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
d0b04c6a
SG
801/* PC0, PC1, PC2 possibly as shadow registers */
802
803 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(10)];
9bddba9a
SG
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 */
d0b04c6a
SG
814
815 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(13)];
9bddba9a
SG
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 */
d0b04c6a
SG
823
824 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
9bddba9a
SG
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 ();
9bddba9a
SG
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{
54847287
SG
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");
9bddba9a 908
9bddba9a
SG
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
54847287
SG
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);
9bddba9a
SG
923}
924
925/**************************************************** UDI_REMOVE_BREAKPOINT */
926static int
927udi_remove_breakpoint (addr, contents_cache)
928 CORE_ADDR addr;
929 char *contents_cache;
930{
54847287
SG
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
9bddba9a
SG
941 bkpt_table[cnt].Type = 0;
942
54847287
SG
943 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
944 if (err == 0) return 0; /* Success */
9bddba9a 945
54847287
SG
946 error("UDIClearBreakpoint returned error code %d\n", err);
947}
9bddba9a 948
9bddba9a
SG
949static void
950udi_kill(arg,from_tty)
b6113cc4
SG
951 char *arg;
952 int from_tty;
9bddba9a 953{
9bddba9a 954
b6113cc4
SG
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();
9bddba9a 962
b6113cc4
SG
963 udi_session_id = -1;
964 inferior_pid = 0;
9bddba9a 965
b6113cc4
SG
966 if (from_tty)
967 printf("Target has been stopped.");
968#else
969 udi_close(0);
970#endif
971 pop_target();
972}
9bddba9a 973
9bddba9a 974/*
b6113cc4
SG
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
9bddba9a 990static void
b6113cc4
SG
991download(load_arg_string, from_tty)
992 char *load_arg_string;
993 int from_tty;
9bddba9a 994{
b6113cc4
SG
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;
9bddba9a
SG
1015
1016 dont_repeat ();
1017
b6113cc4
SG
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 }
9bddba9a 1065 }
b6113cc4
SG
1066
1067 pbfd = bfd_openr (filename, 0);
1068
1069 if (!pbfd)
1070 perror_with_name (filename);
1071
1072 make_cleanup (bfd_close, pbfd);
1073
9bddba9a
SG
1074 QUIT;
1075 immediate_quit++;
b6113cc4
SG
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
9bddba9a 1193 immediate_quit--;
b6113cc4
SG
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);
9bddba9a 1206
b6113cc4 1207 symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
9bddba9a
SG
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
b6113cc4 1227 To.Space = udi_memory_space(memaddr);
9bddba9a
SG
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 }
9bddba9a
SG
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
9bddba9a
SG
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 */
aa1dea48 1295static void
9bddba9a
SG
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
9bddba9a 1307 if (regno == GR1_REGNUM)
d0b04c6a
SG
1308 {
1309 From.Space = UDI29KGlobalRegs;
1310 From.Offset = 1;
1311 }
9bddba9a 1312 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
d0b04c6a
SG
1313 {
1314 From.Space = UDI29KGlobalRegs;
1315 From.Offset = (regno - GR96_REGNUM) + 96;;
1316 }
1317
9bddba9a 1318#if defined(GR64_REGNUM)
d0b04c6a 1319
9bddba9a 1320 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
d0b04c6a
SG
1321 {
1322 From.Space = UDI29KGlobalRegs;
1323 From.Offset = (regno - GR64_REGNUM) + 64;
1324 }
1325
9bddba9a 1326#endif /* GR64_REGNUM */
d0b04c6a 1327
9bddba9a 1328 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
d0b04c6a
SG
1329 {
1330 From.Space = UDI29KLocalRegs;
1331 From.Offset = (regno - LR0_REGNUM);
1332 }
9bddba9a 1333 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
d0b04c6a
SG
1334 {
1335 int val = -1;
1336 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
aa1dea48 1337 return; /* Pretend Success */
d0b04c6a 1338 }
9bddba9a 1339 else
d0b04c6a
SG
1340 {
1341 From.Space = UDI29KSpecialRegs;
1342 From.Offset = regnum_to_srnum(regno);
1343 }
1344
1345 if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
9bddba9a 1346 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a 1347
9bddba9a 1348 supply_register(regno, (char *) &To);
aa1dea48
SG
1349
1350 if (kiodebug)
1351 printf("Fetching register %s = 0x%x\n", reg_names[regno], To);
9bddba9a
SG
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
9bddba9a
SG
1369 From = read_register (regno); /* get data value */
1370
aa1dea48
SG
1371 if (kiodebug)
1372 printf("Storing register %s = 0x%x\n", reg_names[regno], From);
1373
9bddba9a
SG
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
9bddba9a
SG
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);
d0b04c6a 1452 case INTE_REGNUM: return(161);
9bddba9a
SG
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)
b6113cc4 1467CORE_ADDR addr;
9bddba9a
SG
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 = {
aa1dea48
SG
1499 "udi",
1500 "Remote UDI connected TIP",
15ee4caa 1501 "Remote debug an AMD 29k using UDI socket connection to TIP process",
aa1dea48
SG
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,
a03d4f8e 1510 udi_prepare_to_store,
9bddba9a
SG
1511 udi_xfer_inferior_memory,
1512 udi_files_info,
aa1dea48
SG
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 */
9bddba9a
SG
1520 udi_kill, /* FIXME, kill */
1521 udi_load,
1522 0, /* lookup_symbol */
aa1dea48
SG
1523 udi_create_inferior,
1524 udi_mourn, /* mourn_inferior FIXME */
5ee4e16c 1525 0, /* can_run */
3950a34e 1526 0, /* notice_signals */
aa1dea48
SG
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 */
9bddba9a
SG
1536 OPS_MAGIC, /* Always the last thing */
1537};
1538
1539void _initialize_remote_udi()
1540{
1541 add_target (&udi_ops);
aa1dea48
SG
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);
9bddba9a
SG
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.112965 seconds and 4 git commands to generate.