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