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