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