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