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.
28 - David Wood (wood@lab.ultra.nyu.edu) at New York University adapted this
29 file to gdb 3.95. I was unable to get this working on sun3os4
30 with termio, only with sgtty.
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. */
54 extern int stop_soon_quietly
; /* for wait_for_inferior */
55 extern struct value
*call_function_by_hand();
56 static void udi_resume
PARAMS ((int pid
, int step
, int sig
));
57 static void udi_fetch_registers
PARAMS ((int regno
));
58 static void udi_load
PARAMS ((char *args
, int from_tty
));
59 static void fetch_register
PARAMS ((int regno
));
60 static void udi_store_registers
PARAMS ((int regno
));
61 static int store_register
PARAMS ((int regno
));
62 static int regnum_to_srnum
PARAMS ((int regno
));
63 static void udi_close
PARAMS ((int quitting
));
64 static CPUSpace udi_memory_space
PARAMS ((CORE_ADDR addr
));
65 static int udi_write_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
67 static int udi_read_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
69 static void download
PARAMS ((char *load_arg_string
, int from_tty
));
70 char CoffFileName
[100] = "";
74 #define TYPE_UNKNOWN 0
78 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
79 static int processor_type
=TYPE_UNKNOWN
;
80 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
81 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
83 #define LLOG_FILE "udi.log"
84 #if defined (LOG_FILE)
88 static int timeout
= 5;
89 extern struct target_ops udi_ops
; /* Forward declaration */
91 /* Special register enumeration.
94 /******************************************************************* UDI DATA*/
95 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
96 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
97 udi_open knows that we don't have a file open when the program
100 UDISessionId udi_session_id
= -1;
102 CPUOffset IMemStart
= 0;
103 CPUSizeT IMemSize
= 0;
104 CPUOffset DMemStart
= 0;
105 CPUSizeT DMemSize
= 0;
106 CPUOffset RMemStart
= 0;
107 CPUSizeT RMemSize
= 0;
111 UDIMemoryRange address_ranges
[2]; /* Text and data */
112 UDIResource entry
= {0, 0}; /* Entry point */
113 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
115 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
118 typedef struct bkpt_entry_str
123 unsigned int BreakId
;
125 #define BKPT_TABLE_SIZE 40
126 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
127 extern char dfe_errmsg
[]; /* error string */
129 /* malloc'd name of the program on the remote system. */
130 static char *prog_name
= NULL
;
132 /* Number of SIGTRAPs we need to simulate. That is, the next
133 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
134 SIGTRAP without actually waiting for anything. */
136 /* This is called not only when we first attach, but also when the
137 user types "run" after having attached. */
140 udi_create_inferior (execfile
, args
, env
)
149 if (prog_name
!= NULL
)
151 prog_name
= savestring (execfile
, strlen (execfile
));
153 else if (entry
.Offset
)
156 error ("No image loaded into target.");
158 if (udi_session_id
< 0)
160 printf("UDI connection not open yet.\n");
164 inferior_pid
= 40000;
167 download(execfile
, 0);
169 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
171 strcpy (args1
, execfile
);
173 strcat (args1
, args
);
175 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
176 (UDIInt
)2, /* NumberOfRanges */
177 entry
, /* EntryPoint */
178 stack_sizes
, /* *StackSizes */
179 (UDIInt
)2, /* NumberOfStacks */
180 args1
); /* ArgString */
182 init_wait_for_inferior ();
183 clear_proceed_status ();
190 pop_target (); /* Pop back to no-child state */
191 generic_mourn_inferior ();
194 /******************************************************************** UDI_OPEN
195 ** Open a connection to remote TIP.
196 NAME is the socket domain used for communication with the TIP,
197 then a space and the socket name or TIP-host name.
198 '<udi_udi_config_id>' for example.
201 /* XXX - need cleanups for udiconnect for various failures!!! */
203 static char *udi_config_id
;
205 udi_open (name
, from_tty
)
212 UDIMemoryRange KnownMemory
[10];
213 UDIUInt32 ChipVersions
[10];
214 UDIInt NumberOfRanges
= 10;
215 UDIInt NumberOfChips
= 10;
217 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
219 target_preopen(from_tty
);
223 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
224 bkpt_table
[cnt
].Type
= 0;
227 free (udi_config_id
);
230 error("Usage: target udi config_id, where config_id appears in udi_soc file");
232 udi_config_id
= strdup (strtok (name
, " \t"));
234 if (UDIConnect (udi_config_id
, &udi_session_id
))
235 error("UDIConnect() failed: %s\n", dfe_errmsg
);
237 push_target (&udi_ops
);
239 #if defined (LOG_FILE)
240 log_file
= fopen (LOG_FILE
, "w");
241 if (log_file
== NULL
)
242 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
245 ** Initialize target configuration structure (global)
247 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
248 ChipVersions
, &NumberOfChips
))
249 error ("UDIGetTargetConfig() failed");
250 if (NumberOfChips
> 2)
251 fprintf(stderr
,"Target has more than one processor\n");
252 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
254 switch(KnownMemory
[cnt
].Space
)
257 fprintf(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 /* Determine the processor revision level */
277 prl
= (unsigned int)read_register (CFG_REGNUM
) >> 24;
280 fprintf_filtered (stderr
,
281 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
282 processor_type
= TYPE_A29000
;
284 else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
286 fprintf_filtered (stderr
,
287 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
288 processor_type
= TYPE_A29030
;
290 else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
292 fprintf_filtered (stderr
,
293 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
294 processor_type
= TYPE_A29050
;
298 processor_type
= TYPE_UNKNOWN
;
299 fprintf_filtered (stderr
,"WARNING: processor type unknown.\n");
301 if (UDICreateProcess (&PId
))
302 fprintf(stderr
, "UDICreateProcess() failed\n");
304 /* Print out some stuff, letting the user now what's going on */
305 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
307 error ("UDICapabilities() failed");
310 printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
311 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
312 processor_name
[processor_type
],
313 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
314 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
315 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
320 /******************************************************************* UDI_CLOSE
321 Close the open connection to the TIP process.
322 Use this when you want to detach and do something else
325 udi_close (quitting
) /*FIXME: how is quitting used */
328 if (udi_session_id
< 0)
331 /* We should never get here if there isn't something valid in
334 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
335 error ("UDIDisconnect() failed in udi_close");
337 /* Do not try to close udi_session_id again, later in the program. */
341 #if defined (LOG_FILE)
342 if (ferror (log_file
))
343 printf ("Error writing log file.\n");
344 if (fclose (log_file
) != 0)
345 printf ("Error closing log file.\n");
348 printf_filtered (" Ending remote debugging\n");
351 /**************************************************************** UDI_ATACH */
352 /* Attach to a program that is already loaded and running
353 * Upon exiting the process's execution is stopped.
356 udi_attach (args
, from_tty
)
365 UDIBool HostEndian
= 0;
368 if (udi_session_id
< 0)
369 error ("UDI connection not opened yet, use the 'target udi' command.\n");
372 printf ("Attaching to remote program %s...\n", prog_name
);
375 From
.Space
= UDI29KSpecialRegs
;
377 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
378 error ("UDIRead failed in udi_attach");
379 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
381 /************************************************************* UDI_DETACH */
382 /* Terminate the open connection to the TIP process.
383 Use this when you want to detach and do something else
384 with your gdb. Leave remote process running (with no breakpoints set). */
386 udi_detach (args
,from_tty
)
391 remove_breakpoints(); /* Just in case there were any left in */
393 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
394 error ("UDIDisconnect() failed in udi_detach");
396 pop_target(); /* calls udi_close to do the real work */
399 printf ("Ending remote debugging\n");
403 /****************************************************************** UDI_RESUME
404 ** Tell the remote machine to resume. */
407 udi_resume (pid
, step
, sig
)
412 UDIStepType StepType
= UDIStepNatural
;
415 if (step
) /* step 1 instruction */
417 tip_error
= UDIStep (Steps
, StepType
, Range
);
421 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
422 error ("failed in udi_resume");
426 error ("UDIExecute() failed in udi_resume");
429 /******************************************************************** UDI_WAIT
430 ** Wait until the remote machine stops, then return,
431 storing status in STATUS just as `wait' would. */
441 int old_timeout
= timeout
;
442 int old_immediate_quit
= immediate_quit
;
445 WSETEXIT ((*status
), 0);
447 /* wait for message to arrive. It should be:
448 If the target stops executing, udi_wait() should return.
450 timeout
= 0; /* Wait indefinetly for a message */
451 immediate_quit
= 1; /* Helps ability to QUIT */
456 MaxTime
= UDIWaitForever
;
457 UDIWait(MaxTime
, &PId
, &StopReason
);
458 QUIT
; /* Let user quit if they want */
460 switch (StopReason
& UDIGrossState
)
463 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
464 error ("UDIGetStdout() failed in udi_wait");
465 fwrite (sbuf
, 1, CountDone
, stdout
);
469 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
470 fwrite (sbuf
, 1, CountDone
, stderr
);
476 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
479 /* In spite of the fact that we told UDIWait to wait forever, it will
480 return spuriously sometimes. */
489 switch (StopReason
& UDIGrossState
)
492 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
494 switch (StopReason
>> 8)
496 case 0: /* Illegal opcode */
497 printf(" (break point)\n");
498 WSETSTOP ((*status
), SIGTRAP
);
500 case 1: /* Unaligned Access */
501 WSETSTOP ((*status
), SIGBUS
);
505 WSETSTOP ((*status
), SIGFPE
);
507 case 5: /* Protection Violation */
508 WSETSTOP ((*status
), SIGILL
);
512 case 8: /* User Instruction Mapping Miss */
513 case 9: /* User Data Mapping Miss */
514 case 10: /* Supervisor Instruction Mapping Miss */
515 case 11: /* Supervisor Data Mapping Miss */
516 WSETSTOP ((*status
), SIGSEGV
);
520 WSETSTOP ((*status
), SIGILL
);
523 WSETSTOP ((*status
), SIGALRM
);
526 WSETSTOP ((*status
), SIGTRAP
);
531 case 19: /* INTR3/Internal */
534 WSETSTOP ((*status
), SIGINT
);
536 case 22: /* Floating-Point Exception */
537 WSETSTOP ((*status
), SIGILL
);
539 case 77: /* assert 77 */
540 WSETSTOP ((*status
), SIGTRAP
);
543 WSETEXIT ((*status
), 0);
546 case UDINotExecuting
:
547 WSETSTOP ((*status
), SIGTERM
);
550 WSETSTOP ((*status
), SIGTSTP
);
553 WSETSTOP ((*status
), SIGURG
);
557 WSETSTOP ((*status
), SIGTRAP
);
560 WSETSTOP ((*status
), SIGSTOP
);
563 WSETSTOP ((*status
), SIGKILL
);
567 WSETEXIT ((*status
), 0);
570 timeout
= old_timeout
; /* Restore original timeout value */
571 immediate_quit
= old_immediate_quit
;
575 /********************************************************** UDI_FETCH_REGISTERS
576 * Read a remote register 'regno'.
577 * If regno==-1 then read all the registers.
580 udi_fetch_registers (regno
)
588 UDIBool HostEndian
= 0;
593 fetch_register(regno
);
599 From
.Space
= UDI29KGlobalRegs
;
601 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
603 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
604 error("UDIRead() failed in udi_fetch_registers");
606 register_valid
[GR1_REGNUM
] = 1;
608 #if defined(GR64_REGNUM) /* Read gr64-127 */
610 /* Global Registers gr64-gr95 */
612 From
.Space
= UDI29KGlobalRegs
;
614 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
616 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
617 error("UDIRead() failed in udi_fetch_registers");
619 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
620 register_valid
[i
] = 1;
622 #endif /* GR64_REGNUM */
624 /* Global Registers gr96-gr127 */
626 From
.Space
= UDI29KGlobalRegs
;
628 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
630 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
631 error("UDIRead() failed in udi_fetch_registers");
633 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
634 register_valid
[i
] = 1;
636 /* Local Registers */
638 From
.Space
= UDI29KLocalRegs
;
640 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
642 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
643 error("UDIRead() failed in udi_fetch_registers");
645 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
646 register_valid
[i
] = 1;
648 /* Protected Special Registers */
650 From
.Space
= UDI29KSpecialRegs
;
652 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
654 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
655 error("UDIRead() failed in udi_fetch_registers");
657 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
658 register_valid
[i
] = 1;
660 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
661 fetch_register(NPC_REGNUM
);
662 fetch_register(PC_REGNUM
);
663 fetch_register(PC2_REGNUM
);
665 /* Unprotected Special Registers sr128-sr135 */
667 From
.Space
= UDI29KSpecialRegs
;
669 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
671 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
672 error("UDIRead() failed in udi_fetch_registers");
674 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
675 register_valid
[i
] = 1;
680 printf("Fetching all registers\n");
681 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
682 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
683 read_register(PC2_REGNUM
));
686 /* There doesn't seem to be any way to get these. */
689 supply_register (FPE_REGNUM
, (char *) &val
);
690 supply_register (INTE_REGNUM
, (char *) &val
);
691 supply_register (FPS_REGNUM
, (char *) &val
);
692 supply_register (EXO_REGNUM
, (char *) &val
);
697 /********************************************************* UDI_STORE_REGISTERS
698 ** Store register regno into the target.
699 * If regno==-1 then store all the registers.
703 udi_store_registers (regno
)
711 UDIBool HostEndian
= 0;
715 store_register(regno
);
721 printf("Storing all registers\n");
722 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
723 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
728 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
729 To
.Space
= UDI29KGlobalRegs
;
732 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
733 error("UDIWrite() failed in udi_store_regisetrs");
735 #if defined(GR64_REGNUM)
737 /* Global registers gr64-gr95 */
739 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
740 To
.Space
= UDI29KGlobalRegs
;
743 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
744 error("UDIWrite() failed in udi_store_regisetrs");
746 #endif /* GR64_REGNUM */
748 /* Global registers gr96-gr127 */
750 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
751 To
.Space
= UDI29KGlobalRegs
;
754 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
755 error("UDIWrite() failed in udi_store_regisetrs");
757 /* Local Registers */
759 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
760 To
.Space
= UDI29KLocalRegs
;
763 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
764 error("UDIWrite() failed in udi_store_regisetrs");
767 /* Protected Special Registers */ /* VAB through TMR */
769 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
770 To
.Space
= UDI29KSpecialRegs
;
773 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
774 error("UDIWrite() failed in udi_store_regisetrs");
776 /* PC0, PC1, PC2 possibly as shadow registers */
778 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
779 To
.Space
= UDI29KSpecialRegs
;
782 To
.Offset
= 20; /* SPC0 */
784 To
.Offset
= 10; /* PC0 */
785 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
786 error("UDIWrite() failed in udi_store_regisetrs");
790 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
791 To
.Space
= UDI29KSpecialRegs
;
794 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
795 error("UDIWrite() failed in udi_store_regisetrs");
797 /* Unprotected Special Registers */
799 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
800 To
.Space
= UDI29KSpecialRegs
;
803 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
804 error("UDIWrite() failed in udi_store_regisetrs");
806 registers_changed ();
809 /****************************************************** UDI_PREPARE_TO_STORE */
810 /* Get ready to modify the registers array. On machines which store
811 individual registers, this doesn't need to do anything. On machines
812 which store all the registers in one fell swoop, this makes sure
813 that registers contains all the registers from the program being
817 udi_prepare_to_store ()
819 /* Do nothing, since we can store individual regs */
822 /********************************************************** TRANSLATE_ADDR */
827 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
828 /* Check for a virtual address in the kernel */
829 /* Assume physical address of ublock is in paddr_u register */
830 /* FIXME: doesn't work for user virtual addresses */
831 if (addr
>= UVADDR
) {
832 /* PADDR_U register holds the physical address of the ublock */
833 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
834 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
842 /************************************************* UDI_XFER_INFERIOR_MEMORY */
843 /* FIXME! Merge these two. */
845 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
852 memaddr
= translate_addr(memaddr
);
855 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
857 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
860 /********************************************************** UDI_FILES_INFO */
864 printf ("\tAttached to UDI socket to %s and running program %s.\n",
865 udi_config_id
, prog_name
);
868 /**************************************************** UDI_INSERT_BREAKPOINT */
870 udi_insert_breakpoint (addr
, contents_cache
)
872 char *contents_cache
;
877 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
878 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
881 if(cnt
>= BKPT_TABLE_SIZE
)
882 error("Too many breakpoints set");
884 bkpt_table
[cnt
].Addr
.Offset
= addr
;
885 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
886 bkpt_table
[cnt
].PassCount
= 1;
887 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
889 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
890 bkpt_table
[cnt
].PassCount
,
891 bkpt_table
[cnt
].Type
,
892 &bkpt_table
[cnt
].BreakId
);
894 if (err
== 0) return 0; /* Success */
896 bkpt_table
[cnt
].Type
= 0;
897 error("UDISetBreakpoint returned error code %d\n", err
);
900 /**************************************************** UDI_REMOVE_BREAKPOINT */
902 udi_remove_breakpoint (addr
, contents_cache
)
904 char *contents_cache
;
909 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
910 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
913 if(cnt
>= BKPT_TABLE_SIZE
)
914 error("Can't find breakpoint in table");
916 bkpt_table
[cnt
].Type
= 0;
918 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
919 if (err
== 0) return 0; /* Success */
921 error("UDIClearBreakpoint returned error code %d\n", err
);
925 udi_kill(arg
,from_tty
)
932 UDIStop does not really work as advertised. It causes the TIP to close it's
933 connection, which usually results in GDB dying with a SIGPIPE. For now, we
934 just invoke udi_close, which seems to get things right.
942 printf("Target has been stopped.");
950 Load a program into the target. Args are: `program {options}'. The options
951 are used to control loading of the program, and are NOT passed onto the
952 loaded code as arguments. (You need to use the `run' command to do that.)
955 -ms %d Set mem stack size to %d
956 -rs %d Set regular stack size to %d
957 -i send init info (default)
958 -noi don't send init info
959 -[tT] Load Text section
960 -[dD] Load Data section
961 -[bB] Load BSS section
962 -[lL] Load Lit section
966 download(load_arg_string
, from_tty
)
967 char *load_arg_string
;
970 #define DEFAULT_MEM_STACK_SIZE 0x6000
971 #define DEFAULT_REG_STACK_SIZE 0x2000
978 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
980 address_ranges
[0].Space
= UDI29KIRAMSpace
;
981 address_ranges
[0].Offset
= 0xffffffff;
982 address_ranges
[0].Size
= 0;
984 address_ranges
[1].Space
= UDI29KDRAMSpace
;
985 address_ranges
[1].Offset
= 0xffffffff;
986 address_ranges
[1].Size
= 0;
988 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
989 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
993 filename
= strtok(load_arg_string
, " \t");
995 error ("Must specify at least a file name with the load command");
997 filename
= tilde_expand (filename
);
998 make_cleanup (free
, filename
);
1000 while (token
= strtok (NULL
, " \t"))
1002 if (token
[0] == '-')
1006 if (STREQ (token
, "ms"))
1007 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1008 else if (STREQ (token
, "rs"))
1009 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1012 load_text
= load_data
= load_bss
= load_lit
= 0;
1035 error ("Unknown UDI load option -%s", token
-1);
1042 pbfd
= bfd_openr (filename
, gnutarget
);
1045 perror_with_name (filename
);
1047 make_cleanup (bfd_close
, pbfd
);
1052 if (!bfd_check_format (pbfd
, bfd_object
))
1053 error ("It doesn't seem to be an object file");
1055 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1057 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1061 unsigned long section_size
, section_end
;
1062 const char *section_name
;
1064 section_name
= bfd_get_section_name (pbfd
, section
);
1065 if (STREQ (section_name
, ".text") && !load_text
)
1067 else if (STREQ (section_name
, ".data") && !load_data
)
1069 else if (STREQ (section_name
, ".bss") && !load_bss
)
1071 else if (STREQ (section_name
, ".lit") && !load_lit
)
1074 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1075 section_size
= bfd_section_size (pbfd
, section
);
1076 section_end
= To
.Offset
+ section_size
;
1078 printf("[Loading section %s at %x (%d bytes)]\n",
1083 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1085 To
.Space
= UDI29KIRAMSpace
;
1087 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1089 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1091 - address_ranges
[0].Offset
);
1095 To
.Space
= UDI29KDRAMSpace
;
1097 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1099 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1101 - address_ranges
[1].Offset
);
1104 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1110 while (section_size
> 0)
1114 Count
= min (section_size
, 1024);
1116 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1119 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1122 (UDISizeT
)1, /* Size */
1123 &Count
, /* CountDone */
1124 (UDIBool
)0); /* HostEndian */
1126 error ("UDIWrite failed, error = %d", err
);
1130 section_size
-= Count
;
1136 unsigned long zero
= 0;
1138 /* Write a zero byte at the vma */
1139 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1141 (UDICount
)1, /* Count */
1142 (UDISizeT
)4, /* Size */
1143 &Count
, /* CountDone */
1144 (UDIBool
)0); /* HostEndian */
1146 error ("UDIWrite failed, error = %d", err
);
1151 /* Now, duplicate it for the length of the BSS */
1152 err
= UDICopy (From
, /* From */
1154 (UDICount
)(section_size
/4 - 1), /* Count */
1155 (UDISizeT
)4, /* Size */
1156 &Count
, /* CountDone */
1157 (UDIBool
)1); /* Direction */
1163 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1165 fprintf (stderr
, "Error is %s\n", message
);
1167 fprintf (stderr
, "xerr is %d\n", xerr
);
1168 error ("UDICopy failed, error = %d", err
);
1175 entry
.Space
= UDI29KIRAMSpace
;
1176 entry
.Offset
= bfd_get_start_address (pbfd
);
1181 /* User interface to download an image into the remote target. See download()
1182 * for details on args.
1186 udi_load(args
, from_tty
)
1190 download (args
, from_tty
);
1192 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1195 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1196 ** Copy LEN bytes of data from debugger memory at MYADDR
1197 to inferior's memory at MEMADDR. Returns number of bytes written. */
1199 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1209 UDICount CountDone
= 0;
1210 UDIBool HostEndian
= 0;
1212 To
.Space
= udi_memory_space(memaddr
);
1213 From
= (UDIUInt32
*)myaddr
;
1215 while (nwritten
< len
)
1216 { Count
= len
- nwritten
;
1217 if (Count
> MAXDATA
) Count
= MAXDATA
;
1218 To
.Offset
= memaddr
+ nwritten
;
1219 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1220 { error("UDIWrite() failed in udi_write_inferrior_memory");
1224 { nwritten
+= CountDone
;
1231 /**************************************************** UDI_READ_INFERIOR_MEMORY
1232 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1233 at debugger address MYADDR. Returns number of bytes read. */
1235 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1245 UDICount CountDone
= 0;
1246 UDIBool HostEndian
= 0;
1249 From
.Space
= udi_memory_space(memaddr
);
1250 To
= (UDIUInt32
*)myaddr
;
1253 { Count
= len
- nread
;
1254 if (Count
> MAXDATA
) Count
= MAXDATA
;
1255 From
.Offset
= memaddr
+ nread
;
1256 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1257 { error("UDIRead() failed in udi_read_inferrior_memory");
1261 { nread
+= CountDone
;
1268 /********************************************************************* WARNING
1273 error ("ERROR while loading program into remote TIP: $d\n", num
);
1277 /*****************************************************************************/
1278 /* Fetch a single register indicatated by 'regno'.
1279 * Returns 0/-1 on success/failure.
1282 fetch_register (regno
)
1290 UDIBool HostEndian
= 0;
1294 if (regno
== GR1_REGNUM
)
1296 From
.Space
= UDI29KGlobalRegs
;
1299 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1301 From
.Space
= UDI29KGlobalRegs
;
1302 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1305 #if defined(GR64_REGNUM)
1307 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1309 From
.Space
= UDI29KGlobalRegs
;
1310 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1313 #endif /* GR64_REGNUM */
1315 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1317 From
.Space
= UDI29KLocalRegs
;
1318 From
.Offset
= (regno
- LR0_REGNUM
);
1320 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1323 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1324 return; /* Pretend Success */
1328 From
.Space
= UDI29KSpecialRegs
;
1329 From
.Offset
= regnum_to_srnum(regno
);
1332 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1333 error("UDIRead() failed in udi_fetch_registers");
1335 supply_register(regno
, (char *) &To
);
1338 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1340 /*****************************************************************************/
1341 /* Store a single register indicated by 'regno'.
1342 * Returns 0/-1 on success/failure.
1345 store_register (regno
)
1354 UDIBool HostEndian
= 0;
1356 From
= read_register (regno
); /* get data value */
1359 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1361 if (regno
== GR1_REGNUM
)
1362 { To
.Space
= UDI29KGlobalRegs
;
1364 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1365 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1366 * register cache. Do this *after* calling read_register, because we want
1367 * read_register to return the value that write_register has just stuffed
1368 * into the registers array, not the value of the register fetched from
1371 registers_changed ();
1373 #if defined(GR64_REGNUM)
1374 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1375 { To
.Space
= UDI29KGlobalRegs
;
1376 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1377 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1379 #endif /* GR64_REGNUM */
1380 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1381 { To
.Space
= UDI29KGlobalRegs
;
1382 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1383 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1385 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1386 { To
.Space
= UDI29KLocalRegs
;
1387 To
.Offset
= (regno
- LR0_REGNUM
);
1388 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1390 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1392 return 0; /* Pretend Success */
1394 else /* An unprotected or protected special register */
1395 { To
.Space
= UDI29KSpecialRegs
;
1396 To
.Offset
= regnum_to_srnum(regno
);
1397 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1402 error("UDIWrite() failed in store_registers");
1406 /********************************************************** REGNUM_TO_SRNUM */
1408 * Convert a gdb special register number to a 29000 special register number.
1411 regnum_to_srnum(regno
)
1415 case VAB_REGNUM
: return(0);
1416 case OPS_REGNUM
: return(1);
1417 case CPS_REGNUM
: return(2);
1418 case CFG_REGNUM
: return(3);
1419 case CHA_REGNUM
: return(4);
1420 case CHD_REGNUM
: return(5);
1421 case CHC_REGNUM
: return(6);
1422 case RBP_REGNUM
: return(7);
1423 case TMC_REGNUM
: return(8);
1424 case TMR_REGNUM
: return(9);
1425 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1426 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1427 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1428 case MMU_REGNUM
: return(13);
1429 case LRU_REGNUM
: return(14);
1430 case IPC_REGNUM
: return(128);
1431 case IPA_REGNUM
: return(129);
1432 case IPB_REGNUM
: return(130);
1433 case Q_REGNUM
: return(131);
1434 case ALU_REGNUM
: return(132);
1435 case BP_REGNUM
: return(133);
1436 case FC_REGNUM
: return(134);
1437 case CR_REGNUM
: return(135);
1438 case FPE_REGNUM
: return(160);
1439 case INTE_REGNUM
: return(161);
1440 case FPS_REGNUM
: return(162);
1441 case EXO_REGNUM
:return(164);
1443 return(255); /* Failure ? */
1446 /****************************************************************************/
1448 * Determine the Target memory space qualifier based on the addr.
1449 * FIXME: Can't distinguis I_ROM/D_ROM.
1450 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1453 udi_memory_space(addr
)
1456 UDIUInt32 tstart
= IMemStart
;
1457 UDIUInt32 tend
= tstart
+ IMemSize
;
1458 UDIUInt32 dstart
= DMemStart
;
1459 UDIUInt32 dend
= tstart
+ DMemSize
;
1460 UDIUInt32 rstart
= RMemStart
;
1461 UDIUInt32 rend
= tstart
+ RMemSize
;
1463 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1464 return UDI29KIRAMSpace
;
1465 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1466 return UDI29KDRAMSpace
;
1467 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1468 /* FIXME: how do we determine between D_ROM and I_ROM */
1469 return UDI29KIROMSpace
;
1470 } else /* FIXME: what do me do now? */
1471 return UDI29KDRAMSpace
; /* Hmmm! */
1473 /*********************************************************************** STUBS
1476 void convert16() {;}
1477 void convert32() {;}
1478 FILE* EchoFile
= 0; /* used for debugging */
1479 int QuietMode
= 0; /* used for debugging */
1481 /* Target_ops vector. Not static because there does not seem to be
1482 any portable way to do a forward declaration of a static variable.
1483 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1484 /bin/cc doesn't like "static" twice. */
1486 struct target_ops udi_ops
= {
1488 "Remote UDI connected TIP",
1489 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1491 `configuration-id AF_INET hostname port-number'\n\
1492 To connect via the network, where hostname and port-number specify the\n\
1493 host and port where you can connect via UDI.\n\
1494 configuration-id is unused.\n\
1496 `configuration-id AF_UNIX socket-name tip-program'\n\
1497 To connect using a local connection to the \"tip.exe\" program which is\n\
1498 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1499 tip program must already be started; connect to it using that socket.\n\
1500 If not, start up tip-program, which should be the name of the tip\n\
1501 program. If appropriate, the PATH environment variable is searched.\n\
1502 configuration-id is unused.\n\
1504 `configuration-id'\n\
1505 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1506 are files containing lines in the above formats. configuration-id is\n\
1507 used to pick which line of the file to use.",
1514 udi_fetch_registers
,
1515 udi_store_registers
,
1516 udi_prepare_to_store
,
1517 udi_xfer_inferior_memory
,
1519 udi_insert_breakpoint
,
1520 udi_remove_breakpoint
,
1521 0, /* termial_init */
1522 0, /* terminal_inferior */
1523 0, /* terminal_ours_for_output */
1524 0, /* terminal_ours */
1525 0, /* terminal_info */
1526 udi_kill
, /* FIXME, kill */
1528 0, /* lookup_symbol */
1529 udi_create_inferior
,
1530 udi_mourn
, /* mourn_inferior FIXME */
1532 0, /* notice_signals */
1535 1, /* has_all_memory */
1538 1, /* has_registers */
1539 1, /* has_execution */
1541 0, /* sections_end */
1542 OPS_MAGIC
, /* Always the last thing */
1545 void _initialize_remote_udi()
1547 add_target (&udi_ops
);
1549 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1551 "Set debugging of UDI I/O.\n\
1552 When enabled, debugging info is displayed.",
1557 #ifdef NO_HIF_SUPPORT
1561 return(0); /* Emulate a failure */