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