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