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 /* This is said to happen if the program tries to output
465 a whole bunch of output (more than SBUF_MAX, I would
466 guess). It doesn't seem to happen with the simulator. */
467 warning ("UDIGetStdout() failed in udi_wait");
468 fwrite (sbuf
, 1, CountDone
, stdout
);
472 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
473 fwrite (sbuf
, 1, CountDone
, stderr
);
487 } while (i
< SBUF_MAX
&& ch
!= '\n');
488 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
493 /* In spite of the fact that we told UDIWait to wait forever, it will
494 return spuriously sometimes. */
503 switch (StopReason
& UDIGrossState
)
506 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
508 switch (StopReason
>> 8)
510 case 0: /* Illegal opcode */
511 printf(" (break point)\n");
512 WSETSTOP ((*status
), SIGTRAP
);
514 case 1: /* Unaligned Access */
515 WSETSTOP ((*status
), SIGBUS
);
519 WSETSTOP ((*status
), SIGFPE
);
521 case 5: /* Protection Violation */
522 WSETSTOP ((*status
), SIGILL
);
526 case 8: /* User Instruction Mapping Miss */
527 case 9: /* User Data Mapping Miss */
528 case 10: /* Supervisor Instruction Mapping Miss */
529 case 11: /* Supervisor Data Mapping Miss */
530 WSETSTOP ((*status
), SIGSEGV
);
534 WSETSTOP ((*status
), SIGILL
);
537 WSETSTOP ((*status
), SIGALRM
);
540 WSETSTOP ((*status
), SIGTRAP
);
545 case 19: /* INTR3/Internal */
548 WSETSTOP ((*status
), SIGINT
);
550 case 22: /* Floating-Point Exception */
551 WSETSTOP ((*status
), SIGILL
);
553 case 77: /* assert 77 */
554 WSETSTOP ((*status
), SIGTRAP
);
557 WSETEXIT ((*status
), 0);
560 case UDINotExecuting
:
561 WSETSTOP ((*status
), SIGTERM
);
564 WSETSTOP ((*status
), SIGTSTP
);
567 WSETSTOP ((*status
), SIGURG
);
571 WSETSTOP ((*status
), SIGTRAP
);
574 WSETSTOP ((*status
), SIGSTOP
);
577 WSETSTOP ((*status
), SIGKILL
);
581 WSETEXIT ((*status
), 0);
584 timeout
= old_timeout
; /* Restore original timeout value */
585 immediate_quit
= old_immediate_quit
;
589 /********************************************************** UDI_FETCH_REGISTERS
590 * Read a remote register 'regno'.
591 * If regno==-1 then read all the registers.
594 udi_fetch_registers (regno
)
602 UDIBool HostEndian
= 0;
607 fetch_register(regno
);
613 From
.Space
= UDI29KGlobalRegs
;
615 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
617 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
618 error("UDIRead() failed in udi_fetch_registers");
620 register_valid
[GR1_REGNUM
] = 1;
622 #if defined(GR64_REGNUM) /* Read gr64-127 */
624 /* Global Registers gr64-gr95 */
626 From
.Space
= UDI29KGlobalRegs
;
628 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
630 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
631 error("UDIRead() failed in udi_fetch_registers");
633 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
634 register_valid
[i
] = 1;
636 #endif /* GR64_REGNUM */
638 /* Global Registers gr96-gr127 */
640 From
.Space
= UDI29KGlobalRegs
;
642 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
644 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
645 error("UDIRead() failed in udi_fetch_registers");
647 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
648 register_valid
[i
] = 1;
650 /* Local Registers */
652 From
.Space
= UDI29KLocalRegs
;
654 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
656 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
657 error("UDIRead() failed in udi_fetch_registers");
659 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
660 register_valid
[i
] = 1;
662 /* Protected Special Registers */
664 From
.Space
= UDI29KSpecialRegs
;
666 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
668 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
669 error("UDIRead() failed in udi_fetch_registers");
671 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
672 register_valid
[i
] = 1;
674 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
675 fetch_register(NPC_REGNUM
);
676 fetch_register(PC_REGNUM
);
677 fetch_register(PC2_REGNUM
);
679 /* Unprotected Special Registers sr128-sr135 */
681 From
.Space
= UDI29KSpecialRegs
;
683 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
685 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
686 error("UDIRead() failed in udi_fetch_registers");
688 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
689 register_valid
[i
] = 1;
694 printf("Fetching all registers\n");
695 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
696 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
697 read_register(PC2_REGNUM
));
700 /* There doesn't seem to be any way to get these. */
703 supply_register (FPE_REGNUM
, (char *) &val
);
704 supply_register (INTE_REGNUM
, (char *) &val
);
705 supply_register (FPS_REGNUM
, (char *) &val
);
706 supply_register (EXO_REGNUM
, (char *) &val
);
711 /********************************************************* UDI_STORE_REGISTERS
712 ** Store register regno into the target.
713 * If regno==-1 then store all the registers.
717 udi_store_registers (regno
)
725 UDIBool HostEndian
= 0;
729 store_register(regno
);
735 printf("Storing all registers\n");
736 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
737 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
742 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
743 To
.Space
= UDI29KGlobalRegs
;
746 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
747 error("UDIWrite() failed in udi_store_regisetrs");
749 #if defined(GR64_REGNUM)
751 /* Global registers gr64-gr95 */
753 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
754 To
.Space
= UDI29KGlobalRegs
;
757 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
758 error("UDIWrite() failed in udi_store_regisetrs");
760 #endif /* GR64_REGNUM */
762 /* Global registers gr96-gr127 */
764 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
765 To
.Space
= UDI29KGlobalRegs
;
768 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
769 error("UDIWrite() failed in udi_store_regisetrs");
771 /* Local Registers */
773 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
774 To
.Space
= UDI29KLocalRegs
;
777 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
778 error("UDIWrite() failed in udi_store_regisetrs");
781 /* Protected Special Registers */ /* VAB through TMR */
783 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
784 To
.Space
= UDI29KSpecialRegs
;
787 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
788 error("UDIWrite() failed in udi_store_regisetrs");
790 /* PC0, PC1, PC2 possibly as shadow registers */
792 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
793 To
.Space
= UDI29KSpecialRegs
;
796 To
.Offset
= 20; /* SPC0 */
798 To
.Offset
= 10; /* PC0 */
799 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
800 error("UDIWrite() failed in udi_store_regisetrs");
804 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
805 To
.Space
= UDI29KSpecialRegs
;
808 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
809 error("UDIWrite() failed in udi_store_regisetrs");
811 /* Unprotected Special Registers */
813 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
814 To
.Space
= UDI29KSpecialRegs
;
817 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
818 error("UDIWrite() failed in udi_store_regisetrs");
820 registers_changed ();
823 /****************************************************** UDI_PREPARE_TO_STORE */
824 /* Get ready to modify the registers array. On machines which store
825 individual registers, this doesn't need to do anything. On machines
826 which store all the registers in one fell swoop, this makes sure
827 that registers contains all the registers from the program being
831 udi_prepare_to_store ()
833 /* Do nothing, since we can store individual regs */
836 /********************************************************** TRANSLATE_ADDR */
841 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
842 /* Check for a virtual address in the kernel */
843 /* Assume physical address of ublock is in paddr_u register */
844 /* FIXME: doesn't work for user virtual addresses */
845 if (addr
>= UVADDR
) {
846 /* PADDR_U register holds the physical address of the ublock */
847 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
848 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
856 /************************************************* UDI_XFER_INFERIOR_MEMORY */
857 /* FIXME! Merge these two. */
859 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
866 memaddr
= translate_addr(memaddr
);
869 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
871 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
874 /********************************************************** UDI_FILES_INFO */
878 printf ("\tAttached to UDI socket to %s and running program %s.\n",
879 udi_config_id
, prog_name
);
882 /**************************************************** UDI_INSERT_BREAKPOINT */
884 udi_insert_breakpoint (addr
, contents_cache
)
886 char *contents_cache
;
891 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
892 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
895 if(cnt
>= BKPT_TABLE_SIZE
)
896 error("Too many breakpoints set");
898 bkpt_table
[cnt
].Addr
.Offset
= addr
;
899 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
900 bkpt_table
[cnt
].PassCount
= 1;
901 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
903 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
904 bkpt_table
[cnt
].PassCount
,
905 bkpt_table
[cnt
].Type
,
906 &bkpt_table
[cnt
].BreakId
);
908 if (err
== 0) return 0; /* Success */
910 bkpt_table
[cnt
].Type
= 0;
911 error("UDISetBreakpoint returned error code %d\n", err
);
914 /**************************************************** UDI_REMOVE_BREAKPOINT */
916 udi_remove_breakpoint (addr
, contents_cache
)
918 char *contents_cache
;
923 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
924 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
927 if(cnt
>= BKPT_TABLE_SIZE
)
928 error("Can't find breakpoint in table");
930 bkpt_table
[cnt
].Type
= 0;
932 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
933 if (err
== 0) return 0; /* Success */
935 error("UDIClearBreakpoint returned error code %d\n", err
);
939 udi_kill(arg
,from_tty
)
946 UDIStop does not really work as advertised. It causes the TIP to close it's
947 connection, which usually results in GDB dying with a SIGPIPE. For now, we
948 just invoke udi_close, which seems to get things right.
956 printf("Target has been stopped.");
964 Load a program into the target. Args are: `program {options}'. The options
965 are used to control loading of the program, and are NOT passed onto the
966 loaded code as arguments. (You need to use the `run' command to do that.)
969 -ms %d Set mem stack size to %d
970 -rs %d Set regular stack size to %d
971 -i send init info (default)
972 -noi don't send init info
973 -[tT] Load Text section
974 -[dD] Load Data section
975 -[bB] Load BSS section
976 -[lL] Load Lit section
980 download(load_arg_string
, from_tty
)
981 char *load_arg_string
;
984 #define DEFAULT_MEM_STACK_SIZE 0x6000
985 #define DEFAULT_REG_STACK_SIZE 0x2000
992 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
994 address_ranges
[0].Space
= UDI29KIRAMSpace
;
995 address_ranges
[0].Offset
= 0xffffffff;
996 address_ranges
[0].Size
= 0;
998 address_ranges
[1].Space
= UDI29KDRAMSpace
;
999 address_ranges
[1].Offset
= 0xffffffff;
1000 address_ranges
[1].Size
= 0;
1002 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1003 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1007 filename
= strtok(load_arg_string
, " \t");
1009 error ("Must specify at least a file name with the load command");
1011 filename
= tilde_expand (filename
);
1012 make_cleanup (free
, filename
);
1014 while (token
= strtok (NULL
, " \t"))
1016 if (token
[0] == '-')
1020 if (STREQ (token
, "ms"))
1021 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1022 else if (STREQ (token
, "rs"))
1023 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1026 load_text
= load_data
= load_bss
= load_lit
= 0;
1049 error ("Unknown UDI load option -%s", token
-1);
1056 pbfd
= bfd_openr (filename
, gnutarget
);
1059 perror_with_name (filename
);
1061 make_cleanup (bfd_close
, pbfd
);
1066 if (!bfd_check_format (pbfd
, bfd_object
))
1067 error ("It doesn't seem to be an object file");
1069 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1071 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1075 unsigned long section_size
, section_end
;
1076 const char *section_name
;
1078 section_name
= bfd_get_section_name (pbfd
, section
);
1079 if (STREQ (section_name
, ".text") && !load_text
)
1081 else if (STREQ (section_name
, ".data") && !load_data
)
1083 else if (STREQ (section_name
, ".bss") && !load_bss
)
1085 else if (STREQ (section_name
, ".lit") && !load_lit
)
1088 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1089 section_size
= bfd_section_size (pbfd
, section
);
1090 section_end
= To
.Offset
+ section_size
;
1092 printf("[Loading section %s at %x (%d bytes)]\n",
1097 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1099 To
.Space
= UDI29KIRAMSpace
;
1101 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1103 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1105 - address_ranges
[0].Offset
);
1109 To
.Space
= UDI29KDRAMSpace
;
1111 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1113 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1115 - address_ranges
[1].Offset
);
1118 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1124 while (section_size
> 0)
1128 Count
= min (section_size
, 1024);
1130 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1133 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1136 (UDISizeT
)1, /* Size */
1137 &Count
, /* CountDone */
1138 (UDIBool
)0); /* HostEndian */
1140 error ("UDIWrite failed, error = %d", err
);
1144 section_size
-= Count
;
1150 unsigned long zero
= 0;
1152 /* Write a zero byte at the vma */
1153 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1155 (UDICount
)1, /* Count */
1156 (UDISizeT
)4, /* Size */
1157 &Count
, /* CountDone */
1158 (UDIBool
)0); /* HostEndian */
1160 error ("UDIWrite failed, error = %d", err
);
1165 /* Now, duplicate it for the length of the BSS */
1166 err
= UDICopy (From
, /* From */
1168 (UDICount
)(section_size
/4 - 1), /* Count */
1169 (UDISizeT
)4, /* Size */
1170 &Count
, /* CountDone */
1171 (UDIBool
)1); /* Direction */
1177 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1179 fprintf (stderr
, "Error is %s\n", message
);
1181 fprintf (stderr
, "xerr is %d\n", xerr
);
1182 error ("UDICopy failed, error = %d", err
);
1189 entry
.Space
= UDI29KIRAMSpace
;
1190 entry
.Offset
= bfd_get_start_address (pbfd
);
1195 /* User interface to download an image into the remote target. See download()
1196 * for details on args.
1200 udi_load(args
, from_tty
)
1204 download (args
, from_tty
);
1206 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1209 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1210 ** Copy LEN bytes of data from debugger memory at MYADDR
1211 to inferior's memory at MEMADDR. Returns number of bytes written. */
1213 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1223 UDICount CountDone
= 0;
1224 UDIBool HostEndian
= 0;
1226 To
.Space
= udi_memory_space(memaddr
);
1227 From
= (UDIUInt32
*)myaddr
;
1229 while (nwritten
< len
)
1230 { Count
= len
- nwritten
;
1231 if (Count
> MAXDATA
) Count
= MAXDATA
;
1232 To
.Offset
= memaddr
+ nwritten
;
1233 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1234 { error("UDIWrite() failed in udi_write_inferrior_memory");
1238 { nwritten
+= CountDone
;
1245 /**************************************************** UDI_READ_INFERIOR_MEMORY
1246 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1247 at debugger address MYADDR. Returns number of bytes read. */
1249 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1259 UDICount CountDone
= 0;
1260 UDIBool HostEndian
= 0;
1263 From
.Space
= udi_memory_space(memaddr
);
1264 To
= (UDIUInt32
*)myaddr
;
1267 { Count
= len
- nread
;
1268 if (Count
> MAXDATA
) Count
= MAXDATA
;
1269 From
.Offset
= memaddr
+ nread
;
1270 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1271 { error("UDIRead() failed in udi_read_inferrior_memory");
1275 { nread
+= CountDone
;
1282 /********************************************************************* WARNING
1287 error ("ERROR while loading program into remote TIP: $d\n", num
);
1291 /*****************************************************************************/
1292 /* Fetch a single register indicatated by 'regno'.
1293 * Returns 0/-1 on success/failure.
1296 fetch_register (regno
)
1304 UDIBool HostEndian
= 0;
1308 if (regno
== GR1_REGNUM
)
1310 From
.Space
= UDI29KGlobalRegs
;
1313 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1315 From
.Space
= UDI29KGlobalRegs
;
1316 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1319 #if defined(GR64_REGNUM)
1321 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1323 From
.Space
= UDI29KGlobalRegs
;
1324 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1327 #endif /* GR64_REGNUM */
1329 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1331 From
.Space
= UDI29KLocalRegs
;
1332 From
.Offset
= (regno
- LR0_REGNUM
);
1334 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1337 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1338 return; /* Pretend Success */
1342 From
.Space
= UDI29KSpecialRegs
;
1343 From
.Offset
= regnum_to_srnum(regno
);
1346 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1347 error("UDIRead() failed in udi_fetch_registers");
1349 supply_register(regno
, (char *) &To
);
1352 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1354 /*****************************************************************************/
1355 /* Store a single register indicated by 'regno'.
1356 * Returns 0/-1 on success/failure.
1359 store_register (regno
)
1368 UDIBool HostEndian
= 0;
1370 From
= read_register (regno
); /* get data value */
1373 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1375 if (regno
== GR1_REGNUM
)
1376 { To
.Space
= UDI29KGlobalRegs
;
1378 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1379 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1380 * register cache. Do this *after* calling read_register, because we want
1381 * read_register to return the value that write_register has just stuffed
1382 * into the registers array, not the value of the register fetched from
1385 registers_changed ();
1387 #if defined(GR64_REGNUM)
1388 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1389 { To
.Space
= UDI29KGlobalRegs
;
1390 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1391 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1393 #endif /* GR64_REGNUM */
1394 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1395 { To
.Space
= UDI29KGlobalRegs
;
1396 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1397 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1399 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1400 { To
.Space
= UDI29KLocalRegs
;
1401 To
.Offset
= (regno
- LR0_REGNUM
);
1402 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1404 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1406 return 0; /* Pretend Success */
1408 else /* An unprotected or protected special register */
1409 { To
.Space
= UDI29KSpecialRegs
;
1410 To
.Offset
= regnum_to_srnum(regno
);
1411 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1416 error("UDIWrite() failed in store_registers");
1420 /********************************************************** REGNUM_TO_SRNUM */
1422 * Convert a gdb special register number to a 29000 special register number.
1425 regnum_to_srnum(regno
)
1429 case VAB_REGNUM
: return(0);
1430 case OPS_REGNUM
: return(1);
1431 case CPS_REGNUM
: return(2);
1432 case CFG_REGNUM
: return(3);
1433 case CHA_REGNUM
: return(4);
1434 case CHD_REGNUM
: return(5);
1435 case CHC_REGNUM
: return(6);
1436 case RBP_REGNUM
: return(7);
1437 case TMC_REGNUM
: return(8);
1438 case TMR_REGNUM
: return(9);
1439 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1440 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1441 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1442 case MMU_REGNUM
: return(13);
1443 case LRU_REGNUM
: return(14);
1444 case IPC_REGNUM
: return(128);
1445 case IPA_REGNUM
: return(129);
1446 case IPB_REGNUM
: return(130);
1447 case Q_REGNUM
: return(131);
1448 case ALU_REGNUM
: return(132);
1449 case BP_REGNUM
: return(133);
1450 case FC_REGNUM
: return(134);
1451 case CR_REGNUM
: return(135);
1452 case FPE_REGNUM
: return(160);
1453 case INTE_REGNUM
: return(161);
1454 case FPS_REGNUM
: return(162);
1455 case EXO_REGNUM
:return(164);
1457 return(255); /* Failure ? */
1460 /****************************************************************************/
1462 * Determine the Target memory space qualifier based on the addr.
1463 * FIXME: Can't distinguis I_ROM/D_ROM.
1464 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1467 udi_memory_space(addr
)
1470 UDIUInt32 tstart
= IMemStart
;
1471 UDIUInt32 tend
= tstart
+ IMemSize
;
1472 UDIUInt32 dstart
= DMemStart
;
1473 UDIUInt32 dend
= tstart
+ DMemSize
;
1474 UDIUInt32 rstart
= RMemStart
;
1475 UDIUInt32 rend
= tstart
+ RMemSize
;
1477 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1478 return UDI29KIRAMSpace
;
1479 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1480 return UDI29KDRAMSpace
;
1481 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1482 /* FIXME: how do we determine between D_ROM and I_ROM */
1483 return UDI29KIROMSpace
;
1484 } else /* FIXME: what do me do now? */
1485 return UDI29KDRAMSpace
; /* Hmmm! */
1487 /*********************************************************************** STUBS
1490 void convert16() {;}
1491 void convert32() {;}
1492 FILE* EchoFile
= 0; /* used for debugging */
1493 int QuietMode
= 0; /* used for debugging */
1495 /* Target_ops vector. Not static because there does not seem to be
1496 any portable way to do a forward declaration of a static variable.
1497 The RS/6000 doesn't like "extern" followed by "static"; SunOS
1498 /bin/cc doesn't like "static" twice. */
1500 struct target_ops udi_ops
= {
1502 "Remote UDI connected TIP",
1503 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1505 `configuration-id AF_INET hostname port-number'\n\
1506 To connect via the network, where hostname and port-number specify the\n\
1507 host and port where you can connect via UDI.\n\
1508 configuration-id is unused.\n\
1510 `configuration-id AF_UNIX socket-name tip-program'\n\
1511 To connect using a local connection to the \"tip.exe\" program which is\n\
1512 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1513 tip program must already be started; connect to it using that socket.\n\
1514 If not, start up tip-program, which should be the name of the tip\n\
1515 program. If appropriate, the PATH environment variable is searched.\n\
1516 configuration-id is unused.\n\
1518 `configuration-id'\n\
1519 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1520 are files containing lines in the above formats. configuration-id is\n\
1521 used to pick which line of the file to use.",
1528 udi_fetch_registers
,
1529 udi_store_registers
,
1530 udi_prepare_to_store
,
1531 udi_xfer_inferior_memory
,
1533 udi_insert_breakpoint
,
1534 udi_remove_breakpoint
,
1535 0, /* termial_init */
1536 0, /* terminal_inferior */
1537 0, /* terminal_ours_for_output */
1538 0, /* terminal_ours */
1539 0, /* terminal_info */
1540 udi_kill
, /* FIXME, kill */
1542 0, /* lookup_symbol */
1543 udi_create_inferior
,
1544 udi_mourn
, /* mourn_inferior FIXME */
1546 0, /* notice_signals */
1549 1, /* has_all_memory */
1552 1, /* has_registers */
1553 1, /* has_execution */
1555 0, /* sections_end */
1556 OPS_MAGIC
, /* Always the last thing */
1559 void _initialize_remote_udi()
1561 add_target (&udi_ops
);
1563 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1565 "Set debugging of UDI I/O.\n\
1566 When enabled, debugging info is displayed.",
1571 #ifdef NO_HIF_SUPPORT
1575 return(0); /* Emulate a failure */