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