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