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