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