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