1 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2 Copyright 1990, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Written by Daniel Mann. Contributed by AMD.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This is like remote.c but uses the Universal Debug Interface (UDI) to
24 talk to the target hardware (or simulator). UDI is a TCP/IP based
25 protocol; for hardware that doesn't run TCP, an interface adapter
26 daemon talks UDI on one side, and talks to the hardware (typically
27 over a serial port) on the other side.
29 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
31 file to gdb 3.95. I was unable to get this working on sun3os4
32 with termio, only with sgtty.
33 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
34 MiniMON interface with UDI-p interface. */
43 #include "gdb_string.h"
46 #include "29k-share/udi/udiproc.h"
49 #include "gdbcore.h" /* For download function */
52 /* access the register store directly, without going through
53 the normal handler functions. This avoids an extra data copy. */
55 extern int stop_soon_quietly; /* for wait_for_inferior */
56 extern struct value *call_function_by_hand ();
57 static void udi_resume (int pid, int step, enum target_signal sig);
58 static void udi_fetch_registers (int regno);
59 static void udi_load (char *args, int from_tty);
60 static void fetch_register (int regno);
61 static void udi_store_registers (int regno);
62 static int store_register (int regno);
63 static int regnum_to_srnum (int regno);
64 static void udi_close (int quitting);
65 static CPUSpace udi_memory_space (CORE_ADDR addr);
66 static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
68 static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
70 static void download (char *load_arg_string, int from_tty);
71 char CoffFileName[100] = "";
73 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
74 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
76 static int timeout = 5;
77 extern struct target_ops udi_ops; /* Forward declaration */
79 /* Special register enumeration.
82 /******************************************************************* UDI DATA*/
83 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
84 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
85 udi_open knows that we don't have a file open when the program
88 UDISessionId udi_session_id = -1;
89 static char *udi_config_id;
91 CPUOffset IMemStart = 0;
92 CPUSizeT IMemSize = 0;
93 CPUOffset DMemStart = 0;
94 CPUSizeT DMemSize = 0;
95 CPUOffset RMemStart = 0;
96 CPUSizeT RMemSize = 0;
100 UDIMemoryRange address_ranges[2]; /* Text and data */
102 {0, 0}; /* Entry point */
103 CPUSizeT stack_sizes[2]; /* Regular and memory stacks */
105 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
108 typedef struct bkpt_entry_str
113 unsigned int BreakId;
116 #define BKPT_TABLE_SIZE 40
117 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
118 extern char dfe_errmsg[]; /* error string */
120 /* malloc'd name of the program on the remote system. */
121 static char *prog_name = NULL;
123 /* This is called not only when we first attach, but also when the
124 user types "run" after having attached. */
127 udi_create_inferior (char *execfile, char *args, char **env)
133 if (prog_name != NULL)
135 prog_name = savestring (execfile, strlen (execfile));
137 else if (entry.Offset)
140 error ("No image loaded into target.");
142 if (udi_session_id < 0)
144 /* If the TIP is not open, open it. */
145 if (UDIConnect (udi_config_id, &udi_session_id))
146 error ("UDIConnect() failed: %s\n", dfe_errmsg);
147 /* We will need to download the program. */
151 inferior_pid = 40000;
154 download (execfile, 0);
156 args1 = alloca (strlen (execfile) + strlen (args) + 2);
158 if (execfile[0] == '\0')
160 /* It is empty. We need to quote it somehow, or else the target
161 will think there is no argument being passed here. According
162 to the UDI spec it is quoted "according to TIP OS rules" which
163 I guess means quoting it like the Unix shell should work
164 (sounds pretty bogus to me...). In fact it doesn't work (with
165 isstip anyway), but passing in two quotes as the argument seems
166 like a reasonable enough behavior anyway (I guess). */
168 strcpy (args1, "''");
170 strcpy (args1, execfile);
172 strcat (args1, args);
174 UDIInitializeProcess (address_ranges, /* ProcessMemory[] */
175 (UDIInt) 2, /* NumberOfRanges */
176 entry, /* EntryPoint */
177 stack_sizes, /* *StackSizes */
178 (UDIInt) 2, /* NumberOfStacks */
179 args1); /* ArgString */
181 init_wait_for_inferior ();
182 clear_proceed_status ();
183 proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
190 /* Requiring "target udi" each time you run is a major pain. I suspect
191 this was just blindy copied from remote.c, in which "target" and
192 "run" are combined. Having a udi target without an inferior seems
193 to work between "target udi" and "run", so why not now? */
194 pop_target (); /* Pop back to no-child state */
196 /* But if we're going to want to run it again, we better remove the
198 remove_breakpoints ();
199 generic_mourn_inferior ();
202 /******************************************************************** UDI_OPEN
203 ** Open a connection to remote TIP.
204 NAME is the socket domain used for communication with the TIP,
205 then a space and the socket name or TIP-host name.
206 '<udi_udi_config_id>' for example.
209 /* XXX - need cleanups for udiconnect for various failures!!! */
212 udi_open (char *name, int from_tty)
217 UDIMemoryRange KnownMemory[10];
218 UDIUInt32 ChipVersions[10];
219 UDIInt NumberOfRanges = 10;
220 UDIInt NumberOfChips = 10;
222 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
224 target_preopen (from_tty);
228 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
229 bkpt_table[cnt].Type = 0;
232 xfree (udi_config_id);
235 error ("Usage: target udi config_id, where config_id appears in udi_soc file");
237 udi_config_id = xstrdup (strtok (name, " \t"));
239 if (UDIConnect (udi_config_id, &udi_session_id))
240 /* FIXME: Should set udi_session_id to -1 here. */
241 error ("UDIConnect() failed: %s\n", dfe_errmsg);
243 push_target (&udi_ops);
246 ** Initialize target configuration structure (global)
248 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
249 ChipVersions, &NumberOfChips))
250 error ("UDIGetTargetConfig() failed");
251 if (NumberOfChips > 2)
252 fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
253 for (cnt = 0; cnt < NumberOfRanges; cnt++)
255 switch (KnownMemory[cnt].Space)
258 fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
262 case UDI29KIROMSpace:
263 RMemStart = KnownMemory[cnt].Offset;
264 RMemSize = KnownMemory[cnt].Size;
266 case UDI29KIRAMSpace:
267 IMemStart = KnownMemory[cnt].Offset;
268 IMemSize = KnownMemory[cnt].Size;
270 case UDI29KDRAMSpace:
271 DMemStart = KnownMemory[cnt].Offset;
272 DMemSize = KnownMemory[cnt].Size;
277 a29k_get_processor_type ();
279 if (UDICreateProcess (&PId))
280 fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
282 /* Print out some stuff, letting the user now what's going on */
283 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
285 error ("UDICapabilities() failed");
288 printf_filtered ("Connected via UDI socket,\n\
289 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
290 (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
291 (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
292 (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
297 /******************************************************************* UDI_CLOSE
298 Close the open connection to the TIP process.
299 Use this when you want to detach and do something else
302 udi_close ( /*FIXME: how is quitting used */
305 if (udi_session_id < 0)
308 /* We should never get here if there isn't something valid in
311 if (UDIDisconnect (udi_session_id, UDITerminateSession))
314 warning ("UDIDisconnect() failed in udi_close");
316 error ("UDIDisconnect() failed in udi_close");
319 /* Do not try to close udi_session_id again, later in the program. */
323 printf_filtered (" Ending remote debugging\n");
326 /**************************************************************** UDI_ATACH */
327 /* Attach to a program that is already loaded and running
328 * Upon exiting the process's execution is stopped.
331 udi_attach (char *args, int from_tty)
338 UDIBool HostEndian = 0;
342 error_no_arg ("program to attach");
344 if (udi_session_id < 0)
345 error ("UDI connection not opened yet, use the 'target udi' command.\n");
348 printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
351 From.Space = UDI29KSpecialRegs;
353 if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
354 error ("UDIRead failed in udi_attach");
355 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
357 /************************************************************* UDI_DETACH */
358 /* Terminate the open connection to the TIP process.
359 Use this when you want to detach and do something else
360 with your gdb. Leave remote process running (with no breakpoints set). */
362 udi_detach (char *args, int from_tty)
365 remove_breakpoints (); /* Just in case there were any left in */
367 if (UDIDisconnect (udi_session_id, UDIContinueSession))
368 error ("UDIDisconnect() failed in udi_detach");
370 /* Don't try to UDIDisconnect it again in udi_close, which is called from
378 printf_unfiltered ("Detaching from TIP\n");
382 /****************************************************************** UDI_RESUME
383 ** Tell the remote machine to resume. */
386 udi_resume (int pid, int step, enum target_signal sig)
390 UDIStepType StepType = UDIStepNatural;
393 if (step) /* step 1 instruction */
395 tip_error = UDIStep (Steps, StepType, Range);
399 fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
400 error ("failed in udi_resume");
404 error ("UDIExecute() failed in udi_resume");
407 /******************************************************************** UDI_WAIT
408 ** Wait until the remote machine stops, then return,
409 storing status in STATUS just as `wait' would. */
412 udi_wait (int pid, struct target_waitstatus *status)
418 int old_timeout = timeout;
419 int old_immediate_quit = immediate_quit;
422 status->kind = TARGET_WAITKIND_EXITED;
423 status->value.integer = 0;
425 /* wait for message to arrive. It should be:
426 If the target stops executing, udi_wait() should return.
428 timeout = 0; /* Wait indefinetly for a message */
429 immediate_quit = 1; /* Helps ability to QUIT */
434 MaxTime = UDIWaitForever;
435 UDIWait (MaxTime, &PId, &StopReason);
436 QUIT; /* Let user quit if they want */
438 switch (StopReason & UDIGrossState)
441 if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
442 /* This is said to happen if the program tries to output
443 a whole bunch of output (more than SBUF_MAX, I would
444 guess). It doesn't seem to happen with the simulator. */
445 warning ("UDIGetStdout() failed in udi_wait");
446 fwrite (sbuf, 1, CountDone, stdout);
447 gdb_flush (gdb_stdout);
451 UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
452 fwrite (sbuf, 1, CountDone, stderr);
453 gdb_flush (gdb_stderr);
467 while (i < SBUF_MAX && ch != '\n');
468 UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
473 /* In spite of the fact that we told UDIWait to wait forever, it will
474 return spuriously sometimes. */
483 switch (StopReason & UDIGrossState)
486 printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
488 switch ((StopReason >> 8) & 0xff)
490 case 0: /* Illegal opcode */
491 printf_unfiltered (" (break point)\n");
492 status->kind = TARGET_WAITKIND_STOPPED;
493 status->value.sig = TARGET_SIGNAL_TRAP;
495 case 1: /* Unaligned Access */
496 status->kind = TARGET_WAITKIND_STOPPED;
497 status->value.sig = TARGET_SIGNAL_BUS;
501 status->kind = TARGET_WAITKIND_STOPPED;
502 status->value.sig = TARGET_SIGNAL_FPE;
504 case 5: /* Protection Violation */
505 status->kind = TARGET_WAITKIND_STOPPED;
506 /* Why not SEGV? What is a Protection Violation? */
507 status->value.sig = TARGET_SIGNAL_ILL;
511 case 8: /* User Instruction Mapping Miss */
512 case 9: /* User Data Mapping Miss */
513 case 10: /* Supervisor Instruction Mapping Miss */
514 case 11: /* Supervisor Data Mapping Miss */
515 status->kind = TARGET_WAITKIND_STOPPED;
516 status->value.sig = TARGET_SIGNAL_SEGV;
520 status->kind = TARGET_WAITKIND_STOPPED;
521 status->value.sig = TARGET_SIGNAL_ILL;
524 status->kind = TARGET_WAITKIND_STOPPED;
525 status->value.sig = TARGET_SIGNAL_ALRM;
528 status->kind = TARGET_WAITKIND_STOPPED;
529 status->value.sig = TARGET_SIGNAL_TRAP;
534 case 19: /* INTR3/Internal */
537 status->kind = TARGET_WAITKIND_STOPPED;
538 status->value.sig = TARGET_SIGNAL_INT;
540 case 22: /* Floating-Point Exception */
541 status->kind = TARGET_WAITKIND_STOPPED;
543 status->value.sig = TARGET_SIGNAL_ILL;
545 case 77: /* assert 77 */
546 status->kind = TARGET_WAITKIND_STOPPED;
547 status->value.sig = TARGET_SIGNAL_TRAP;
550 status->kind = TARGET_WAITKIND_EXITED;
551 status->value.integer = 0;
554 case UDINotExecuting:
555 status->kind = TARGET_WAITKIND_STOPPED;
556 status->value.sig = TARGET_SIGNAL_TERM;
559 status->kind = TARGET_WAITKIND_STOPPED;
560 status->value.sig = TARGET_SIGNAL_TSTP;
563 status->kind = TARGET_WAITKIND_STOPPED;
564 status->value.sig = TARGET_SIGNAL_URG;
568 status->kind = TARGET_WAITKIND_STOPPED;
569 status->value.sig = TARGET_SIGNAL_TRAP;
572 status->kind = TARGET_WAITKIND_STOPPED;
573 status->value.sig = TARGET_SIGNAL_STOP;
576 status->kind = TARGET_WAITKIND_STOPPED;
577 status->value.sig = TARGET_SIGNAL_KILL;
581 status->kind = TARGET_WAITKIND_EXITED;
582 status->value.integer = 0;
585 timeout = old_timeout; /* Restore original timeout value */
586 immediate_quit = old_immediate_quit;
591 /* Handy for debugging */
599 UDIBool HostEndian = 0;
602 unsigned long myregs[256];
605 From.Space = UDI29KPC;
607 To = (UDIUInt32 *) pc;
610 err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
612 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
613 err, CountDone, pc[0], pc[1]);
615 udi_fetch_registers (-1);
617 printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) ®isters[4 * PC_REGNUM],
618 *(int *) ®isters[4 * NPC_REGNUM]);
620 /* Now, read all the registers globally */
622 From.Space = UDI29KGlobalRegs;
624 err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
626 printf ("err = %d, CountDone = %d\n", err, CountDone);
630 for (i = 0; i < 256; i += 2)
631 printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
632 myregs[i + 1], myregs[i + 1]);
639 /********************************************************** UDI_FETCH_REGISTERS
640 * Read a remote register 'regno'.
641 * If regno==-1 then read all the registers.
644 udi_fetch_registers (int regno)
651 UDIBool HostEndian = 0;
657 fetch_register (regno);
663 From.Space = UDI29KGlobalRegs;
665 To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
667 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
668 error ("UDIRead() failed in udi_fetch_registers");
670 register_valid[GR1_REGNUM] = 1;
672 #if defined(GR64_REGNUM) /* Read gr64-127 */
674 /* Global Registers gr64-gr95 */
676 From.Space = UDI29KGlobalRegs;
678 To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
680 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
681 error ("UDIRead() failed in udi_fetch_registers");
683 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
684 register_valid[i] = 1;
686 #endif /* GR64_REGNUM */
688 /* Global Registers gr96-gr127 */
690 From.Space = UDI29KGlobalRegs;
692 To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
694 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
695 error ("UDIRead() failed in udi_fetch_registers");
697 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
698 register_valid[i] = 1;
700 /* Local Registers */
702 From.Space = UDI29KLocalRegs;
704 To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
706 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
707 error ("UDIRead() failed in udi_fetch_registers");
709 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
710 register_valid[i] = 1;
712 /* Protected Special Registers */
714 From.Space = UDI29KSpecialRegs;
716 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
718 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
719 error ("UDIRead() failed in udi_fetch_registers");
721 for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
722 register_valid[i] = 1;
725 { /* Let regno_to_srnum() handle the register number */
726 fetch_register (NPC_REGNUM);
727 fetch_register (PC_REGNUM);
728 fetch_register (PC2_REGNUM);
730 /* Unprotected Special Registers sr128-sr135 */
732 From.Space = UDI29KSpecialRegs;
734 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
735 Count = 135 - 128 + 1;
736 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
737 error ("UDIRead() failed in udi_fetch_registers");
739 for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
740 register_valid[i] = 1;
745 fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
746 fprintf_unfiltered (gdb_stdlog,
747 "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
748 read_register (NPC_REGNUM),
749 read_register (PC_REGNUM),
750 read_register (PC2_REGNUM));
753 /* There doesn't seem to be any way to get these. */
756 supply_register (FPE_REGNUM, (char *) &val);
757 supply_register (INTE_REGNUM, (char *) &val);
758 supply_register (FPS_REGNUM, (char *) &val);
759 supply_register (EXO_REGNUM, (char *) &val);
764 /********************************************************* UDI_STORE_REGISTERS
765 ** Store register regno into the target.
766 * If regno==-1 then store all the registers.
770 udi_store_registers (int regno)
777 UDIBool HostEndian = 0;
781 store_register (regno);
787 fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
788 fprintf_unfiltered (gdb_stdlog,
789 "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
790 read_register (NPC_REGNUM),
791 read_register (PC_REGNUM),
792 read_register (PC2_REGNUM));
797 From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
798 To.Space = UDI29KGlobalRegs;
801 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
802 error ("UDIWrite() failed in udi_store_regisetrs");
804 #if defined(GR64_REGNUM)
806 /* Global registers gr64-gr95 */
808 From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
809 To.Space = UDI29KGlobalRegs;
812 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
813 error ("UDIWrite() failed in udi_store_regisetrs");
815 #endif /* GR64_REGNUM */
817 /* Global registers gr96-gr127 */
819 From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
820 To.Space = UDI29KGlobalRegs;
823 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
824 error ("UDIWrite() failed in udi_store_regisetrs");
826 /* Local Registers */
828 From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
829 To.Space = UDI29KLocalRegs;
832 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
833 error ("UDIWrite() failed in udi_store_regisetrs");
836 /* Protected Special Registers *//* VAB through TMR */
838 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
839 To.Space = UDI29KSpecialRegs;
842 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
843 error ("UDIWrite() failed in udi_store_regisetrs");
845 /* PC0, PC1, PC2 possibly as shadow registers */
847 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
848 To.Space = UDI29KSpecialRegs;
851 To.Offset = 20; /* SPC0 */
853 To.Offset = 10; /* PC0 */
854 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
855 error ("UDIWrite() failed in udi_store_regisetrs");
857 /* PC1 via UDI29KPC */
859 From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
861 To.Offset = 0; /* PC1 */
863 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
864 error ("UDIWrite() failed in udi_store_regisetrs");
868 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
869 To.Space = UDI29KSpecialRegs;
872 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
873 error ("UDIWrite() failed in udi_store_regisetrs");
875 /* Unprotected Special Registers */
877 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
878 To.Space = UDI29KSpecialRegs;
880 Count = 135 - 128 + 1;
881 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
882 error ("UDIWrite() failed in udi_store_regisetrs");
884 registers_changed ();
887 /****************************************************** UDI_PREPARE_TO_STORE */
888 /* Get ready to modify the registers array. On machines which store
889 individual registers, this doesn't need to do anything. On machines
890 which store all the registers in one fell swoop, this makes sure
891 that registers contains all the registers from the program being
895 udi_prepare_to_store (void)
897 /* Do nothing, since we can store individual regs */
900 /********************************************************** TRANSLATE_ADDR */
902 translate_addr (CORE_ADDR addr)
904 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
905 /* Check for a virtual address in the kernel */
906 /* Assume physical address of ublock is in paddr_u register */
907 /* FIXME: doesn't work for user virtual addresses */
910 /* PADDR_U register holds the physical address of the ublock */
911 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
912 return (i + addr - (CORE_ADDR) UVADDR);
922 /************************************************* UDI_XFER_INFERIOR_MEMORY */
923 /* FIXME! Merge these two. */
925 udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
926 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
927 struct target_ops *target ATTRIBUTE_UNUSED)
930 memaddr = translate_addr (memaddr);
933 return udi_write_inferior_memory (memaddr, myaddr, len);
935 return udi_read_inferior_memory (memaddr, myaddr, len);
938 /********************************************************** UDI_FILES_INFO */
940 udi_files_info (struct target_ops *target)
942 printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
943 if (prog_name != NULL)
944 printf_unfiltered ("and running program %s", prog_name);
945 printf_unfiltered (".\n");
948 /**************************************************** UDI_INSERT_BREAKPOINT */
950 udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
955 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
956 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
959 if (cnt >= BKPT_TABLE_SIZE)
960 error ("Too many breakpoints set");
962 bkpt_table[cnt].Addr.Offset = addr;
963 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
964 bkpt_table[cnt].PassCount = 1;
965 bkpt_table[cnt].Type = UDIBreakFlagExecute;
967 err = UDISetBreakpoint (bkpt_table[cnt].Addr,
968 bkpt_table[cnt].PassCount,
969 bkpt_table[cnt].Type,
970 &bkpt_table[cnt].BreakId);
973 return 0; /* Success */
975 bkpt_table[cnt].Type = 0;
976 error ("UDISetBreakpoint returned error code %d\n", err);
979 /**************************************************** UDI_REMOVE_BREAKPOINT */
981 udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
986 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
987 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
990 if (cnt >= BKPT_TABLE_SIZE)
991 error ("Can't find breakpoint in table");
993 bkpt_table[cnt].Type = 0;
995 err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
997 return 0; /* Success */
999 error ("UDIClearBreakpoint returned error code %d\n", err);
1008 UDIStop does not really work as advertised. It causes the TIP to close it's
1009 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1010 just invoke udi_close, which seems to get things right.
1014 udi_session_id = -1;
1018 printf_unfiltered ("Target has been stopped.");
1025 /* Keep the target around, e.g. so "run" can do the right thing when
1026 we are already debugging something. */
1028 if (UDIDisconnect (udi_session_id, UDITerminateSession))
1030 warning ("UDIDisconnect() failed");
1033 /* Do not try to close udi_session_id again, later in the program. */
1034 udi_session_id = -1;
1039 Load a program into the target. Args are: `program {options}'. The options
1040 are used to control loading of the program, and are NOT passed onto the
1041 loaded code as arguments. (You need to use the `run' command to do that.)
1044 -ms %d Set mem stack size to %d
1045 -rs %d Set regular stack size to %d
1046 -i send init info (default)
1047 -noi don't send init info
1048 -[tT] Load Text section
1049 -[dD] Load Data section
1050 -[bB] Load BSS section
1051 -[lL] Load Lit section
1055 download (char *load_arg_string, int from_tty)
1057 #define DEFAULT_MEM_STACK_SIZE 0x6000
1058 #define DEFAULT_REG_STACK_SIZE 0x2000
1065 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1067 address_ranges[0].Space = UDI29KIRAMSpace;
1068 address_ranges[0].Offset = 0xffffffff;
1069 address_ranges[0].Size = 0;
1071 address_ranges[1].Space = UDI29KDRAMSpace;
1072 address_ranges[1].Offset = 0xffffffff;
1073 address_ranges[1].Size = 0;
1075 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1076 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1080 filename = strtok (load_arg_string, " \t");
1082 error ("Must specify at least a file name with the load command");
1084 filename = tilde_expand (filename);
1085 make_cleanup (xfree, filename);
1087 while (token = strtok (NULL, " \t"))
1089 if (token[0] == '-')
1093 if (STREQ (token, "ms"))
1094 stack_sizes[1] = atol (strtok (NULL, " \t"));
1095 else if (STREQ (token, "rs"))
1096 stack_sizes[0] = atol (strtok (NULL, " \t"));
1099 load_text = load_data = load_bss = load_lit = 0;
1122 error ("Unknown UDI load option -%s", token - 1);
1129 pbfd = bfd_openr (filename, gnutarget);
1132 /* FIXME: should be using bfd_errmsg, not assuming it was
1133 bfd_error_system_call. */
1134 perror_with_name (filename);
1136 /* FIXME: should be checking for errors from bfd_close (for one thing,
1137 on error it does not free all the storage associated with the
1139 make_cleanup_bfd_close (pbfd);
1144 if (!bfd_check_format (pbfd, bfd_object))
1145 error ("It doesn't seem to be an object file");
1147 for (section = pbfd->sections; section; section = section->next)
1149 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1153 unsigned long section_size, section_end;
1154 const char *section_name;
1156 section_name = bfd_get_section_name (pbfd, section);
1157 if (STREQ (section_name, ".text") && !load_text)
1159 else if (STREQ (section_name, ".data") && !load_data)
1161 else if (STREQ (section_name, ".bss") && !load_bss)
1163 else if (STREQ (section_name, ".lit") && !load_lit)
1166 To.Offset = bfd_get_section_vma (pbfd, section);
1167 section_size = bfd_section_size (pbfd, section);
1168 section_end = To.Offset + section_size;
1170 if (section_size == 0)
1171 /* This is needed at least in the BSS case, where the code
1172 below starts writing before it even checks the size. */
1175 printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
1180 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1182 To.Space = UDI29KIRAMSpace;
1184 address_ranges[0].Offset = min (address_ranges[0].Offset,
1186 address_ranges[0].Size = max (address_ranges[0].Size,
1188 - address_ranges[0].Offset);
1192 To.Space = UDI29KDRAMSpace;
1194 address_ranges[1].Offset = min (address_ranges[1].Offset,
1196 address_ranges[1].Size = max (address_ranges[1].Size,
1198 - address_ranges[1].Offset);
1201 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1207 while (section_size > 0)
1211 Count = min (section_size, 1024);
1213 bfd_get_section_contents (pbfd, section, buffer, fptr,
1216 err = UDIWrite ((UDIHostMemPtr) buffer, /* From */
1219 (UDISizeT) 1, /* Size */
1220 &Count, /* CountDone */
1221 (UDIBool) 0); /* HostEndian */
1223 error ("UDIWrite failed, error = %d", err);
1227 section_size -= Count;
1234 unsigned long zero = 0;
1236 /* Write a zero byte at the vma */
1237 /* FIXME: Broken for sections of 1-3 bytes (we test for
1239 err = UDIWrite ((UDIHostMemPtr) & zero, /* From */
1241 (UDICount) 1, /* Count */
1242 (UDISizeT) 4, /* Size */
1243 &Count, /* CountDone */
1244 (UDIBool) 0); /* HostEndian */
1246 error ("UDIWrite failed, error = %d", err);
1251 /* Now, duplicate it for the length of the BSS */
1252 err = UDICopy (From, /* From */
1254 (UDICount) (section_size / 4 - 1), /* Count */
1255 (UDISizeT) 4, /* Size */
1256 &Count, /* CountDone */
1257 (UDIBool) 1); /* Direction */
1263 xerr = UDIGetErrorMsg (err, 100, message, &Count);
1265 fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1267 fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1268 error ("UDICopy failed, error = %d", err);
1275 entry.Space = UDI29KIRAMSpace;
1276 entry.Offset = bfd_get_start_address (pbfd);
1281 /* Function to download an image into the remote target. */
1284 udi_load (char *args, int from_tty)
1286 download (args, from_tty);
1288 /* As a convenience, pick up any symbol info that is in the program
1289 being loaded. Note that we assume that the program is the``mainline'';
1290 if this is not always true, then this code will need to be augmented. */
1291 symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
1293 /* Getting new symbols may change our opinion about what is
1295 reinit_frame_cache ();
1298 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1299 ** Copy LEN bytes of data from debugger memory at MYADDR
1300 to inferior's memory at MEMADDR. Returns number of bytes written. */
1302 udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1309 UDICount CountDone = 0;
1310 UDIBool HostEndian = 0;
1312 To.Space = udi_memory_space (memaddr);
1313 From = (UDIUInt32 *) myaddr;
1315 while (nwritten < len)
1317 Count = len - nwritten;
1318 if (Count > MAXDATA)
1320 To.Offset = memaddr + nwritten;
1321 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
1323 error ("UDIWrite() failed in udi_write_inferior_memory");
1328 nwritten += CountDone;
1335 /**************************************************** UDI_READ_INFERIOR_MEMORY
1336 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1337 at debugger address MYADDR. Returns number of bytes read. */
1339 udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1346 UDICount CountDone = 0;
1347 UDIBool HostEndian = 0;
1350 From.Space = udi_memory_space (memaddr);
1351 To = (UDIUInt32 *) myaddr;
1355 Count = len - nread;
1356 if (Count > MAXDATA)
1358 From.Offset = memaddr + nread;
1359 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
1361 error ("UDIRead() failed in udi_read_inferior_memory");
1373 /********************************************************************* WARNING
1375 udi_warning (int num)
1377 error ("ERROR while loading program into remote TIP: $d\n", num);
1381 /*****************************************************************************/
1382 /* Fetch a single register indicatated by 'regno'.
1383 * Returns 0/-1 on success/failure.
1386 fetch_register (int regno)
1393 UDIBool HostEndian = 0;
1397 if (regno == GR1_REGNUM)
1399 From.Space = UDI29KGlobalRegs;
1402 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1404 From.Space = UDI29KGlobalRegs;
1405 From.Offset = (regno - GR96_REGNUM) + 96;;
1408 #if defined(GR64_REGNUM)
1410 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1412 From.Space = UDI29KGlobalRegs;
1413 From.Offset = (regno - GR64_REGNUM) + 64;
1416 #endif /* GR64_REGNUM */
1418 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1420 From.Space = UDI29KLocalRegs;
1421 From.Offset = (regno - LR0_REGNUM);
1423 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1426 /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */
1427 supply_register (regno, (char *) &val);
1428 return; /* Pretend Success */
1432 From.Space = UDI29KSpecialRegs;
1433 From.Offset = regnum_to_srnum (regno);
1436 if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
1437 error ("UDIRead() failed in udi_fetch_registers");
1439 supply_register (regno, (char *) &To);
1442 fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
1443 REGISTER_NAME (regno), To);
1445 /*****************************************************************************/
1446 /* Store a single register indicated by 'regno'.
1447 * Returns 0/-1 on success/failure.
1450 store_register (int regno)
1458 UDIBool HostEndian = 0;
1460 From = read_register (regno); /* get data value */
1463 fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
1464 REGISTER_NAME (regno), From);
1466 if (regno == GR1_REGNUM)
1468 To.Space = UDI29KGlobalRegs;
1470 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1471 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1472 * register cache. Do this *after* calling read_register, because we want
1473 * read_register to return the value that write_register has just stuffed
1474 * into the registers array, not the value of the register fetched from
1477 registers_changed ();
1479 #if defined(GR64_REGNUM)
1480 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1482 To.Space = UDI29KGlobalRegs;
1483 To.Offset = (regno - GR64_REGNUM) + 64;
1484 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1486 #endif /* GR64_REGNUM */
1487 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1489 To.Space = UDI29KGlobalRegs;
1490 To.Offset = (regno - GR96_REGNUM) + 96;
1491 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1493 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1495 To.Space = UDI29KLocalRegs;
1496 To.Offset = (regno - LR0_REGNUM);
1497 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1499 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1500 return 0; /* Pretend Success */
1501 else if (regno == PC_REGNUM)
1503 /* PC1 via UDI29KPC */
1505 To.Space = UDI29KPC;
1506 To.Offset = 0; /* PC1 */
1507 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1509 /* Writing to this loc actually changes the values of pc0 & pc1 */
1511 register_valid[PC_REGNUM] = 0; /* pc1 */
1512 register_valid[NPC_REGNUM] = 0; /* pc0 */
1515 /* An unprotected or protected special register */
1517 To.Space = UDI29KSpecialRegs;
1518 To.Offset = regnum_to_srnum (regno);
1519 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1523 error ("UDIWrite() failed in store_registers");
1527 /********************************************************** REGNUM_TO_SRNUM */
1529 * Convert a gdb special register number to a 29000 special register number.
1532 regnum_to_srnum (int regno)
1557 return (USE_SHADOW_PC ? (20) : (10));
1559 return (USE_SHADOW_PC ? (21) : (11));
1561 return (USE_SHADOW_PC ? (22) : (12));
1591 return (255); /* Failure ? */
1594 /****************************************************************************/
1596 * Determine the Target memory space qualifier based on the addr.
1597 * FIXME: Can't distinguis I_ROM/D_ROM.
1598 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1601 udi_memory_space (CORE_ADDR addr)
1603 UDIUInt32 tstart = IMemStart;
1604 UDIUInt32 tend = tstart + IMemSize;
1605 UDIUInt32 dstart = DMemStart;
1606 UDIUInt32 dend = tstart + DMemSize;
1607 UDIUInt32 rstart = RMemStart;
1608 UDIUInt32 rend = tstart + RMemSize;
1610 if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
1612 return UDI29KIRAMSpace;
1614 else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
1616 return UDI29KDRAMSpace;
1618 else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
1620 /* FIXME: how do we determine between D_ROM and I_ROM */
1621 return UDI29KIROMSpace;
1623 else /* FIXME: what do me do now? */
1624 return UDI29KDRAMSpace; /* Hmmm! */
1626 /*********************************************************************** STUBS
1637 struct ui_file *EchoFile = 0; /* used for debugging */
1638 int QuietMode = 0; /* used for debugging */
1640 #ifdef NO_HIF_SUPPORT
1641 service_HIF (union msg_t *msg)
1643 return (0); /* Emulate a failure */
1647 /* Target_ops vector. Not static because there does not seem to be
1648 any portable way to do a forward declaration of a static variable.
1649 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1650 /bin/cc doesn't like "static" twice. */
1652 struct target_ops udi_ops;
1657 udi_ops.to_shortname = "udi";
1658 udi_ops.to_longname = "Remote UDI connected TIP";
1659 udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1661 `configuration-id AF_INET hostname port-number'\n\
1662 To connect via the network, where hostname and port-number specify the\n\
1663 host and port where you can connect via UDI.\n\
1664 configuration-id is unused.\n\
1666 `configuration-id AF_UNIX socket-name tip-program'\n\
1667 To connect using a local connection to the \"tip.exe\" program which is\n\
1668 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1669 tip program must already be started; connect to it using that socket.\n\
1670 If not, start up tip-program, which should be the name of the tip\n\
1671 program. If appropriate, the PATH environment variable is searched.\n\
1672 configuration-id is unused.\n\
1674 `configuration-id'\n\
1675 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1676 are files containing lines in the above formats. configuration-id is\n\
1677 used to pick which line of the file to use.";
1678 udi_ops.to_open = udi_open;
1679 udi_ops.to_close = udi_close;
1680 udi_ops.to_attach = udi_attach;
1681 udi_ops.to_detach = udi_detach;
1682 udi_ops.to_resume = udi_resume;
1683 udi_ops.to_wait = udi_wait;
1684 udi_ops.to_fetch_registers = udi_fetch_registers;
1685 udi_ops.to_store_registers = udi_store_registers;
1686 udi_ops.to_prepare_to_store = udi_prepare_to_store;
1687 udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
1688 udi_ops.to_files_info = udi_files_info;
1689 udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
1690 udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
1691 udi_ops.to_terminal_init = 0;
1692 udi_ops.to_terminal_inferior = 0;
1693 udi_ops.to_terminal_ours_for_output = 0;
1694 udi_ops.to_terminal_ours = 0;
1695 udi_ops.to_terminal_info = 0;
1696 udi_ops.to_kill = udi_kill;
1697 udi_ops.to_load = udi_load;
1698 udi_ops.to_lookup_symbol = 0;
1699 udi_ops.to_create_inferior = udi_create_inferior;
1700 udi_ops.to_mourn_inferior = udi_mourn;
1701 udi_ops.to_can_run = 0;
1702 udi_ops.to_notice_signals = 0;
1703 udi_ops.to_thread_alive = 0;
1704 udi_ops.to_stop = 0;
1705 udi_ops.to_stratum = process_stratum;
1706 udi_ops.DONT_USE = 0;
1707 udi_ops.to_has_all_memory = 1;
1708 udi_ops.to_has_memory = 1;
1709 udi_ops.to_has_stack = 1;
1710 udi_ops.to_has_registers = 1;
1711 udi_ops.to_has_execution = 1;
1712 udi_ops.to_sections = 0;
1713 udi_ops.to_sections_end = 0;
1714 udi_ops.to_magic = OPS_MAGIC;
1718 _initialize_remote_udi (void)
1721 add_target (&udi_ops);