* gdb.texinfo (Break Commands): Remove stuff about flushing terminal
[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;
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 WSETSTOP ((*status), SIGURG);
aa1dea48
SG
587 break;
588 case UDIStepped:
589 case UDIBreak:
9bddba9a 590 WSETSTOP ((*status), SIGTRAP);
aa1dea48
SG
591 break;
592 case UDIWaiting:
9bddba9a 593 WSETSTOP ((*status), SIGSTOP);
aa1dea48
SG
594 break;
595 case UDIHalted:
9bddba9a 596 WSETSTOP ((*status), SIGKILL);
aa1dea48
SG
597 break;
598 case UDIExited:
599 default:
600 WSETEXIT ((*status), 0);
601 }
9bddba9a
SG
602
603 timeout = old_timeout; /* Restore original timeout value */
604 immediate_quit = old_immediate_quit;
9bddba9a
SG
605 return 0;
606}
607
608/********************************************************** UDI_FETCH_REGISTERS
609 * Read a remote register 'regno'.
610 * If regno==-1 then read all the registers.
611 */
612static void
613udi_fetch_registers (regno)
614int regno;
615{
616 UDIResource From;
617 UDIUInt32 *To;
618 UDICount Count;
619 UDISizeT Size = 4;
620 UDICount CountDone;
621 UDIBool HostEndian = 0;
b5a3d2aa 622 UDIError err;
9bddba9a
SG
623 int i;
624
625 if (regno >= 0) {
d0b04c6a
SG
626 fetch_register(regno);
627 return;
9bddba9a 628 }
9bddba9a
SG
629
630/* Gr1/rsp */
d0b04c6a 631
9bddba9a
SG
632 From.Space = UDI29KGlobalRegs;
633 From.Offset = 1;
d0b04c6a 634 To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a 635 Count = 1;
b5a3d2aa 636 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 637 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
638
639 register_valid[GR1_REGNUM] = 1;
9bddba9a
SG
640
641#if defined(GR64_REGNUM) /* Read gr64-127 */
d0b04c6a 642
9bddba9a 643/* Global Registers gr64-gr95 */
d0b04c6a 644
9bddba9a
SG
645 From.Space = UDI29KGlobalRegs;
646 From.Offset = 64;
d0b04c6a 647 To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a 648 Count = 32;
b5a3d2aa 649 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 650 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
651
652 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
653 register_valid[i] = 1;
654
9bddba9a
SG
655#endif /* GR64_REGNUM */
656
657/* Global Registers gr96-gr127 */
d0b04c6a 658
9bddba9a 659 From.Space = UDI29KGlobalRegs;
d0b04c6a
SG
660 From.Offset = 96;
661 To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a 662 Count = 32;
b5a3d2aa 663 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 664 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 665
d0b04c6a
SG
666 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
667 register_valid[i] = 1;
668
669/* Local Registers */
670
9bddba9a
SG
671 From.Space = UDI29KLocalRegs;
672 From.Offset = 0;
d0b04c6a 673 To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a 674 Count = 128;
b5a3d2aa 675 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 676 error("UDIRead() failed in udi_fetch_registers");
9bddba9a 677
d0b04c6a
SG
678 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
679 register_valid[i] = 1;
680
681/* Protected Special Registers */
682
9bddba9a
SG
683 From.Space = UDI29KSpecialRegs;
684 From.Offset = 0;
d0b04c6a 685 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a 686 Count = 15;
b5a3d2aa 687 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 688 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
689
690 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
691 register_valid[i] = 1;
9bddba9a
SG
692
693 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
d0b04c6a
SG
694 fetch_register(NPC_REGNUM);
695 fetch_register(PC_REGNUM);
696 fetch_register(PC2_REGNUM);
9bddba9a 697
d0b04c6a
SG
698/* Unprotected Special Registers sr128-sr135 */
699
700 From.Space = UDI29KSpecialRegs;
9bddba9a 701 From.Offset = 128;
d0b04c6a
SG
702 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
703 Count = 135-128 + 1;
b5a3d2aa 704 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
9bddba9a 705 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a
SG
706
707 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
708 register_valid[i] = 1;
9bddba9a
SG
709 }
710
aa1dea48
SG
711 if (kiodebug)
712 {
713 printf("Fetching all registers\n");
714 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
715 read_register(NPC_REGNUM), read_register(PC_REGNUM),
716 read_register(PC2_REGNUM));
717 }
718
9bddba9a
SG
719 /* There doesn't seem to be any way to get these. */
720 {
721 int val = -1;
722 supply_register (FPE_REGNUM, (char *) &val);
d0b04c6a 723 supply_register (INTE_REGNUM, (char *) &val);
9bddba9a
SG
724 supply_register (FPS_REGNUM, (char *) &val);
725 supply_register (EXO_REGNUM, (char *) &val);
726 }
9bddba9a
SG
727}
728
729
730/********************************************************* UDI_STORE_REGISTERS
731** Store register regno into the target.
732 * If regno==-1 then store all the registers.
733 */
734
735static void
736udi_store_registers (regno)
737int regno;
738{
739 UDIUInt32 *From;
740 UDIResource To;
741 UDICount Count;
742 UDISizeT Size = 4;
743 UDICount CountDone;
744 UDIBool HostEndian = 0;
745
746 if (regno >= 0)
747 {
748 store_register(regno);
749 return;
750 }
751
aa1dea48
SG
752 if (kiodebug)
753 {
754 printf("Storing all registers\n");
755 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM),
756 read_register(PC_REGNUM), read_register(PC2_REGNUM));
757 }
758
9bddba9a 759/* Gr1/rsp */
d0b04c6a
SG
760
761 From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
9bddba9a
SG
762 To.Space = UDI29KGlobalRegs;
763 To.Offset = 1;
764 Count = 1;
765 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
766 error("UDIWrite() failed in udi_store_regisetrs");
767
768#if defined(GR64_REGNUM)
d0b04c6a 769
9bddba9a 770/* Global registers gr64-gr95 */
d0b04c6a
SG
771
772 From = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
9bddba9a
SG
773 To.Space = UDI29KGlobalRegs;
774 To.Offset = 64;
775 Count = 32;
776 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
777 error("UDIWrite() failed in udi_store_regisetrs");
d0b04c6a 778
9bddba9a
SG
779#endif /* GR64_REGNUM */
780
781/* Global registers gr96-gr127 */
d0b04c6a
SG
782
783 From = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
9bddba9a
SG
784 To.Space = UDI29KGlobalRegs;
785 To.Offset = 96;
786 Count = 32;
787 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
788 error("UDIWrite() failed in udi_store_regisetrs");
789
790/* Local Registers */
d0b04c6a
SG
791
792 From = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
9bddba9a
SG
793 To.Space = UDI29KLocalRegs;
794 To.Offset = 0;
795 Count = 128;
796 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
797 error("UDIWrite() failed in udi_store_regisetrs");
798
799
800/* Protected Special Registers */ /* VAB through TMR */
d0b04c6a
SG
801
802 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
9bddba9a
SG
803 To.Space = UDI29KSpecialRegs;
804 To.Offset = 0;
805 Count = 10;
806 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
807 error("UDIWrite() failed in udi_store_regisetrs");
808
d0b04c6a
SG
809/* PC0, PC1, PC2 possibly as shadow registers */
810
811 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(10)];
9bddba9a
SG
812 To.Space = UDI29KSpecialRegs;
813 Count = 3;
814 if (USE_SHADOW_PC)
815 To.Offset = 20; /* SPC0 */
816 else
817 To.Offset = 10; /* PC0 */
818 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
819 error("UDIWrite() failed in udi_store_regisetrs");
820
821 /* LRU and MMU */
d0b04c6a
SG
822
823 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(13)];
9bddba9a
SG
824 To.Space = UDI29KSpecialRegs;
825 To.Offset = 13;
826 Count = 2;
827 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
828 error("UDIWrite() failed in udi_store_regisetrs");
829
830/* Unprotected Special Registers */
d0b04c6a
SG
831
832 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
9bddba9a
SG
833 To.Space = UDI29KSpecialRegs;
834 To.Offset = 128;
835 Count = 135-128 +1;
836 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
837 error("UDIWrite() failed in udi_store_regisetrs");
838
839 registers_changed ();
9bddba9a
SG
840}
841
842/****************************************************** UDI_PREPARE_TO_STORE */
843/* Get ready to modify the registers array. On machines which store
844 individual registers, this doesn't need to do anything. On machines
845 which store all the registers in one fell swoop, this makes sure
846 that registers contains all the registers from the program being
847 debugged. */
848
849static void
850udi_prepare_to_store ()
851{
852 /* Do nothing, since we can store individual regs */
853}
854
855/********************************************************** TRANSLATE_ADDR */
856static CORE_ADDR
857translate_addr(addr)
858CORE_ADDR addr;
859{
860#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
861 /* Check for a virtual address in the kernel */
862 /* Assume physical address of ublock is in paddr_u register */
863 /* FIXME: doesn't work for user virtual addresses */
864 if (addr >= UVADDR) {
865 /* PADDR_U register holds the physical address of the ublock */
866 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
867 return(i + addr - (CORE_ADDR)UVADDR);
868 } else {
869 return(addr);
870 }
871#else
872 return(addr);
873#endif
874}
875/************************************************* UDI_XFER_INFERIOR_MEMORY */
876/* FIXME! Merge these two. */
877static int
878udi_xfer_inferior_memory (memaddr, myaddr, len, write)
879 CORE_ADDR memaddr;
880 char *myaddr;
881 int len;
882 int write;
883{
884
885 memaddr = translate_addr(memaddr);
886
887 if (write)
888 return udi_write_inferior_memory (memaddr, myaddr, len);
889 else
890 return udi_read_inferior_memory (memaddr, myaddr, len);
891}
892
893/********************************************************** UDI_FILES_INFO */
894static void
895udi_files_info ()
896{
897 printf ("\tAttached to UDI socket to %s and running program %s.\n",
898 udi_config_id, prog_name);
899}
900
901/**************************************************** UDI_INSERT_BREAKPOINT */
902static int
903udi_insert_breakpoint (addr, contents_cache)
904 CORE_ADDR addr;
905 char *contents_cache;
906{
54847287
SG
907 int cnt;
908 UDIError err;
909
910 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
911 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
912 break;
913
914 if(cnt >= BKPT_TABLE_SIZE)
915 error("Too many breakpoints set");
9bddba9a 916
9bddba9a
SG
917 bkpt_table[cnt].Addr.Offset = addr;
918 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
919 bkpt_table[cnt].PassCount = 1;
920 bkpt_table[cnt].Type = UDIBreakFlagExecute;
921
54847287
SG
922 err = UDISetBreakpoint(bkpt_table[cnt].Addr,
923 bkpt_table[cnt].PassCount,
924 bkpt_table[cnt].Type,
925 &bkpt_table[cnt].BreakId);
926
927 if (err == 0) return 0; /* Success */
928
929 bkpt_table[cnt].Type = 0;
930 error("UDISetBreakpoint returned error code %d\n", err);
9bddba9a
SG
931}
932
933/**************************************************** UDI_REMOVE_BREAKPOINT */
934static int
935udi_remove_breakpoint (addr, contents_cache)
936 CORE_ADDR addr;
937 char *contents_cache;
938{
54847287
SG
939 int cnt;
940 UDIError err;
941
942 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
943 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
944 break;
945
946 if(cnt >= BKPT_TABLE_SIZE)
947 error("Can't find breakpoint in table");
948
9bddba9a
SG
949 bkpt_table[cnt].Type = 0;
950
54847287
SG
951 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
952 if (err == 0) return 0; /* Success */
9bddba9a 953
54847287
SG
954 error("UDIClearBreakpoint returned error code %d\n", err);
955}
9bddba9a 956
9bddba9a
SG
957static void
958udi_kill(arg,from_tty)
b6113cc4
SG
959 char *arg;
960 int from_tty;
9bddba9a 961{
9bddba9a 962
b6113cc4
SG
963#if 0
964/*
965UDIStop does not really work as advertised. It causes the TIP to close it's
966connection, which usually results in GDB dying with a SIGPIPE. For now, we
967just invoke udi_close, which seems to get things right.
968*/
969 UDIStop();
9bddba9a 970
b6113cc4
SG
971 udi_session_id = -1;
972 inferior_pid = 0;
9bddba9a 973
b6113cc4
SG
974 if (from_tty)
975 printf("Target has been stopped.");
976#else
977 udi_close(0);
978#endif
979 pop_target();
980}
9bddba9a 981
9bddba9a 982/*
b6113cc4
SG
983 Load a program into the target. Args are: `program {options}'. The options
984 are used to control loading of the program, and are NOT passed onto the
985 loaded code as arguments. (You need to use the `run' command to do that.)
986
987 The options are:
988 -ms %d Set mem stack size to %d
989 -rs %d Set regular stack size to %d
990 -i send init info (default)
991 -noi don't send init info
992 -[tT] Load Text section
993 -[dD] Load Data section
994 -[bB] Load BSS section
995 -[lL] Load Lit section
996 */
997
9bddba9a 998static void
b6113cc4
SG
999download(load_arg_string, from_tty)
1000 char *load_arg_string;
1001 int from_tty;
9bddba9a 1002{
b6113cc4
SG
1003#define DEFAULT_MEM_STACK_SIZE 0x6000
1004#define DEFAULT_REG_STACK_SIZE 0x2000
1005
1006 char *token;
1007 char *filename;
1008 asection *section;
1009 bfd *pbfd;
1010 UDIError err;
1011 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1012
1013 address_ranges[0].Space = UDI29KIRAMSpace;
1014 address_ranges[0].Offset = 0xffffffff;
1015 address_ranges[0].Size = 0;
1016
1017 address_ranges[1].Space = UDI29KDRAMSpace;
1018 address_ranges[1].Offset = 0xffffffff;
1019 address_ranges[1].Size = 0;
1020
1021 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1022 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
9bddba9a
SG
1023
1024 dont_repeat ();
1025
b6113cc4
SG
1026 filename = strtok(load_arg_string, " \t");
1027 if (!filename)
1028 error ("Must specify at least a file name with the load command");
1029
1030 filename = tilde_expand (filename);
1031 make_cleanup (free, filename);
1032
1033 while (token = strtok (NULL, " \t"))
1034 {
1035 if (token[0] == '-')
1036 {
1037 token++;
1038
2e4964ad 1039 if (STREQ (token, "ms"))
b6113cc4 1040 stack_sizes[1] = atol (strtok (NULL, " \t"));
2e4964ad 1041 else if (STREQ (token, "rs"))
b6113cc4
SG
1042 stack_sizes[0] = atol (strtok (NULL, " \t"));
1043 else
1044 {
1045 load_text = load_data = load_bss = load_lit = 0;
1046
1047 while (*token)
1048 {
1049 switch (*token++)
1050 {
1051 case 't':
1052 case 'T':
1053 load_text = 1;
1054 break;
1055 case 'd':
1056 case 'D':
1057 load_data = 1;
1058 break;
1059 case 'b':
1060 case 'B':
1061 load_bss = 1;
1062 break;
1063 case 'l':
1064 case 'L':
1065 load_lit = 1;
1066 break;
1067 default:
1068 error ("Unknown UDI load option -%s", token-1);
1069 }
1070 }
1071 }
1072 }
9bddba9a 1073 }
b6113cc4
SG
1074
1075 pbfd = bfd_openr (filename, 0);
1076
1077 if (!pbfd)
1078 perror_with_name (filename);
1079
1080 make_cleanup (bfd_close, pbfd);
1081
9bddba9a
SG
1082 QUIT;
1083 immediate_quit++;
b6113cc4
SG
1084
1085 if (!bfd_check_format (pbfd, bfd_object))
1086 error ("It doesn't seem to be an object file");
1087
1088 for (section = pbfd->sections; section; section = section->next)
1089 {
1090 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1091 {
1092 UDIResource To;
1093 UDICount Count;
1094 unsigned long section_size, section_end;
1095 const char *section_name;
1096
1097 section_name = bfd_get_section_name (pbfd, section);
2e4964ad 1098 if (STREQ (section_name, ".text") && !load_text)
b6113cc4 1099 continue;
2e4964ad 1100 else if (STREQ (section_name, ".data") && !load_data)
b6113cc4 1101 continue;
2e4964ad 1102 else if (STREQ (section_name, ".bss") && !load_bss)
b6113cc4 1103 continue;
2e4964ad 1104 else if (STREQ (section_name, ".lit") && !load_lit)
b6113cc4
SG
1105 continue;
1106
1107 To.Offset = bfd_get_section_vma (pbfd, section);
1108 section_size = bfd_section_size (pbfd, section);
1109 section_end = To.Offset + section_size;
1110
1111 printf("[Loading section %s at %x (%d bytes)]\n",
1112 section_name,
1113 To.Offset,
1114 section_size);
1115
1116 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1117 {
1118 To.Space = UDI29KIRAMSpace;
1119
1120 address_ranges[0].Offset = min (address_ranges[0].Offset,
1121 To.Offset);
1122 address_ranges[0].Size = max (address_ranges[0].Size,
1123 section_end
1124 - address_ranges[0].Offset);
1125 }
1126 else
1127 {
1128 To.Space = UDI29KDRAMSpace;
1129
1130 address_ranges[1].Offset = min (address_ranges[1].Offset,
1131 To.Offset);
1132 address_ranges[1].Size = max (address_ranges[1].Size,
1133 section_end
1134 - address_ranges[1].Offset);
1135 }
1136
1137 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1138 {
1139 file_ptr fptr;
1140
1141 fptr = 0;
1142
1143 while (section_size > 0)
1144 {
1145 char buffer[1024];
1146
1147 Count = min (section_size, 1024);
1148
1149 bfd_get_section_contents (pbfd, section, buffer, fptr,
1150 Count);
1151
1152 err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
1153 To, /* To */
1154 Count, /* Count */
1155 (UDISizeT)1, /* Size */
1156 &Count, /* CountDone */
1157 (UDIBool)0); /* HostEndian */
1158 if (err)
1159 error ("UDIWrite failed, error = %d", err);
1160
1161 To.Offset += Count;
1162 fptr += Count;
1163 section_size -= Count;
1164 }
1165 }
1166 else /* BSS */
1167 {
1168 UDIResource From;
b5a3d2aa 1169 unsigned long zero = 0;
b6113cc4
SG
1170
1171 /* Write a zero byte at the vma */
1172 err = UDIWrite ((UDIHostMemPtr)&zero, /* From */
1173 To, /* To */
1174 (UDICount)1, /* Count */
b5a3d2aa 1175 (UDISizeT)4, /* Size */
b6113cc4
SG
1176 &Count, /* CountDone */
1177 (UDIBool)0); /* HostEndian */
1178 if (err)
1179 error ("UDIWrite failed, error = %d", err);
1180
1181 From = To;
b5a3d2aa 1182 To.Offset+=4;
b6113cc4
SG
1183
1184 /* Now, duplicate it for the length of the BSS */
1185 err = UDICopy (From, /* From */
1186 To, /* To */
b5a3d2aa
SG
1187 (UDICount)(section_size/4 - 1), /* Count */
1188 (UDISizeT)4, /* Size */
b6113cc4
SG
1189 &Count, /* CountDone */
1190 (UDIBool)1); /* Direction */
1191 if (err)
b5a3d2aa
SG
1192 {
1193 char message[100];
1194 int xerr;
1195
1196 xerr = UDIGetErrorMsg(err, 100, message, &Count);
1197 if (!xerr)
1198 fprintf (stderr, "Error is %s\n", message);
1199 else
1200 fprintf (stderr, "xerr is %d\n", xerr);
1201 error ("UDICopy failed, error = %d", err);
1202 }
b6113cc4
SG
1203 }
1204
1205 }
1206 }
1207
1208 entry.Space = UDI29KIRAMSpace;
1209 entry.Offset = bfd_get_start_address (pbfd);
1210
9bddba9a 1211 immediate_quit--;
b6113cc4
SG
1212}
1213
1214/* User interface to download an image into the remote target. See download()
1215 * for details on args.
1216 */
1217
1218static void
1219udi_load(args, from_tty)
1220 char *args;
1221 int from_tty;
1222{
1223 download (args, from_tty);
9bddba9a 1224
b6113cc4 1225 symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
9bddba9a
SG
1226}
1227
1228/*************************************************** UDI_WRITE_INFERIOR_MEMORY
1229** Copy LEN bytes of data from debugger memory at MYADDR
1230 to inferior's memory at MEMADDR. Returns number of bytes written. */
1231static int
1232udi_write_inferior_memory (memaddr, myaddr, len)
1233 CORE_ADDR memaddr;
1234 char *myaddr;
1235 int len;
1236{
1237 int nwritten = 0;
1238 UDIUInt32 *From;
1239 UDIResource To;
1240 UDICount Count;
1241 UDISizeT Size = 1;
1242 UDICount CountDone = 0;
1243 UDIBool HostEndian = 0;
1244
b6113cc4 1245 To.Space = udi_memory_space(memaddr);
9bddba9a
SG
1246 From = (UDIUInt32*)myaddr;
1247
1248 while (nwritten < len)
1249 { Count = len - nwritten;
1250 if (Count > MAXDATA) Count = MAXDATA;
1251 To.Offset = memaddr + nwritten;
1252 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1253 { error("UDIWrite() failed in udi_write_inferrior_memory");
1254 break;
1255 }
1256 else
1257 { nwritten += CountDone;
1258 From += CountDone;
1259 }
1260 }
9bddba9a
SG
1261 return(nwritten);
1262}
1263
1264/**************************************************** UDI_READ_INFERIOR_MEMORY
1265** Read LEN bytes from inferior memory at MEMADDR. Put the result
1266 at debugger address MYADDR. Returns number of bytes read. */
1267static int
1268udi_read_inferior_memory(memaddr, myaddr, len)
1269 CORE_ADDR memaddr;
1270 char *myaddr;
1271 int len;
1272{
1273 int nread = 0;
1274 UDIResource From;
1275 UDIUInt32 *To;
1276 UDICount Count;
1277 UDISizeT Size = 1;
1278 UDICount CountDone = 0;
1279 UDIBool HostEndian = 0;
b5a3d2aa 1280 UDIError err;
9bddba9a 1281
9bddba9a
SG
1282 From.Space = udi_memory_space(memaddr);
1283 To = (UDIUInt32*)myaddr;
1284
1285 while (nread < len)
1286 { Count = len - nread;
1287 if (Count > MAXDATA) Count = MAXDATA;
1288 From.Offset = memaddr + nread;
b5a3d2aa
SG
1289 if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1290 { error("UDIRead() failed in udi_read_inferrior_memory");
9bddba9a
SG
1291 break;
1292 }
1293 else
1294 { nread += CountDone;
1295 To += CountDone;
1296 }
1297 }
1298 return(nread);
1299}
1300
1301/********************************************************************* WARNING
1302*/
1303udi_warning(num)
1304int num;
1305{
1306 error ("ERROR while loading program into remote TIP: $d\n", num);
1307}
1308
1309
1310/*****************************************************************************/
1311/* Fetch a single register indicatated by 'regno'.
1312 * Returns 0/-1 on success/failure.
1313 */
aa1dea48 1314static void
9bddba9a
SG
1315fetch_register (regno)
1316 int regno;
1317{
1318 UDIResource From;
1319 UDIUInt32 To;
1320 UDICount Count = 1;
1321 UDISizeT Size = 4;
1322 UDICount CountDone;
1323 UDIBool HostEndian = 0;
b5a3d2aa 1324 UDIError err;
9bddba9a
SG
1325 int result;
1326
9bddba9a 1327 if (regno == GR1_REGNUM)
d0b04c6a
SG
1328 {
1329 From.Space = UDI29KGlobalRegs;
1330 From.Offset = 1;
1331 }
9bddba9a 1332 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
d0b04c6a
SG
1333 {
1334 From.Space = UDI29KGlobalRegs;
1335 From.Offset = (regno - GR96_REGNUM) + 96;;
1336 }
1337
9bddba9a 1338#if defined(GR64_REGNUM)
d0b04c6a 1339
9bddba9a 1340 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
d0b04c6a
SG
1341 {
1342 From.Space = UDI29KGlobalRegs;
1343 From.Offset = (regno - GR64_REGNUM) + 64;
1344 }
1345
9bddba9a 1346#endif /* GR64_REGNUM */
d0b04c6a 1347
9bddba9a 1348 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
d0b04c6a
SG
1349 {
1350 From.Space = UDI29KLocalRegs;
1351 From.Offset = (regno - LR0_REGNUM);
1352 }
9bddba9a 1353 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
d0b04c6a
SG
1354 {
1355 int val = -1;
1356 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
aa1dea48 1357 return; /* Pretend Success */
d0b04c6a 1358 }
9bddba9a 1359 else
d0b04c6a
SG
1360 {
1361 From.Space = UDI29KSpecialRegs;
1362 From.Offset = regnum_to_srnum(regno);
1363 }
1364
b5a3d2aa 1365 if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
9bddba9a 1366 error("UDIRead() failed in udi_fetch_registers");
d0b04c6a 1367
9bddba9a 1368 supply_register(regno, (char *) &To);
aa1dea48
SG
1369
1370 if (kiodebug)
1371 printf("Fetching register %s = 0x%x\n", reg_names[regno], To);
9bddba9a
SG
1372}
1373/*****************************************************************************/
1374/* Store a single register indicated by 'regno'.
1375 * Returns 0/-1 on success/failure.
1376 */
1377static int
1378store_register (regno)
1379 int regno;
1380{
1381 int result;
1382 UDIUInt32 From;
1383 UDIResource To;
1384 UDICount Count = 1;
1385 UDISizeT Size = 4;
1386 UDICount CountDone;
1387 UDIBool HostEndian = 0;
1388
9bddba9a
SG
1389 From = read_register (regno); /* get data value */
1390
aa1dea48
SG
1391 if (kiodebug)
1392 printf("Storing register %s = 0x%x\n", reg_names[regno], From);
1393
9bddba9a
SG
1394 if (regno == GR1_REGNUM)
1395 { To.Space = UDI29KGlobalRegs;
1396 To.Offset = 1;
1397 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1398 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1399 * register cache. Do this *after* calling read_register, because we want
1400 * read_register to return the value that write_register has just stuffed
1401 * into the registers array, not the value of the register fetched from
1402 * the inferior.
1403 */
1404 registers_changed ();
1405 }
1406#if defined(GR64_REGNUM)
1407 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1408 { To.Space = UDI29KGlobalRegs;
1409 To.Offset = (regno - GR64_REGNUM) + 64;
1410 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1411 }
1412#endif /* GR64_REGNUM */
1413 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1414 { To.Space = UDI29KGlobalRegs;
1415 To.Offset = (regno - GR96_REGNUM) + 96;
1416 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1417 }
1418 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1419 { To.Space = UDI29KLocalRegs;
1420 To.Offset = (regno - LR0_REGNUM);
1421 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1422 }
1423 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1424 {
1425 return 0; /* Pretend Success */
1426 }
1427 else /* An unprotected or protected special register */
1428 { To.Space = UDI29KSpecialRegs;
1429 To.Offset = regnum_to_srnum(regno);
1430 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1431 }
1432
9bddba9a
SG
1433 if(result)
1434 { result = -1;
1435 error("UDIWrite() failed in store_registers");
1436 }
1437 return result;
1438}
1439/********************************************************** REGNUM_TO_SRNUM */
1440/*
1441 * Convert a gdb special register number to a 29000 special register number.
1442 */
1443static int
1444regnum_to_srnum(regno)
1445int regno;
1446{
1447 switch(regno) {
1448 case VAB_REGNUM: return(0);
1449 case OPS_REGNUM: return(1);
1450 case CPS_REGNUM: return(2);
1451 case CFG_REGNUM: return(3);
1452 case CHA_REGNUM: return(4);
1453 case CHD_REGNUM: return(5);
1454 case CHC_REGNUM: return(6);
1455 case RBP_REGNUM: return(7);
1456 case TMC_REGNUM: return(8);
1457 case TMR_REGNUM: return(9);
1458 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1459 case PC_REGNUM: return(USE_SHADOW_PC ? (21) : (11));
1460 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1461 case MMU_REGNUM: return(13);
1462 case LRU_REGNUM: return(14);
1463 case IPC_REGNUM: return(128);
1464 case IPA_REGNUM: return(129);
1465 case IPB_REGNUM: return(130);
1466 case Q_REGNUM: return(131);
1467 case ALU_REGNUM: return(132);
1468 case BP_REGNUM: return(133);
1469 case FC_REGNUM: return(134);
1470 case CR_REGNUM: return(135);
1471 case FPE_REGNUM: return(160);
d0b04c6a 1472 case INTE_REGNUM: return(161);
9bddba9a
SG
1473 case FPS_REGNUM: return(162);
1474 case EXO_REGNUM:return(164);
1475 default:
1476 return(255); /* Failure ? */
1477 }
1478}
1479/****************************************************************************/
1480/*
1481 * Determine the Target memory space qualifier based on the addr.
1482 * FIXME: Can't distinguis I_ROM/D_ROM.
1483 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1484 */
1485static CPUSpace
1486udi_memory_space(addr)
b6113cc4 1487CORE_ADDR addr;
9bddba9a
SG
1488{
1489 UDIUInt32 tstart = IMemStart;
1490 UDIUInt32 tend = tstart + IMemSize;
1491 UDIUInt32 dstart = DMemStart;
1492 UDIUInt32 dend = tstart + DMemSize;
1493 UDIUInt32 rstart = RMemStart;
1494 UDIUInt32 rend = tstart + RMemSize;
1495
1496 if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) {
1497 return UDI29KIRAMSpace;
1498 } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) {
1499 return UDI29KDRAMSpace;
1500 } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1501 /* FIXME: how do we determine between D_ROM and I_ROM */
1502 return UDI29KIROMSpace;
1503 } else /* FIXME: what do me do now? */
1504 return UDI29KDRAMSpace; /* Hmmm! */
1505}
1506/*********************************************************************** STUBS
1507*/
1508
1509void convert16() {;}
1510void convert32() {;}
1511FILE* EchoFile = 0; /* used for debugging */
1512int QuietMode = 0; /* used for debugging */
1513
1514/****************************************************************************/
1515/*
1516 * Define the target subroutine names
1517 */
1518static struct target_ops udi_ops = {
aa1dea48
SG
1519 "udi",
1520 "Remote UDI connected TIP",
a38b1233
JK
1521 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1522Arguments are\n\
1523`configuration-id AF_INET hostname port-number'\n\
1524 To connect via the network, where hostname and port-number specify the\n\
1525 host and port where you can connect via UDI.\n\
1526 configuration-id is unused.\n\
1527\n\
1528`configuration-id AF_UNIX socket-name tip-program'\n\
fe76016a 1529 To connect using a local connection to the \"tip.exe\" program which is\n\
a38b1233
JK
1530 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1531 tip program must already be started; connect to it using that socket.\n\
1532 If not, start up tip-program, which should be the name of the tip\n\
1533 program. If appropriate, the PATH environment variable is searched.\n\
1534 configuration-id is unused.\n\
1535\n\
1536`configuration-id'\n\
1537 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1538 are files containing lines in the above formats. configuration-id is\n\
1539 used to pick which line of the file to use.",
aa1dea48
SG
1540 udi_open,
1541 udi_close,
1542 udi_attach,
1543 udi_detach,
1544 udi_resume,
1545 udi_wait,
1546 udi_fetch_registers,
1547 udi_store_registers,
a03d4f8e 1548 udi_prepare_to_store,
9bddba9a
SG
1549 udi_xfer_inferior_memory,
1550 udi_files_info,
aa1dea48
SG
1551 udi_insert_breakpoint,
1552 udi_remove_breakpoint,
1553 0, /* termial_init */
1554 0, /* terminal_inferior */
1555 0, /* terminal_ours_for_output */
1556 0, /* terminal_ours */
1557 0, /* terminal_info */
9bddba9a
SG
1558 udi_kill, /* FIXME, kill */
1559 udi_load,
1560 0, /* lookup_symbol */
aa1dea48
SG
1561 udi_create_inferior,
1562 udi_mourn, /* mourn_inferior FIXME */
5ee4e16c 1563 0, /* can_run */
3950a34e 1564 0, /* notice_signals */
aa1dea48
SG
1565 process_stratum,
1566 0, /* next */
1567 1, /* has_all_memory */
1568 1, /* has_memory */
1569 1, /* has_stack */
1570 1, /* has_registers */
1571 1, /* has_execution */
1572 0, /* sections */
1573 0, /* sections_end */
9bddba9a
SG
1574 OPS_MAGIC, /* Always the last thing */
1575};
1576
1577void _initialize_remote_udi()
1578{
1579 add_target (&udi_ops);
aa1dea48
SG
1580 add_show_from_set (
1581 add_set_cmd ("remotedebug", no_class, var_boolean,
1582 (char *)&kiodebug,
1583 "Set debugging of UDI I/O.\n\
1584When enabled, debugging info is displayed.",
1585 &setlist),
1586 &showlist);
9bddba9a
SG
1587}
1588
1589#ifdef NO_HIF_SUPPORT
1590service_HIF(msg)
1591union msg_t *msg;
1592{
1593 return(0); /* Emulate a failure */
1594}
1595#endif
This page took 0.26297 seconds and 4 git commands to generate.