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