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