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. */
42 #include "gdb_string.h"
45 #include "29k-share/udi/udiproc.h"
48 #include "gdbcore.h" /* For download function */
50 /* access the register store directly, without going through
51 the normal handler functions. This avoids an extra data copy. */
53 extern int stop_soon_quietly; /* for wait_for_inferior */
54 extern struct value *call_function_by_hand ();
55 static void udi_resume (int pid, int step, enum target_signal sig);
56 static void udi_fetch_registers (int regno);
57 static void udi_load (char *args, int from_tty);
58 static void fetch_register (int regno);
59 static void udi_store_registers (int regno);
60 static int store_register (int regno);
61 static int regnum_to_srnum (int regno);
62 static void udi_close (int quitting);
63 static CPUSpace udi_memory_space (CORE_ADDR addr);
64 static int udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr,
66 static int udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr,
68 static void download (char *load_arg_string, int from_tty);
69 char CoffFileName[100] = "";
71 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
72 #define USE_SHADOW_PC ((processor_type == a29k_freeze_mode) && FREEZE_MODE)
74 static int timeout = 5;
75 extern struct target_ops udi_ops; /* Forward declaration */
77 /* Special register enumeration.
80 /******************************************************************* UDI DATA*/
81 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
82 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
83 udi_open knows that we don't have a file open when the program
86 UDISessionId udi_session_id = -1;
87 static char *udi_config_id;
89 CPUOffset IMemStart = 0;
90 CPUSizeT IMemSize = 0;
91 CPUOffset DMemStart = 0;
92 CPUSizeT DMemSize = 0;
93 CPUOffset RMemStart = 0;
94 CPUSizeT RMemSize = 0;
98 UDIMemoryRange address_ranges[2]; /* Text and data */
100 {0, 0}; /* Entry point */
101 CPUSizeT stack_sizes[2]; /* Regular and memory stacks */
103 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
106 typedef struct bkpt_entry_str
111 unsigned int BreakId;
114 #define BKPT_TABLE_SIZE 40
115 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
116 extern char dfe_errmsg[]; /* error string */
118 /* malloc'd name of the program on the remote system. */
119 static char *prog_name = NULL;
121 /* This is called not only when we first attach, but also when the
122 user types "run" after having attached. */
125 udi_create_inferior (char *execfile, char *args, char **env)
131 if (prog_name != NULL)
133 prog_name = savestring (execfile, strlen (execfile));
135 else if (entry.Offset)
138 error ("No image loaded into target.");
140 if (udi_session_id < 0)
142 /* If the TIP is not open, open it. */
143 if (UDIConnect (udi_config_id, &udi_session_id))
144 error ("UDIConnect() failed: %s\n", dfe_errmsg);
145 /* We will need to download the program. */
149 inferior_pid = 40000;
152 download (execfile, 0);
154 args1 = alloca (strlen (execfile) + strlen (args) + 2);
156 if (execfile[0] == '\0')
158 /* It is empty. We need to quote it somehow, or else the target
159 will think there is no argument being passed here. According
160 to the UDI spec it is quoted "according to TIP OS rules" which
161 I guess means quoting it like the Unix shell should work
162 (sounds pretty bogus to me...). In fact it doesn't work (with
163 isstip anyway), but passing in two quotes as the argument seems
164 like a reasonable enough behavior anyway (I guess). */
166 strcpy (args1, "''");
168 strcpy (args1, execfile);
170 strcat (args1, args);
172 UDIInitializeProcess (address_ranges, /* ProcessMemory[] */
173 (UDIInt) 2, /* NumberOfRanges */
174 entry, /* EntryPoint */
175 stack_sizes, /* *StackSizes */
176 (UDIInt) 2, /* NumberOfStacks */
177 args1); /* ArgString */
179 init_wait_for_inferior ();
180 clear_proceed_status ();
181 proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
188 /* Requiring "target udi" each time you run is a major pain. I suspect
189 this was just blindy copied from remote.c, in which "target" and
190 "run" are combined. Having a udi target without an inferior seems
191 to work between "target udi" and "run", so why not now? */
192 pop_target (); /* Pop back to no-child state */
194 /* But if we're going to want to run it again, we better remove the
196 remove_breakpoints ();
197 generic_mourn_inferior ();
200 /******************************************************************** UDI_OPEN
201 ** Open a connection to remote TIP.
202 NAME is the socket domain used for communication with the TIP,
203 then a space and the socket name or TIP-host name.
204 '<udi_udi_config_id>' for example.
207 /* XXX - need cleanups for udiconnect for various failures!!! */
210 udi_open (char *name, int from_tty)
215 UDIMemoryRange KnownMemory[10];
216 UDIUInt32 ChipVersions[10];
217 UDIInt NumberOfRanges = 10;
218 UDIInt NumberOfChips = 10;
220 UDIUInt32 TIPId, TargetId, DFEId, DFE, TIP, DFEIPCId, TIPIPCId;
222 target_preopen (from_tty);
226 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
227 bkpt_table[cnt].Type = 0;
230 xfree (udi_config_id);
233 error ("Usage: target udi config_id, where config_id appears in udi_soc file");
235 udi_config_id = xstrdup (strtok (name, " \t"));
237 if (UDIConnect (udi_config_id, &udi_session_id))
238 /* FIXME: Should set udi_session_id to -1 here. */
239 error ("UDIConnect() failed: %s\n", dfe_errmsg);
241 push_target (&udi_ops);
244 ** Initialize target configuration structure (global)
246 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
247 ChipVersions, &NumberOfChips))
248 error ("UDIGetTargetConfig() failed");
249 if (NumberOfChips > 2)
250 fprintf_unfiltered (gdb_stderr, "Target has more than one processor\n");
251 for (cnt = 0; cnt < NumberOfRanges; cnt++)
253 switch (KnownMemory[cnt].Space)
256 fprintf_unfiltered (gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
260 case UDI29KIROMSpace:
261 RMemStart = KnownMemory[cnt].Offset;
262 RMemSize = KnownMemory[cnt].Size;
264 case UDI29KIRAMSpace:
265 IMemStart = KnownMemory[cnt].Offset;
266 IMemSize = KnownMemory[cnt].Size;
268 case UDI29KDRAMSpace:
269 DMemStart = KnownMemory[cnt].Offset;
270 DMemSize = KnownMemory[cnt].Size;
275 a29k_get_processor_type ();
277 if (UDICreateProcess (&PId))
278 fprintf_unfiltered (gdb_stderr, "UDICreateProcess() failed\n");
280 /* Print out some stuff, letting the user now what's going on */
281 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
283 error ("UDICapabilities() failed");
286 printf_filtered ("Connected via UDI socket,\n\
287 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
288 (DFEIPCId >> 8) & 0xf, (DFEIPCId >> 4) & 0xf, DFEIPCId & 0xf,
289 (TIPIPCId >> 8) & 0xf, (TIPIPCId >> 4) & 0xf, TIPIPCId & 0xf,
290 (TargetId >> 8) & 0xf, (TargetId >> 4) & 0xf, TargetId & 0xf,
295 /******************************************************************* UDI_CLOSE
296 Close the open connection to the TIP process.
297 Use this when you want to detach and do something else
300 udi_close ( /*FIXME: how is quitting used */
303 if (udi_session_id < 0)
306 /* We should never get here if there isn't something valid in
309 if (UDIDisconnect (udi_session_id, UDITerminateSession))
312 warning ("UDIDisconnect() failed in udi_close");
314 error ("UDIDisconnect() failed in udi_close");
317 /* Do not try to close udi_session_id again, later in the program. */
321 printf_filtered (" Ending remote debugging\n");
324 /**************************************************************** UDI_ATACH */
325 /* Attach to a program that is already loaded and running
326 * Upon exiting the process's execution is stopped.
329 udi_attach (char *args, int from_tty)
336 UDIBool HostEndian = 0;
340 error_no_arg ("program to attach");
342 if (udi_session_id < 0)
343 error ("UDI connection not opened yet, use the 'target udi' command.\n");
346 printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
349 From.Space = UDI29KSpecialRegs;
351 if (err = UDIRead (From, &PC_adds, Count, Size, &CountDone, HostEndian))
352 error ("UDIRead failed in udi_attach");
353 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
355 /************************************************************* UDI_DETACH */
356 /* Terminate the open connection to the TIP process.
357 Use this when you want to detach and do something else
358 with your gdb. Leave remote process running (with no breakpoints set). */
360 udi_detach (char *args, int from_tty)
363 remove_breakpoints (); /* Just in case there were any left in */
365 if (UDIDisconnect (udi_session_id, UDIContinueSession))
366 error ("UDIDisconnect() failed in udi_detach");
368 /* Don't try to UDIDisconnect it again in udi_close, which is called from
376 printf_unfiltered ("Detaching from TIP\n");
380 /****************************************************************** UDI_RESUME
381 ** Tell the remote machine to resume. */
384 udi_resume (int pid, int step, enum target_signal sig)
388 UDIStepType StepType = UDIStepNatural;
391 if (step) /* step 1 instruction */
393 tip_error = UDIStep (Steps, StepType, Range);
397 fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
398 error ("failed in udi_resume");
402 error ("UDIExecute() failed in udi_resume");
405 /******************************************************************** UDI_WAIT
406 ** Wait until the remote machine stops, then return,
407 storing status in STATUS just as `wait' would. */
410 udi_wait (int pid, struct target_waitstatus *status)
416 int old_timeout = timeout;
417 int old_immediate_quit = immediate_quit;
420 status->kind = TARGET_WAITKIND_EXITED;
421 status->value.integer = 0;
423 /* wait for message to arrive. It should be:
424 If the target stops executing, udi_wait() should return.
426 timeout = 0; /* Wait indefinetly for a message */
427 immediate_quit = 1; /* Helps ability to QUIT */
432 MaxTime = UDIWaitForever;
433 UDIWait (MaxTime, &PId, &StopReason);
434 QUIT; /* Let user quit if they want */
436 switch (StopReason & UDIGrossState)
439 if (UDIGetStdout (sbuf, (UDISizeT) SBUF_MAX, &CountDone))
440 /* This is said to happen if the program tries to output
441 a whole bunch of output (more than SBUF_MAX, I would
442 guess). It doesn't seem to happen with the simulator. */
443 warning ("UDIGetStdout() failed in udi_wait");
444 fwrite (sbuf, 1, CountDone, stdout);
445 gdb_flush (gdb_stdout);
449 UDIGetStderr (sbuf, (UDISizeT) SBUF_MAX, &CountDone);
450 fwrite (sbuf, 1, CountDone, stderr);
451 gdb_flush (gdb_stderr);
465 while (i < SBUF_MAX && ch != '\n');
466 UDIPutStdin (sbuf, (UDISizeT) i, &CountDone);
471 /* In spite of the fact that we told UDIWait to wait forever, it will
472 return spuriously sometimes. */
481 switch (StopReason & UDIGrossState)
484 printf_unfiltered ("Am290*0 received vector number %d\n", StopReason >> 24);
486 switch ((StopReason >> 8) & 0xff)
488 case 0: /* Illegal opcode */
489 printf_unfiltered (" (break point)\n");
490 status->kind = TARGET_WAITKIND_STOPPED;
491 status->value.sig = TARGET_SIGNAL_TRAP;
493 case 1: /* Unaligned Access */
494 status->kind = TARGET_WAITKIND_STOPPED;
495 status->value.sig = TARGET_SIGNAL_BUS;
499 status->kind = TARGET_WAITKIND_STOPPED;
500 status->value.sig = TARGET_SIGNAL_FPE;
502 case 5: /* Protection Violation */
503 status->kind = TARGET_WAITKIND_STOPPED;
504 /* Why not SEGV? What is a Protection Violation? */
505 status->value.sig = TARGET_SIGNAL_ILL;
509 case 8: /* User Instruction Mapping Miss */
510 case 9: /* User Data Mapping Miss */
511 case 10: /* Supervisor Instruction Mapping Miss */
512 case 11: /* Supervisor Data Mapping Miss */
513 status->kind = TARGET_WAITKIND_STOPPED;
514 status->value.sig = TARGET_SIGNAL_SEGV;
518 status->kind = TARGET_WAITKIND_STOPPED;
519 status->value.sig = TARGET_SIGNAL_ILL;
522 status->kind = TARGET_WAITKIND_STOPPED;
523 status->value.sig = TARGET_SIGNAL_ALRM;
526 status->kind = TARGET_WAITKIND_STOPPED;
527 status->value.sig = TARGET_SIGNAL_TRAP;
532 case 19: /* INTR3/Internal */
535 status->kind = TARGET_WAITKIND_STOPPED;
536 status->value.sig = TARGET_SIGNAL_INT;
538 case 22: /* Floating-Point Exception */
539 status->kind = TARGET_WAITKIND_STOPPED;
541 status->value.sig = TARGET_SIGNAL_ILL;
543 case 77: /* assert 77 */
544 status->kind = TARGET_WAITKIND_STOPPED;
545 status->value.sig = TARGET_SIGNAL_TRAP;
548 status->kind = TARGET_WAITKIND_EXITED;
549 status->value.integer = 0;
552 case UDINotExecuting:
553 status->kind = TARGET_WAITKIND_STOPPED;
554 status->value.sig = TARGET_SIGNAL_TERM;
557 status->kind = TARGET_WAITKIND_STOPPED;
558 status->value.sig = TARGET_SIGNAL_TSTP;
561 status->kind = TARGET_WAITKIND_STOPPED;
562 status->value.sig = TARGET_SIGNAL_URG;
566 status->kind = TARGET_WAITKIND_STOPPED;
567 status->value.sig = TARGET_SIGNAL_TRAP;
570 status->kind = TARGET_WAITKIND_STOPPED;
571 status->value.sig = TARGET_SIGNAL_STOP;
574 status->kind = TARGET_WAITKIND_STOPPED;
575 status->value.sig = TARGET_SIGNAL_KILL;
579 status->kind = TARGET_WAITKIND_EXITED;
580 status->value.integer = 0;
583 timeout = old_timeout; /* Restore original timeout value */
584 immediate_quit = old_immediate_quit;
589 /* Handy for debugging */
597 UDIBool HostEndian = 0;
600 unsigned long myregs[256];
603 From.Space = UDI29KPC;
605 To = (UDIUInt32 *) pc;
608 err = UDIRead (From, To, Count, Size, &CountDone, HostEndian);
610 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
611 err, CountDone, pc[0], pc[1]);
613 udi_fetch_registers (-1);
615 printf_unfiltered ("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *) ®isters[4 * PC_REGNUM],
616 *(int *) ®isters[4 * NPC_REGNUM]);
618 /* Now, read all the registers globally */
620 From.Space = UDI29KGlobalRegs;
622 err = UDIRead (From, myregs, 256, 4, &CountDone, HostEndian);
624 printf ("err = %d, CountDone = %d\n", err, CountDone);
628 for (i = 0; i < 256; i += 2)
629 printf ("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
630 myregs[i + 1], myregs[i + 1]);
637 /********************************************************** UDI_FETCH_REGISTERS
638 * Read a remote register 'regno'.
639 * If regno==-1 then read all the registers.
642 udi_fetch_registers (int regno)
649 UDIBool HostEndian = 0;
655 fetch_register (regno);
661 From.Space = UDI29KGlobalRegs;
663 To = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
665 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
666 error ("UDIRead() failed in udi_fetch_registers");
668 register_valid[GR1_REGNUM] = 1;
670 #if defined(GR64_REGNUM) /* Read gr64-127 */
672 /* Global Registers gr64-gr95 */
674 From.Space = UDI29KGlobalRegs;
676 To = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
678 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
679 error ("UDIRead() failed in udi_fetch_registers");
681 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
682 register_valid[i] = 1;
684 #endif /* GR64_REGNUM */
686 /* Global Registers gr96-gr127 */
688 From.Space = UDI29KGlobalRegs;
690 To = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
692 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
693 error ("UDIRead() failed in udi_fetch_registers");
695 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
696 register_valid[i] = 1;
698 /* Local Registers */
700 From.Space = UDI29KLocalRegs;
702 To = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
704 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
705 error ("UDIRead() failed in udi_fetch_registers");
707 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
708 register_valid[i] = 1;
710 /* Protected Special Registers */
712 From.Space = UDI29KSpecialRegs;
714 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
716 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
717 error ("UDIRead() failed in udi_fetch_registers");
719 for (i = SR_REGNUM (0); i < SR_REGNUM (0) + 15; i++)
720 register_valid[i] = 1;
723 { /* Let regno_to_srnum() handle the register number */
724 fetch_register (NPC_REGNUM);
725 fetch_register (PC_REGNUM);
726 fetch_register (PC2_REGNUM);
728 /* Unprotected Special Registers sr128-sr135 */
730 From.Space = UDI29KSpecialRegs;
732 To = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
733 Count = 135 - 128 + 1;
734 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
735 error ("UDIRead() failed in udi_fetch_registers");
737 for (i = SR_REGNUM (128); i < SR_REGNUM (128) + 135 - 128 + 1; i++)
738 register_valid[i] = 1;
743 fprintf_unfiltered (gdb_stdlog, "Fetching all registers\n");
744 fprintf_unfiltered (gdb_stdlog,
745 "Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
746 read_register (NPC_REGNUM),
747 read_register (PC_REGNUM),
748 read_register (PC2_REGNUM));
751 /* There doesn't seem to be any way to get these. */
754 supply_register (FPE_REGNUM, (char *) &val);
755 supply_register (INTE_REGNUM, (char *) &val);
756 supply_register (FPS_REGNUM, (char *) &val);
757 supply_register (EXO_REGNUM, (char *) &val);
762 /********************************************************* UDI_STORE_REGISTERS
763 ** Store register regno into the target.
764 * If regno==-1 then store all the registers.
768 udi_store_registers (int regno)
775 UDIBool HostEndian = 0;
779 store_register (regno);
785 fprintf_unfiltered (gdb_stdlog, "Storing all registers\n");
786 fprintf_unfiltered (gdb_stdlog,
787 "PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
788 read_register (NPC_REGNUM),
789 read_register (PC_REGNUM),
790 read_register (PC2_REGNUM));
795 From = (UDIUInt32 *) & registers[4 * GR1_REGNUM];
796 To.Space = UDI29KGlobalRegs;
799 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
800 error ("UDIWrite() failed in udi_store_regisetrs");
802 #if defined(GR64_REGNUM)
804 /* Global registers gr64-gr95 */
806 From = (UDIUInt32 *) & registers[4 * GR64_REGNUM];
807 To.Space = UDI29KGlobalRegs;
810 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
811 error ("UDIWrite() failed in udi_store_regisetrs");
813 #endif /* GR64_REGNUM */
815 /* Global registers gr96-gr127 */
817 From = (UDIUInt32 *) & registers[4 * GR96_REGNUM];
818 To.Space = UDI29KGlobalRegs;
821 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
822 error ("UDIWrite() failed in udi_store_regisetrs");
824 /* Local Registers */
826 From = (UDIUInt32 *) & registers[4 * LR0_REGNUM];
827 To.Space = UDI29KLocalRegs;
830 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
831 error ("UDIWrite() failed in udi_store_regisetrs");
834 /* Protected Special Registers *//* VAB through TMR */
836 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (0)];
837 To.Space = UDI29KSpecialRegs;
840 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
841 error ("UDIWrite() failed in udi_store_regisetrs");
843 /* PC0, PC1, PC2 possibly as shadow registers */
845 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (10)];
846 To.Space = UDI29KSpecialRegs;
849 To.Offset = 20; /* SPC0 */
851 To.Offset = 10; /* PC0 */
852 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
853 error ("UDIWrite() failed in udi_store_regisetrs");
855 /* PC1 via UDI29KPC */
857 From = (UDIUInt32 *) & registers[4 * PC_REGNUM];
859 To.Offset = 0; /* PC1 */
861 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
862 error ("UDIWrite() failed in udi_store_regisetrs");
866 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (13)];
867 To.Space = UDI29KSpecialRegs;
870 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
871 error ("UDIWrite() failed in udi_store_regisetrs");
873 /* Unprotected Special Registers */
875 From = (UDIUInt32 *) & registers[4 * SR_REGNUM (128)];
876 To.Space = UDI29KSpecialRegs;
878 Count = 135 - 128 + 1;
879 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
880 error ("UDIWrite() failed in udi_store_regisetrs");
882 registers_changed ();
885 /****************************************************** UDI_PREPARE_TO_STORE */
886 /* Get ready to modify the registers array. On machines which store
887 individual registers, this doesn't need to do anything. On machines
888 which store all the registers in one fell swoop, this makes sure
889 that registers contains all the registers from the program being
893 udi_prepare_to_store (void)
895 /* Do nothing, since we can store individual regs */
898 /********************************************************** TRANSLATE_ADDR */
900 translate_addr (CORE_ADDR addr)
902 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
903 /* Check for a virtual address in the kernel */
904 /* Assume physical address of ublock is in paddr_u register */
905 /* FIXME: doesn't work for user virtual addresses */
908 /* PADDR_U register holds the physical address of the ublock */
909 CORE_ADDR i = (CORE_ADDR) read_register (PADDR_U_REGNUM);
910 return (i + addr - (CORE_ADDR) UVADDR);
920 /************************************************* UDI_XFER_INFERIOR_MEMORY */
921 /* FIXME! Merge these two. */
923 udi_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
924 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
925 struct target_ops *target ATTRIBUTE_UNUSED)
928 memaddr = translate_addr (memaddr);
931 return udi_write_inferior_memory (memaddr, myaddr, len);
933 return udi_read_inferior_memory (memaddr, myaddr, len);
936 /********************************************************** UDI_FILES_INFO */
938 udi_files_info (struct target_ops *target)
940 printf_unfiltered ("\tAttached to UDI socket to %s", udi_config_id);
941 if (prog_name != NULL)
942 printf_unfiltered ("and running program %s", prog_name);
943 printf_unfiltered (".\n");
946 /**************************************************** UDI_INSERT_BREAKPOINT */
948 udi_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
953 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
954 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
957 if (cnt >= BKPT_TABLE_SIZE)
958 error ("Too many breakpoints set");
960 bkpt_table[cnt].Addr.Offset = addr;
961 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
962 bkpt_table[cnt].PassCount = 1;
963 bkpt_table[cnt].Type = UDIBreakFlagExecute;
965 err = UDISetBreakpoint (bkpt_table[cnt].Addr,
966 bkpt_table[cnt].PassCount,
967 bkpt_table[cnt].Type,
968 &bkpt_table[cnt].BreakId);
971 return 0; /* Success */
973 bkpt_table[cnt].Type = 0;
974 error ("UDISetBreakpoint returned error code %d\n", err);
977 /**************************************************** UDI_REMOVE_BREAKPOINT */
979 udi_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
984 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
985 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
988 if (cnt >= BKPT_TABLE_SIZE)
989 error ("Can't find breakpoint in table");
991 bkpt_table[cnt].Type = 0;
993 err = UDIClearBreakpoint (bkpt_table[cnt].BreakId);
995 return 0; /* Success */
997 error ("UDIClearBreakpoint returned error code %d\n", err);
1006 UDIStop does not really work as advertised. It causes the TIP to close it's
1007 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1008 just invoke udi_close, which seems to get things right.
1012 udi_session_id = -1;
1016 printf_unfiltered ("Target has been stopped.");
1023 /* Keep the target around, e.g. so "run" can do the right thing when
1024 we are already debugging something. */
1026 if (UDIDisconnect (udi_session_id, UDITerminateSession))
1028 warning ("UDIDisconnect() failed");
1031 /* Do not try to close udi_session_id again, later in the program. */
1032 udi_session_id = -1;
1037 Load a program into the target. Args are: `program {options}'. The options
1038 are used to control loading of the program, and are NOT passed onto the
1039 loaded code as arguments. (You need to use the `run' command to do that.)
1042 -ms %d Set mem stack size to %d
1043 -rs %d Set regular stack size to %d
1044 -i send init info (default)
1045 -noi don't send init info
1046 -[tT] Load Text section
1047 -[dD] Load Data section
1048 -[bB] Load BSS section
1049 -[lL] Load Lit section
1053 download (char *load_arg_string, int from_tty)
1055 #define DEFAULT_MEM_STACK_SIZE 0x6000
1056 #define DEFAULT_REG_STACK_SIZE 0x2000
1063 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1065 address_ranges[0].Space = UDI29KIRAMSpace;
1066 address_ranges[0].Offset = 0xffffffff;
1067 address_ranges[0].Size = 0;
1069 address_ranges[1].Space = UDI29KDRAMSpace;
1070 address_ranges[1].Offset = 0xffffffff;
1071 address_ranges[1].Size = 0;
1073 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1074 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1078 filename = strtok (load_arg_string, " \t");
1080 error ("Must specify at least a file name with the load command");
1082 filename = tilde_expand (filename);
1083 make_cleanup (xfree, filename);
1085 while (token = strtok (NULL, " \t"))
1087 if (token[0] == '-')
1091 if (STREQ (token, "ms"))
1092 stack_sizes[1] = atol (strtok (NULL, " \t"));
1093 else if (STREQ (token, "rs"))
1094 stack_sizes[0] = atol (strtok (NULL, " \t"));
1097 load_text = load_data = load_bss = load_lit = 0;
1120 error ("Unknown UDI load option -%s", token - 1);
1127 pbfd = bfd_openr (filename, gnutarget);
1130 /* FIXME: should be using bfd_errmsg, not assuming it was
1131 bfd_error_system_call. */
1132 perror_with_name (filename);
1134 /* FIXME: should be checking for errors from bfd_close (for one thing,
1135 on error it does not free all the storage associated with the
1137 make_cleanup_bfd_close (pbfd);
1142 if (!bfd_check_format (pbfd, bfd_object))
1143 error ("It doesn't seem to be an object file");
1145 for (section = pbfd->sections; section; section = section->next)
1147 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1151 unsigned long section_size, section_end;
1152 const char *section_name;
1154 section_name = bfd_get_section_name (pbfd, section);
1155 if (STREQ (section_name, ".text") && !load_text)
1157 else if (STREQ (section_name, ".data") && !load_data)
1159 else if (STREQ (section_name, ".bss") && !load_bss)
1161 else if (STREQ (section_name, ".lit") && !load_lit)
1164 To.Offset = bfd_get_section_vma (pbfd, section);
1165 section_size = bfd_section_size (pbfd, section);
1166 section_end = To.Offset + section_size;
1168 if (section_size == 0)
1169 /* This is needed at least in the BSS case, where the code
1170 below starts writing before it even checks the size. */
1173 printf_unfiltered ("[Loading section %s at %x (%d bytes)]\n",
1178 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1180 To.Space = UDI29KIRAMSpace;
1182 address_ranges[0].Offset = min (address_ranges[0].Offset,
1184 address_ranges[0].Size = max (address_ranges[0].Size,
1186 - address_ranges[0].Offset);
1190 To.Space = UDI29KDRAMSpace;
1192 address_ranges[1].Offset = min (address_ranges[1].Offset,
1194 address_ranges[1].Size = max (address_ranges[1].Size,
1196 - address_ranges[1].Offset);
1199 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1205 while (section_size > 0)
1209 Count = min (section_size, 1024);
1211 bfd_get_section_contents (pbfd, section, buffer, fptr,
1214 err = UDIWrite ((UDIHostMemPtr) buffer, /* From */
1217 (UDISizeT) 1, /* Size */
1218 &Count, /* CountDone */
1219 (UDIBool) 0); /* HostEndian */
1221 error ("UDIWrite failed, error = %d", err);
1225 section_size -= Count;
1232 unsigned long zero = 0;
1234 /* Write a zero byte at the vma */
1235 /* FIXME: Broken for sections of 1-3 bytes (we test for
1237 err = UDIWrite ((UDIHostMemPtr) & zero, /* From */
1239 (UDICount) 1, /* Count */
1240 (UDISizeT) 4, /* Size */
1241 &Count, /* CountDone */
1242 (UDIBool) 0); /* HostEndian */
1244 error ("UDIWrite failed, error = %d", err);
1249 /* Now, duplicate it for the length of the BSS */
1250 err = UDICopy (From, /* From */
1252 (UDICount) (section_size / 4 - 1), /* Count */
1253 (UDISizeT) 4, /* Size */
1254 &Count, /* CountDone */
1255 (UDIBool) 1); /* Direction */
1261 xerr = UDIGetErrorMsg (err, 100, message, &Count);
1263 fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1265 fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1266 error ("UDICopy failed, error = %d", err);
1273 entry.Space = UDI29KIRAMSpace;
1274 entry.Offset = bfd_get_start_address (pbfd);
1279 /* Function to download an image into the remote target. */
1282 udi_load (char *args, int from_tty)
1284 download (args, from_tty);
1286 /* As a convenience, pick up any symbol info that is in the program
1287 being loaded. Note that we assume that the program is the``mainline'';
1288 if this is not always true, then this code will need to be augmented. */
1289 symbol_file_add (strtok (args, " \t"), from_tty, NULL, 1, 0);
1291 /* Getting new symbols may change our opinion about what is
1293 reinit_frame_cache ();
1296 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1297 ** Copy LEN bytes of data from debugger memory at MYADDR
1298 to inferior's memory at MEMADDR. Returns number of bytes written. */
1300 udi_write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1307 UDICount CountDone = 0;
1308 UDIBool HostEndian = 0;
1310 To.Space = udi_memory_space (memaddr);
1311 From = (UDIUInt32 *) myaddr;
1313 while (nwritten < len)
1315 Count = len - nwritten;
1316 if (Count > MAXDATA)
1318 To.Offset = memaddr + nwritten;
1319 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
1321 error ("UDIWrite() failed in udi_write_inferior_memory");
1326 nwritten += CountDone;
1333 /**************************************************** UDI_READ_INFERIOR_MEMORY
1334 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1335 at debugger address MYADDR. Returns number of bytes read. */
1337 udi_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
1344 UDICount CountDone = 0;
1345 UDIBool HostEndian = 0;
1348 From.Space = udi_memory_space (memaddr);
1349 To = (UDIUInt32 *) myaddr;
1353 Count = len - nread;
1354 if (Count > MAXDATA)
1356 From.Offset = memaddr + nread;
1357 if (err = UDIRead (From, To, Count, Size, &CountDone, HostEndian))
1359 error ("UDIRead() failed in udi_read_inferior_memory");
1371 /********************************************************************* WARNING
1373 udi_warning (int num)
1375 error ("ERROR while loading program into remote TIP: $d\n", num);
1379 /*****************************************************************************/
1380 /* Fetch a single register indicatated by 'regno'.
1381 * Returns 0/-1 on success/failure.
1384 fetch_register (int regno)
1391 UDIBool HostEndian = 0;
1395 if (regno == GR1_REGNUM)
1397 From.Space = UDI29KGlobalRegs;
1400 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1402 From.Space = UDI29KGlobalRegs;
1403 From.Offset = (regno - GR96_REGNUM) + 96;;
1406 #if defined(GR64_REGNUM)
1408 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1410 From.Space = UDI29KGlobalRegs;
1411 From.Offset = (regno - GR64_REGNUM) + 64;
1414 #endif /* GR64_REGNUM */
1416 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1418 From.Space = UDI29KLocalRegs;
1419 From.Offset = (regno - LR0_REGNUM);
1421 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1424 /*supply_register(160 + (regno - FPE_REGNUM),(char *) &val); */
1425 supply_register (regno, (char *) &val);
1426 return; /* Pretend Success */
1430 From.Space = UDI29KSpecialRegs;
1431 From.Offset = regnum_to_srnum (regno);
1434 if (err = UDIRead (From, &To, Count, Size, &CountDone, HostEndian))
1435 error ("UDIRead() failed in udi_fetch_registers");
1437 supply_register (regno, (char *) &To);
1440 fprintf_unfiltered (gdb_stdlog, "Fetching register %s = 0x%x\n",
1441 REGISTER_NAME (regno), To);
1443 /*****************************************************************************/
1444 /* Store a single register indicated by 'regno'.
1445 * Returns 0/-1 on success/failure.
1448 store_register (int regno)
1456 UDIBool HostEndian = 0;
1458 From = read_register (regno); /* get data value */
1461 fprintf_unfiltered (gdb_stdlog, "Storing register %s = 0x%x\n",
1462 REGISTER_NAME (regno), From);
1464 if (regno == GR1_REGNUM)
1466 To.Space = UDI29KGlobalRegs;
1468 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1469 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1470 * register cache. Do this *after* calling read_register, because we want
1471 * read_register to return the value that write_register has just stuffed
1472 * into the registers array, not the value of the register fetched from
1475 registers_changed ();
1477 #if defined(GR64_REGNUM)
1478 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32)
1480 To.Space = UDI29KGlobalRegs;
1481 To.Offset = (regno - GR64_REGNUM) + 64;
1482 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1484 #endif /* GR64_REGNUM */
1485 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1487 To.Space = UDI29KGlobalRegs;
1488 To.Offset = (regno - GR96_REGNUM) + 96;
1489 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1491 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1493 To.Space = UDI29KLocalRegs;
1494 To.Offset = (regno - LR0_REGNUM);
1495 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1497 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1498 return 0; /* Pretend Success */
1499 else if (regno == PC_REGNUM)
1501 /* PC1 via UDI29KPC */
1503 To.Space = UDI29KPC;
1504 To.Offset = 0; /* PC1 */
1505 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1507 /* Writing to this loc actually changes the values of pc0 & pc1 */
1509 register_valid[PC_REGNUM] = 0; /* pc1 */
1510 register_valid[NPC_REGNUM] = 0; /* pc0 */
1513 /* An unprotected or protected special register */
1515 To.Space = UDI29KSpecialRegs;
1516 To.Offset = regnum_to_srnum (regno);
1517 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1521 error ("UDIWrite() failed in store_registers");
1525 /********************************************************** REGNUM_TO_SRNUM */
1527 * Convert a gdb special register number to a 29000 special register number.
1530 regnum_to_srnum (int regno)
1555 return (USE_SHADOW_PC ? (20) : (10));
1557 return (USE_SHADOW_PC ? (21) : (11));
1559 return (USE_SHADOW_PC ? (22) : (12));
1589 return (255); /* Failure ? */
1592 /****************************************************************************/
1594 * Determine the Target memory space qualifier based on the addr.
1595 * FIXME: Can't distinguis I_ROM/D_ROM.
1596 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1599 udi_memory_space (CORE_ADDR addr)
1601 UDIUInt32 tstart = IMemStart;
1602 UDIUInt32 tend = tstart + IMemSize;
1603 UDIUInt32 dstart = DMemStart;
1604 UDIUInt32 dend = tstart + DMemSize;
1605 UDIUInt32 rstart = RMemStart;
1606 UDIUInt32 rend = tstart + RMemSize;
1608 if (((UDIUInt32) addr >= tstart) && ((UDIUInt32) addr < tend))
1610 return UDI29KIRAMSpace;
1612 else if (((UDIUInt32) addr >= dstart) && ((UDIUInt32) addr < dend))
1614 return UDI29KDRAMSpace;
1616 else if (((UDIUInt32) addr >= rstart) && ((UDIUInt32) addr < rend))
1618 /* FIXME: how do we determine between D_ROM and I_ROM */
1619 return UDI29KIROMSpace;
1621 else /* FIXME: what do me do now? */
1622 return UDI29KDRAMSpace; /* Hmmm! */
1624 /*********************************************************************** STUBS
1635 struct ui_file *EchoFile = 0; /* used for debugging */
1636 int QuietMode = 0; /* used for debugging */
1638 #ifdef NO_HIF_SUPPORT
1639 service_HIF (union msg_t *msg)
1641 return (0); /* Emulate a failure */
1645 /* Target_ops vector. Not static because there does not seem to be
1646 any portable way to do a forward declaration of a static variable.
1647 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1648 /bin/cc doesn't like "static" twice. */
1650 struct target_ops udi_ops;
1655 udi_ops.to_shortname = "udi";
1656 udi_ops.to_longname = "Remote UDI connected TIP";
1657 udi_ops.to_doc = "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1659 `configuration-id AF_INET hostname port-number'\n\
1660 To connect via the network, where hostname and port-number specify the\n\
1661 host and port where you can connect via UDI.\n\
1662 configuration-id is unused.\n\
1664 `configuration-id AF_UNIX socket-name tip-program'\n\
1665 To connect using a local connection to the \"tip.exe\" program which is\n\
1666 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1667 tip program must already be started; connect to it using that socket.\n\
1668 If not, start up tip-program, which should be the name of the tip\n\
1669 program. If appropriate, the PATH environment variable is searched.\n\
1670 configuration-id is unused.\n\
1672 `configuration-id'\n\
1673 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1674 are files containing lines in the above formats. configuration-id is\n\
1675 used to pick which line of the file to use.";
1676 udi_ops.to_open = udi_open;
1677 udi_ops.to_close = udi_close;
1678 udi_ops.to_attach = udi_attach;
1679 udi_ops.to_detach = udi_detach;
1680 udi_ops.to_resume = udi_resume;
1681 udi_ops.to_wait = udi_wait;
1682 udi_ops.to_fetch_registers = udi_fetch_registers;
1683 udi_ops.to_store_registers = udi_store_registers;
1684 udi_ops.to_prepare_to_store = udi_prepare_to_store;
1685 udi_ops.to_xfer_memory = udi_xfer_inferior_memory;
1686 udi_ops.to_files_info = udi_files_info;
1687 udi_ops.to_insert_breakpoint = udi_insert_breakpoint;
1688 udi_ops.to_remove_breakpoint = udi_remove_breakpoint;
1689 udi_ops.to_terminal_init = 0;
1690 udi_ops.to_terminal_inferior = 0;
1691 udi_ops.to_terminal_ours_for_output = 0;
1692 udi_ops.to_terminal_ours = 0;
1693 udi_ops.to_terminal_info = 0;
1694 udi_ops.to_kill = udi_kill;
1695 udi_ops.to_load = udi_load;
1696 udi_ops.to_lookup_symbol = 0;
1697 udi_ops.to_create_inferior = udi_create_inferior;
1698 udi_ops.to_mourn_inferior = udi_mourn;
1699 udi_ops.to_can_run = 0;
1700 udi_ops.to_notice_signals = 0;
1701 udi_ops.to_thread_alive = 0;
1702 udi_ops.to_stop = 0;
1703 udi_ops.to_stratum = process_stratum;
1704 udi_ops.DONT_USE = 0;
1705 udi_ops.to_has_all_memory = 1;
1706 udi_ops.to_has_memory = 1;
1707 udi_ops.to_has_stack = 1;
1708 udi_ops.to_has_registers = 1;
1709 udi_ops.to_has_execution = 1;
1710 udi_ops.to_sections = 0;
1711 udi_ops.to_sections_end = 0;
1712 udi_ops.to_magic = OPS_MAGIC;
1716 _initialize_remote_udi (void)
1719 add_target (&udi_ops);