Phase 1 of the ptid_t changes.
[deliverable/binutils-gdb.git] / gdb / remote-udi.c
CommitLineData
c906108c 1/* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
b6ba6518
KB
2 Copyright 1990, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
c906108c
SS
4 Written by Daniel Mann. Contributed by AMD.
5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
c906108c 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
c906108c 17
c5aa993b
JM
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23/* This is like remote.c but uses the Universal Debug Interface (UDI) to
24 talk to the target hardware (or simulator). UDI is a TCP/IP based
25 protocol; for hardware that doesn't run TCP, an interface adapter
26 daemon talks UDI on one side, and talks to the hardware (typically
27 over a serial port) on the other side.
28
c5aa993b
JM
29 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
30 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
31 file to gdb 3.95. I was unable to get this working on sun3os4
32 with termio, only with sgtty.
33 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
34 MiniMON interface with UDI-p interface. */
35
c906108c
SS
36#include "defs.h"
37#include "frame.h"
38#include "inferior.h"
c906108c
SS
39#include "value.h"
40#include <ctype.h>
41#include <fcntl.h>
c906108c
SS
42#include <errno.h>
43#include "gdb_string.h"
44#include "terminal.h"
45#include "target.h"
46#include "29k-share/udi/udiproc.h"
47#include "gdbcmd.h"
48#include "bfd.h"
c5aa993b 49#include "gdbcore.h" /* For download function */
4e052eda 50#include "regcache.h"
c906108c
SS
51
52/* access the register store directly, without going through
53 the normal handler functions. This avoids an extra data copy. */
54
c5aa993b
JM
55extern int stop_soon_quietly; /* for wait_for_inferior */
56extern struct value *call_function_by_hand ();
39f77062 57static void udi_resume (ptid_t ptid, int step, enum target_signal sig);
a14ed312
KB
58static void udi_fetch_registers (int regno);
59static void udi_load (char *args, int from_tty);
60static void fetch_register (int regno);
61static void udi_store_registers (int regno);
62static int store_register (int regno);
63static int regnum_to_srnum (int regno);
64static void udi_close (int quitting);
65static CPUSpace udi_memory_space (CORE_ADDR addr);
66static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
67 int len);
68static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
69 int len);
70static void download (char *load_arg_string, int from_tty);
c5aa993b 71char CoffFileName[100] = "";
c906108c
SS
72
73#define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
74#define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
75
76static int timeout = 5;
c5aa993b 77extern struct target_ops udi_ops; /* Forward declaration */
c906108c
SS
78
79/* Special register enumeration.
c5aa993b 80 */
c906108c
SS
81
82/******************************************************************* UDI DATA*/
c5aa993b 83#define MAXDATA 2*1024 /* max UDI[read/write] byte size */
c906108c
SS
84/* Descriptor for I/O to remote machine. Initialize it to -1 so that
85 udi_open knows that we don't have a file open when the program
86 starts. */
87
88UDISessionId udi_session_id = -1;
89static char *udi_config_id;
90
91CPUOffset IMemStart = 0;
92CPUSizeT IMemSize = 0;
93CPUOffset DMemStart = 0;
94CPUSizeT DMemSize = 0;
95CPUOffset RMemStart = 0;
96CPUSizeT RMemSize = 0;
97UDIUInt32 CPUPRL;
98UDIUInt32 CoProcPRL;
99
c5aa993b
JM
100UDIMemoryRange address_ranges[2]; /* Text and data */
101UDIResource entry =
102{0, 0}; /* Entry point */
c906108c
SS
103CPUSizeT stack_sizes[2]; /* Regular and memory stacks */
104
105#define SBUF_MAX 1024 /* maximum size of string handling buffer */
106char sbuf[SBUF_MAX];
107
c5aa993b
JM
108typedef struct bkpt_entry_str
109 {
110 UDIResource Addr;
111 UDIUInt32 PassCount;
c906108c
SS
112 UDIBreakType Type;
113 unsigned int BreakId;
c5aa993b
JM
114 }
115bkpt_entry_t;
c906108c 116#define BKPT_TABLE_SIZE 40
c5aa993b
JM
117static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
118extern char dfe_errmsg[]; /* error string */
c906108c
SS
119
120/* malloc'd name of the program on the remote system. */
121static char *prog_name = NULL;
122
123/* This is called not only when we first attach, but also when the
124 user types "run" after having attached. */
125
126static void
fba45db2 127udi_create_inferior (char *execfile, char *args, char **env)
c906108c
SS
128{
129 char *args1;
130
131 if (execfile)
132 {
133 if (prog_name != NULL)
b8c9b27d 134 xfree (prog_name);
c906108c
SS
135 prog_name = savestring (execfile, strlen (execfile));
136 }
137 else if (entry.Offset)
138 execfile = "";
139 else
140 error ("No image loaded into target.");
141
142 if (udi_session_id < 0)
143 {
144 /* If the TIP is not open, open it. */
145 if (UDIConnect (udi_config_id, &udi_session_id))
c5aa993b 146 error ("UDIConnect() failed: %s\n", dfe_errmsg);
c906108c
SS
147 /* We will need to download the program. */
148 entry.Offset = 0;
149 }
150
39f77062 151 inferior_ptid = pid_to_ptid (40000);
c906108c
SS
152
153 if (!entry.Offset)
c5aa993b 154 download (execfile, 0);
c906108c 155
c5aa993b 156 args1 = alloca (strlen (execfile) + strlen (args) + 2);
c906108c
SS
157
158 if (execfile[0] == '\0')
159
160 /* It is empty. We need to quote it somehow, or else the target
161 will think there is no argument being passed here. According
162 to the UDI spec it is quoted "according to TIP OS rules" which
163 I guess means quoting it like the Unix shell should work
164 (sounds pretty bogus to me...). In fact it doesn't work (with
165 isstip anyway), but passing in two quotes as the argument seems
166 like a reasonable enough behavior anyway (I guess). */
167
168 strcpy (args1, "''");
169 else
170 strcpy (args1, execfile);
171 strcat (args1, " ");
172 strcat (args1, args);
173
174 UDIInitializeProcess (address_ranges, /* ProcessMemory[] */
c5aa993b
JM
175 (UDIInt) 2, /* NumberOfRanges */
176 entry, /* EntryPoint */
177 stack_sizes, /* *StackSizes */
178 (UDIInt) 2, /* NumberOfStacks */
179 args1); /* ArgString */
c906108c
SS
180
181 init_wait_for_inferior ();
182 clear_proceed_status ();
183 proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
184}
185
186static void
fba45db2 187udi_mourn (void)
c906108c
SS
188{
189#if 0
190 /* Requiring "target udi" each time you run is a major pain. I suspect
191 this was just blindy copied from remote.c, in which "target" and
192 "run" are combined. Having a udi target without an inferior seems
193 to work between "target udi" and "run", so why not now? */
c5aa993b 194 pop_target (); /* Pop back to no-child state */
c906108c
SS
195#endif
196 /* But if we're going to want to run it again, we better remove the
197 breakpoints... */
198 remove_breakpoints ();
199 generic_mourn_inferior ();
200}
201
202/******************************************************************** UDI_OPEN
203** Open a connection to remote TIP.
204 NAME is the socket domain used for communication with the TIP,
205 then a space and the socket name or TIP-host name.
206 '<udi_udi_config_id>' for example.
207 */
208
209/* XXX - need cleanups for udiconnect for various failures!!! */
210
211static void
fba45db2 212udi_open (char *name, int from_tty)
c906108c
SS
213{
214 unsigned int prl;
215 char *p;
216 int cnt;
217 UDIMemoryRange KnownMemory[10];
218 UDIUInt32 ChipVersions[10];
219 UDIInt NumberOfRanges = 10;
220 UDIInt NumberOfChips = 10;
221 UDIPId PId;
222 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
223
c5aa993b 224 target_preopen (from_tty);
c906108c
SS
225
226 entry.Offset = 0;
227
228 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
229 bkpt_table[cnt].Type = 0;
230
231 if (udi_config_id)
b8c9b27d 232 xfree (udi_config_id);
c906108c
SS
233
234 if (!name)
c5aa993b 235 error ("Usage: target udi config_id, where config_id appears in udi_soc file");
c906108c 236
5b616ba1 237 udi_config_id = xstrdup (strtok (name, " \t"));
c906108c
SS
238
239 if (UDIConnect (udi_config_id, &udi_session_id))
240 /* FIXME: Should set udi_session_id to -1 here. */
c5aa993b 241 error ("UDIConnect() failed: %s\n", dfe_errmsg);
c906108c
SS
242
243 push_target (&udi_ops);
244
245 /*
c5aa993b
JM
246 ** Initialize target configuration structure (global)
247 */
c906108c
SS
248 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
249 ChipVersions, &NumberOfChips))
250 error ("UDIGetTargetConfig() failed");
251 if (NumberOfChips > 2)
c5aa993b
JM
252 fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
253 for (cnt = 0; cnt < NumberOfRanges; cnt++)
c906108c 254 {
c5aa993b 255 switch (KnownMemory[cnt].Space)
c906108c
SS
256 {
257 default:
c5aa993b 258 fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
c906108c
SS
259 break;
260 case UDI29KCP_S:
261 break;
262 case UDI29KIROMSpace:
263 RMemStart = KnownMemory[cnt].Offset;
264 RMemSize = KnownMemory[cnt].Size;
265 break;
266 case UDI29KIRAMSpace:
267 IMemStart = KnownMemory[cnt].Offset;
268 IMemSize = KnownMemory[cnt].Size;
269 break;
270 case UDI29KDRAMSpace:
271 DMemStart = KnownMemory[cnt].Offset;
272 DMemSize = KnownMemory[cnt].Size;
273 break;
274 }
275 }
276
277 a29k_get_processor_type ();
278
279 if (UDICreateProcess (&PId))
c5aa993b 280 fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
c906108c
SS
281
282 /* Print out some stuff, letting the user now what's going on */
283 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
284 &TIPIPCId, sbuf))
285 error ("UDICapabilities() failed");
286 if (from_tty)
287 {
288 printf_filtered ("Connected via UDI socket,\n\
289 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
c5aa993b
JM
290 (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
291 (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
292 (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
c906108c
SS
293 sbuf);
294 }
295}
296
297/******************************************************************* UDI_CLOSE
298 Close the open connection to the TIP process.
299 Use this when you want to detach and do something else
300 with your gdb. */
301static void
fba45db2
KB
302udi_close ( /*FIXME: how is quitting used */
303 int quitting)
c906108c
SS
304{
305 if (udi_session_id < 0)
306 return;
307
308 /* We should never get here if there isn't something valid in
309 udi_session_id. */
310
311 if (UDIDisconnect (udi_session_id, UDITerminateSession))
312 {
313 if (quitting)
314 warning ("UDIDisconnect() failed in udi_close");
315 else
316 error ("UDIDisconnect() failed in udi_close");
317 }
318
319 /* Do not try to close udi_session_id again, later in the program. */
320 udi_session_id = -1;
39f77062 321 inferior_ptid = null_ptid;
c906108c
SS
322
323 printf_filtered (" Ending remote debugging\n");
c5aa993b 324}
c906108c
SS
325
326/**************************************************************** UDI_ATACH */
327/* Attach to a program that is already loaded and running
328 * Upon exiting the process's execution is stopped.
329 */
330static void
fba45db2 331udi_attach (char *args, int from_tty)
c906108c 332{
c5aa993b
JM
333 UDIResource From;
334 UDIInt32 PC_adds;
335 UDICount Count = 1;
336 UDISizeT Size = 4;
337 UDICount CountDone;
338 UDIBool HostEndian = 0;
339 UDIError err;
c906108c
SS
340
341 if (args == NULL)
342 error_no_arg ("program to attach");
343
344 if (udi_session_id < 0)
c5aa993b
JM
345 error ("UDI connection not opened yet, use the 'target udi' command.\n");
346
c906108c 347 if (from_tty)
c5aa993b 348 printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
c906108c 349
c5aa993b 350 UDIStop ();
c906108c
SS
351 From.Space = UDI29KSpecialRegs;
352 From.Offset = 11;
c5aa993b 353 if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
c906108c
SS
354 error ("UDIRead failed in udi_attach");
355 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
356}
357/************************************************************* UDI_DETACH */
358/* Terminate the open connection to the TIP process.
359 Use this when you want to detach and do something else
360 with your gdb. Leave remote process running (with no breakpoints set). */
361static void
fba45db2 362udi_detach (char *args, int from_tty)
c906108c
SS
363{
364
c5aa993b 365 remove_breakpoints (); /* Just in case there were any left in */
c906108c
SS
366
367 if (UDIDisconnect (udi_session_id, UDIContinueSession))
368 error ("UDIDisconnect() failed in udi_detach");
369
370 /* Don't try to UDIDisconnect it again in udi_close, which is called from
371 pop_target. */
372 udi_session_id = -1;
39f77062 373 inferior_ptid = null_ptid;
c906108c 374
c5aa993b 375 pop_target ();
c906108c
SS
376
377 if (from_tty)
378 printf_unfiltered ("Detaching from TIP\n");
379}
380
381
382/****************************************************************** UDI_RESUME
383** Tell the remote machine to resume. */
384
385static void
39f77062 386udi_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c
SS
387{
388 UDIError tip_error;
389 UDIUInt32 Steps = 1;
390 UDIStepType StepType = UDIStepNatural;
391 UDIRange Range;
392
c5aa993b 393 if (step) /* step 1 instruction */
c906108c
SS
394 {
395 tip_error = UDIStep (Steps, StepType, Range);
396 if (!tip_error)
397 return;
398
c5aa993b 399 fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
c906108c
SS
400 error ("failed in udi_resume");
401 }
402
c5aa993b 403 if (UDIExecute ())
c906108c
SS
404 error ("UDIExecute() failed in udi_resume");
405}
406
407/******************************************************************** UDI_WAIT
408** Wait until the remote machine stops, then return,
409 storing status in STATUS just as `wait' would. */
410
39f77062
KB
411static ptid_t
412udi_wait (int ptid_t, struct target_waitstatus *status)
c906108c 413{
c5aa993b
JM
414 UDIInt32 MaxTime;
415 UDIPId PId;
416 UDIInt32 StopReason;
417 UDISizeT CountDone;
418 int old_timeout = timeout;
419 int old_immediate_quit = immediate_quit;
420 int i;
c906108c
SS
421
422 status->kind = TARGET_WAITKIND_EXITED;
423 status->value.integer = 0;
424
425/* wait for message to arrive. It should be:
c5aa993b
JM
426 If the target stops executing, udi_wait() should return.
427 */
c906108c 428 timeout = 0; /* Wait indefinetly for a message */
c5aa993b 429 immediate_quit = 1; /* Helps ability to QUIT */
c906108c 430
c5aa993b 431 while (1)
c906108c
SS
432 {
433 i = 0;
434 MaxTime = UDIWaitForever;
c5aa993b 435 UDIWait (MaxTime, &PId, &StopReason);
c906108c
SS
436 QUIT; /* Let user quit if they want */
437
438 switch (StopReason & UDIGrossState)
439 {
440 case UDIStdoutReady:
c5aa993b 441 if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
c906108c
SS
442 /* This is said to happen if the program tries to output
443 a whole bunch of output (more than SBUF_MAX, I would
444 guess). It doesn't seem to happen with the simulator. */
445 warning ("UDIGetStdout() failed in udi_wait");
446 fwrite (sbuf, 1, CountDone, stdout);
c5aa993b 447 gdb_flush (gdb_stdout);
c906108c
SS
448 continue;
449
450 case UDIStderrReady:
c5aa993b 451 UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
c906108c 452 fwrite (sbuf, 1, CountDone, stderr);
c5aa993b 453 gdb_flush (gdb_stderr);
c906108c
SS
454 continue;
455
456 case UDIStdinNeeded:
457 {
458 int ch;
459 i = 0;
460 do
461 {
462 ch = getchar ();
463 if (ch == EOF)
464 break;
465 sbuf[i++] = ch;
c5aa993b
JM
466 }
467 while (i < SBUF_MAX && ch != '\n');
468 UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
c906108c
SS
469 continue;
470 }
471
472 case UDIRunning:
473 /* In spite of the fact that we told UDIWait to wait forever, it will
474 return spuriously sometimes. */
475 case UDIStdinModeX:
476 continue;
477 default:
478 break;
479 }
480 break;
481 }
482
483 switch (StopReason & UDIGrossState)
484 {
485 case UDITrapped:
c5aa993b
JM
486 printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
487
488 switch ((StopReason >> 8) & 0xff)
c906108c 489 {
c5aa993b
JM
490 case 0: /* Illegal opcode */
491 printf_unfiltered (" (break point)\n");
c906108c
SS
492 status->kind = TARGET_WAITKIND_STOPPED;
493 status->value.sig = TARGET_SIGNAL_TRAP;
494 break;
c5aa993b 495 case 1: /* Unaligned Access */
c906108c
SS
496 status->kind = TARGET_WAITKIND_STOPPED;
497 status->value.sig = TARGET_SIGNAL_BUS;
498 break;
499 case 3:
500 case 4:
501 status->kind = TARGET_WAITKIND_STOPPED;
502 status->value.sig = TARGET_SIGNAL_FPE;
503 break;
c5aa993b 504 case 5: /* Protection Violation */
c906108c
SS
505 status->kind = TARGET_WAITKIND_STOPPED;
506 /* Why not SEGV? What is a Protection Violation? */
507 status->value.sig = TARGET_SIGNAL_ILL;
508 break;
509 case 6:
510 case 7:
c5aa993b
JM
511 case 8: /* User Instruction Mapping Miss */
512 case 9: /* User Data Mapping Miss */
c906108c
SS
513 case 10: /* Supervisor Instruction Mapping Miss */
514 case 11: /* Supervisor Data Mapping Miss */
515 status->kind = TARGET_WAITKIND_STOPPED;
516 status->value.sig = TARGET_SIGNAL_SEGV;
517 break;
518 case 12:
519 case 13:
520 status->kind = TARGET_WAITKIND_STOPPED;
521 status->value.sig = TARGET_SIGNAL_ILL;
522 break;
523 case 14: /* Timer */
524 status->kind = TARGET_WAITKIND_STOPPED;
525 status->value.sig = TARGET_SIGNAL_ALRM;
526 break;
527 case 15: /* Trace */
528 status->kind = TARGET_WAITKIND_STOPPED;
529 status->value.sig = TARGET_SIGNAL_TRAP;
530 break;
531 case 16: /* INTR0 */
532 case 17: /* INTR1 */
533 case 18: /* INTR2 */
534 case 19: /* INTR3/Internal */
535 case 20: /* TRAP0 */
536 case 21: /* TRAP1 */
537 status->kind = TARGET_WAITKIND_STOPPED;
538 status->value.sig = TARGET_SIGNAL_INT;
539 break;
540 case 22: /* Floating-Point Exception */
541 status->kind = TARGET_WAITKIND_STOPPED;
542 /* Why not FPE? */
543 status->value.sig = TARGET_SIGNAL_ILL;
544 break;
545 case 77: /* assert 77 */
546 status->kind = TARGET_WAITKIND_STOPPED;
547 status->value.sig = TARGET_SIGNAL_TRAP;
548 break;
549 default:
550 status->kind = TARGET_WAITKIND_EXITED;
551 status->value.integer = 0;
552 }
553 break;
554 case UDINotExecuting:
555 status->kind = TARGET_WAITKIND_STOPPED;
556 status->value.sig = TARGET_SIGNAL_TERM;
557 break;
558 case UDIStopped:
559 status->kind = TARGET_WAITKIND_STOPPED;
560 status->value.sig = TARGET_SIGNAL_TSTP;
561 break;
562 case UDIWarned:
563 status->kind = TARGET_WAITKIND_STOPPED;
564 status->value.sig = TARGET_SIGNAL_URG;
565 break;
566 case UDIStepped:
567 case UDIBreak:
568 status->kind = TARGET_WAITKIND_STOPPED;
569 status->value.sig = TARGET_SIGNAL_TRAP;
570 break;
571 case UDIWaiting:
572 status->kind = TARGET_WAITKIND_STOPPED;
573 status->value.sig = TARGET_SIGNAL_STOP;
574 break;
575 case UDIHalted:
576 status->kind = TARGET_WAITKIND_STOPPED;
577 status->value.sig = TARGET_SIGNAL_KILL;
578 break;
579 case UDIExited:
580 default:
581 status->kind = TARGET_WAITKIND_EXITED;
582 status->value.integer = 0;
583 }
584
585 timeout = old_timeout; /* Restore original timeout value */
586 immediate_quit = old_immediate_quit;
39f77062 587 return inferior_ptid;
c906108c
SS
588}
589
590#if 0
591/* Handy for debugging */
fba45db2 592udi_pc (void)
c906108c 593{
c5aa993b
JM
594 UDIResource From;
595 UDIUInt32 *To;
596 UDICount Count;
597 UDISizeT Size = 4;
598 UDICount CountDone;
599 UDIBool HostEndian = 0;
600 UDIError err;
c906108c
SS
601 int pc[2];
602 unsigned long myregs[256];
603 int i;
604
605 From.Space = UDI29KPC;
606 From.Offset = 0;
c5aa993b 607 To = (UDIUInt32 *) pc;
c906108c
SS
608 Count = 2;
609
c5aa993b 610 err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
c906108c
SS
611
612 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
c5aa993b 613 err, CountDone, pc[0], pc[1]);
c906108c 614
c5aa993b 615 udi_fetch_registers (-1);
c906108c 616
c5aa993b
JM
617 printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) &registers[4 * PC_REGNUM],
618 *(int *) &registers[4 * NPC_REGNUM]);
c906108c
SS
619
620 /* Now, read all the registers globally */
621
622 From.Space = UDI29KGlobalRegs;
623 From.Offset = 0;
c5aa993b 624 err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
c906108c
SS
625
626 printf ("err = %d, CountDone = %d\n", err, CountDone);
627
c5aa993b 628 printf ("\n");
c906108c
SS
629
630 for (i = 0; i < 256; i += 2)
c5aa993b
JM
631 printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
632 myregs[i + 1], myregs[i + 1]);
633 printf ("\n");
c906108c
SS
634
635 return pc[0];
636}
637#endif
638
639/********************************************************** UDI_FETCH_REGISTERS
640 * Read a remote register 'regno'.
641 * If regno==-1 then read all the registers.
642 */
c5aa993b 643static void
fba45db2 644udi_fetch_registers (int regno)
c906108c 645{
c5aa993b
JM
646 UDIResource From;
647 UDIUInt32 *To;
648 UDICount Count;
649 UDISizeT Size = 4;
650 UDICount CountDone;
651 UDIBool HostEndian = 0;
652 UDIError err;
653 int i;
654
655 if (regno >= 0)
656 {
657 fetch_register (regno);
658 return;
659 }
c906108c
SS
660
661/* Gr1/rsp */
662
663 From.Space = UDI29KGlobalRegs;
664 From.Offset = 1;
c5aa993b 665 To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
c906108c 666 Count = 1;
c5aa993b
JM
667 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
668 error ("UDIRead() failed in udi_fetch_registers");
c906108c
SS
669
670 register_valid[GR1_REGNUM] = 1;
671
672#if defined(GR64_REGNUM) /* Read gr64-127 */
673
c5aa993b 674/* Global Registers gr64-gr95 */
c906108c
SS
675
676 From.Space = UDI29KGlobalRegs;
677 From.Offset = 64;
c5aa993b 678 To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
c906108c 679 Count = 32;
c5aa993b
JM
680 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
681 error ("UDIRead() failed in udi_fetch_registers");
c906108c
SS
682
683 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
684 register_valid[i] = 1;
685
c5aa993b 686#endif /* GR64_REGNUM */
c906108c 687
c5aa993b 688/* Global Registers gr96-gr127 */
c906108c
SS
689
690 From.Space = UDI29KGlobalRegs;
691 From.Offset = 96;
c5aa993b 692 To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
c906108c 693 Count = 32;
c5aa993b
JM
694 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
695 error ("UDIRead() failed in udi_fetch_registers");
c906108c
SS
696
697 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
698 register_valid[i] = 1;
699
700/* Local Registers */
701
702 From.Space = UDI29KLocalRegs;
703 From.Offset = 0;
c5aa993b 704 To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
c906108c 705 Count = 128;
c5aa993b
JM
706 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
707 error ("UDIRead() failed in udi_fetch_registers");
c906108c
SS
708
709 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
710 register_valid[i] = 1;
711
712/* Protected Special Registers */
713
714 From.Space = UDI29KSpecialRegs;
715 From.Offset = 0;
c5aa993b 716 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
c906108c 717 Count = 15;
c5aa993b
JM
718 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
719 error ("UDIRead() failed in udi_fetch_registers");
c906108c 720
c5aa993b 721 for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
c906108c
SS
722 register_valid[i] = 1;
723
c5aa993b
JM
724 if (USE_SHADOW_PC)
725 { /* Let regno_to_srnum() handle the register number */
726 fetch_register (NPC_REGNUM);
727 fetch_register (PC_REGNUM);
728 fetch_register (PC2_REGNUM);
c906108c
SS
729
730/* Unprotected Special Registers sr128-sr135 */
731
c5aa993b
JM
732 From.Space = UDI29KSpecialRegs;
733 From.Offset = 128;
734 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
735 Count = 135 - 128 + 1;
736 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
737 error ("UDIRead() failed in udi_fetch_registers");
738
739 for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
740 register_valid[i] = 1;
741 }
c906108c
SS
742
743 if (remote_debug)
744 {
9846de1b
JM
745 fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
746 fprintf_unfiltered (gdb_stdlog,
747 "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
748 read_register (NPC_REGNUM),
749 read_register (PC_REGNUM),
750 read_register (PC2_REGNUM));
c906108c
SS
751 }
752
753 /* There doesn't seem to be any way to get these. */
754 {
755 int val = -1;
756 supply_register (FPE_REGNUM, (char *) &val);
757 supply_register (INTE_REGNUM, (char *) &val);
758 supply_register (FPS_REGNUM, (char *) &val);
759 supply_register (EXO_REGNUM, (char *) &val);
760 }
761}
762
763
764/********************************************************* UDI_STORE_REGISTERS
765** Store register regno into the target.
766 * If regno==-1 then store all the registers.
767 */
768
769static void
fba45db2 770udi_store_registers (int regno)
c906108c 771{
c5aa993b
JM
772 UDIUInt32 *From;
773 UDIResource To;
774 UDICount Count;
775 UDISizeT Size = 4;
776 UDICount CountDone;
777 UDIBool HostEndian = 0;
778
c906108c
SS
779 if (regno >= 0)
780 {
c5aa993b 781 store_register (regno);
c906108c
SS
782 return;
783 }
784
785 if (remote_debug)
786 {
9846de1b
JM
787 fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
788 fprintf_unfiltered (gdb_stdlog,
789 "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
790 read_register (NPC_REGNUM),
791 read_register (PC_REGNUM),
792 read_register (PC2_REGNUM));
c906108c
SS
793 }
794
795/* Gr1/rsp */
796
c5aa993b 797 From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
c906108c
SS
798 To.Space = UDI29KGlobalRegs;
799 To.Offset = 1;
800 Count = 1;
c5aa993b
JM
801 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
802 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
803
804#if defined(GR64_REGNUM)
805
806/* Global registers gr64-gr95 */
807
c5aa993b 808 From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
c906108c
SS
809 To.Space = UDI29KGlobalRegs;
810 To.Offset = 64;
811 Count = 32;
c5aa993b
JM
812 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
813 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c 814
c5aa993b 815#endif /* GR64_REGNUM */
c906108c
SS
816
817/* Global registers gr96-gr127 */
818
c5aa993b 819 From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
c906108c
SS
820 To.Space = UDI29KGlobalRegs;
821 To.Offset = 96;
822 Count = 32;
c5aa993b
JM
823 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
824 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
825
826/* Local Registers */
827
c5aa993b 828 From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
c906108c
SS
829 To.Space = UDI29KLocalRegs;
830 To.Offset = 0;
831 Count = 128;
c5aa993b
JM
832 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
833 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
834
835
c5aa993b 836 /* Protected Special Registers *//* VAB through TMR */
c906108c 837
c5aa993b 838 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
c906108c
SS
839 To.Space = UDI29KSpecialRegs;
840 To.Offset = 0;
841 Count = 10;
c5aa993b
JM
842 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
843 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
844
845/* PC0, PC1, PC2 possibly as shadow registers */
846
c5aa993b 847 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
c906108c
SS
848 To.Space = UDI29KSpecialRegs;
849 Count = 3;
c5aa993b
JM
850 if (USE_SHADOW_PC)
851 To.Offset = 20; /* SPC0 */
852 else
853 To.Offset = 10; /* PC0 */
854 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
855 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
856
857/* PC1 via UDI29KPC */
858
c5aa993b 859 From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
c906108c 860 To.Space = UDI29KPC;
c5aa993b 861 To.Offset = 0; /* PC1 */
c906108c
SS
862 Count = 1;
863 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
864 error ("UDIWrite() failed in udi_store_regisetrs");
865
866 /* LRU and MMU */
867
c5aa993b 868 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
c906108c
SS
869 To.Space = UDI29KSpecialRegs;
870 To.Offset = 13;
871 Count = 2;
c5aa993b
JM
872 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
873 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c 874
c5aa993b 875/* Unprotected Special Registers */
c906108c 876
c5aa993b 877 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
c906108c
SS
878 To.Space = UDI29KSpecialRegs;
879 To.Offset = 128;
c5aa993b
JM
880 Count = 135 - 128 + 1;
881 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
882 error ("UDIWrite() failed in udi_store_regisetrs");
c906108c
SS
883
884 registers_changed ();
885}
886
887/****************************************************** UDI_PREPARE_TO_STORE */
888/* Get ready to modify the registers array. On machines which store
889 individual registers, this doesn't need to do anything. On machines
890 which store all the registers in one fell swoop, this makes sure
891 that registers contains all the registers from the program being
892 debugged. */
893
894static void
fba45db2 895udi_prepare_to_store (void)
c906108c
SS
896{
897 /* Do nothing, since we can store individual regs */
898}
899
900/********************************************************** TRANSLATE_ADDR */
901static CORE_ADDR
fba45db2 902translate_addr (CORE_ADDR addr)
c906108c
SS
903{
904#if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
c5aa993b
JM
905 /* Check for a virtual address in the kernel */
906 /* Assume physical address of ublock is in paddr_u register */
907 /* FIXME: doesn't work for user virtual addresses */
908 if (addr >= UVADDR)
909 {
910 /* PADDR_U register holds the physical address of the ublock */
911 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
912 return (i + addr - (CORE_ADDR) UVADDR);
913 }
914 else
915 {
916 return (addr);
917 }
c906108c 918#else
c5aa993b 919 return (addr);
c906108c
SS
920#endif
921}
922/************************************************* UDI_XFER_INFERIOR_MEMORY */
923/* FIXME! Merge these two. */
924static int
4e005f2e 925udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
29e57380
C
926 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
927 struct target_ops *target ATTRIBUTE_UNUSED)
c906108c
SS
928{
929
c5aa993b 930 memaddr = translate_addr (memaddr);
c906108c
SS
931
932 if (write)
933 return udi_write_inferior_memory (memaddr, myaddr, len);
934 else
935 return udi_read_inferior_memory (memaddr, myaddr, len);
936}
937
938/********************************************************** UDI_FILES_INFO */
939static void
4e005f2e 940udi_files_info (struct target_ops *target)
c906108c
SS
941{
942 printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
943 if (prog_name != NULL)
944 printf_unfiltered ("and running program %s", prog_name);
945 printf_unfiltered (".\n");
946}
947
948/**************************************************** UDI_INSERT_BREAKPOINT */
949static int
fba45db2 950udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
951{
952 int cnt;
953 UDIError err;
954
955 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
c5aa993b 956 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
c906108c
SS
957 break;
958
c5aa993b
JM
959 if (cnt >= BKPT_TABLE_SIZE)
960 error ("Too many breakpoints set");
c906108c
SS
961
962 bkpt_table[cnt].Addr.Offset = addr;
c5aa993b 963 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
c906108c
SS
964 bkpt_table[cnt].PassCount = 1;
965 bkpt_table[cnt].Type = UDIBreakFlagExecute;
c906108c 966
c5aa993b
JM
967 err = UDISetBreakpoint (bkpt_table[cnt].Addr,
968 bkpt_table[cnt].PassCount,
969 bkpt_table[cnt].Type,
970 &bkpt_table[cnt].BreakId);
971
972 if (err == 0)
973 return 0; /* Success */
c906108c
SS
974
975 bkpt_table[cnt].Type = 0;
c5aa993b 976 error ("UDISetBreakpoint returned error code %d\n", err);
c906108c
SS
977}
978
979/**************************************************** UDI_REMOVE_BREAKPOINT */
980static int
fba45db2 981udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
c906108c
SS
982{
983 int cnt;
984 UDIError err;
985
986 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
c5aa993b 987 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
c906108c
SS
988 break;
989
c5aa993b
JM
990 if (cnt >= BKPT_TABLE_SIZE)
991 error ("Can't find breakpoint in table");
c906108c
SS
992
993 bkpt_table[cnt].Type = 0;
994
c5aa993b
JM
995 err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
996 if (err == 0)
997 return 0; /* Success */
c906108c 998
c5aa993b 999 error ("UDIClearBreakpoint returned error code %d\n", err);
c906108c
SS
1000}
1001
1002static void
4e005f2e 1003udi_kill (void)
c906108c
SS
1004{
1005
1006#if 0
1007/*
c5aa993b
JM
1008 UDIStop does not really work as advertised. It causes the TIP to close it's
1009 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1010 just invoke udi_close, which seems to get things right.
1011 */
1012 UDIStop ();
c906108c
SS
1013
1014 udi_session_id = -1;
39f77062 1015 inferior_ptid = null_ptid;
c906108c
SS
1016
1017 if (from_tty)
c5aa993b 1018 printf_unfiltered ("Target has been stopped.");
c906108c
SS
1019#endif /* 0 */
1020#if 0
c5aa993b
JM
1021 udi_close (0);
1022 pop_target ();
c906108c
SS
1023#endif /* 0 */
1024
1025 /* Keep the target around, e.g. so "run" can do the right thing when
1026 we are already debugging something. */
1027
1028 if (UDIDisconnect (udi_session_id, UDITerminateSession))
1029 {
1030 warning ("UDIDisconnect() failed");
1031 }
1032
1033 /* Do not try to close udi_session_id again, later in the program. */
1034 udi_session_id = -1;
39f77062 1035 inferior_ptid = null_ptid;
c906108c
SS
1036}
1037
1038/*
1039 Load a program into the target. Args are: `program {options}'. The options
1040 are used to control loading of the program, and are NOT passed onto the
1041 loaded code as arguments. (You need to use the `run' command to do that.)
1042
1043 The options are:
c5aa993b
JM
1044 -ms %d Set mem stack size to %d
1045 -rs %d Set regular stack size to %d
1046 -i send init info (default)
1047 -noi don't send init info
1048 -[tT] Load Text section
1049 -[dD] Load Data section
1050 -[bB] Load BSS section
1051 -[lL] Load Lit section
1052 */
c906108c
SS
1053
1054static void
fba45db2 1055download (char *load_arg_string, int from_tty)
c906108c
SS
1056{
1057#define DEFAULT_MEM_STACK_SIZE 0x6000
1058#define DEFAULT_REG_STACK_SIZE 0x2000
1059
1060 char *token;
1061 char *filename;
1062 asection *section;
1063 bfd *pbfd;
1064 UDIError err;
1065 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1066
1067 address_ranges[0].Space = UDI29KIRAMSpace;
1068 address_ranges[0].Offset = 0xffffffff;
1069 address_ranges[0].Size = 0;
1070
1071 address_ranges[1].Space = UDI29KDRAMSpace;
1072 address_ranges[1].Offset = 0xffffffff;
1073 address_ranges[1].Size = 0;
1074
1075 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1076 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1077
1078 dont_repeat ();
1079
c5aa993b 1080 filename = strtok (load_arg_string, " \t");
c906108c
SS
1081 if (!filename)
1082 error ("Must specify at least a file name with the load command");
1083
1084 filename = tilde_expand (filename);
b8c9b27d 1085 make_cleanup (xfree, filename);
c906108c
SS
1086
1087 while (token = strtok (NULL, " \t"))
1088 {
1089 if (token[0] == '-')
1090 {
1091 token++;
1092
1093 if (STREQ (token, "ms"))
1094 stack_sizes[1] = atol (strtok (NULL, " \t"));
1095 else if (STREQ (token, "rs"))
1096 stack_sizes[0] = atol (strtok (NULL, " \t"));
1097 else
1098 {
1099 load_text = load_data = load_bss = load_lit = 0;
1100
1101 while (*token)
1102 {
1103 switch (*token++)
1104 {
1105 case 't':
1106 case 'T':
1107 load_text = 1;
1108 break;
1109 case 'd':
1110 case 'D':
1111 load_data = 1;
1112 break;
1113 case 'b':
1114 case 'B':
1115 load_bss = 1;
1116 break;
1117 case 'l':
1118 case 'L':
1119 load_lit = 1;
1120 break;
1121 default:
c5aa993b 1122 error ("Unknown UDI load option -%s", token - 1);
c906108c
SS
1123 }
1124 }
1125 }
1126 }
1127 }
1128
1129 pbfd = bfd_openr (filename, gnutarget);
1130
c5aa993b 1131 if (!pbfd)
c906108c
SS
1132 /* FIXME: should be using bfd_errmsg, not assuming it was
1133 bfd_error_system_call. */
1134 perror_with_name (filename);
c5aa993b 1135
c906108c
SS
1136 /* FIXME: should be checking for errors from bfd_close (for one thing,
1137 on error it does not free all the storage associated with the
1138 bfd). */
5c65bbb6 1139 make_cleanup_bfd_close (pbfd);
c906108c
SS
1140
1141 QUIT;
1142 immediate_quit++;
1143
c5aa993b 1144 if (!bfd_check_format (pbfd, bfd_object))
c906108c 1145 error ("It doesn't seem to be an object file");
c5aa993b
JM
1146
1147 for (section = pbfd->sections; section; section = section->next)
c906108c
SS
1148 {
1149 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1150 {
1151 UDIResource To;
1152 UDICount Count;
1153 unsigned long section_size, section_end;
1154 const char *section_name;
1155
1156 section_name = bfd_get_section_name (pbfd, section);
1157 if (STREQ (section_name, ".text") && !load_text)
1158 continue;
1159 else if (STREQ (section_name, ".data") && !load_data)
1160 continue;
1161 else if (STREQ (section_name, ".bss") && !load_bss)
1162 continue;
1163 else if (STREQ (section_name, ".lit") && !load_lit)
1164 continue;
1165
1166 To.Offset = bfd_get_section_vma (pbfd, section);
1167 section_size = bfd_section_size (pbfd, section);
1168 section_end = To.Offset + section_size;
1169
1170 if (section_size == 0)
1171 /* This is needed at least in the BSS case, where the code
1172 below starts writing before it even checks the size. */
1173 continue;
1174
c5aa993b
JM
1175 printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
1176 section_name,
1177 To.Offset,
1178 section_size);
c906108c
SS
1179
1180 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1181 {
1182 To.Space = UDI29KIRAMSpace;
1183
1184 address_ranges[0].Offset = min (address_ranges[0].Offset,
1185 To.Offset);
1186 address_ranges[0].Size = max (address_ranges[0].Size,
1187 section_end
1188 - address_ranges[0].Offset);
1189 }
1190 else
1191 {
1192 To.Space = UDI29KDRAMSpace;
1193
1194 address_ranges[1].Offset = min (address_ranges[1].Offset,
1195 To.Offset);
1196 address_ranges[1].Size = max (address_ranges[1].Size,
1197 section_end
1198 - address_ranges[1].Offset);
1199 }
1200
c5aa993b 1201 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
c906108c
SS
1202 {
1203 file_ptr fptr;
1204
1205 fptr = 0;
1206
1207 while (section_size > 0)
1208 {
1209 char buffer[1024];
1210
1211 Count = min (section_size, 1024);
1212
1213 bfd_get_section_contents (pbfd, section, buffer, fptr,
1214 Count);
1215
c5aa993b
JM
1216 err = UDIWrite ((UDIHostMemPtr) buffer, /* From */
1217 To, /* To */
1218 Count, /* Count */
1219 (UDISizeT) 1, /* Size */
1220 &Count, /* CountDone */
1221 (UDIBool) 0); /* HostEndian */
c906108c
SS
1222 if (err)
1223 error ("UDIWrite failed, error = %d", err);
1224
1225 To.Offset += Count;
1226 fptr += Count;
1227 section_size -= Count;
1228 }
1229 }
c5aa993b
JM
1230 else
1231 /* BSS */
c906108c
SS
1232 {
1233 UDIResource From;
1234 unsigned long zero = 0;
1235
1236 /* Write a zero byte at the vma */
1237 /* FIXME: Broken for sections of 1-3 bytes (we test for
c5aa993b
JM
1238 zero above). */
1239 err = UDIWrite ((UDIHostMemPtr) & zero, /* From */
1240 To, /* To */
1241 (UDICount) 1, /* Count */
1242 (UDISizeT) 4, /* Size */
1243 &Count, /* CountDone */
1244 (UDIBool) 0); /* HostEndian */
c906108c
SS
1245 if (err)
1246 error ("UDIWrite failed, error = %d", err);
1247
1248 From = To;
c5aa993b 1249 To.Offset += 4;
c906108c
SS
1250
1251 /* Now, duplicate it for the length of the BSS */
c5aa993b
JM
1252 err = UDICopy (From, /* From */
1253 To, /* To */
1254 (UDICount) (section_size / 4 - 1), /* Count */
1255 (UDISizeT) 4, /* Size */
1256 &Count, /* CountDone */
1257 (UDIBool) 1); /* Direction */
c906108c
SS
1258 if (err)
1259 {
1260 char message[100];
1261 int xerr;
1262
c5aa993b 1263 xerr = UDIGetErrorMsg (err, 100, message, &Count);
c906108c
SS
1264 if (!xerr)
1265 fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1266 else
1267 fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1268 error ("UDICopy failed, error = %d", err);
1269 }
1270 }
1271
1272 }
1273 }
1274
1275 entry.Space = UDI29KIRAMSpace;
1276 entry.Offset = bfd_get_start_address (pbfd);
c5aa993b 1277
c906108c
SS
1278 immediate_quit--;
1279}
1280
1281/* Function to download an image into the remote target. */
1282
1283static void
fba45db2 1284udi_load (char *args, int from_tty)
c906108c
SS
1285{
1286 download (args, from_tty);
1287
1288 /* As a convenience, pick up any symbol info that is in the program
1289 being loaded. Note that we assume that the program is the``mainline'';
1290 if this is not always true, then this code will need to be augmented. */
2df3850c 1291 symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
c906108c
SS
1292
1293 /* Getting new symbols may change our opinion about what is
1294 frameless. */
1295 reinit_frame_cache ();
1296}
1297
1298/*************************************************** UDI_WRITE_INFERIOR_MEMORY
1299** Copy LEN bytes of data from debugger memory at MYADDR
1300 to inferior's memory at MEMADDR. Returns number of bytes written. */
1301static int
fba45db2 1302udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c 1303{
c5aa993b
JM
1304 int nwritten = 0;
1305 UDIUInt32 *From;
1306 UDIResource To;
1307 UDICount Count;
1308 UDISizeT Size = 1;
1309 UDICount CountDone = 0;
1310 UDIBool HostEndian = 0;
1311
1312 To.Space = udi_memory_space (memaddr);
1313 From = (UDIUInt32 *) myaddr;
c906108c
SS
1314
1315 while (nwritten < len)
c5aa993b
JM
1316 {
1317 Count = len - nwritten;
1318 if (Count > MAXDATA)
1319 Count = MAXDATA;
1320 To.Offset = memaddr + nwritten;
1321 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
1322 {
1323 error ("UDIWrite() failed in udi_write_inferior_memory");
1324 break;
c906108c 1325 }
c5aa993b
JM
1326 else
1327 {
1328 nwritten += CountDone;
1329 From += CountDone;
c906108c 1330 }
c5aa993b
JM
1331 }
1332 return (nwritten);
c906108c
SS
1333}
1334
1335/**************************************************** UDI_READ_INFERIOR_MEMORY
1336** Read LEN bytes from inferior memory at MEMADDR. Put the result
1337 at debugger address MYADDR. Returns number of bytes read. */
1338static int
fba45db2 1339udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c 1340{
c5aa993b
JM
1341 int nread = 0;
1342 UDIResource From;
1343 UDIUInt32 *To;
1344 UDICount Count;
1345 UDISizeT Size = 1;
1346 UDICount CountDone = 0;
1347 UDIBool HostEndian = 0;
1348 UDIError err;
1349
1350 From.Space = udi_memory_space (memaddr);
1351 To = (UDIUInt32 *) myaddr;
c906108c
SS
1352
1353 while (nread < len)
c5aa993b
JM
1354 {
1355 Count = len - nread;
1356 if (Count > MAXDATA)
1357 Count = MAXDATA;
1358 From.Offset = memaddr + nread;
1359 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
1360 {
1361 error ("UDIRead() failed in udi_read_inferior_memory");
1362 break;
c906108c 1363 }
c5aa993b
JM
1364 else
1365 {
1366 nread += CountDone;
1367 To += CountDone;
c906108c 1368 }
c5aa993b
JM
1369 }
1370 return (nread);
c906108c
SS
1371}
1372
1373/********************************************************************* WARNING
1374*/
fba45db2 1375udi_warning (int num)
c906108c 1376{
c5aa993b 1377 error ("ERROR while loading program into remote TIP: $d\n", num);
c906108c
SS
1378}
1379
1380
c5aa993b 1381/*****************************************************************************/
c906108c
SS
1382/* Fetch a single register indicatated by 'regno'.
1383 * Returns 0/-1 on success/failure.
1384 */
1385static void
fba45db2 1386fetch_register (int regno)
c906108c 1387{
c5aa993b
JM
1388 UDIResource From;
1389 UDIUInt32 To;
1390 UDICount Count = 1;
1391 UDISizeT Size = 4;
1392 UDICount CountDone;
1393 UDIBool HostEndian = 0;
1394 UDIError err;
1395 int result;
c906108c
SS
1396
1397 if (regno == GR1_REGNUM)
1398 {
1399 From.Space = UDI29KGlobalRegs;
1400 From.Offset = 1;
1401 }
1402 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1403 {
1404 From.Space = UDI29KGlobalRegs;
1405 From.Offset = (regno - GR96_REGNUM) + 96;;
1406 }
1407
1408#if defined(GR64_REGNUM)
1409
c5aa993b 1410 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
c906108c
SS
1411 {
1412 From.Space = UDI29KGlobalRegs;
1413 From.Offset = (regno - GR64_REGNUM) + 64;
1414 }
1415
c5aa993b 1416#endif /* GR64_REGNUM */
c906108c
SS
1417
1418 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1419 {
1420 From.Space = UDI29KLocalRegs;
1421 From.Offset = (regno - LR0_REGNUM);
1422 }
c5aa993b 1423 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
c906108c
SS
1424 {
1425 int val = -1;
c5aa993b
JM
1426 /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */
1427 supply_register (regno, (char *) &val);
1428 return; /* Pretend Success */
c906108c 1429 }
c5aa993b 1430 else
c906108c
SS
1431 {
1432 From.Space = UDI29KSpecialRegs;
c5aa993b 1433 From.Offset = regnum_to_srnum (regno);
c906108c
SS
1434 }
1435
c5aa993b
JM
1436 if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
1437 error ("UDIRead() failed in udi_fetch_registers");
c906108c 1438
c5aa993b 1439 supply_register (regno, (char *) &To);
c906108c
SS
1440
1441 if (remote_debug)
9846de1b
JM
1442 fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
1443 REGISTER_NAME (regno), To);
c906108c 1444}
c5aa993b 1445/*****************************************************************************/
c906108c
SS
1446/* Store a single register indicated by 'regno'.
1447 * Returns 0/-1 on success/failure.
1448 */
1449static int
fba45db2 1450store_register (int regno)
c906108c 1451{
c5aa993b
JM
1452 int result;
1453 UDIUInt32 From;
1454 UDIResource To;
1455 UDICount Count = 1;
1456 UDISizeT Size = 4;
1457 UDICount CountDone;
1458 UDIBool HostEndian = 0;
c906108c 1459
c5aa993b 1460 From = read_register (regno); /* get data value */
c906108c
SS
1461
1462 if (remote_debug)
9846de1b
JM
1463 fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
1464 REGISTER_NAME (regno), From);
c906108c
SS
1465
1466 if (regno == GR1_REGNUM)
1467 {
1468 To.Space = UDI29KGlobalRegs;
1469 To.Offset = 1;
c5aa993b 1470 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
c906108c
SS
1471 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1472 * register cache. Do this *after* calling read_register, because we want
1473 * read_register to return the value that write_register has just stuffed
1474 * into the registers array, not the value of the register fetched from
1475 * the inferior.
1476 */
1477 registers_changed ();
1478 }
1479#if defined(GR64_REGNUM)
c5aa993b 1480 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
c906108c
SS
1481 {
1482 To.Space = UDI29KGlobalRegs;
1483 To.Offset = (regno - GR64_REGNUM) + 64;
c5aa993b 1484 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
c906108c 1485 }
c5aa993b 1486#endif /* GR64_REGNUM */
c906108c
SS
1487 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1488 {
1489 To.Space = UDI29KGlobalRegs;
1490 To.Offset = (regno - GR96_REGNUM) + 96;
c5aa993b 1491 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
c906108c
SS
1492 }
1493 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1494 {
1495 To.Space = UDI29KLocalRegs;
1496 To.Offset = (regno - LR0_REGNUM);
c5aa993b 1497 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
c906108c 1498 }
c5aa993b
JM
1499 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1500 return 0; /* Pretend Success */
c906108c 1501 else if (regno == PC_REGNUM)
c5aa993b 1502 {
c906108c
SS
1503 /* PC1 via UDI29KPC */
1504
1505 To.Space = UDI29KPC;
1506 To.Offset = 0; /* PC1 */
1507 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1508
1509 /* Writing to this loc actually changes the values of pc0 & pc1 */
1510
c5aa993b
JM
1511 register_valid[PC_REGNUM] = 0; /* pc1 */
1512 register_valid[NPC_REGNUM] = 0; /* pc0 */
c906108c 1513 }
c5aa993b
JM
1514 else
1515 /* An unprotected or protected special register */
c906108c
SS
1516 {
1517 To.Space = UDI29KSpecialRegs;
c5aa993b
JM
1518 To.Offset = regnum_to_srnum (regno);
1519 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
c906108c
SS
1520 }
1521
1522 if (result != 0)
c5aa993b 1523 error ("UDIWrite() failed in store_registers");
c906108c
SS
1524
1525 return 0;
1526}
1527/********************************************************** REGNUM_TO_SRNUM */
1528/*
1529 * Convert a gdb special register number to a 29000 special register number.
1530 */
1531static int
fba45db2 1532regnum_to_srnum (int regno)
c906108c 1533{
c5aa993b
JM
1534 switch (regno)
1535 {
1536 case VAB_REGNUM:
1537 return (0);
1538 case OPS_REGNUM:
1539 return (1);
1540 case CPS_REGNUM:
1541 return (2);
1542 case CFG_REGNUM:
1543 return (3);
1544 case CHA_REGNUM:
1545 return (4);
1546 case CHD_REGNUM:
1547 return (5);
1548 case CHC_REGNUM:
1549 return (6);
1550 case RBP_REGNUM:
1551 return (7);
1552 case TMC_REGNUM:
1553 return (8);
1554 case TMR_REGNUM:
1555 return (9);
1556 case NPC_REGNUM:
1557 return (USE_SHADOW_PC ? (20) : (10));
1558 case PC_REGNUM:
1559 return (USE_SHADOW_PC ? (21) : (11));
1560 case PC2_REGNUM:
1561 return (USE_SHADOW_PC ? (22) : (12));
1562 case MMU_REGNUM:
1563 return (13);
1564 case LRU_REGNUM:
1565 return (14);
1566 case IPC_REGNUM:
1567 return (128);
1568 case IPA_REGNUM:
1569 return (129);
1570 case IPB_REGNUM:
1571 return (130);
1572 case Q_REGNUM:
1573 return (131);
1574 case ALU_REGNUM:
1575 return (132);
1576 case BP_REGNUM:
1577 return (133);
1578 case FC_REGNUM:
1579 return (134);
1580 case CR_REGNUM:
1581 return (135);
1582 case FPE_REGNUM:
1583 return (160);
1584 case INTE_REGNUM:
1585 return (161);
1586 case FPS_REGNUM:
1587 return (162);
1588 case EXO_REGNUM:
1589 return (164);
1590 default:
1591 return (255); /* Failure ? */
1592 }
c906108c
SS
1593}
1594/****************************************************************************/
1595/*
1596 * Determine the Target memory space qualifier based on the addr.
1597 * FIXME: Can't distinguis I_ROM/D_ROM.
1598 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1599 */
1600static CPUSpace
fba45db2 1601udi_memory_space (CORE_ADDR addr)
c906108c 1602{
c5aa993b
JM
1603 UDIUInt32 tstart = IMemStart;
1604 UDIUInt32 tend = tstart + IMemSize;
1605 UDIUInt32 dstart = DMemStart;
1606 UDIUInt32 dend = tstart + DMemSize;
1607 UDIUInt32 rstart = RMemStart;
1608 UDIUInt32 rend = tstart + RMemSize;
1609
1610 if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
1611 {
1612 return UDI29KIRAMSpace;
1613 }
1614 else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
1615 {
1616 return UDI29KDRAMSpace;
1617 }
1618 else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
1619 {
1620 /* FIXME: how do we determine between D_ROM and I_ROM */
1621 return UDI29KIROMSpace;
1622 }
1623 else /* FIXME: what do me do now? */
1624 return UDI29KDRAMSpace; /* Hmmm! */
c906108c
SS
1625}
1626/*********************************************************************** STUBS
1627*/
1628
c5aa993b 1629void
fba45db2 1630convert16 (void)
c5aa993b
JM
1631{;
1632}
1633void
fba45db2 1634convert32 (void)
c5aa993b
JM
1635{;
1636}
d9fcf2fb 1637struct ui_file *EchoFile = 0; /* used for debugging */
c5aa993b 1638int QuietMode = 0; /* used for debugging */
c906108c
SS
1639\f
1640#ifdef NO_HIF_SUPPORT
fba45db2 1641service_HIF (union msg_t *msg)
c906108c 1642{
c5aa993b 1643 return (0); /* Emulate a failure */
c906108c
SS
1644}
1645#endif
1646\f
1647/* Target_ops vector. Not static because there does not seem to be
1648 any portable way to do a forward declaration of a static variable.
1649 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1650 /bin/cc doesn't like "static" twice. */
1651
1652struct target_ops udi_ops;
1653
c5aa993b
JM
1654static void
1655init_udi_ops (void)
c906108c 1656{
c5aa993b
JM
1657 udi_ops.to_shortname = "udi";
1658 udi_ops.to_longname = "Remote UDI connected TIP";
1659 udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
c906108c
SS
1660Arguments are\n\
1661`configuration-id AF_INET hostname port-number'\n\
1662To connect via the network, where hostname and port-number specify the\n\
1663host and port where you can connect via UDI.\n\
1664configuration-id is unused.\n\
1665\n\
1666`configuration-id AF_UNIX socket-name tip-program'\n\
1667To connect using a local connection to the \"tip.exe\" program which is\n\
1668 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1669 tip program must already be started; connect to it using that socket.\n\
1670 If not, start up tip-program, which should be the name of the tip\n\
1671 program. If appropriate, the PATH environment variable is searched.\n\
1672 configuration-id is unused.\n\
1673\n\
1674`configuration-id'\n\
1675 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1676 are files containing lines in the above formats. configuration-id is\n\
c5aa993b
JM
1677 used to pick which line of the file to use.";
1678 udi_ops.to_open = udi_open;
1679 udi_ops.to_close = udi_close;
1680 udi_ops.to_attach = udi_attach;
1681 udi_ops.to_detach = udi_detach;
1682 udi_ops.to_resume = udi_resume;
1683 udi_ops.to_wait = udi_wait;
1684 udi_ops.to_fetch_registers = udi_fetch_registers;
1685 udi_ops.to_store_registers = udi_store_registers;
1686 udi_ops.to_prepare_to_store = udi_prepare_to_store;
1687 udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
1688 udi_ops.to_files_info = udi_files_info;
1689 udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
1690 udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
1691 udi_ops.to_terminal_init = 0;
1692 udi_ops.to_terminal_inferior = 0;
1693 udi_ops.to_terminal_ours_for_output = 0;
1694 udi_ops.to_terminal_ours = 0;
1695 udi_ops.to_terminal_info = 0;
1696 udi_ops.to_kill = udi_kill;
1697 udi_ops.to_load = udi_load;
1698 udi_ops.to_lookup_symbol = 0;
1699 udi_ops.to_create_inferior = udi_create_inferior;
1700 udi_ops.to_mourn_inferior = udi_mourn;
1701 udi_ops.to_can_run = 0;
1702 udi_ops.to_notice_signals = 0;
1703 udi_ops.to_thread_alive = 0;
1704 udi_ops.to_stop = 0;
1705 udi_ops.to_stratum = process_stratum;
1706 udi_ops.DONT_USE = 0;
1707 udi_ops.to_has_all_memory = 1;
1708 udi_ops.to_has_memory = 1;
1709 udi_ops.to_has_stack = 1;
1710 udi_ops.to_has_registers = 1;
1711 udi_ops.to_has_execution = 1;
1712 udi_ops.to_sections = 0;
1713 udi_ops.to_sections_end = 0;
1714 udi_ops.to_magic = OPS_MAGIC;
c906108c
SS
1715};
1716
1717void
fba45db2 1718_initialize_remote_udi (void)
c906108c 1719{
c5aa993b 1720 init_udi_ops ();
c906108c
SS
1721 add_target (&udi_ops);
1722}
This page took 0.236484 seconds and 4 git commands to generate.