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