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