1 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2 Copyright 1990, 1992, 1995, 2000, 2001 Free Software Foundation, Inc.
3 Written by Daniel Mann. Contributed by AMD.
5 This file is part of GDB.
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.
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.
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., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This is like remote.c but uses the Universal Debug Interface (UDI) to
23 talk to the target hardware (or simulator). UDI is a TCP/IP based
24 protocol; for hardware that doesn't run TCP, an interface adapter
25 daemon talks UDI on one side, and talks to the hardware (typically
26 over a serial port) on the other side.
28 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
30 file to gdb 3.95. I was unable to get this working on sun3os4
31 with termio, only with sgtty.
32 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
33 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 */
51 /* access the register store directly, without going through
52 the normal handler functions. This avoids an extra data copy. */
54 extern int stop_soon_quietly; /* for wait_for_inferior */
55 extern struct value *call_function_by_hand ();
56 static void udi_resume (int pid, int step, enum target_signal sig);
57 static void udi_fetch_registers (int regno);
58 static void udi_load (char *args, int from_tty);
59 static void fetch_register (int regno);
60 static void udi_store_registers (int regno);
61 static int store_register (int regno);
62 static int regnum_to_srnum (int regno);
63 static void udi_close (int quitting);
64 static CPUSpace udi_memory_space (CORE_ADDR addr);
65 static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
67 static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
69 static void download (char *load_arg_string, int from_tty);
70 char CoffFileName[100] = "";
72 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
73 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
75 static int timeout = 5;
76 extern struct target_ops udi_ops; /* Forward declaration */
78 /* Special register enumeration.
81 /******************************************************************* UDI DATA*/
82 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
83 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
84 udi_open knows that we don't have a file open when the program
87 UDISessionId udi_session_id = -1;
88 static char *udi_config_id;
90 CPUOffset IMemStart = 0;
91 CPUSizeT IMemSize = 0;
92 CPUOffset DMemStart = 0;
93 CPUSizeT DMemSize = 0;
94 CPUOffset RMemStart = 0;
95 CPUSizeT RMemSize = 0;
99 UDIMemoryRange address_ranges[2]; /* Text and data */
101 {0, 0}; /* Entry point */
102 CPUSizeT stack_sizes[2]; /* Regular and memory stacks */
104 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
107 typedef struct bkpt_entry_str
112 unsigned int BreakId;
115 #define BKPT_TABLE_SIZE 40
116 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
117 extern char dfe_errmsg[]; /* error string */
119 /* malloc'd name of the program on the remote system. */
120 static char *prog_name = NULL;
122 /* This is called not only when we first attach, but also when the
123 user types "run" after having attached. */
126 udi_create_inferior (char *execfile, char *args, char **env)
132 if (prog_name != NULL)
134 prog_name = savestring (execfile, strlen (execfile));
136 else if (entry.Offset)
139 error ("No image loaded into target.");
141 if (udi_session_id < 0)
143 /* If the TIP is not open, open it. */
144 if (UDIConnect (udi_config_id, &udi_session_id))
145 error ("UDIConnect() failed: %s\n", dfe_errmsg);
146 /* We will need to download the program. */
150 inferior_pid = 40000;
153 download (execfile, 0);
155 args1 = alloca (strlen (execfile) + strlen (args) + 2);
157 if (execfile[0] == '\0')
159 /* It is empty. We need to quote it somehow, or else the target
160 will think there is no argument being passed here. According
161 to the UDI spec it is quoted "according to TIP OS rules" which
162 I guess means quoting it like the Unix shell should work
163 (sounds pretty bogus to me...). In fact it doesn't work (with
164 isstip anyway), but passing in two quotes as the argument seems
165 like a reasonable enough behavior anyway (I guess). */
167 strcpy (args1, "''");
169 strcpy (args1, execfile);
171 strcat (args1, args);
173 UDIInitializeProcess (address_ranges, /* ProcessMemory[] */
174 (UDIInt) 2, /* NumberOfRanges */
175 entry, /* EntryPoint */
176 stack_sizes, /* *StackSizes */
177 (UDIInt) 2, /* NumberOfStacks */
178 args1); /* ArgString */
180 init_wait_for_inferior ();
181 clear_proceed_status ();
182 proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
189 /* Requiring "target udi" each time you run is a major pain. I suspect
190 this was just blindy copied from remote.c, in which "target" and
191 "run" are combined. Having a udi target without an inferior seems
192 to work between "target udi" and "run", so why not now? */
193 pop_target (); /* Pop back to no-child state */
195 /* But if we're going to want to run it again, we better remove the
197 remove_breakpoints ();
198 generic_mourn_inferior ();
201 /******************************************************************** UDI_OPEN
202 ** Open a connection to remote TIP.
203 NAME is the socket domain used for communication with the TIP,
204 then a space and the socket name or TIP-host name.
205 '<udi_udi_config_id>' for example.
208 /* XXX - need cleanups for udiconnect for various failures!!! */
211 udi_open (char *name, int from_tty)
216 UDIMemoryRange KnownMemory[10];
217 UDIUInt32 ChipVersions[10];
218 UDIInt NumberOfRanges = 10;
219 UDIInt NumberOfChips = 10;
221 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
223 target_preopen (from_tty);
227 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
228 bkpt_table[cnt].Type = 0;
231 xfree (udi_config_id);
234 error ("Usage: target udi config_id, where config_id appears in udi_soc file");
236 udi_config_id = xstrdup (strtok (name, " \t"));
238 if (UDIConnect (udi_config_id, &udi_session_id))
239 /* FIXME: Should set udi_session_id to -1 here. */
240 error ("UDIConnect() failed: %s\n", dfe_errmsg);
242 push_target (&udi_ops);
245 ** Initialize target configuration structure (global)
247 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
248 ChipVersions, &NumberOfChips))
249 error ("UDIGetTargetConfig() failed");
250 if (NumberOfChips > 2)
251 fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
252 for (cnt = 0; cnt < NumberOfRanges; cnt++)
254 switch (KnownMemory[cnt].Space)
257 fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
261 case UDI29KIROMSpace:
262 RMemStart = KnownMemory[cnt].Offset;
263 RMemSize = KnownMemory[cnt].Size;
265 case UDI29KIRAMSpace:
266 IMemStart = KnownMemory[cnt].Offset;
267 IMemSize = KnownMemory[cnt].Size;
269 case UDI29KDRAMSpace:
270 DMemStart = KnownMemory[cnt].Offset;
271 DMemSize = KnownMemory[cnt].Size;
276 a29k_get_processor_type ();
278 if (UDICreateProcess (&PId))
279 fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
281 /* Print out some stuff, letting the user now what's going on */
282 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
284 error ("UDICapabilities() failed");
287 printf_filtered ("Connected via UDI socket,\n\
288 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
289 (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
290 (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
291 (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
296 /******************************************************************* UDI_CLOSE
297 Close the open connection to the TIP process.
298 Use this when you want to detach and do something else
301 udi_close ( /*FIXME: how is quitting used */
304 if (udi_session_id < 0)
307 /* We should never get here if there isn't something valid in
310 if (UDIDisconnect (udi_session_id, UDITerminateSession))
313 warning ("UDIDisconnect() failed in udi_close");
315 error ("UDIDisconnect() failed in udi_close");
318 /* Do not try to close udi_session_id again, later in the program. */
322 printf_filtered (" Ending remote debugging\n");
325 /**************************************************************** UDI_ATACH */
326 /* Attach to a program that is already loaded and running
327 * Upon exiting the process's execution is stopped.
330 udi_attach (char *args, int from_tty)
337 UDIBool HostEndian = 0;
341 error_no_arg ("program to attach");
343 if (udi_session_id < 0)
344 error ("UDI connection not opened yet, use the 'target udi' command.\n");
347 printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
350 From.Space = UDI29KSpecialRegs;
352 if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
353 error ("UDIRead failed in udi_attach");
354 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
356 /************************************************************* UDI_DETACH */
357 /* Terminate the open connection to the TIP process.
358 Use this when you want to detach and do something else
359 with your gdb. Leave remote process running (with no breakpoints set). */
361 udi_detach (char *args, int from_tty)
364 remove_breakpoints (); /* Just in case there were any left in */
366 if (UDIDisconnect (udi_session_id, UDIContinueSession))
367 error ("UDIDisconnect() failed in udi_detach");
369 /* Don't try to UDIDisconnect it again in udi_close, which is called from
377 printf_unfiltered ("Detaching from TIP\n");
381 /****************************************************************** UDI_RESUME
382 ** Tell the remote machine to resume. */
385 udi_resume (int pid, int step, enum target_signal sig)
389 UDIStepType StepType = UDIStepNatural;
392 if (step) /* step 1 instruction */
394 tip_error = UDIStep (Steps, StepType, Range);
398 fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
399 error ("failed in udi_resume");
403 error ("UDIExecute() failed in udi_resume");
406 /******************************************************************** UDI_WAIT
407 ** Wait until the remote machine stops, then return,
408 storing status in STATUS just as `wait' would. */
411 udi_wait (int pid, struct target_waitstatus *status)
417 int old_timeout = timeout;
418 int old_immediate_quit = immediate_quit;
421 status->kind = TARGET_WAITKIND_EXITED;
422 status->value.integer = 0;
424 /* wait for message to arrive. It should be:
425 If the target stops executing, udi_wait() should return.
427 timeout = 0; /* Wait indefinetly for a message */
428 immediate_quit = 1; /* Helps ability to QUIT */
433 MaxTime = UDIWaitForever;
434 UDIWait (MaxTime, &PId, &StopReason);
435 QUIT; /* Let user quit if they want */
437 switch (StopReason & UDIGrossState)
440 if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
441 /* This is said to happen if the program tries to output
442 a whole bunch of output (more than SBUF_MAX, I would
443 guess). It doesn't seem to happen with the simulator. */
444 warning ("UDIGetStdout() failed in udi_wait");
445 fwrite (sbuf, 1, CountDone, stdout);
446 gdb_flush (gdb_stdout);
450 UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
451 fwrite (sbuf, 1, CountDone, stderr);
452 gdb_flush (gdb_stderr);
466 while (i < SBUF_MAX && ch != '\n');
467 UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
472 /* In spite of the fact that we told UDIWait to wait forever, it will
473 return spuriously sometimes. */
482 switch (StopReason & UDIGrossState)
485 printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
487 switch ((StopReason >> 8) & 0xff)
489 case 0: /* Illegal opcode */
490 printf_unfiltered (" (break point)\n");
491 status->kind = TARGET_WAITKIND_STOPPED;
492 status->value.sig = TARGET_SIGNAL_TRAP;
494 case 1: /* Unaligned Access */
495 status->kind = TARGET_WAITKIND_STOPPED;
496 status->value.sig = TARGET_SIGNAL_BUS;
500 status->kind = TARGET_WAITKIND_STOPPED;
501 status->value.sig = TARGET_SIGNAL_FPE;
503 case 5: /* Protection Violation */
504 status->kind = TARGET_WAITKIND_STOPPED;
505 /* Why not SEGV? What is a Protection Violation? */
506 status->value.sig = TARGET_SIGNAL_ILL;
510 case 8: /* User Instruction Mapping Miss */
511 case 9: /* User Data Mapping Miss */
512 case 10: /* Supervisor Instruction Mapping Miss */
513 case 11: /* Supervisor Data Mapping Miss */
514 status->kind = TARGET_WAITKIND_STOPPED;
515 status->value.sig = TARGET_SIGNAL_SEGV;
519 status->kind = TARGET_WAITKIND_STOPPED;
520 status->value.sig = TARGET_SIGNAL_ILL;
523 status->kind = TARGET_WAITKIND_STOPPED;
524 status->value.sig = TARGET_SIGNAL_ALRM;
527 status->kind = TARGET_WAITKIND_STOPPED;
528 status->value.sig = TARGET_SIGNAL_TRAP;
533 case 19: /* INTR3/Internal */
536 status->kind = TARGET_WAITKIND_STOPPED;
537 status->value.sig = TARGET_SIGNAL_INT;
539 case 22: /* Floating-Point Exception */
540 status->kind = TARGET_WAITKIND_STOPPED;
542 status->value.sig = TARGET_SIGNAL_ILL;
544 case 77: /* assert 77 */
545 status->kind = TARGET_WAITKIND_STOPPED;
546 status->value.sig = TARGET_SIGNAL_TRAP;
549 status->kind = TARGET_WAITKIND_EXITED;
550 status->value.integer = 0;
553 case UDINotExecuting:
554 status->kind = TARGET_WAITKIND_STOPPED;
555 status->value.sig = TARGET_SIGNAL_TERM;
558 status->kind = TARGET_WAITKIND_STOPPED;
559 status->value.sig = TARGET_SIGNAL_TSTP;
562 status->kind = TARGET_WAITKIND_STOPPED;
563 status->value.sig = TARGET_SIGNAL_URG;
567 status->kind = TARGET_WAITKIND_STOPPED;
568 status->value.sig = TARGET_SIGNAL_TRAP;
571 status->kind = TARGET_WAITKIND_STOPPED;
572 status->value.sig = TARGET_SIGNAL_STOP;
575 status->kind = TARGET_WAITKIND_STOPPED;
576 status->value.sig = TARGET_SIGNAL_KILL;
580 status->kind = TARGET_WAITKIND_EXITED;
581 status->value.integer = 0;
584 timeout = old_timeout; /* Restore original timeout value */
585 immediate_quit = old_immediate_quit;
590 /* Handy for debugging */
598 UDIBool HostEndian = 0;
601 unsigned long myregs[256];
604 From.Space = UDI29KPC;
606 To = (UDIUInt32 *) pc;
609 err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
611 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
612 err, CountDone, pc[0], pc[1]);
614 udi_fetch_registers (-1);
616 printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) ®isters[4 * PC_REGNUM],
617 *(int *) ®isters[4 * NPC_REGNUM]);
619 /* Now, read all the registers globally */
621 From.Space = UDI29KGlobalRegs;
623 err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
625 printf ("err = %d, CountDone = %d\n", err, CountDone);
629 for (i = 0; i < 256; i += 2)
630 printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
631 myregs[i + 1], myregs[i + 1]);
638 /********************************************************** UDI_FETCH_REGISTERS
639 * Read a remote register 'regno'.
640 * If regno==-1 then read all the registers.
643 udi_fetch_registers (int regno)
650 UDIBool HostEndian = 0;
656 fetch_register (regno);
662 From.Space = UDI29KGlobalRegs;
664 To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
666 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
667 error ("UDIRead() failed in udi_fetch_registers");
669 register_valid[GR1_REGNUM] = 1;
671 #if defined(GR64_REGNUM) /* Read gr64-127 */
673 /* Global Registers gr64-gr95 */
675 From.Space = UDI29KGlobalRegs;
677 To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
679 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
680 error ("UDIRead() failed in udi_fetch_registers");
682 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
683 register_valid[i] = 1;
685 #endif /* GR64_REGNUM */
687 /* Global Registers gr96-gr127 */
689 From.Space = UDI29KGlobalRegs;
691 To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
693 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
694 error ("UDIRead() failed in udi_fetch_registers");
696 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
697 register_valid[i] = 1;
699 /* Local Registers */
701 From.Space = UDI29KLocalRegs;
703 To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
705 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
706 error ("UDIRead() failed in udi_fetch_registers");
708 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
709 register_valid[i] = 1;
711 /* Protected Special Registers */
713 From.Space = UDI29KSpecialRegs;
715 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
717 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
718 error ("UDIRead() failed in udi_fetch_registers");
720 for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
721 register_valid[i] = 1;
724 { /* Let regno_to_srnum() handle the register number */
725 fetch_register (NPC_REGNUM);
726 fetch_register (PC_REGNUM);
727 fetch_register (PC2_REGNUM);
729 /* Unprotected Special Registers sr128-sr135 */
731 From.Space = UDI29KSpecialRegs;
733 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
734 Count = 135 - 128 + 1;
735 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
736 error ("UDIRead() failed in udi_fetch_registers");
738 for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
739 register_valid[i] = 1;
744 fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
745 fprintf_unfiltered (gdb_stdlog,
746 "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
747 read_register (NPC_REGNUM),
748 read_register (PC_REGNUM),
749 read_register (PC2_REGNUM));
752 /* There doesn't seem to be any way to get these. */
755 supply_register (FPE_REGNUM, (char *) &val);
756 supply_register (INTE_REGNUM, (char *) &val);
757 supply_register (FPS_REGNUM, (char *) &val);
758 supply_register (EXO_REGNUM, (char *) &val);
763 /********************************************************* UDI_STORE_REGISTERS
764 ** Store register regno into the target.
765 * If regno==-1 then store all the registers.
769 udi_store_registers (int regno)
776 UDIBool HostEndian = 0;
780 store_register (regno);
786 fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
787 fprintf_unfiltered (gdb_stdlog,
788 "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
789 read_register (NPC_REGNUM),
790 read_register (PC_REGNUM),
791 read_register (PC2_REGNUM));
796 From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
797 To.Space = UDI29KGlobalRegs;
800 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
801 error ("UDIWrite() failed in udi_store_regisetrs");
803 #if defined(GR64_REGNUM)
805 /* Global registers gr64-gr95 */
807 From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
808 To.Space = UDI29KGlobalRegs;
811 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
812 error ("UDIWrite() failed in udi_store_regisetrs");
814 #endif /* GR64_REGNUM */
816 /* Global registers gr96-gr127 */
818 From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
819 To.Space = UDI29KGlobalRegs;
822 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
823 error ("UDIWrite() failed in udi_store_regisetrs");
825 /* Local Registers */
827 From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
828 To.Space = UDI29KLocalRegs;
831 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
832 error ("UDIWrite() failed in udi_store_regisetrs");
835 /* Protected Special Registers *//* VAB through TMR */
837 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
838 To.Space = UDI29KSpecialRegs;
841 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
842 error ("UDIWrite() failed in udi_store_regisetrs");
844 /* PC0, PC1, PC2 possibly as shadow registers */
846 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
847 To.Space = UDI29KSpecialRegs;
850 To.Offset = 20; /* SPC0 */
852 To.Offset = 10; /* PC0 */
853 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
854 error ("UDIWrite() failed in udi_store_regisetrs");
856 /* PC1 via UDI29KPC */
858 From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
860 To.Offset = 0; /* PC1 */
862 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
863 error ("UDIWrite() failed in udi_store_regisetrs");
867 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
868 To.Space = UDI29KSpecialRegs;
871 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
872 error ("UDIWrite() failed in udi_store_regisetrs");
874 /* Unprotected Special Registers */
876 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
877 To.Space = UDI29KSpecialRegs;
879 Count = 135 - 128 + 1;
880 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
881 error ("UDIWrite() failed in udi_store_regisetrs");
883 registers_changed ();
886 /****************************************************** UDI_PREPARE_TO_STORE */
887 /* Get ready to modify the registers array. On machines which store
888 individual registers, this doesn't need to do anything. On machines
889 which store all the registers in one fell swoop, this makes sure
890 that registers contains all the registers from the program being
894 udi_prepare_to_store (void)
896 /* Do nothing, since we can store individual regs */
899 /********************************************************** TRANSLATE_ADDR */
901 translate_addr (CORE_ADDR addr)
903 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
904 /* Check for a virtual address in the kernel */
905 /* Assume physical address of ublock is in paddr_u register */
906 /* FIXME: doesn't work for user virtual addresses */
909 /* PADDR_U register holds the physical address of the ublock */
910 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
911 return (i + addr - (CORE_ADDR) UVADDR);
921 /************************************************* UDI_XFER_INFERIOR_MEMORY */
922 /* FIXME! Merge these two. */
924 udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
925 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
926 struct target_ops *target ATTRIBUTE_UNUSED)
929 memaddr = translate_addr (memaddr);
932 return udi_write_inferior_memory (memaddr, myaddr, len);
934 return udi_read_inferior_memory (memaddr, myaddr, len);
937 /********************************************************** UDI_FILES_INFO */
939 udi_files_info (struct target_ops *target)
941 printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
942 if (prog_name != NULL)
943 printf_unfiltered ("and running program %s", prog_name);
944 printf_unfiltered (".\n");
947 /**************************************************** UDI_INSERT_BREAKPOINT */
949 udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
954 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
955 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
958 if (cnt >= BKPT_TABLE_SIZE)
959 error ("Too many breakpoints set");
961 bkpt_table[cnt].Addr.Offset = addr;
962 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
963 bkpt_table[cnt].PassCount = 1;
964 bkpt_table[cnt].Type = UDIBreakFlagExecute;
966 err = UDISetBreakpoint (bkpt_table[cnt].Addr,
967 bkpt_table[cnt].PassCount,
968 bkpt_table[cnt].Type,
969 &bkpt_table[cnt].BreakId);
972 return 0; /* Success */
974 bkpt_table[cnt].Type = 0;
975 error ("UDISetBreakpoint returned error code %d\n", err);
978 /**************************************************** UDI_REMOVE_BREAKPOINT */
980 udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
985 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
986 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
989 if (cnt >= BKPT_TABLE_SIZE)
990 error ("Can't find breakpoint in table");
992 bkpt_table[cnt].Type = 0;
994 err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
996 return 0; /* Success */
998 error ("UDIClearBreakpoint returned error code %d\n", err);
1007 UDIStop does not really work as advertised. It causes the TIP to close it's
1008 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1009 just invoke udi_close, which seems to get things right.
1013 udi_session_id = -1;
1017 printf_unfiltered ("Target has been stopped.");
1024 /* Keep the target around, e.g. so "run" can do the right thing when
1025 we are already debugging something. */
1027 if (UDIDisconnect (udi_session_id, UDITerminateSession))
1029 warning ("UDIDisconnect() failed");
1032 /* Do not try to close udi_session_id again, later in the program. */
1033 udi_session_id = -1;
1038 Load a program into the target. Args are: `program {options}'. The options
1039 are used to control loading of the program, and are NOT passed onto the
1040 loaded code as arguments. (You need to use the `run' command to do that.)
1043 -ms %d Set mem stack size to %d
1044 -rs %d Set regular stack size to %d
1045 -i send init info (default)
1046 -noi don't send init info
1047 -[tT] Load Text section
1048 -[dD] Load Data section
1049 -[bB] Load BSS section
1050 -[lL] Load Lit section
1054 download (char *load_arg_string, int from_tty)
1056 #define DEFAULT_MEM_STACK_SIZE 0x6000
1057 #define DEFAULT_REG_STACK_SIZE 0x2000
1064 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1066 address_ranges[0].Space = UDI29KIRAMSpace;
1067 address_ranges[0].Offset = 0xffffffff;
1068 address_ranges[0].Size = 0;
1070 address_ranges[1].Space = UDI29KDRAMSpace;
1071 address_ranges[1].Offset = 0xffffffff;
1072 address_ranges[1].Size = 0;
1074 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1075 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1079 filename = strtok (load_arg_string, " \t");
1081 error ("Must specify at least a file name with the load command");
1083 filename = tilde_expand (filename);
1084 make_cleanup (xfree, filename);
1086 while (token = strtok (NULL, " \t"))
1088 if (token[0] == '-')
1092 if (STREQ (token, "ms"))
1093 stack_sizes[1] = atol (strtok (NULL, " \t"));
1094 else if (STREQ (token, "rs"))
1095 stack_sizes[0] = atol (strtok (NULL, " \t"));
1098 load_text = load_data = load_bss = load_lit = 0;
1121 error ("Unknown UDI load option -%s", token - 1);
1128 pbfd = bfd_openr (filename, gnutarget);
1131 /* FIXME: should be using bfd_errmsg, not assuming it was
1132 bfd_error_system_call. */
1133 perror_with_name (filename);
1135 /* FIXME: should be checking for errors from bfd_close (for one thing,
1136 on error it does not free all the storage associated with the
1138 make_cleanup_bfd_close (pbfd);
1143 if (!bfd_check_format (pbfd, bfd_object))
1144 error ("It doesn't seem to be an object file");
1146 for (section = pbfd->sections; section; section = section->next)
1148 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1152 unsigned long section_size, section_end;
1153 const char *section_name;
1155 section_name = bfd_get_section_name (pbfd, section);
1156 if (STREQ (section_name, ".text") && !load_text)
1158 else if (STREQ (section_name, ".data") && !load_data)
1160 else if (STREQ (section_name, ".bss") && !load_bss)
1162 else if (STREQ (section_name, ".lit") && !load_lit)
1165 To.Offset = bfd_get_section_vma (pbfd, section);
1166 section_size = bfd_section_size (pbfd, section);
1167 section_end = To.Offset + section_size;
1169 if (section_size == 0)
1170 /* This is needed at least in the BSS case, where the code
1171 below starts writing before it even checks the size. */
1174 printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
1179 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1181 To.Space = UDI29KIRAMSpace;
1183 address_ranges[0].Offset = min (address_ranges[0].Offset,
1185 address_ranges[0].Size = max (address_ranges[0].Size,
1187 - address_ranges[0].Offset);
1191 To.Space = UDI29KDRAMSpace;
1193 address_ranges[1].Offset = min (address_ranges[1].Offset,
1195 address_ranges[1].Size = max (address_ranges[1].Size,
1197 - address_ranges[1].Offset);
1200 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1206 while (section_size > 0)
1210 Count = min (section_size, 1024);
1212 bfd_get_section_contents (pbfd, section, buffer, fptr,
1215 err = UDIWrite ((UDIHostMemPtr) buffer, /* From */
1218 (UDISizeT) 1, /* Size */
1219 &Count, /* CountDone */
1220 (UDIBool) 0); /* HostEndian */
1222 error ("UDIWrite failed, error = %d", err);
1226 section_size -= Count;
1233 unsigned long zero = 0;
1235 /* Write a zero byte at the vma */
1236 /* FIXME: Broken for sections of 1-3 bytes (we test for
1238 err = UDIWrite ((UDIHostMemPtr) & zero, /* From */
1240 (UDICount) 1, /* Count */
1241 (UDISizeT) 4, /* Size */
1242 &Count, /* CountDone */
1243 (UDIBool) 0); /* HostEndian */
1245 error ("UDIWrite failed, error = %d", err);
1250 /* Now, duplicate it for the length of the BSS */
1251 err = UDICopy (From, /* From */
1253 (UDICount) (section_size / 4 - 1), /* Count */
1254 (UDISizeT) 4, /* Size */
1255 &Count, /* CountDone */
1256 (UDIBool) 1); /* Direction */
1262 xerr = UDIGetErrorMsg (err, 100, message, &Count);
1264 fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1266 fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1267 error ("UDICopy failed, error = %d", err);
1274 entry.Space = UDI29KIRAMSpace;
1275 entry.Offset = bfd_get_start_address (pbfd);
1280 /* Function to download an image into the remote target. */
1283 udi_load (char *args, int from_tty)
1285 download (args, from_tty);
1287 /* As a convenience, pick up any symbol info that is in the program
1288 being loaded. Note that we assume that the program is the``mainline'';
1289 if this is not always true, then this code will need to be augmented. */
1290 symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
1292 /* Getting new symbols may change our opinion about what is
1294 reinit_frame_cache ();
1297 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1298 ** Copy LEN bytes of data from debugger memory at MYADDR
1299 to inferior's memory at MEMADDR. Returns number of bytes written. */
1301 udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1308 UDICount CountDone = 0;
1309 UDIBool HostEndian = 0;
1311 To.Space = udi_memory_space (memaddr);
1312 From = (UDIUInt32 *) myaddr;
1314 while (nwritten < len)
1316 Count = len - nwritten;
1317 if (Count > MAXDATA)
1319 To.Offset = memaddr + nwritten;
1320 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
1322 error ("UDIWrite() failed in udi_write_inferior_memory");
1327 nwritten += CountDone;
1334 /**************************************************** UDI_READ_INFERIOR_MEMORY
1335 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1336 at debugger address MYADDR. Returns number of bytes read. */
1338 udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1345 UDICount CountDone = 0;
1346 UDIBool HostEndian = 0;
1349 From.Space = udi_memory_space (memaddr);
1350 To = (UDIUInt32 *) myaddr;
1354 Count = len - nread;
1355 if (Count > MAXDATA)
1357 From.Offset = memaddr + nread;
1358 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
1360 error ("UDIRead() failed in udi_read_inferior_memory");
1372 /********************************************************************* WARNING
1374 udi_warning (int num)
1376 error ("ERROR while loading program into remote TIP: $d\n", num);
1380 /*****************************************************************************/
1381 /* Fetch a single register indicatated by 'regno'.
1382 * Returns 0/-1 on success/failure.
1385 fetch_register (int regno)
1392 UDIBool HostEndian = 0;
1396 if (regno == GR1_REGNUM)
1398 From.Space = UDI29KGlobalRegs;
1401 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1403 From.Space = UDI29KGlobalRegs;
1404 From.Offset = (regno - GR96_REGNUM) + 96;;
1407 #if defined(GR64_REGNUM)
1409 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1411 From.Space = UDI29KGlobalRegs;
1412 From.Offset = (regno - GR64_REGNUM) + 64;
1415 #endif /* GR64_REGNUM */
1417 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1419 From.Space = UDI29KLocalRegs;
1420 From.Offset = (regno - LR0_REGNUM);
1422 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1425 /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */
1426 supply_register (regno, (char *) &val);
1427 return; /* Pretend Success */
1431 From.Space = UDI29KSpecialRegs;
1432 From.Offset = regnum_to_srnum (regno);
1435 if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
1436 error ("UDIRead() failed in udi_fetch_registers");
1438 supply_register (regno, (char *) &To);
1441 fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
1442 REGISTER_NAME (regno), To);
1444 /*****************************************************************************/
1445 /* Store a single register indicated by 'regno'.
1446 * Returns 0/-1 on success/failure.
1449 store_register (int regno)
1457 UDIBool HostEndian = 0;
1459 From = read_register (regno); /* get data value */
1462 fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
1463 REGISTER_NAME (regno), From);
1465 if (regno == GR1_REGNUM)
1467 To.Space = UDI29KGlobalRegs;
1469 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1470 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1471 * register cache. Do this *after* calling read_register, because we want
1472 * read_register to return the value that write_register has just stuffed
1473 * into the registers array, not the value of the register fetched from
1476 registers_changed ();
1478 #if defined(GR64_REGNUM)
1479 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1481 To.Space = UDI29KGlobalRegs;
1482 To.Offset = (regno - GR64_REGNUM) + 64;
1483 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1485 #endif /* GR64_REGNUM */
1486 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1488 To.Space = UDI29KGlobalRegs;
1489 To.Offset = (regno - GR96_REGNUM) + 96;
1490 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1492 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1494 To.Space = UDI29KLocalRegs;
1495 To.Offset = (regno - LR0_REGNUM);
1496 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1498 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1499 return 0; /* Pretend Success */
1500 else if (regno == PC_REGNUM)
1502 /* PC1 via UDI29KPC */
1504 To.Space = UDI29KPC;
1505 To.Offset = 0; /* PC1 */
1506 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1508 /* Writing to this loc actually changes the values of pc0 & pc1 */
1510 register_valid[PC_REGNUM] = 0; /* pc1 */
1511 register_valid[NPC_REGNUM] = 0; /* pc0 */
1514 /* An unprotected or protected special register */
1516 To.Space = UDI29KSpecialRegs;
1517 To.Offset = regnum_to_srnum (regno);
1518 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1522 error ("UDIWrite() failed in store_registers");
1526 /********************************************************** REGNUM_TO_SRNUM */
1528 * Convert a gdb special register number to a 29000 special register number.
1531 regnum_to_srnum (int regno)
1556 return (USE_SHADOW_PC ? (20) : (10));
1558 return (USE_SHADOW_PC ? (21) : (11));
1560 return (USE_SHADOW_PC ? (22) : (12));
1590 return (255); /* Failure ? */
1593 /****************************************************************************/
1595 * Determine the Target memory space qualifier based on the addr.
1596 * FIXME: Can't distinguis I_ROM/D_ROM.
1597 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1600 udi_memory_space (CORE_ADDR addr)
1602 UDIUInt32 tstart = IMemStart;
1603 UDIUInt32 tend = tstart + IMemSize;
1604 UDIUInt32 dstart = DMemStart;
1605 UDIUInt32 dend = tstart + DMemSize;
1606 UDIUInt32 rstart = RMemStart;
1607 UDIUInt32 rend = tstart + RMemSize;
1609 if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
1611 return UDI29KIRAMSpace;
1613 else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
1615 return UDI29KDRAMSpace;
1617 else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
1619 /* FIXME: how do we determine between D_ROM and I_ROM */
1620 return UDI29KIROMSpace;
1622 else /* FIXME: what do me do now? */
1623 return UDI29KDRAMSpace; /* Hmmm! */
1625 /*********************************************************************** STUBS
1636 struct ui_file *EchoFile = 0; /* used for debugging */
1637 int QuietMode = 0; /* used for debugging */
1639 #ifdef NO_HIF_SUPPORT
1640 service_HIF (union msg_t *msg)
1642 return (0); /* Emulate a failure */
1646 /* Target_ops vector. Not static because there does not seem to be
1647 any portable way to do a forward declaration of a static variable.
1648 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1649 /bin/cc doesn't like "static" twice. */
1651 struct target_ops udi_ops;
1656 udi_ops.to_shortname = "udi";
1657 udi_ops.to_longname = "Remote UDI connected TIP";
1658 udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1660 `configuration-id AF_INET hostname port-number'\n\
1661 To connect via the network, where hostname and port-number specify the\n\
1662 host and port where you can connect via UDI.\n\
1663 configuration-id is unused.\n\
1665 `configuration-id AF_UNIX socket-name tip-program'\n\
1666 To connect using a local connection to the \"tip.exe\" program which is\n\
1667 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1668 tip program must already be started; connect to it using that socket.\n\
1669 If not, start up tip-program, which should be the name of the tip\n\
1670 program. If appropriate, the PATH environment variable is searched.\n\
1671 configuration-id is unused.\n\
1673 `configuration-id'\n\
1674 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1675 are files containing lines in the above formats. configuration-id is\n\
1676 used to pick which line of the file to use.";
1677 udi_ops.to_open = udi_open;
1678 udi_ops.to_close = udi_close;
1679 udi_ops.to_attach = udi_attach;
1680 udi_ops.to_detach = udi_detach;
1681 udi_ops.to_resume = udi_resume;
1682 udi_ops.to_wait = udi_wait;
1683 udi_ops.to_fetch_registers = udi_fetch_registers;
1684 udi_ops.to_store_registers = udi_store_registers;
1685 udi_ops.to_prepare_to_store = udi_prepare_to_store;
1686 udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
1687 udi_ops.to_files_info = udi_files_info;
1688 udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
1689 udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
1690 udi_ops.to_terminal_init = 0;
1691 udi_ops.to_terminal_inferior = 0;
1692 udi_ops.to_terminal_ours_for_output = 0;
1693 udi_ops.to_terminal_ours = 0;
1694 udi_ops.to_terminal_info = 0;
1695 udi_ops.to_kill = udi_kill;
1696 udi_ops.to_load = udi_load;
1697 udi_ops.to_lookup_symbol = 0;
1698 udi_ops.to_create_inferior = udi_create_inferior;
1699 udi_ops.to_mourn_inferior = udi_mourn;
1700 udi_ops.to_can_run = 0;
1701 udi_ops.to_notice_signals = 0;
1702 udi_ops.to_thread_alive = 0;
1703 udi_ops.to_stop = 0;
1704 udi_ops.to_stratum = process_stratum;
1705 udi_ops.DONT_USE = 0;
1706 udi_ops.to_has_all_memory = 1;
1707 udi_ops.to_has_memory = 1;
1708 udi_ops.to_has_stack = 1;
1709 udi_ops.to_has_registers = 1;
1710 udi_ops.to_has_execution = 1;
1711 udi_ops.to_sections = 0;
1712 udi_ops.to_sections_end = 0;
1713 udi_ops.to_magic = OPS_MAGIC;
1717 _initialize_remote_udi (void)
1720 add_target (&udi_ops);