1 /* Remote debugging interface for AMD 29k interfaced via UDI, for GDB.
2 Copyright 1990, 1992 Free Software Foundation, Inc.
3 Written by Daniel Mann. Contributed by AMD.
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This is like remote.c but uses the Universal Debug Interface (UDI) to
22 talk to the target hardware (or simulator). UDI is a TCP/IP based
23 protocol; for hardware that doesn't run TCP, an interface adapter
24 daemon talks UDI on one side, and talks to the hardware (typically
25 over a serial port) on the other side.
27 - Originally written by Daniel Mann at AMD for MiniMON and gdb 3.91.6.
29 file to gdb 3.95. I was unable to get this working on sun3os4
30 with termio, only with sgtty.
31 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
32 MiniMON interface with UDI-p interface. */
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 PARAMS ((int pid, int step, enum target_signal sig));
56 static void udi_fetch_registers PARAMS ((int regno));
57 static void udi_load PARAMS ((char *args, int from_tty));
58 static void fetch_register PARAMS ((int regno));
59 static void udi_store_registers PARAMS ((int regno));
60 static int store_register PARAMS ((int regno));
61 static int regnum_to_srnum PARAMS ((int regno));
62 static void udi_close PARAMS ((int quitting));
63 static CPUSpace udi_memory_space PARAMS ((CORE_ADDR addr));
64 static int udi_write_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
66 static int udi_read_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
68 static void download PARAMS ((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;
88 CPUOffset IMemStart = 0;
89 CPUSizeT IMemSize = 0;
90 CPUOffset DMemStart = 0;
91 CPUSizeT DMemSize = 0;
92 CPUOffset RMemStart = 0;
93 CPUSizeT RMemSize = 0;
97 UDIMemoryRange address_ranges[2]; /* Text and data */
98 UDIResource entry = {0, 0}; /* Entry point */
99 CPUSizeT stack_sizes[2]; /* Regular and memory stacks */
101 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
104 typedef struct bkpt_entry_str
109 unsigned int BreakId;
111 #define BKPT_TABLE_SIZE 40
112 static bkpt_entry_t bkpt_table[BKPT_TABLE_SIZE];
113 extern char dfe_errmsg[]; /* error string */
115 /* malloc'd name of the program on the remote system. */
116 static char *prog_name = NULL;
118 /* This is called not only when we first attach, but also when the
119 user types "run" after having attached. */
122 udi_create_inferior (execfile, args, 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 printf_unfiltered("UDI connection not open yet.\n");
146 inferior_pid = 40000;
149 download(execfile, 0);
151 args1 = alloca (strlen(execfile) + strlen(args) + 2);
153 if (execfile[0] == '\0')
155 /* It is empty. We need to quote it somehow, or else the target
156 will think there is no argument being passed here. According
157 to the UDI spec it is quoted "according to TIP OS rules" which
158 I guess means quoting it like the Unix shell should work
159 (sounds pretty bogus to me...). In fact it doesn't work (with
160 isstip anyway), but passing in two quotes as the argument seems
161 like a reasonable enough behavior anyway (I guess). */
163 strcpy (args1, "''");
165 strcpy (args1, execfile);
167 strcat (args1, args);
169 UDIInitializeProcess (address_ranges, /* ProcessMemory[] */
170 (UDIInt)2, /* NumberOfRanges */
171 entry, /* EntryPoint */
172 stack_sizes, /* *StackSizes */
173 (UDIInt)2, /* NumberOfStacks */
174 args1); /* ArgString */
176 init_wait_for_inferior ();
177 clear_proceed_status ();
178 proceed (-1, TARGET_SIGNAL_DEFAULT, 0);
185 /* Requiring "target udi" each time you run is a major pain. I suspect
186 this was just blindy copied from remote.c, in which "target" and
187 "run" are combined. Having a udi target without an inferior seems
188 to work between "target udi" and "run", so why not now? */
189 pop_target (); /* Pop back to no-child state */
191 /* But if we're going to want to run it again, we better remove the
193 remove_breakpoints ();
194 generic_mourn_inferior ();
197 /******************************************************************** UDI_OPEN
198 ** Open a connection to remote TIP.
199 NAME is the socket domain used for communication with the TIP,
200 then a space and the socket name or TIP-host name.
201 '<udi_udi_config_id>' for example.
204 /* XXX - need cleanups for udiconnect for various failures!!! */
206 static char *udi_config_id;
208 udi_open (name, 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 free (udi_config_id);
233 error("Usage: target udi config_id, where config_id appears in udi_soc file");
235 udi_config_id = strdup (strtok (name, " \t"));
237 if (UDIConnect (udi_config_id, &udi_session_id))
238 error("UDIConnect() failed: %s\n", dfe_errmsg);
240 push_target (&udi_ops);
243 ** Initialize target configuration structure (global)
245 if (UDIGetTargetConfig (KnownMemory, &NumberOfRanges,
246 ChipVersions, &NumberOfChips))
247 error ("UDIGetTargetConfig() failed");
248 if (NumberOfChips > 2)
249 fprintf_unfiltered(gdb_stderr,"Target has more than one processor\n");
250 for (cnt=0; cnt < NumberOfRanges; cnt++)
252 switch(KnownMemory[cnt].Space)
255 fprintf_unfiltered(gdb_stderr, "UDIGetTargetConfig() unknown memory space\n");
259 case UDI29KIROMSpace:
260 RMemStart = KnownMemory[cnt].Offset;
261 RMemSize = KnownMemory[cnt].Size;
263 case UDI29KIRAMSpace:
264 IMemStart = KnownMemory[cnt].Offset;
265 IMemSize = KnownMemory[cnt].Size;
267 case UDI29KDRAMSpace:
268 DMemStart = KnownMemory[cnt].Offset;
269 DMemSize = KnownMemory[cnt].Size;
274 a29k_get_processor_type ();
276 if (UDICreateProcess (&PId))
277 fprintf_unfiltered(gdb_stderr, "UDICreateProcess() failed\n");
279 /* Print out some stuff, letting the user now what's going on */
280 if (UDICapabilities (&TIPId, &TargetId, DFEId, DFE, &TIP, &DFEIPCId,
282 error ("UDICapabilities() failed");
285 printf_filtered ("Connected via UDI socket,\n\
286 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
287 (DFEIPCId>>8)&0xf, (DFEIPCId>>4)&0xf, DFEIPCId&0xf,
288 (TIPIPCId>>8)&0xf, (TIPIPCId>>4)&0xf, TIPIPCId&0xf,
289 (TargetId>>8)&0xf, (TargetId>>4)&0xf, TargetId&0xf,
294 /******************************************************************* UDI_CLOSE
295 Close the open connection to the TIP process.
296 Use this when you want to detach and do something else
299 udi_close (quitting) /*FIXME: how is quitting used */
302 if (udi_session_id < 0)
305 /* We should never get here if there isn't something valid in
308 if (UDIDisconnect (udi_session_id, UDITerminateSession))
309 error ("UDIDisconnect() failed in udi_close");
311 /* Do not try to close udi_session_id again, later in the program. */
315 printf_filtered (" Ending remote debugging\n");
318 /**************************************************************** UDI_ATACH */
319 /* Attach to a program that is already loaded and running
320 * Upon exiting the process's execution is stopped.
323 udi_attach (args, from_tty)
332 UDIBool HostEndian = 0;
335 if (udi_session_id < 0)
336 error ("UDI connection not opened yet, use the 'target udi' command.\n");
339 printf_unfiltered ("Attaching to remote program %s...\n", prog_name);
342 From.Space = UDI29KSpecialRegs;
344 if (err = UDIRead(From, &PC_adds, Count, Size, &CountDone, HostEndian))
345 error ("UDIRead failed in udi_attach");
346 printf_unfiltered ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds);
348 /************************************************************* UDI_DETACH */
349 /* Terminate the open connection to the TIP process.
350 Use this when you want to detach and do something else
351 with your gdb. Leave remote process running (with no breakpoints set). */
353 udi_detach (args,from_tty)
358 remove_breakpoints(); /* Just in case there were any left in */
360 if (UDIDisconnect (udi_session_id, UDIContinueSession))
361 error ("UDIDisconnect() failed in udi_detach");
363 /* calls udi_close to do the real work (which looks like it calls
364 UDIDisconnect with UDITerminateSession, FIXME). */
367 /* FIXME, message too similar to what udi_close prints. */
369 printf_unfiltered ("Ending remote debugging\n");
373 /****************************************************************** UDI_RESUME
374 ** Tell the remote machine to resume. */
377 udi_resume (pid, step, sig)
379 enum target_signal sig;
383 UDIStepType StepType = UDIStepNatural;
386 if (step) /* step 1 instruction */
388 tip_error = UDIStep (Steps, StepType, Range);
392 fprintf_unfiltered (gdb_stderr, "UDIStep() error = %d\n", tip_error);
393 error ("failed in udi_resume");
397 error ("UDIExecute() failed in udi_resume");
400 /******************************************************************** UDI_WAIT
401 ** Wait until the remote machine stops, then return,
402 storing status in STATUS just as `wait' would. */
405 udi_wait (pid, status)
407 struct target_waitstatus *status;
413 int old_timeout = timeout;
414 int old_immediate_quit = immediate_quit;
417 status->kind = TARGET_WAITKIND_EXITED;
418 status->value.integer = 0;
420 /* wait for message to arrive. It should be:
421 If the target stops executing, udi_wait() should return.
423 timeout = 0; /* Wait indefinetly for a message */
424 immediate_quit = 1; /* Helps ability to QUIT */
429 MaxTime = UDIWaitForever;
430 UDIWait(MaxTime, &PId, &StopReason);
431 QUIT; /* Let user quit if they want */
433 switch (StopReason & UDIGrossState)
436 if (UDIGetStdout (sbuf, (UDISizeT)SBUF_MAX, &CountDone))
437 /* This is said to happen if the program tries to output
438 a whole bunch of output (more than SBUF_MAX, I would
439 guess). It doesn't seem to happen with the simulator. */
440 warning ("UDIGetStdout() failed in udi_wait");
441 fwrite (sbuf, 1, CountDone, gdb_stdout);
442 gdb_flush(gdb_stdout);
446 UDIGetStderr (sbuf, (UDISizeT)SBUF_MAX, &CountDone);
447 fwrite (sbuf, 1, CountDone, gdb_stderr);
448 gdb_flush(gdb_stderr);
461 } while (i < SBUF_MAX && ch != '\n');
462 UDIPutStdin (sbuf, (UDISizeT)i, &CountDone);
467 /* In spite of the fact that we told UDIWait to wait forever, it will
468 return spuriously sometimes. */
477 switch (StopReason & UDIGrossState)
480 printf_unfiltered("Am290*0 received vector number %d\n", StopReason >> 24);
482 switch (StopReason >> 8)
484 case 0: /* Illegal opcode */
485 printf_unfiltered(" (break point)\n");
486 status->kind = TARGET_WAITKIND_STOPPED;
487 status->value.sig = TARGET_SIGNAL_TRAP;
489 case 1: /* Unaligned Access */
490 status->kind = TARGET_WAITKIND_STOPPED;
491 status->value.sig = TARGET_SIGNAL_BUS;
495 status->kind = TARGET_WAITKIND_STOPPED;
496 status->value.sig = TARGET_SIGNAL_FPE;
498 case 5: /* Protection Violation */
499 status->kind = TARGET_WAITKIND_STOPPED;
500 /* Why not SEGV? What is a Protection Violation? */
501 status->value.sig = TARGET_SIGNAL_ILL;
505 case 8: /* User Instruction Mapping Miss */
506 case 9: /* User Data Mapping Miss */
507 case 10: /* Supervisor Instruction Mapping Miss */
508 case 11: /* Supervisor Data Mapping Miss */
509 status->kind = TARGET_WAITKIND_STOPPED;
510 status->value.sig = TARGET_SIGNAL_SEGV;
514 status->kind = TARGET_WAITKIND_STOPPED;
515 status->value.sig = TARGET_SIGNAL_ILL;
518 status->kind = TARGET_WAITKIND_STOPPED;
519 status->value.sig = TARGET_SIGNAL_ALRM;
522 status->kind = TARGET_WAITKIND_STOPPED;
523 status->value.sig = TARGET_SIGNAL_TRAP;
528 case 19: /* INTR3/Internal */
531 status->kind = TARGET_WAITKIND_STOPPED;
532 status->value.sig = TARGET_SIGNAL_INT;
534 case 22: /* Floating-Point Exception */
535 status->kind = TARGET_WAITKIND_STOPPED;
537 status->value.sig = TARGET_SIGNAL_ILL;
539 case 77: /* assert 77 */
540 status->kind = TARGET_WAITKIND_STOPPED;
541 status->value.sig = TARGET_SIGNAL_TRAP;
544 status->kind = TARGET_WAITKIND_EXITED;
545 status->value.integer = 0;
548 case UDINotExecuting:
549 status->kind = TARGET_WAITKIND_STOPPED;
550 status->value.sig = TARGET_SIGNAL_TERM;
553 status->kind = TARGET_WAITKIND_STOPPED;
554 status->value.sig = TARGET_SIGNAL_TSTP;
557 status->kind = TARGET_WAITKIND_STOPPED;
558 status->value.sig = TARGET_SIGNAL_URG;
562 status->kind = TARGET_WAITKIND_STOPPED;
563 status->value.sig = TARGET_SIGNAL_TRAP;
566 status->kind = TARGET_WAITKIND_STOPPED;
567 status->value.sig = TARGET_SIGNAL_STOP;
570 status->kind = TARGET_WAITKIND_STOPPED;
571 status->value.sig = TARGET_SIGNAL_KILL;
575 status->kind = TARGET_WAITKIND_EXITED;
576 status->value.integer = 0;
579 timeout = old_timeout; /* Restore original timeout value */
580 immediate_quit = old_immediate_quit;
585 /* Handy for debugging */
593 UDIBool HostEndian = 0;
596 unsigned long myregs[256];
599 From.Space = UDI29KPC;
601 To = (UDIUInt32 *)pc;
604 err = UDIRead(From, To, Count, Size, &CountDone, HostEndian);
606 printf_unfiltered ("err = %d, CountDone = %d, pc[0] = 0x%x, pc[1] = 0x%x\n",
607 err, CountDone, pc[0], pc[1]);
609 udi_fetch_registers(-1);
611 printf_unfiltered("other pc1 = 0x%x, pc0 = 0x%x\n", *(int *)®isters[4 * PC_REGNUM],
612 *(int *)®isters[4 * NPC_REGNUM]);
614 /* Now, read all the registers globally */
616 From.Space = UDI29KGlobalRegs;
618 err = UDIRead(From, myregs, 256, 4, &CountDone, HostEndian);
620 printf ("err = %d, CountDone = %d\n", err, CountDone);
624 for (i = 0; i < 256; i += 2)
625 printf("%d:\t%#10x\t%11d\t%#10x\t%11d\n", i, myregs[i], myregs[i],
626 myregs[i+1], myregs[i+1]);
633 /********************************************************** UDI_FETCH_REGISTERS
634 * Read a remote register 'regno'.
635 * If regno==-1 then read all the registers.
638 udi_fetch_registers (regno)
646 UDIBool HostEndian = 0;
651 fetch_register(regno);
657 From.Space = UDI29KGlobalRegs;
659 To = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
661 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
662 error("UDIRead() failed in udi_fetch_registers");
664 register_valid[GR1_REGNUM] = 1;
666 #if defined(GR64_REGNUM) /* Read gr64-127 */
668 /* Global Registers gr64-gr95 */
670 From.Space = UDI29KGlobalRegs;
672 To = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
674 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
675 error("UDIRead() failed in udi_fetch_registers");
677 for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++)
678 register_valid[i] = 1;
680 #endif /* GR64_REGNUM */
682 /* Global Registers gr96-gr127 */
684 From.Space = UDI29KGlobalRegs;
686 To = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
688 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
689 error("UDIRead() failed in udi_fetch_registers");
691 for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++)
692 register_valid[i] = 1;
694 /* Local Registers */
696 From.Space = UDI29KLocalRegs;
698 To = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
700 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
701 error("UDIRead() failed in udi_fetch_registers");
703 for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++)
704 register_valid[i] = 1;
706 /* Protected Special Registers */
708 From.Space = UDI29KSpecialRegs;
710 To = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
712 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
713 error("UDIRead() failed in udi_fetch_registers");
715 for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++)
716 register_valid[i] = 1;
718 if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */
719 fetch_register(NPC_REGNUM);
720 fetch_register(PC_REGNUM);
721 fetch_register(PC2_REGNUM);
723 /* Unprotected Special Registers sr128-sr135 */
725 From.Space = UDI29KSpecialRegs;
727 To = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
729 if (err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
730 error("UDIRead() failed in udi_fetch_registers");
732 for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++)
733 register_valid[i] = 1;
738 printf_unfiltered("Fetching all registers\n");
739 printf_unfiltered("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
740 read_register(NPC_REGNUM), read_register(PC_REGNUM),
741 read_register(PC2_REGNUM));
744 /* There doesn't seem to be any way to get these. */
747 supply_register (FPE_REGNUM, (char *) &val);
748 supply_register (INTE_REGNUM, (char *) &val);
749 supply_register (FPS_REGNUM, (char *) &val);
750 supply_register (EXO_REGNUM, (char *) &val);
755 /********************************************************* UDI_STORE_REGISTERS
756 ** Store register regno into the target.
757 * If regno==-1 then store all the registers.
761 udi_store_registers (regno)
769 UDIBool HostEndian = 0;
773 store_register(regno);
779 printf_unfiltered("Storing all registers\n");
780 printf_unfiltered("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM),
781 read_register(PC_REGNUM), read_register(PC2_REGNUM));
786 From = (UDIUInt32 *)®isters[4 * GR1_REGNUM];
787 To.Space = UDI29KGlobalRegs;
790 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
791 error("UDIWrite() failed in udi_store_regisetrs");
793 #if defined(GR64_REGNUM)
795 /* Global registers gr64-gr95 */
797 From = (UDIUInt32 *)®isters[4 * GR64_REGNUM];
798 To.Space = UDI29KGlobalRegs;
801 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
802 error("UDIWrite() failed in udi_store_regisetrs");
804 #endif /* GR64_REGNUM */
806 /* Global registers gr96-gr127 */
808 From = (UDIUInt32 *)®isters[4 * GR96_REGNUM];
809 To.Space = UDI29KGlobalRegs;
812 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
813 error("UDIWrite() failed in udi_store_regisetrs");
815 /* Local Registers */
817 From = (UDIUInt32 *)®isters[4 * LR0_REGNUM];
818 To.Space = UDI29KLocalRegs;
821 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
822 error("UDIWrite() failed in udi_store_regisetrs");
825 /* Protected Special Registers */ /* VAB through TMR */
827 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)];
828 To.Space = UDI29KSpecialRegs;
831 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
832 error("UDIWrite() failed in udi_store_regisetrs");
834 /* PC0, PC1, PC2 possibly as shadow registers */
836 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(10)];
837 To.Space = UDI29KSpecialRegs;
840 To.Offset = 20; /* SPC0 */
842 To.Offset = 10; /* PC0 */
843 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
844 error("UDIWrite() failed in udi_store_regisetrs");
846 /* PC1 via UDI29KPC */
848 From = (UDIUInt32 *)®isters[4 * PC_REGNUM];
850 To.Offset = 0; /* PC1 */
852 if (UDIWrite (From, To, Count, Size, &CountDone, HostEndian))
853 error ("UDIWrite() failed in udi_store_regisetrs");
857 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(13)];
858 To.Space = UDI29KSpecialRegs;
861 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
862 error("UDIWrite() failed in udi_store_regisetrs");
864 /* Unprotected Special Registers */
866 From = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)];
867 To.Space = UDI29KSpecialRegs;
870 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
871 error("UDIWrite() failed in udi_store_regisetrs");
873 registers_changed ();
876 /****************************************************** UDI_PREPARE_TO_STORE */
877 /* Get ready to modify the registers array. On machines which store
878 individual registers, this doesn't need to do anything. On machines
879 which store all the registers in one fell swoop, this makes sure
880 that registers contains all the registers from the program being
884 udi_prepare_to_store ()
886 /* Do nothing, since we can store individual regs */
889 /********************************************************** TRANSLATE_ADDR */
894 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
895 /* Check for a virtual address in the kernel */
896 /* Assume physical address of ublock is in paddr_u register */
897 /* FIXME: doesn't work for user virtual addresses */
898 if (addr >= UVADDR) {
899 /* PADDR_U register holds the physical address of the ublock */
900 CORE_ADDR i = (CORE_ADDR)read_register(PADDR_U_REGNUM);
901 return(i + addr - (CORE_ADDR)UVADDR);
909 /************************************************* UDI_XFER_INFERIOR_MEMORY */
910 /* FIXME! Merge these two. */
912 udi_xfer_inferior_memory (memaddr, myaddr, len, write)
919 memaddr = translate_addr(memaddr);
922 return udi_write_inferior_memory (memaddr, myaddr, len);
924 return udi_read_inferior_memory (memaddr, myaddr, len);
927 /********************************************************** UDI_FILES_INFO */
931 printf_unfiltered ("\tAttached to UDI socket to %s and running program %s.\n",
932 udi_config_id, prog_name);
935 /**************************************************** UDI_INSERT_BREAKPOINT */
937 udi_insert_breakpoint (addr, contents_cache)
939 char *contents_cache;
944 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
945 if (bkpt_table[cnt].Type == 0) /* Find first free slot */
948 if(cnt >= BKPT_TABLE_SIZE)
949 error("Too many breakpoints set");
951 bkpt_table[cnt].Addr.Offset = addr;
952 bkpt_table[cnt].Addr.Space = UDI29KIRAMSpace;
953 bkpt_table[cnt].PassCount = 1;
954 bkpt_table[cnt].Type = UDIBreakFlagExecute;
956 err = UDISetBreakpoint(bkpt_table[cnt].Addr,
957 bkpt_table[cnt].PassCount,
958 bkpt_table[cnt].Type,
959 &bkpt_table[cnt].BreakId);
961 if (err == 0) return 0; /* Success */
963 bkpt_table[cnt].Type = 0;
964 error("UDISetBreakpoint returned error code %d\n", err);
967 /**************************************************** UDI_REMOVE_BREAKPOINT */
969 udi_remove_breakpoint (addr, contents_cache)
971 char *contents_cache;
976 for (cnt = 0; cnt < BKPT_TABLE_SIZE; cnt++)
977 if (bkpt_table[cnt].Addr.Offset == addr) /* Find matching breakpoint */
980 if(cnt >= BKPT_TABLE_SIZE)
981 error("Can't find breakpoint in table");
983 bkpt_table[cnt].Type = 0;
985 err = UDIClearBreakpoint(bkpt_table[cnt].BreakId);
986 if (err == 0) return 0; /* Success */
988 error("UDIClearBreakpoint returned error code %d\n", err);
992 udi_kill(arg,from_tty)
999 UDIStop does not really work as advertised. It causes the TIP to close it's
1000 connection, which usually results in GDB dying with a SIGPIPE. For now, we
1001 just invoke udi_close, which seems to get things right.
1005 udi_session_id = -1;
1009 printf_unfiltered("Target has been stopped.");
1016 /* Keep the target around, e.g. so "run" can do the right thing when
1017 we are already debugging something. FIXME-maybe: should we kill the
1018 TIP with UDIDisconnect using UDITerminateSession, and then restart
1019 it on the next "run"? */
1025 Load a program into the target. Args are: `program {options}'. The options
1026 are used to control loading of the program, and are NOT passed onto the
1027 loaded code as arguments. (You need to use the `run' command to do that.)
1030 -ms %d Set mem stack size to %d
1031 -rs %d Set regular stack size to %d
1032 -i send init info (default)
1033 -noi don't send init info
1034 -[tT] Load Text section
1035 -[dD] Load Data section
1036 -[bB] Load BSS section
1037 -[lL] Load Lit section
1041 download(load_arg_string, from_tty)
1042 char *load_arg_string;
1045 #define DEFAULT_MEM_STACK_SIZE 0x6000
1046 #define DEFAULT_REG_STACK_SIZE 0x2000
1053 int load_text = 1, load_data = 1, load_bss = 1, load_lit = 1;
1055 address_ranges[0].Space = UDI29KIRAMSpace;
1056 address_ranges[0].Offset = 0xffffffff;
1057 address_ranges[0].Size = 0;
1059 address_ranges[1].Space = UDI29KDRAMSpace;
1060 address_ranges[1].Offset = 0xffffffff;
1061 address_ranges[1].Size = 0;
1063 stack_sizes[0] = DEFAULT_REG_STACK_SIZE;
1064 stack_sizes[1] = DEFAULT_MEM_STACK_SIZE;
1068 filename = strtok(load_arg_string, " \t");
1070 error ("Must specify at least a file name with the load command");
1072 filename = tilde_expand (filename);
1073 make_cleanup (free, filename);
1075 while (token = strtok (NULL, " \t"))
1077 if (token[0] == '-')
1081 if (STREQ (token, "ms"))
1082 stack_sizes[1] = atol (strtok (NULL, " \t"));
1083 else if (STREQ (token, "rs"))
1084 stack_sizes[0] = atol (strtok (NULL, " \t"));
1087 load_text = load_data = load_bss = load_lit = 0;
1110 error ("Unknown UDI load option -%s", token-1);
1117 pbfd = bfd_openr (filename, gnutarget);
1120 perror_with_name (filename);
1122 make_cleanup (bfd_close, pbfd);
1127 if (!bfd_check_format (pbfd, bfd_object))
1128 error ("It doesn't seem to be an object file");
1130 for (section = pbfd->sections; section; section = section->next)
1132 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
1136 unsigned long section_size, section_end;
1137 const char *section_name;
1139 section_name = bfd_get_section_name (pbfd, section);
1140 if (STREQ (section_name, ".text") && !load_text)
1142 else if (STREQ (section_name, ".data") && !load_data)
1144 else if (STREQ (section_name, ".bss") && !load_bss)
1146 else if (STREQ (section_name, ".lit") && !load_lit)
1149 To.Offset = bfd_get_section_vma (pbfd, section);
1150 section_size = bfd_section_size (pbfd, section);
1151 section_end = To.Offset + section_size;
1153 if (section_size == 0)
1154 /* This is needed at least in the BSS case, where the code
1155 below starts writing before it even checks the size. */
1158 printf_unfiltered("[Loading section %s at %x (%d bytes)]\n",
1163 if (bfd_get_section_flags (pbfd, section) & SEC_CODE)
1165 To.Space = UDI29KIRAMSpace;
1167 address_ranges[0].Offset = min (address_ranges[0].Offset,
1169 address_ranges[0].Size = max (address_ranges[0].Size,
1171 - address_ranges[0].Offset);
1175 To.Space = UDI29KDRAMSpace;
1177 address_ranges[1].Offset = min (address_ranges[1].Offset,
1179 address_ranges[1].Size = max (address_ranges[1].Size,
1181 - address_ranges[1].Offset);
1184 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
1190 while (section_size > 0)
1194 Count = min (section_size, 1024);
1196 bfd_get_section_contents (pbfd, section, buffer, fptr,
1199 err = UDIWrite ((UDIHostMemPtr)buffer, /* From */
1202 (UDISizeT)1, /* Size */
1203 &Count, /* CountDone */
1204 (UDIBool)0); /* HostEndian */
1206 error ("UDIWrite failed, error = %d", err);
1210 section_size -= Count;
1216 unsigned long zero = 0;
1218 /* Write a zero byte at the vma */
1219 /* FIXME: Broken for sections of 1-3 bytes (we test for
1221 err = UDIWrite ((UDIHostMemPtr)&zero, /* From */
1223 (UDICount)1, /* Count */
1224 (UDISizeT)4, /* Size */
1225 &Count, /* CountDone */
1226 (UDIBool)0); /* HostEndian */
1228 error ("UDIWrite failed, error = %d", err);
1233 /* Now, duplicate it for the length of the BSS */
1234 err = UDICopy (From, /* From */
1236 (UDICount)(section_size/4 - 1), /* Count */
1237 (UDISizeT)4, /* Size */
1238 &Count, /* CountDone */
1239 (UDIBool)1); /* Direction */
1245 xerr = UDIGetErrorMsg(err, 100, message, &Count);
1247 fprintf_unfiltered (gdb_stderr, "Error is %s\n", message);
1249 fprintf_unfiltered (gdb_stderr, "xerr is %d\n", xerr);
1250 error ("UDICopy failed, error = %d", err);
1257 entry.Space = UDI29KIRAMSpace;
1258 entry.Offset = bfd_get_start_address (pbfd);
1263 /* User interface to download an image into the remote target. See download()
1264 * for details on args.
1268 udi_load(args, from_tty)
1272 download (args, from_tty);
1274 symbol_file_add (strtok (args, " \t"), from_tty, 0, 0, 0, 0);
1277 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1278 ** Copy LEN bytes of data from debugger memory at MYADDR
1279 to inferior's memory at MEMADDR. Returns number of bytes written. */
1281 udi_write_inferior_memory (memaddr, myaddr, len)
1291 UDICount CountDone = 0;
1292 UDIBool HostEndian = 0;
1294 To.Space = udi_memory_space(memaddr);
1295 From = (UDIUInt32*)myaddr;
1297 while (nwritten < len)
1298 { Count = len - nwritten;
1299 if (Count > MAXDATA) Count = MAXDATA;
1300 To.Offset = memaddr + nwritten;
1301 if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian))
1302 { error("UDIWrite() failed in udi_write_inferrior_memory");
1306 { nwritten += CountDone;
1313 /**************************************************** UDI_READ_INFERIOR_MEMORY
1314 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1315 at debugger address MYADDR. Returns number of bytes read. */
1317 udi_read_inferior_memory(memaddr, myaddr, len)
1327 UDICount CountDone = 0;
1328 UDIBool HostEndian = 0;
1331 From.Space = udi_memory_space(memaddr);
1332 To = (UDIUInt32*)myaddr;
1335 { Count = len - nread;
1336 if (Count > MAXDATA) Count = MAXDATA;
1337 From.Offset = memaddr + nread;
1338 if(err = UDIRead(From, To, Count, Size, &CountDone, HostEndian))
1339 { error("UDIRead() failed in udi_read_inferrior_memory");
1343 { nread += CountDone;
1350 /********************************************************************* WARNING
1355 error ("ERROR while loading program into remote TIP: $d\n", num);
1359 /*****************************************************************************/
1360 /* Fetch a single register indicatated by 'regno'.
1361 * Returns 0/-1 on success/failure.
1364 fetch_register (regno)
1372 UDIBool HostEndian = 0;
1376 if (regno == GR1_REGNUM)
1378 From.Space = UDI29KGlobalRegs;
1381 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1383 From.Space = UDI29KGlobalRegs;
1384 From.Offset = (regno - GR96_REGNUM) + 96;;
1387 #if defined(GR64_REGNUM)
1389 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1391 From.Space = UDI29KGlobalRegs;
1392 From.Offset = (regno - GR64_REGNUM) + 64;
1395 #endif /* GR64_REGNUM */
1397 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1399 From.Space = UDI29KLocalRegs;
1400 From.Offset = (regno - LR0_REGNUM);
1402 else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM)
1405 supply_register(160 + (regno - FPE_REGNUM),(char *) &val);
1406 return; /* Pretend Success */
1410 From.Space = UDI29KSpecialRegs;
1411 From.Offset = regnum_to_srnum(regno);
1414 if (err = UDIRead(From, &To, Count, Size, &CountDone, HostEndian))
1415 error("UDIRead() failed in udi_fetch_registers");
1417 supply_register(regno, (char *) &To);
1420 printf_unfiltered("Fetching register %s = 0x%x\n", reg_names[regno], To);
1422 /*****************************************************************************/
1423 /* Store a single register indicated by 'regno'.
1424 * Returns 0/-1 on success/failure.
1427 store_register (regno)
1436 UDIBool HostEndian = 0;
1438 From = read_register (regno); /* get data value */
1441 printf_unfiltered("Storing register %s = 0x%x\n", reg_names[regno], From);
1443 if (regno == GR1_REGNUM)
1445 To.Space = UDI29KGlobalRegs;
1447 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1448 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1449 * register cache. Do this *after* calling read_register, because we want
1450 * read_register to return the value that write_register has just stuffed
1451 * into the registers array, not the value of the register fetched from
1454 registers_changed ();
1456 #if defined(GR64_REGNUM)
1457 else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 )
1459 To.Space = UDI29KGlobalRegs;
1460 To.Offset = (regno - GR64_REGNUM) + 64;
1461 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1463 #endif /* GR64_REGNUM */
1464 else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
1466 To.Space = UDI29KGlobalRegs;
1467 To.Offset = (regno - GR96_REGNUM) + 96;
1468 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1470 else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
1472 To.Space = UDI29KLocalRegs;
1473 To.Offset = (regno - LR0_REGNUM);
1474 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1476 else if (regno >= FPE_REGNUM && regno <= EXO_REGNUM)
1477 return 0; /* Pretend Success */
1478 else if (regno == PC_REGNUM)
1480 /* PC1 via UDI29KPC */
1482 To.Space = UDI29KPC;
1483 To.Offset = 0; /* PC1 */
1484 result = UDIWrite (&From, To, Count, Size, &CountDone, HostEndian);
1486 /* Writing to this loc actually changes the values of pc0 & pc1 */
1488 register_valid[PC_REGNUM] = 0; /* pc1 */
1489 register_valid[NPC_REGNUM] = 0; /* pc0 */
1491 else /* An unprotected or protected special register */
1493 To.Space = UDI29KSpecialRegs;
1494 To.Offset = regnum_to_srnum(regno);
1495 result = UDIWrite(&From, To, Count, Size, &CountDone, HostEndian);
1499 error("UDIWrite() failed in store_registers");
1503 /********************************************************** REGNUM_TO_SRNUM */
1505 * Convert a gdb special register number to a 29000 special register number.
1508 regnum_to_srnum(regno)
1512 case VAB_REGNUM: return(0);
1513 case OPS_REGNUM: return(1);
1514 case CPS_REGNUM: return(2);
1515 case CFG_REGNUM: return(3);
1516 case CHA_REGNUM: return(4);
1517 case CHD_REGNUM: return(5);
1518 case CHC_REGNUM: return(6);
1519 case RBP_REGNUM: return(7);
1520 case TMC_REGNUM: return(8);
1521 case TMR_REGNUM: return(9);
1522 case NPC_REGNUM: return(USE_SHADOW_PC ? (20) : (10));
1523 case PC_REGNUM: return(USE_SHADOW_PC ? (21) : (11));
1524 case PC2_REGNUM: return(USE_SHADOW_PC ? (22) : (12));
1525 case MMU_REGNUM: return(13);
1526 case LRU_REGNUM: return(14);
1527 case IPC_REGNUM: return(128);
1528 case IPA_REGNUM: return(129);
1529 case IPB_REGNUM: return(130);
1530 case Q_REGNUM: return(131);
1531 case ALU_REGNUM: return(132);
1532 case BP_REGNUM: return(133);
1533 case FC_REGNUM: return(134);
1534 case CR_REGNUM: return(135);
1535 case FPE_REGNUM: return(160);
1536 case INTE_REGNUM: return(161);
1537 case FPS_REGNUM: return(162);
1538 case EXO_REGNUM:return(164);
1540 return(255); /* Failure ? */
1543 /****************************************************************************/
1545 * Determine the Target memory space qualifier based on the addr.
1546 * FIXME: Can't distinguis I_ROM/D_ROM.
1547 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1550 udi_memory_space(addr)
1553 UDIUInt32 tstart = IMemStart;
1554 UDIUInt32 tend = tstart + IMemSize;
1555 UDIUInt32 dstart = DMemStart;
1556 UDIUInt32 dend = tstart + DMemSize;
1557 UDIUInt32 rstart = RMemStart;
1558 UDIUInt32 rend = tstart + RMemSize;
1560 if (((UDIUInt32)addr >= tstart) && ((UDIUInt32)addr < tend)) {
1561 return UDI29KIRAMSpace;
1562 } else if (((UDIUInt32)addr >= dstart) && ((UDIUInt32)addr < dend)) {
1563 return UDI29KDRAMSpace;
1564 } else if (((UDIUInt32)addr >= rstart) && ((UDIUInt32)addr < rend)) {
1565 /* FIXME: how do we determine between D_ROM and I_ROM */
1566 return UDI29KIROMSpace;
1567 } else /* FIXME: what do me do now? */
1568 return UDI29KDRAMSpace; /* Hmmm! */
1570 /*********************************************************************** STUBS
1573 void convert16() {;}
1574 void convert32() {;}
1575 GDB_FILE * EchoFile = 0; /* used for debugging */
1576 int QuietMode = 0; /* used for debugging */
1578 #ifdef NO_HIF_SUPPORT
1582 return(0); /* Emulate a failure */
1586 /* Target_ops vector. Not static because there does not seem to be
1587 any portable way to do a forward declaration of a static variable.
1588 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1589 /bin/cc doesn't like "static" twice. */
1591 struct target_ops udi_ops = {
1593 "Remote UDI connected TIP",
1594 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1596 `configuration-id AF_INET hostname port-number'\n\
1597 To connect via the network, where hostname and port-number specify the\n\
1598 host and port where you can connect via UDI.\n\
1599 configuration-id is unused.\n\
1601 `configuration-id AF_UNIX socket-name tip-program'\n\
1602 To connect using a local connection to the \"tip.exe\" program which is\n\
1603 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1604 tip program must already be started; connect to it using that socket.\n\
1605 If not, start up tip-program, which should be the name of the tip\n\
1606 program. If appropriate, the PATH environment variable is searched.\n\
1607 configuration-id is unused.\n\
1609 `configuration-id'\n\
1610 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1611 are files containing lines in the above formats. configuration-id is\n\
1612 used to pick which line of the file to use.",
1619 udi_fetch_registers,
1620 udi_store_registers,
1621 udi_prepare_to_store,
1622 udi_xfer_inferior_memory,
1624 udi_insert_breakpoint,
1625 udi_remove_breakpoint,
1626 0, /* termial_init */
1627 0, /* terminal_inferior */
1628 0, /* terminal_ours_for_output */
1629 0, /* terminal_ours */
1630 0, /* terminal_info */
1631 udi_kill, /* FIXME, kill */
1633 0, /* lookup_symbol */
1634 udi_create_inferior,
1635 udi_mourn, /* mourn_inferior FIXME */
1637 0, /* notice_signals */
1640 1, /* has_all_memory */
1643 1, /* has_registers */
1644 1, /* has_execution */
1646 0, /* sections_end */
1647 OPS_MAGIC, /* Always the last thing */
1651 _initialize_remote_udi ()
1653 add_target (&udi_ops);