* coffread.c (decode_type): Call alloc_type to alloc new
[deliverable/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. Because we are only attempting to
31 use this module to debug our kernel, which is already loaded when
32 gdb is started up, I did not code up the file downloading facilities.
33 As a result this module has only the stubs to download files.
34 You should get tagged at compile time if you need to make any
35 changes/additions.
36 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
37 MiniMON interface with UDI-p interface. */
38
39 #include "defs.h"
40 #include "inferior.h"
41 #include "wait.h"
42 #include "value.h"
43 #include <ctype.h>
44 #include <fcntl.h>
45 #include <signal.h>
46 #include <errno.h>
47 #include <string.h>
48 #include "terminal.h"
49 #include "target.h"
50 #include "29k-share/udi/udiproc.h"
51
52 /* access the register store directly, without going through
53 the normal handler functions. This avoids an extra data copy
54 */
55
56 /* #define DEBUG 1 /* */
57 #ifdef DEBUG
58 # define DENTER(NAME) (printf("Entering %s\n",NAME), fflush(stdout))
59 # define DEXIT(NAME) (printf("Exiting %s\n",NAME), fflush(stdout))
60 #else
61 # define DENTER(NAME)
62 # define DEXIT(NAME)
63 #endif
64
65
66 extern int stop_soon_quietly; /* for wait_for_inferior */
67 extern struct value *call_function_by_hand();
68 static void udi_resume();
69 static void udi_fetch_registers ();
70 static void udi_load();
71 static int fetch_register ();
72 static void udi_store_registers ();
73 static int store_register ();
74 static int regnum_to_srnum();
75 static void udi_close ();
76 static CPUSpace udi_memory_space();
77 static int udi_write_inferior_memory();
78 static int udi_read_inferior_memory();
79 char CoffFileName[100] = "";
80 /*
81 * Processor types.
82 */
83 #define TYPE_UNKNOWN 0
84 #define TYPE_A29000 1
85 #define TYPE_A29030 2
86 #define TYPE_A29050 3
87 static char *processor_name[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
88 static int processor_type=TYPE_UNKNOWN;
89 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
90 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
91
92 #define LLOG_FILE "udi.log"
93 #if defined (LOG_FILE)
94 FILE *log_file;
95 #endif
96
97 static int timeout = 5;
98 extern struct target_ops udi_ops; /* Forward declaration */
99
100 /* Special register enumeration.
101 */
102
103 /******************************************************************* UDI DATA*/
104 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
105 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
106 udi_open knows that we don't have a file open when the program
107 starts. */
108 UDISessionId udi_session_id = -1;
109
110 CPUOffset IMemStart = 0;
111 CPUSizeT IMemSize = 0;
112 CPUOffset DMemStart = 0;
113 CPUSizeT DMemSize = 0;
114 CPUOffset RMemStart = 0;
115 CPUSizeT RMemSize = 0;
116 UDIUInt32 CPUPRL;
117 UDIUInt32 CoProcPRL;
118
119 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
120 char sbuf[SBUF_MAX];
121
122 typedef struct bkpt_entry_str
123 {
124 UDIResource Addr;
125 UDIUInt32 PassCount;
126 UDIBreakType Type;
127 unsigned int BreakId;
128 } bkpt_entry_t;
129 #define BKPT_TABLE_SIZE 40
130 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
131 extern char dfe_errmsg[]; /* error string */
132
133 /*********************************************************** SIGNAL SUPPORT */
134 /* Called when SIGALRM signal sent due to alarm() timeout. */
135 #ifndef HAVE_TERMIO
136
137 #ifndef __STDC__
138 # ifndef volatile
139 # define volatile /**/
140 # endif
141 #endif
142 volatile int n_alarms;
143
144 static void
145 udi_timer ()
146 {
147 #if 0
148 if (kiodebug)
149 printf ("udi_timer called\n");
150 #endif
151 n_alarms++;
152 }
153 #endif /* HAVE_TERMIO */
154
155 /* malloc'd name of the program on the remote system. */
156 static char *prog_name = NULL;
157
158
159 /* Number of SIGTRAPs we need to simulate. That is, the next
160 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
161 SIGTRAP without actually waiting for anything. */
162
163 /******************************************************* UDI_CREATE_INFERIOR */
164 /* This is called not only when we first attach, but also when the
165 user types "run" after having attached. */
166 static void
167 udi_create_inferior (execfile, args, env)
168 char *execfile;
169 char *args;
170 char **env;
171 {
172 DENTER("udi_create_inferior()");
173
174 if (execfile)
175 { if (prog_name != NULL)
176 free (prog_name);
177 prog_name = savestring (execfile, strlen (execfile));
178 }
179
180 if (prog_name == 0 /* || exec_bfd == 0 */ )
181 error ("No exec file specified");
182
183 if (udi_session_id < 0){
184 printf("UDI connection not open yet.\n");
185 return;
186 }
187
188 inferior_pid = 40000;
189
190 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
191 /* On ultra3 (NYU) we assume the kernel is already running so there is
192 * no file to download
193 */
194 #else
195 if(*args == '\0') args = prog_name;
196 udi_load(args, 0);
197 #endif /* !ULTRA3 */
198
199 /* We will get a task spawn event immediately. */
200 #ifdef NOTDEF /* start_remote() now does a wait without a resume
201 so don't use it*/
202 start_remote ();
203 #else
204 init_wait_for_inferior ();
205 clear_proceed_status ();
206 proceed(-1,-1,0);
207 #endif
208 DEXIT("udi_create_inferior()");
209 }
210 /******************************************************* UDI_MOURN_INFERIOR */
211 static void
212 udi_mourn()
213 {
214 DENTER("udi_mourn()");
215 pop_target (); /* Pop back to no-child state */
216 generic_mourn_inferior ();
217 DEXIT("udi_mourn()");
218 }
219
220 /******************************************************************** UDI_OPEN
221 ** Open a connection to remote TIP.
222 NAME is the socket domain used for communication with the TIP,
223 then a space and the socket name or TIP-host name.
224 '<udi_udi_config_id> [progname]' for example.
225 */
226
227 /* XXX - need cleanups for udiconnect for various failures!!! */
228
229 static char *udi_config_id;
230 static void
231 udi_open (name, from_tty)
232 char *name;
233 int from_tty;
234 {
235 unsigned int prl;
236 char *p;
237 int cnt;
238 UDIMemoryRange KnownMemory[10];
239 UDIUInt32 ChipVersions[10];
240 UDIInt NumberOfRanges = 10;
241 UDIInt NumberOfChips = 10;
242 UDIPId PId;
243 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
244
245 DENTER("udi_open()");
246
247 target_preopen(from_tty);
248
249 /* Find the first whitespace character, it separates udi_config_id
250 from prog_name. */
251 if(!name) goto erroid;
252 for (p = name;
253 *p != '\0' && !isspace (*p); p++)
254 ;
255 if (*p == '\0')
256 erroid:
257 error("Usage: target udi config_id progname, where config_id appears in udi_soc file");
258
259 udi_config_id = (char*)malloc (p - name + 1);
260 strncpy (udi_config_id, name, p - name);
261 udi_config_id[p - name] = '\0';
262
263 /* Skip over the whitespace after udi_config_id */
264 for (; isspace (*p); p++)
265 /*EMPTY*/;
266
267 if (prog_name != NULL)
268 free (prog_name);
269 prog_name = savestring (p, strlen (p));
270
271 if (UDIConnect(udi_config_id, &udi_session_id))
272 error("UDIConnect() failed: %s\n", dfe_errmsg);
273
274 push_target (&udi_ops);
275
276 #ifndef HAVE_TERMIO
277 #ifndef NO_SIGINTERRUPT
278 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
279 the read. */
280 if (siginterrupt (SIGALRM, 1) != 0)
281 error ("udi_open: siginterrupt() %s", safe_strerror(errno));
282 #endif
283
284 /* Set up read timeout timer. */
285 if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1)
286 error ("udi_open: signal() %s", safe_strerror(errno));
287 #endif
288
289 #if defined (LOG_FILE)
290 log_file = fopen (LOG_FILE, "w");
291 if (log_file == NULL)
292 error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno));
293 #endif
294 /*
295 ** Initialize target configuration structure (global)
296 */
297 if(UDIGetTargetConfig( KnownMemory, &NumberOfRanges,
298 ChipVersions, &NumberOfChips))
299 error ("UDIGetTargetConfig() failed");
300 if(NumberOfChips > 2)
301 fprintf(stderr,"Taret has more than one processor\n");
302 for(cnt=0; cnt<NumberOfRanges; cnt++)
303 { switch(KnownMemory[cnt].Space)
304 {
305 default: fprintf(stderr, "UDIGetTargetConfig() unknown memory space\n");
306 break;
307 case UDI29KCP_S:
308 break;
309 case UDI29KIROMSpace:
310 RMemStart = KnownMemory[cnt].Offset;
311 RMemSize = KnownMemory[cnt].Size;
312 break;
313 case UDI29KIRAMSpace:
314 IMemStart = KnownMemory[cnt].Offset;
315 IMemSize = KnownMemory[cnt].Size;
316 break;
317 case UDI29KDRAMSpace:
318 DMemStart = KnownMemory[cnt].Offset;
319 DMemSize = KnownMemory[cnt].Size;
320 break;
321 }
322 }
323
324 /* Determine the processor revision level */
325 prl = (unsigned int)read_register(CFG_REGNUM) >> 24;
326 if ((prl&0xe0) == 0)
327 { fprintf_filtered(stderr,
328 "Remote debugging Am29000 rev %c\n",'A'+(prl&0x1f));
329 processor_type = TYPE_A29000;
330 } else if ((prl&0xe0) == 0x40) /* 29030 = 0x4* */
331 { fprintf_filtered(stderr,
332 "Remote debugging Am2903* rev %c\n",'A'+(prl&0x1f));
333 processor_type = TYPE_A29030;
334 } else if ((prl&0xe0) == 0x20) /* 29050 = 0x2* */
335 { fprintf_filtered(stderr,
336 "Remote debugging Am29050 rev %c\n",'A'+(prl&0x1f));
337 processor_type = TYPE_A29050;
338 } else {
339 processor_type = TYPE_UNKNOWN;
340 fprintf_filtered(stderr,"WARNING: processor type unknown.\n");
341 }
342 if(UDICreateProcess(&PId))
343 fprintf(stderr, "UDICreateProcess() failed\n");
344
345 /* Print out some stuff, letting the user now what's going on */
346 if(UDICapabilities( &TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
347 &TIPIPCId, sbuf))
348 error ("UDICapabilities() failed");
349 if (from_tty) {
350 printf_filtered("Remote debugging an %s connected via UDI socket,\n\
351 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
352 processor_name[processor_type],
353 (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
354 (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
355 (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
356 sbuf);
357 #ifdef ULTRA3
358 /* FIXME: can this restriction be removed? */
359 printf_filtered("Remote debugging using virtual addresses works only\n");
360 printf_filtered(" when virtual addresses map 1:1 to physical addresses.\n");
361 #endif
362 }
363 #ifdef ULTRA3
364 if (processor_type != TYPE_A29050) {
365 fprintf_filtered(stderr,
366 "Freeze-mode debugging can only be done on an Am29050,\n");
367 fprintf_filtered(stderr,
368 " unless GDB is being used with a 29K simulator.\n");
369 }
370 #endif
371 }
372
373 /******************************************************************* UDI_CLOSE
374 Close the open connection to the TIP process.
375 Use this when you want to detach and do something else
376 with your gdb. */
377 static void
378 udi_close (quitting) /*FIXME: how is quitting used */
379 int quitting;
380 {
381 int Terminate = -1;
382 DENTER("udi_close()");
383
384 if (udi_session_id < 0)
385 error ("Can't close udi connection: not debugging remotely.");
386
387 /* We should never get here if there isn't something valid in
388 udi_session_id.
389
390 if(UDIDisconnect(udi_stream, Terminate);)
391 error ("UDIDisconnect() failed in udi_close");
392
393 /* Do not try to close udi_session_id again, later in the program. */
394 udi_session_id = -1;
395 inferior_pid = 0;
396
397 #if defined (LOG_FILE)
398 if (ferror (log_file))
399 printf ("Error writing log file.\n");
400 if (fclose (log_file) != 0)
401 printf ("Error closing log file.\n");
402 #endif
403
404 printf_filtered (" Ending remote debugging\n");
405
406 DEXIT("udi_close()");
407 }
408
409 /**************************************************************** UDI_ATACH */
410 /* Attach to a program that is already loaded and running
411 * Upon exiting the process's execution is stopped.
412 */
413 static void
414 udi_attach (args, from_tty)
415 char *args;
416 int from_tty;
417 {
418 UDIResource From;
419 UDIInt32 PC_adds;
420 UDICount Count = 1;
421 UDISizeT Size = 4;
422 UDICount CountDone;
423 UDIBool HostEndian = 0;
424 DENTER("udi_attach()");
425
426 if (udi_session_id < 0)
427 printf ("UDI connection not opened yet, use the 'target udi' command.\n");
428
429 if (from_tty)
430 printf ("Attaching to remote program %s...\n", prog_name);
431
432 mark_breakpoints_out ();
433 UDIStop();
434 From.Space = 11;
435 From.Offset = UDI29KSpecialRegs;
436 if(UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
437 error ("UDIRead failed in udi_attach");
438 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
439
440 DEXIT("udi_attach()");
441 }
442 /************************************************************* UDI_DETACH */
443 /* Terminate the open connection to the TIP process.
444 Use this when you want to detach and do something else
445 with your gdb. Leave remote process running (with no breakpoints set). */
446 static void
447 udi_detach (args,from_tty)
448 char *args;
449 int from_tty;
450 {
451 DENTER("udi_dettach()");
452 remove_breakpoints(); /* Just in case there were any left in */
453 if(UDIDisconnect(udi_session_id))
454 error ("UDIDisconnect() failed in udi_detach");
455 pop_target(); /* calls udi_close to do the real work */
456 if (from_tty)
457 printf ("Ending remote debugging\n");
458 DEXIT("udi_dettach()");
459 }
460
461
462 /****************************************************************** UDI_RESUME
463 ** Tell the remote machine to resume. */
464
465 static void
466 udi_resume (step, sig)
467 int step, sig;
468 {
469 UDIError tip_error;
470 UDIUInt32 Steps = 1;
471 UDIStepType StepType = UDIStepNatural;
472 UDIRange Range;
473 DENTER("udi_resume()");
474 if (step) /* step 1 instruction */
475 { tip_error = tip_error = UDIStep(Steps, StepType, Range);
476 if(tip_error)fprintf(stderr, "UDIStep() error = %d\n", tip_error);
477 if(tip_error)error ("failed in udi_resume");
478
479 }
480 else
481 { if(UDIExecute())
482 error ("UDIExecute() failed in udi_resume");
483 }
484
485 DEXIT("udi_resume()");
486 }
487
488 /******************************************************************** UDI_WAIT
489 ** Wait until the remote machine stops, then return,
490 storing status in STATUS just as `wait' would. */
491
492 static int
493 udi_wait (status)
494 WAITTYPE *status;
495 {
496 UDIInt32 MaxTime;
497 UDIPId PId;
498 UDIInt32 StopReason;
499 UDISizeT CountDone;
500 int old_timeout = timeout;
501 int old_immediate_quit = immediate_quit;
502 int i;
503
504 DENTER("udi_wait()");
505 WSETEXIT ((*status), 0);
506
507 /* wait for message to arrive. It should be:
508 If the target stops executing, udi_wait() should return.
509 */
510 timeout = 0; /* Wait indefinetly for a message */
511 immediate_quit = 1; /* Helps ability to QUIT */
512 while(1)
513 {
514 i = 0;
515 MaxTime = UDIWaitForever;
516 UDIWait(MaxTime, &PId, &StopReason);
517 QUIT; /* Let user quit if they want */
518 switch (StopReason & 0xff)
519 {
520 default:
521 goto halted;
522 case UDIStdoutReady:
523 if(UDIGetStdout(sbuf, (UDISizeT)SBUF_MAX, &CountDone))
524 error("UDIGetStdin() failed in udi_wait");
525 while(CountDone--)putc(sbuf[i++], stdout);
526 fflush(stdout);
527 break;
528 case UDIStderrReady:
529 UDIGetStderr(sbuf, (UDISizeT)SBUF_MAX, &CountDone);
530 while(CountDone--)putc(sbuf[i++], stderr);
531 fflush(stderr);
532 fflush(stderr);
533 break;
534 case UDIStdinNeeded:
535 printf("DEBUG: stdin requested ... continue\n");
536 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
537 break;
538 case UDIStdinModeX:
539 break;
540 }
541 continue;
542 }
543 halted:
544 if (StopReason & 0xff == UDITrapped ) /* lower 8-bits == 0 */
545 {
546 if (StopReason >> 24 == 0)
547 { printf("Am290*0 received vector number 0 (break point)\n");
548 WSETSTOP ((*status), SIGTRAP);
549 }
550 else if (StopReason >> 24 == 1)
551 { printf("Am290*0 received vector 1\n");
552 WSETSTOP ((*status), SIGBUS);
553 }
554 else if (StopReason >> 24 == 3
555 || StopReason >> 24 == 4)
556 { printf("Am290*0 received vector number %d\n",
557 StopReason >> 24);
558 WSETSTOP ((*status), SIGFPE);
559 }
560 else if (StopReason >> 24 == 5)
561 { printf("Am290*0 received vector number %d\n",
562 StopReason >> 24);
563 WSETSTOP ((*status), SIGILL);
564 }
565 else if (StopReason >> 24 >= 6
566 && StopReason >> 24 <= 11)
567 { printf("Am290*0 received vector number %d\n",
568 StopReason >> 24);
569 WSETSTOP ((*status), SIGSEGV);
570 }
571 else if (StopReason >> 24 == 12
572 || StopReason >> 24 == 13)
573 { printf("Am290*0 received vector number %d\n",
574 StopReason >> 24);
575 WSETSTOP ((*status), SIGILL);
576 }
577 else if ((StopReason & 0xff) == 14)
578 { printf("Am290*0 received vector number %d\n",
579 StopReason >> 24);
580 WSETSTOP ((*status), SIGALRM);
581 }
582 else if ((StopReason & 0xff) == 15)
583 WSETSTOP ((*status), SIGTRAP);
584 else if ((StopReason >> 24) >= 16
585 && (StopReason >> 24) <= 21)
586 { printf("Am290*0 received vector number %d\n",
587 StopReason >> 24);
588 WSETSTOP ((*status), SIGINT);
589 }
590 else if ((StopReason & 0xff) == 22)
591 { printf("Am290*0 received vector number %d\n",
592 StopReason >> 24);
593 WSETSTOP ((*status), SIGILL);
594 }
595 else if ((StopReason & 0xff) == 77)
596 WSETSTOP ((*status), SIGTRAP);
597 else
598 exit:
599 WSETEXIT ((*status), 0);
600 }
601 else if ((StopReason & 0xff) == UDIBreak)
602 WSETSTOP ((*status), SIGTRAP);
603 else if ((StopReason & 0xff) == UDINotExecuting)
604 WSETSTOP ((*status), SIGTERM);
605 else if ((StopReason & 0xff) == UDIRunning)
606 WSETSTOP ((*status), SIGILL);
607 else if ((StopReason & 0xff) == UDIStopped)
608 WSETSTOP ((*status), SIGTSTP);
609 else if ((StopReason & 0xff) == UDIWarned)
610 WSETSTOP ((*status), SIGLOST);
611 else if ((StopReason & 0xff) == UDIStepped)
612 WSETSTOP ((*status), SIGTRAP);
613 else if ((StopReason & 0xff) == UDIWaiting)
614 WSETSTOP ((*status), SIGSTOP);
615 else if ((StopReason & 0xff) == UDIHalted)
616 WSETSTOP ((*status), SIGKILL);
617 else
618 WSETEXIT ((*status), 0);
619
620 timeout = old_timeout; /* Restore original timeout value */
621 immediate_quit = old_immediate_quit;
622 DEXIT("udi_wait()");
623 return 0;
624 }
625
626 /********************************************************** UDI_FETCH_REGISTERS
627 * Read a remote register 'regno'.
628 * If regno==-1 then read all the registers.
629 */
630 static void
631 udi_fetch_registers (regno)
632 int regno;
633 {
634 UDIResource From;
635 UDIUInt32 *To;
636 UDICount Count;
637 UDISizeT Size = 4;
638 UDICount CountDone;
639 UDIBool HostEndian = 0;
640 int i;
641
642 if (regno >= 0) {
643 fetch_register(regno);
644 return;
645 }
646
647 /* Gr1/rsp */
648
649 From.Space = UDI29KGlobalRegs;
650 From.Offset = 1;
651 To = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
652 Count = 1;
653 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
654 error("UDIRead() failed in udi_fetch_registers");
655
656 register_valid[GR1_REGNUM] = 1;
657
658 #if defined(GR64_REGNUM) /* Read gr64-127 */
659
660 /* Global Registers gr64-gr95 */
661
662 From.Space = UDI29KGlobalRegs;
663 From.Offset = 64;
664 To = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
665 Count = 32;
666 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
667 error("UDIRead() failed in udi_fetch_registers");
668
669 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
670 register_valid[i] = 1;
671
672 #endif /* GR64_REGNUM */
673
674 /* Global Registers gr96-gr127 */
675
676 From.Space = UDI29KGlobalRegs;
677 From.Offset = 96;
678 To = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
679 Count = 32;
680 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
681 error("UDIRead() failed in udi_fetch_registers");
682
683 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
684 register_valid[i] = 1;
685
686 /* Local Registers */
687
688 From.Space = UDI29KLocalRegs;
689 From.Offset = 0;
690 To = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
691 Count = 128;
692 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
693 error("UDIRead() failed in udi_fetch_registers");
694
695 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
696 register_valid[i] = 1;
697
698 /* Protected Special Registers */
699
700 From.Space = UDI29KSpecialRegs;
701 From.Offset = 0;
702 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
703 Count = 15;
704 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
705 error("UDIRead() failed in udi_fetch_registers");
706
707 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
708 register_valid[i] = 1;
709
710 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
711 fetch_register(NPC_REGNUM);
712 fetch_register(PC_REGNUM);
713 fetch_register(PC2_REGNUM);
714
715 /* Unprotected Special Registers sr128-sr135 */
716
717 From.Space = UDI29KSpecialRegs;
718 From.Offset = 128;
719 To = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
720 Count = 135-128 + 1;
721 if (UDIRead(From, To, Count, Size, &CountDone, HostEndian))
722 error("UDIRead() failed in udi_fetch_registers");
723
724 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
725 register_valid[i] = 1;
726 }
727
728 /* There doesn't seem to be any way to get these. */
729 {
730 int val = -1;
731 supply_register (FPE_REGNUM, (char *) &val);
732 supply_register (INTE_REGNUM, (char *) &val);
733 supply_register (FPS_REGNUM, (char *) &val);
734 supply_register (EXO_REGNUM, (char *) &val);
735 }
736 }
737
738
739 /********************************************************* UDI_STORE_REGISTERS
740 ** Store register regno into the target.
741 * If regno==-1 then store all the registers.
742 */
743
744 static void
745 udi_store_registers (regno)
746 int regno;
747 {
748 UDIUInt32 *From;
749 UDIResource To;
750 UDICount Count;
751 UDISizeT Size = 4;
752 UDICount CountDone;
753 UDIBool HostEndian = 0;
754
755 if (regno >= 0)
756 {
757 store_register(regno);
758 return;
759 }
760
761 /* Gr1/rsp */
762
763 From = (UDIUInt32 *)&registers[4 * GR1_REGNUM];
764 To.Space = UDI29KGlobalRegs;
765 To.Offset = 1;
766 Count = 1;
767 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
768 error("UDIWrite() failed in udi_store_regisetrs");
769
770 #if defined(GR64_REGNUM)
771
772 /* Global registers gr64-gr95 */
773
774 From = (UDIUInt32 *)&registers[4 * GR64_REGNUM];
775 To.Space = UDI29KGlobalRegs;
776 To.Offset = 64;
777 Count = 32;
778 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
779 error("UDIWrite() failed in udi_store_regisetrs");
780
781 #endif /* GR64_REGNUM */
782
783 /* Global registers gr96-gr127 */
784
785 From = (UDIUInt32 *)&registers[4 * GR96_REGNUM];
786 To.Space = UDI29KGlobalRegs;
787 To.Offset = 96;
788 Count = 32;
789 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
790 error("UDIWrite() failed in udi_store_regisetrs");
791
792 /* Local Registers */
793
794 From = (UDIUInt32 *)&registers[4 * LR0_REGNUM];
795 To.Space = UDI29KLocalRegs;
796 To.Offset = 0;
797 Count = 128;
798 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
799 error("UDIWrite() failed in udi_store_regisetrs");
800
801
802 /* Protected Special Registers */ /* VAB through TMR */
803
804 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(0)];
805 To.Space = UDI29KSpecialRegs;
806 To.Offset = 0;
807 Count = 10;
808 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
809 error("UDIWrite() failed in udi_store_regisetrs");
810
811 /* PC0, PC1, PC2 possibly as shadow registers */
812
813 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(10)];
814 To.Space = UDI29KSpecialRegs;
815 Count = 3;
816 if (USE_SHADOW_PC)
817 To.Offset = 20; /* SPC0 */
818 else
819 To.Offset = 10; /* PC0 */
820 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
821 error("UDIWrite() failed in udi_store_regisetrs");
822
823 /* LRU and MMU */
824
825 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(13)];
826 To.Space = UDI29KSpecialRegs;
827 To.Offset = 13;
828 Count = 2;
829 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
830 error("UDIWrite() failed in udi_store_regisetrs");
831
832 /* Unprotected Special Registers */
833
834 From = (UDIUInt32 *)&registers[4 * SR_REGNUM(128)];
835 To.Space = UDI29KSpecialRegs;
836 To.Offset = 128;
837 Count = 135-128 +1;
838 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
839 error("UDIWrite() failed in udi_store_regisetrs");
840
841 registers_changed ();
842 }
843
844 /****************************************************** UDI_PREPARE_TO_STORE */
845 /* Get ready to modify the registers array. On machines which store
846 individual registers, this doesn't need to do anything. On machines
847 which store all the registers in one fell swoop, this makes sure
848 that registers contains all the registers from the program being
849 debugged. */
850
851 static void
852 udi_prepare_to_store ()
853 {
854 /* Do nothing, since we can store individual regs */
855 }
856
857 /********************************************************** TRANSLATE_ADDR */
858 static CORE_ADDR
859 translate_addr(addr)
860 CORE_ADDR addr;
861 {
862 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
863 /* Check for a virtual address in the kernel */
864 /* Assume physical address of ublock is in paddr_u register */
865 /* FIXME: doesn't work for user virtual addresses */
866 if (addr >= UVADDR) {
867 /* PADDR_U register holds the physical address of the ublock */
868 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
869 return(i + addr - (CORE_ADDR)UVADDR);
870 } else {
871 return(addr);
872 }
873 #else
874 return(addr);
875 #endif
876 }
877 /************************************************* UDI_XFER_INFERIOR_MEMORY */
878 /* FIXME! Merge these two. */
879 static int
880 udi_xfer_inferior_memory (memaddr, myaddr, len, write)
881 CORE_ADDR memaddr;
882 char *myaddr;
883 int len;
884 int write;
885 {
886
887 memaddr = translate_addr(memaddr);
888
889 if (write)
890 return udi_write_inferior_memory (memaddr, myaddr, len);
891 else
892 return udi_read_inferior_memory (memaddr, myaddr, len);
893 }
894
895 /********************************************************** UDI_FILES_INFO */
896 static void
897 udi_files_info ()
898 {
899 printf ("\tAttached to UDI socket to %s and running program %s.\n",
900 udi_config_id, prog_name);
901 }
902
903 /**************************************************** UDI_INSERT_BREAKPOINT */
904 static int
905 udi_insert_breakpoint (addr, contents_cache)
906 CORE_ADDR addr;
907 char *contents_cache;
908 {
909 int cnt;
910 UDIError err;
911
912 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
913 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
914 break;
915
916 if(cnt >= BKPT_TABLE_SIZE)
917 error("Too many breakpoints set");
918
919 bkpt_table[cnt].Addr.Offset = addr;
920 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
921 bkpt_table[cnt].PassCount = 1;
922 bkpt_table[cnt].Type = UDIBreakFlagExecute;
923
924 err = UDISetBreakpoint(bkpt_table[cnt].Addr,
925 bkpt_table[cnt].PassCount,
926 bkpt_table[cnt].Type,
927 &bkpt_table[cnt].BreakId);
928
929 if (err == 0) return 0; /* Success */
930
931 bkpt_table[cnt].Type = 0;
932 error("UDISetBreakpoint returned error code %d\n", err);
933 }
934
935 /**************************************************** UDI_REMOVE_BREAKPOINT */
936 static int
937 udi_remove_breakpoint (addr, contents_cache)
938 CORE_ADDR addr;
939 char *contents_cache;
940 {
941 int cnt;
942 UDIError err;
943
944 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
945 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
946 break;
947
948 if(cnt >= BKPT_TABLE_SIZE)
949 error("Can't find breakpoint in table");
950
951 bkpt_table[cnt].Type = 0;
952
953 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
954 if (err == 0) return 0; /* Success */
955
956 error("UDIClearBreakpoint returned error code %d\n", err);
957 }
958
959 /***************************************************************** UDI_KILL */
960 static void
961 udi_kill(arg,from_tty)
962 char *arg;
963 int from_tty;
964 {
965 char buf[4];
966
967 DENTER("udi_kill()");
968 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
969 /* We don't ever kill the kernel */
970 if (from_tty) {
971 printf_filtered("Kernel not killed, but left in current state.\n");
972 printf_filtered("Use detach to leave kernel running.\n");
973 }
974 #else
975 UDIStop();
976 inferior_pid = 0;
977 if (from_tty) {
978 printf("Target has been stopped.");
979 }
980 pop_target();
981 #endif
982 DEXIT("udi_kill()");
983 }
984
985
986
987 /***************************************************************** UDI_LOAD */
988 /*
989 * Load a program into the target.
990 */
991 static void
992 udi_load(arg_string,from_tty)
993 char *arg_string;
994 int from_tty;
995 {
996 #define MAX_TOKENS 25
997 #define BUFFER_SIZE 256
998 int token_count;
999 char *token[MAX_TOKENS];
1000 char cmd_line[BUFFER_SIZE];
1001
1002 dont_repeat ();
1003
1004 #if defined(KERNEL_DEBUGGING) && defined(ULTRA3)
1005 printf("The kernel had better be loaded already! Loading not done.\n");
1006 #else
1007 if (arg_string == 0)
1008 error ("The load command takes a file name");
1009 arg_string = tilde_expand (arg_string);
1010 sprintf(cmd_line,"y %s %s", prog_name, arg_string);
1011
1012 token_count = 0;
1013 token[0] = cmd_line;
1014
1015 if (cmd_line[0] != '\0')
1016 { token[token_count] = strtok(cmd_line, " \t,;\n\r");
1017
1018 if (token[token_count] != NULL)
1019 { do {
1020 token_count = token_count + 1;
1021 token[token_count] = strtok((char *) NULL, " \t,;\n\r");
1022 } while ((token[token_count] != NULL) &&
1023 (token_count < MAX_TOKENS));
1024 }
1025 else
1026 *token[0] = '\0';
1027 }
1028 make_cleanup (free, arg_string);
1029 QUIT;
1030 immediate_quit++;
1031 if(yank_cmd(token, token_count))
1032 error("Failure when tring to load program");
1033 immediate_quit--;
1034 symbol_file_add (arg_string, from_tty, 0, 0, 0, 0);/*DEBUG need to add text_addr */
1035 #endif
1036
1037 }
1038
1039 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1040 ** Copy LEN bytes of data from debugger memory at MYADDR
1041 to inferior's memory at MEMADDR. Returns number of bytes written. */
1042 static int
1043 udi_write_inferior_memory (memaddr, myaddr, len)
1044 CORE_ADDR memaddr;
1045 char *myaddr;
1046 int len;
1047 {
1048 int nwritten = 0;
1049 UDIUInt32 *From;
1050 UDIResource To;
1051 UDICount Count;
1052 UDISizeT Size = 1;
1053 UDICount CountDone = 0;
1054 UDIBool HostEndian = 0;
1055
1056
1057 /* DENTER("udi_write_inferior_memory()"); */
1058 To.Space = udi_memory_space(memaddr);
1059 From = (UDIUInt32*)myaddr;
1060
1061 while (nwritten < len)
1062 { Count = len - nwritten;
1063 if (Count > MAXDATA) Count = MAXDATA;
1064 To.Offset = memaddr + nwritten;
1065 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1066 { error("UDIWrite() failed in udi_write_inferrior_memory");
1067 break;
1068 }
1069 else
1070 { nwritten += CountDone;
1071 From += CountDone;
1072 }
1073 }
1074 /* DEXIT("udi_write_inferior_memory()"); */
1075 return(nwritten);
1076 }
1077
1078 /**************************************************** UDI_READ_INFERIOR_MEMORY
1079 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1080 at debugger address MYADDR. Returns number of bytes read. */
1081 static int
1082 udi_read_inferior_memory(memaddr, myaddr, len)
1083 CORE_ADDR memaddr;
1084 char *myaddr;
1085 int len;
1086 {
1087 int nread = 0;
1088 UDIResource From;
1089 UDIUInt32 *To;
1090 UDICount Count;
1091 UDISizeT Size = 1;
1092 UDICount CountDone = 0;
1093 UDIBool HostEndian = 0;
1094
1095
1096 /* DENTER("udi_read_inferior_memory()"); */
1097 From.Space = udi_memory_space(memaddr);
1098 To = (UDIUInt32*)myaddr;
1099
1100 while (nread < len)
1101 { Count = len - nread;
1102 if (Count > MAXDATA) Count = MAXDATA;
1103 From.Offset = memaddr + nread;
1104 if(UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1105 { error("UDIWrite() failed in udi_read_inferrior_memory");
1106 break;
1107 }
1108 else
1109 { nread += CountDone;
1110 To += CountDone;
1111 }
1112 }
1113 return(nread);
1114 }
1115
1116 /********************************************************************* WARNING
1117 */
1118 udi_warning(num)
1119 int num;
1120 {
1121 error ("ERROR while loading program into remote TIP: $d\n", num);
1122 }
1123
1124
1125 /*****************************************************************************/
1126 /* Fetch a single register indicatated by 'regno'.
1127 * Returns 0/-1 on success/failure.
1128 */
1129 static int
1130 fetch_register (regno)
1131 int regno;
1132 {
1133 UDIResource From;
1134 UDIUInt32 To;
1135 UDICount Count = 1;
1136 UDISizeT Size = 4;
1137 UDICount CountDone;
1138 UDIBool HostEndian = 0;
1139 int result;
1140
1141 if (regno == GR1_REGNUM)
1142 {
1143 From.Space = UDI29KGlobalRegs;
1144 From.Offset = 1;
1145 }
1146 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1147 {
1148 From.Space = UDI29KGlobalRegs;
1149 From.Offset = (regno - GR96_REGNUM) + 96;;
1150 }
1151
1152 #if defined(GR64_REGNUM)
1153
1154 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1155 {
1156 From.Space = UDI29KGlobalRegs;
1157 From.Offset = (regno - GR64_REGNUM) + 64;
1158 }
1159
1160 #endif /* GR64_REGNUM */
1161
1162 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1163 {
1164 From.Space = UDI29KLocalRegs;
1165 From.Offset = (regno - LR0_REGNUM);
1166 }
1167 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1168 {
1169 int val = -1;
1170 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
1171 return 0; /* Pretend Success */
1172 }
1173 else
1174 {
1175 From.Space = UDI29KSpecialRegs;
1176 From.Offset = regnum_to_srnum(regno);
1177 }
1178
1179 if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
1180 error("UDIRead() failed in udi_fetch_registers");
1181
1182 supply_register(regno, (char *) &To);
1183 return result;
1184 }
1185 /*****************************************************************************/
1186 /* Store a single register indicated by 'regno'.
1187 * Returns 0/-1 on success/failure.
1188 */
1189 static int
1190 store_register (regno)
1191 int regno;
1192 {
1193 int result;
1194 UDIUInt32 From;
1195 UDIResource To;
1196 UDICount Count = 1;
1197 UDISizeT Size = 4;
1198 UDICount CountDone;
1199 UDIBool HostEndian = 0;
1200
1201 DENTER("store_register()");
1202 From = read_register (regno); /* get data value */
1203
1204 if (regno == GR1_REGNUM)
1205 { To.Space = UDI29KGlobalRegs;
1206 To.Offset = 1;
1207 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1208 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1209 * register cache. Do this *after* calling read_register, because we want
1210 * read_register to return the value that write_register has just stuffed
1211 * into the registers array, not the value of the register fetched from
1212 * the inferior.
1213 */
1214 registers_changed ();
1215 }
1216 #if defined(GR64_REGNUM)
1217 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1218 { To.Space = UDI29KGlobalRegs;
1219 To.Offset = (regno - GR64_REGNUM) + 64;
1220 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1221 }
1222 #endif /* GR64_REGNUM */
1223 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1224 { To.Space = UDI29KGlobalRegs;
1225 To.Offset = (regno - GR96_REGNUM) + 96;
1226 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1227 }
1228 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1229 { To.Space = UDI29KLocalRegs;
1230 To.Offset = (regno - LR0_REGNUM);
1231 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1232 }
1233 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1234 {
1235 return 0; /* Pretend Success */
1236 }
1237 else /* An unprotected or protected special register */
1238 { To.Space = UDI29KSpecialRegs;
1239 To.Offset = regnum_to_srnum(regno);
1240 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1241 }
1242
1243 DEXIT("store_register()");
1244 if(result)
1245 { result = -1;
1246 error("UDIWrite() failed in store_registers");
1247 }
1248 return result;
1249 }
1250 /********************************************************** REGNUM_TO_SRNUM */
1251 /*
1252 * Convert a gdb special register number to a 29000 special register number.
1253 */
1254 static int
1255 regnum_to_srnum(regno)
1256 int regno;
1257 {
1258 switch(regno) {
1259 case VAB_REGNUM: return(0);
1260 case OPS_REGNUM: return(1);
1261 case CPS_REGNUM: return(2);
1262 case CFG_REGNUM: return(3);
1263 case CHA_REGNUM: return(4);
1264 case CHD_REGNUM: return(5);
1265 case CHC_REGNUM: return(6);
1266 case RBP_REGNUM: return(7);
1267 case TMC_REGNUM: return(8);
1268 case TMR_REGNUM: return(9);
1269 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1270 case PC_REGNUM: return(USE_SHADOW_PC ? (21) : (11));
1271 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1272 case MMU_REGNUM: return(13);
1273 case LRU_REGNUM: return(14);
1274 case IPC_REGNUM: return(128);
1275 case IPA_REGNUM: return(129);
1276 case IPB_REGNUM: return(130);
1277 case Q_REGNUM: return(131);
1278 case ALU_REGNUM: return(132);
1279 case BP_REGNUM: return(133);
1280 case FC_REGNUM: return(134);
1281 case CR_REGNUM: return(135);
1282 case FPE_REGNUM: return(160);
1283 case INTE_REGNUM: return(161);
1284 case FPS_REGNUM: return(162);
1285 case EXO_REGNUM:return(164);
1286 default:
1287 return(255); /* Failure ? */
1288 }
1289 }
1290 /****************************************************************************/
1291 /*
1292 * Determine the Target memory space qualifier based on the addr.
1293 * FIXME: Can't distinguis I_ROM/D_ROM.
1294 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1295 */
1296 static CPUSpace
1297 udi_memory_space(addr)
1298 CORE_ADDR *addr;
1299 {
1300 UDIUInt32 tstart = IMemStart;
1301 UDIUInt32 tend = tstart + IMemSize;
1302 UDIUInt32 dstart = DMemStart;
1303 UDIUInt32 dend = tstart + DMemSize;
1304 UDIUInt32 rstart = RMemStart;
1305 UDIUInt32 rend = tstart + RMemSize;
1306
1307 if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) {
1308 return UDI29KIRAMSpace;
1309 } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) {
1310 return UDI29KDRAMSpace;
1311 } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1312 /* FIXME: how do we determine between D_ROM and I_ROM */
1313 return UDI29KIROMSpace;
1314 } else /* FIXME: what do me do now? */
1315 return UDI29KDRAMSpace; /* Hmmm! */
1316 }
1317 /*********************************************************************** STUBS
1318 */
1319
1320 void convert16() {;}
1321 void convert32() {;}
1322 FILE* EchoFile = 0; /* used for debugging */
1323 int QuietMode = 0; /* used for debugging */
1324
1325 /****************************************************************************/
1326 /*
1327 * Define the target subroutine names
1328 */
1329 static struct target_ops udi_ops = {
1330 "udi", "Remote UDI connected TIP",
1331 "Remote debug an AMD 29k using UDI socket connection to TIP process",
1332 udi_open, udi_close,
1333 udi_attach, udi_detach, udi_resume, udi_wait,
1334 udi_fetch_registers, udi_store_registers,
1335 udi_prepare_to_store, 0, 0, /* conv_to, conv_from */
1336 udi_xfer_inferior_memory,
1337 udi_files_info,
1338 udi_insert_breakpoint, udi_remove_breakpoint, /* Breakpoints */
1339 0, 0, 0, 0, 0, /* Terminal handling */
1340 udi_kill, /* FIXME, kill */
1341 udi_load,
1342 0, /* lookup_symbol */
1343 udi_create_inferior, /* create_inferior */
1344 udi_mourn, /* mourn_inferior FIXME */
1345 process_stratum, 0, /* next */
1346 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1347 0, 0, /* Section pointers */
1348 OPS_MAGIC, /* Always the last thing */
1349 };
1350
1351 void _initialize_remote_udi()
1352 {
1353 add_target (&udi_ops);
1354 }
1355
1356 #ifdef NO_HIF_SUPPORT
1357 service_HIF(msg)
1358 union msg_t *msg;
1359 {
1360 return(0); /* Emulate a failure */
1361 }
1362 #endif
This page took 0.098336 seconds and 4 git commands to generate.