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"
49 /* access the register store directly, without going through
50 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 step
, int 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] = "";
73 #define TYPE_UNKNOWN 0
77 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
78 static int processor_type
=TYPE_UNKNOWN
;
79 #define FREEZE_MODE (read_register(CPS_REGNUM) & 0x400)
80 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
82 #define LLOG_FILE "udi.log"
83 #if defined (LOG_FILE)
87 static int timeout
= 5;
88 extern struct target_ops udi_ops
; /* Forward declaration */
90 /* Special register enumeration.
93 /******************************************************************* UDI DATA*/
94 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
95 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
96 udi_open knows that we don't have a file open when the program
99 UDISessionId udi_session_id
= -1;
101 CPUOffset IMemStart
= 0;
102 CPUSizeT IMemSize
= 0;
103 CPUOffset DMemStart
= 0;
104 CPUSizeT DMemSize
= 0;
105 CPUOffset RMemStart
= 0;
106 CPUSizeT RMemSize
= 0;
110 UDIMemoryRange address_ranges
[2]; /* Text and data */
111 UDIResource entry
= {0, 0}; /* Entry point */
112 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
114 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
117 typedef struct bkpt_entry_str
122 unsigned int BreakId
;
124 #define BKPT_TABLE_SIZE 40
125 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
126 extern char dfe_errmsg
[]; /* error string */
128 /* malloc'd name of the program on the remote system. */
129 static char *prog_name
= NULL
;
131 /* Number of SIGTRAPs we need to simulate. That is, the next
132 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
133 SIGTRAP without actually waiting for anything. */
135 /* This is called not only when we first attach, but also when the
136 user types "run" after having attached. */
139 udi_create_inferior (execfile
, args
, env
)
148 if (prog_name
!= NULL
)
150 prog_name
= savestring (execfile
, strlen (execfile
));
152 else if (entry
.Offset
)
155 error ("No image loaded into target.");
157 if (udi_session_id
< 0)
159 printf("UDI connection not open yet.\n");
163 inferior_pid
= 40000;
166 download(execfile
, 0);
168 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
170 strcpy (args1
, execfile
);
172 strcat (args1
, args
);
174 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
175 (UDIInt
)2, /* NumberOfRanges */
176 entry
, /* EntryPoint */
177 stack_sizes
, /* *StackSizes */
178 (UDIInt
)2, /* NumberOfStacks */
179 args1
); /* ArgString */
181 init_wait_for_inferior ();
182 clear_proceed_status ();
189 pop_target (); /* Pop back to no-child state */
190 generic_mourn_inferior ();
193 /******************************************************************** UDI_OPEN
194 ** Open a connection to remote TIP.
195 NAME is the socket domain used for communication with the TIP,
196 then a space and the socket name or TIP-host name.
197 '<udi_udi_config_id>' for example.
200 /* XXX - need cleanups for udiconnect for various failures!!! */
202 static char *udi_config_id
;
204 udi_open (name
, from_tty
)
211 UDIMemoryRange KnownMemory
[10];
212 UDIUInt32 ChipVersions
[10];
213 UDIInt NumberOfRanges
= 10;
214 UDIInt NumberOfChips
= 10;
216 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
218 target_preopen(from_tty
);
222 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
223 bkpt_table
[cnt
].Type
= 0;
226 free (udi_config_id
);
229 error("Usage: target udi config_id, where config_id appears in udi_soc file");
231 udi_config_id
= strdup (strtok (name
, " \t"));
233 if (UDIConnect (udi_config_id
, &udi_session_id
))
234 error("UDIConnect() failed: %s\n", dfe_errmsg
);
236 push_target (&udi_ops
);
238 #if defined (LOG_FILE)
239 log_file
= fopen (LOG_FILE
, "w");
240 if (log_file
== NULL
)
241 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
244 ** Initialize target configuration structure (global)
246 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
247 ChipVersions
, &NumberOfChips
))
248 error ("UDIGetTargetConfig() failed");
249 if (NumberOfChips
> 2)
250 fprintf(stderr
,"Target has more than one processor\n");
251 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
253 switch(KnownMemory
[cnt
].Space
)
256 fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
260 case UDI29KIROMSpace
:
261 RMemStart
= KnownMemory
[cnt
].Offset
;
262 RMemSize
= KnownMemory
[cnt
].Size
;
264 case UDI29KIRAMSpace
:
265 IMemStart
= KnownMemory
[cnt
].Offset
;
266 IMemSize
= KnownMemory
[cnt
].Size
;
268 case UDI29KDRAMSpace
:
269 DMemStart
= KnownMemory
[cnt
].Offset
;
270 DMemSize
= KnownMemory
[cnt
].Size
;
275 /* Determine the processor revision level */
276 prl
= (unsigned int)read_register (CFG_REGNUM
) >> 24;
279 fprintf_filtered (stderr
,
280 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
281 processor_type
= TYPE_A29000
;
283 else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
285 fprintf_filtered (stderr
,
286 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
287 processor_type
= TYPE_A29030
;
289 else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
291 fprintf_filtered (stderr
,
292 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
293 processor_type
= TYPE_A29050
;
297 processor_type
= TYPE_UNKNOWN
;
298 fprintf_filtered (stderr
,"WARNING: processor type unknown.\n");
300 if (UDICreateProcess (&PId
))
301 fprintf(stderr
, "UDICreateProcess() failed\n");
303 /* Print out some stuff, letting the user now what's going on */
304 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
306 error ("UDICapabilities() failed");
309 printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
310 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
311 processor_name
[processor_type
],
312 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
313 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
314 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
319 /******************************************************************* UDI_CLOSE
320 Close the open connection to the TIP process.
321 Use this when you want to detach and do something else
324 udi_close (quitting
) /*FIXME: how is quitting used */
327 if (udi_session_id
< 0)
330 /* We should never get here if there isn't something valid in
333 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
334 error ("UDIDisconnect() failed in udi_close");
336 /* Do not try to close udi_session_id again, later in the program. */
340 #if defined (LOG_FILE)
341 if (ferror (log_file
))
342 printf ("Error writing log file.\n");
343 if (fclose (log_file
) != 0)
344 printf ("Error closing log file.\n");
347 printf_filtered (" Ending remote debugging\n");
350 /**************************************************************** UDI_ATACH */
351 /* Attach to a program that is already loaded and running
352 * Upon exiting the process's execution is stopped.
355 udi_attach (args
, from_tty
)
364 UDIBool HostEndian
= 0;
367 if (udi_session_id
< 0)
368 error ("UDI connection not opened yet, use the 'target udi' command.\n");
371 printf ("Attaching to remote program %s...\n", prog_name
);
374 From
.Space
= UDI29KSpecialRegs
;
376 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
377 error ("UDIRead failed in udi_attach");
378 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
380 /************************************************************* UDI_DETACH */
381 /* Terminate the open connection to the TIP process.
382 Use this when you want to detach and do something else
383 with your gdb. Leave remote process running (with no breakpoints set). */
385 udi_detach (args
,from_tty
)
390 remove_breakpoints(); /* Just in case there were any left in */
392 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
393 error ("UDIDisconnect() failed in udi_detach");
395 pop_target(); /* calls udi_close to do the real work */
398 printf ("Ending remote debugging\n");
402 /****************************************************************** UDI_RESUME
403 ** Tell the remote machine to resume. */
406 udi_resume (step
, sig
)
411 UDIStepType StepType
= UDIStepNatural
;
414 if (step
) /* step 1 instruction */
416 tip_error
= UDIStep (Steps
, StepType
, Range
);
420 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
421 error ("failed in udi_resume");
425 error ("UDIExecute() failed in udi_resume");
428 /******************************************************************** UDI_WAIT
429 ** Wait until the remote machine stops, then return,
430 storing status in STATUS just as `wait' would. */
440 int old_timeout
= timeout
;
441 int old_immediate_quit
= immediate_quit
;
444 WSETEXIT ((*status
), 0);
446 /* wait for message to arrive. It should be:
447 If the target stops executing, udi_wait() should return.
449 timeout
= 0; /* Wait indefinetly for a message */
450 immediate_quit
= 1; /* Helps ability to QUIT */
455 MaxTime
= UDIWaitForever
;
456 UDIWait(MaxTime
, &PId
, &StopReason
);
457 QUIT
; /* Let user quit if they want */
459 switch (StopReason
& UDIGrossState
)
462 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
463 error ("UDIGetStdout() failed in udi_wait");
464 fwrite (sbuf
, 1, CountDone
, stdout
);
468 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
469 fwrite (sbuf
, 1, CountDone
, stderr
);
475 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
478 /* In spite of the fact that we told UDIWait to wait forever, it will
479 return spuriously sometimes. */
488 switch (StopReason
& UDIGrossState
)
491 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
493 switch (StopReason
>> 8)
495 case 0: /* Illegal opcode */
496 printf(" (break point)\n");
497 WSETSTOP ((*status
), SIGTRAP
);
499 case 1: /* Unaligned Access */
500 WSETSTOP ((*status
), SIGBUS
);
504 WSETSTOP ((*status
), SIGFPE
);
506 case 5: /* Protection Violation */
507 WSETSTOP ((*status
), SIGILL
);
511 case 8: /* User Instruction Mapping Miss */
512 case 9: /* User Data Mapping Miss */
513 case 10: /* Supervisor Instruction Mapping Miss */
514 case 11: /* Supervisor Data Mapping Miss */
515 WSETSTOP ((*status
), SIGSEGV
);
519 WSETSTOP ((*status
), SIGILL
);
522 WSETSTOP ((*status
), SIGALRM
);
525 WSETSTOP ((*status
), SIGTRAP
);
530 case 19: /* INTR3/Internal */
533 WSETSTOP ((*status
), SIGINT
);
535 case 22: /* Floating-Point Exception */
536 WSETSTOP ((*status
), SIGILL
);
538 case 77: /* assert 77 */
539 WSETSTOP ((*status
), SIGTRAP
);
542 WSETEXIT ((*status
), 0);
545 case UDINotExecuting
:
546 WSETSTOP ((*status
), SIGTERM
);
549 WSETSTOP ((*status
), SIGTSTP
);
552 WSETSTOP ((*status
), SIGURG
);
556 WSETSTOP ((*status
), SIGTRAP
);
559 WSETSTOP ((*status
), SIGSTOP
);
562 WSETSTOP ((*status
), SIGKILL
);
566 WSETEXIT ((*status
), 0);
569 timeout
= old_timeout
; /* Restore original timeout value */
570 immediate_quit
= old_immediate_quit
;
574 /********************************************************** UDI_FETCH_REGISTERS
575 * Read a remote register 'regno'.
576 * If regno==-1 then read all the registers.
579 udi_fetch_registers (regno
)
587 UDIBool HostEndian
= 0;
592 fetch_register(regno
);
598 From
.Space
= UDI29KGlobalRegs
;
600 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
602 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
603 error("UDIRead() failed in udi_fetch_registers");
605 register_valid
[GR1_REGNUM
] = 1;
607 #if defined(GR64_REGNUM) /* Read gr64-127 */
609 /* Global Registers gr64-gr95 */
611 From
.Space
= UDI29KGlobalRegs
;
613 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
615 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
616 error("UDIRead() failed in udi_fetch_registers");
618 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
619 register_valid
[i
] = 1;
621 #endif /* GR64_REGNUM */
623 /* Global Registers gr96-gr127 */
625 From
.Space
= UDI29KGlobalRegs
;
627 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
629 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
630 error("UDIRead() failed in udi_fetch_registers");
632 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
633 register_valid
[i
] = 1;
635 /* Local Registers */
637 From
.Space
= UDI29KLocalRegs
;
639 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
641 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
642 error("UDIRead() failed in udi_fetch_registers");
644 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
645 register_valid
[i
] = 1;
647 /* Protected Special Registers */
649 From
.Space
= UDI29KSpecialRegs
;
651 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
653 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
654 error("UDIRead() failed in udi_fetch_registers");
656 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
657 register_valid
[i
] = 1;
659 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
660 fetch_register(NPC_REGNUM
);
661 fetch_register(PC_REGNUM
);
662 fetch_register(PC2_REGNUM
);
664 /* Unprotected Special Registers sr128-sr135 */
666 From
.Space
= UDI29KSpecialRegs
;
668 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
670 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
671 error("UDIRead() failed in udi_fetch_registers");
673 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
674 register_valid
[i
] = 1;
679 printf("Fetching all registers\n");
680 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
681 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
682 read_register(PC2_REGNUM
));
685 /* There doesn't seem to be any way to get these. */
688 supply_register (FPE_REGNUM
, (char *) &val
);
689 supply_register (INTE_REGNUM
, (char *) &val
);
690 supply_register (FPS_REGNUM
, (char *) &val
);
691 supply_register (EXO_REGNUM
, (char *) &val
);
696 /********************************************************* UDI_STORE_REGISTERS
697 ** Store register regno into the target.
698 * If regno==-1 then store all the registers.
702 udi_store_registers (regno
)
710 UDIBool HostEndian
= 0;
714 store_register(regno
);
720 printf("Storing all registers\n");
721 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
722 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
727 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
728 To
.Space
= UDI29KGlobalRegs
;
731 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
732 error("UDIWrite() failed in udi_store_regisetrs");
734 #if defined(GR64_REGNUM)
736 /* Global registers gr64-gr95 */
738 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
739 To
.Space
= UDI29KGlobalRegs
;
742 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
743 error("UDIWrite() failed in udi_store_regisetrs");
745 #endif /* GR64_REGNUM */
747 /* Global registers gr96-gr127 */
749 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
750 To
.Space
= UDI29KGlobalRegs
;
753 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
754 error("UDIWrite() failed in udi_store_regisetrs");
756 /* Local Registers */
758 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
759 To
.Space
= UDI29KLocalRegs
;
762 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
763 error("UDIWrite() failed in udi_store_regisetrs");
766 /* Protected Special Registers */ /* VAB through TMR */
768 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
769 To
.Space
= UDI29KSpecialRegs
;
772 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
773 error("UDIWrite() failed in udi_store_regisetrs");
775 /* PC0, PC1, PC2 possibly as shadow registers */
777 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
778 To
.Space
= UDI29KSpecialRegs
;
781 To
.Offset
= 20; /* SPC0 */
783 To
.Offset
= 10; /* PC0 */
784 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
785 error("UDIWrite() failed in udi_store_regisetrs");
789 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
790 To
.Space
= UDI29KSpecialRegs
;
793 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
794 error("UDIWrite() failed in udi_store_regisetrs");
796 /* Unprotected Special Registers */
798 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
799 To
.Space
= UDI29KSpecialRegs
;
802 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
803 error("UDIWrite() failed in udi_store_regisetrs");
805 registers_changed ();
808 /****************************************************** UDI_PREPARE_TO_STORE */
809 /* Get ready to modify the registers array. On machines which store
810 individual registers, this doesn't need to do anything. On machines
811 which store all the registers in one fell swoop, this makes sure
812 that registers contains all the registers from the program being
816 udi_prepare_to_store ()
818 /* Do nothing, since we can store individual regs */
821 /********************************************************** TRANSLATE_ADDR */
826 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
827 /* Check for a virtual address in the kernel */
828 /* Assume physical address of ublock is in paddr_u register */
829 /* FIXME: doesn't work for user virtual addresses */
830 if (addr
>= UVADDR
) {
831 /* PADDR_U register holds the physical address of the ublock */
832 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
833 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
841 /************************************************* UDI_XFER_INFERIOR_MEMORY */
842 /* FIXME! Merge these two. */
844 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
851 memaddr
= translate_addr(memaddr
);
854 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
856 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
859 /********************************************************** UDI_FILES_INFO */
863 printf ("\tAttached to UDI socket to %s and running program %s.\n",
864 udi_config_id
, prog_name
);
867 /**************************************************** UDI_INSERT_BREAKPOINT */
869 udi_insert_breakpoint (addr
, contents_cache
)
871 char *contents_cache
;
876 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
877 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
880 if(cnt
>= BKPT_TABLE_SIZE
)
881 error("Too many breakpoints set");
883 bkpt_table
[cnt
].Addr
.Offset
= addr
;
884 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
885 bkpt_table
[cnt
].PassCount
= 1;
886 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
888 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
889 bkpt_table
[cnt
].PassCount
,
890 bkpt_table
[cnt
].Type
,
891 &bkpt_table
[cnt
].BreakId
);
893 if (err
== 0) return 0; /* Success */
895 bkpt_table
[cnt
].Type
= 0;
896 error("UDISetBreakpoint returned error code %d\n", err
);
899 /**************************************************** UDI_REMOVE_BREAKPOINT */
901 udi_remove_breakpoint (addr
, contents_cache
)
903 char *contents_cache
;
908 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
909 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
912 if(cnt
>= BKPT_TABLE_SIZE
)
913 error("Can't find breakpoint in table");
915 bkpt_table
[cnt
].Type
= 0;
917 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
918 if (err
== 0) return 0; /* Success */
920 error("UDIClearBreakpoint returned error code %d\n", err
);
924 udi_kill(arg
,from_tty
)
931 UDIStop does not really work as advertised. It causes the TIP to close it's
932 connection, which usually results in GDB dying with a SIGPIPE. For now, we
933 just invoke udi_close, which seems to get things right.
941 printf("Target has been stopped.");
949 Load a program into the target. Args are: `program {options}'. The options
950 are used to control loading of the program, and are NOT passed onto the
951 loaded code as arguments. (You need to use the `run' command to do that.)
954 -ms %d Set mem stack size to %d
955 -rs %d Set regular stack size to %d
956 -i send init info (default)
957 -noi don't send init info
958 -[tT] Load Text section
959 -[dD] Load Data section
960 -[bB] Load BSS section
961 -[lL] Load Lit section
965 download(load_arg_string
, from_tty
)
966 char *load_arg_string
;
969 #define DEFAULT_MEM_STACK_SIZE 0x6000
970 #define DEFAULT_REG_STACK_SIZE 0x2000
977 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
979 address_ranges
[0].Space
= UDI29KIRAMSpace
;
980 address_ranges
[0].Offset
= 0xffffffff;
981 address_ranges
[0].Size
= 0;
983 address_ranges
[1].Space
= UDI29KDRAMSpace
;
984 address_ranges
[1].Offset
= 0xffffffff;
985 address_ranges
[1].Size
= 0;
987 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
988 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
992 filename
= strtok(load_arg_string
, " \t");
994 error ("Must specify at least a file name with the load command");
996 filename
= tilde_expand (filename
);
997 make_cleanup (free
, filename
);
999 while (token
= strtok (NULL
, " \t"))
1001 if (token
[0] == '-')
1005 if (STREQ (token
, "ms"))
1006 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1007 else if (STREQ (token
, "rs"))
1008 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1011 load_text
= load_data
= load_bss
= load_lit
= 0;
1034 error ("Unknown UDI load option -%s", token
-1);
1041 pbfd
= bfd_openr (filename
, 0);
1044 perror_with_name (filename
);
1046 make_cleanup (bfd_close
, pbfd
);
1051 if (!bfd_check_format (pbfd
, bfd_object
))
1052 error ("It doesn't seem to be an object file");
1054 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1056 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1060 unsigned long section_size
, section_end
;
1061 const char *section_name
;
1063 section_name
= bfd_get_section_name (pbfd
, section
);
1064 if (STREQ (section_name
, ".text") && !load_text
)
1066 else if (STREQ (section_name
, ".data") && !load_data
)
1068 else if (STREQ (section_name
, ".bss") && !load_bss
)
1070 else if (STREQ (section_name
, ".lit") && !load_lit
)
1073 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1074 section_size
= bfd_section_size (pbfd
, section
);
1075 section_end
= To
.Offset
+ section_size
;
1077 printf("[Loading section %s at %x (%d bytes)]\n",
1082 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1084 To
.Space
= UDI29KIRAMSpace
;
1086 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1088 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1090 - address_ranges
[0].Offset
);
1094 To
.Space
= UDI29KDRAMSpace
;
1096 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1098 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1100 - address_ranges
[1].Offset
);
1103 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1109 while (section_size
> 0)
1113 Count
= min (section_size
, 1024);
1115 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1118 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1121 (UDISizeT
)1, /* Size */
1122 &Count
, /* CountDone */
1123 (UDIBool
)0); /* HostEndian */
1125 error ("UDIWrite failed, error = %d", err
);
1129 section_size
-= Count
;
1135 unsigned long zero
= 0;
1137 /* Write a zero byte at the vma */
1138 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1140 (UDICount
)1, /* Count */
1141 (UDISizeT
)4, /* Size */
1142 &Count
, /* CountDone */
1143 (UDIBool
)0); /* HostEndian */
1145 error ("UDIWrite failed, error = %d", err
);
1150 /* Now, duplicate it for the length of the BSS */
1151 err
= UDICopy (From
, /* From */
1153 (UDICount
)(section_size
/4 - 1), /* Count */
1154 (UDISizeT
)4, /* Size */
1155 &Count
, /* CountDone */
1156 (UDIBool
)1); /* Direction */
1162 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1164 fprintf (stderr
, "Error is %s\n", message
);
1166 fprintf (stderr
, "xerr is %d\n", xerr
);
1167 error ("UDICopy failed, error = %d", err
);
1174 entry
.Space
= UDI29KIRAMSpace
;
1175 entry
.Offset
= bfd_get_start_address (pbfd
);
1180 /* User interface to download an image into the remote target. See download()
1181 * for details on args.
1185 udi_load(args
, from_tty
)
1189 download (args
, from_tty
);
1191 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1194 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1195 ** Copy LEN bytes of data from debugger memory at MYADDR
1196 to inferior's memory at MEMADDR. Returns number of bytes written. */
1198 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1208 UDICount CountDone
= 0;
1209 UDIBool HostEndian
= 0;
1211 To
.Space
= udi_memory_space(memaddr
);
1212 From
= (UDIUInt32
*)myaddr
;
1214 while (nwritten
< len
)
1215 { Count
= len
- nwritten
;
1216 if (Count
> MAXDATA
) Count
= MAXDATA
;
1217 To
.Offset
= memaddr
+ nwritten
;
1218 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1219 { error("UDIWrite() failed in udi_write_inferrior_memory");
1223 { nwritten
+= CountDone
;
1230 /**************************************************** UDI_READ_INFERIOR_MEMORY
1231 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1232 at debugger address MYADDR. Returns number of bytes read. */
1234 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1244 UDICount CountDone
= 0;
1245 UDIBool HostEndian
= 0;
1248 From
.Space
= udi_memory_space(memaddr
);
1249 To
= (UDIUInt32
*)myaddr
;
1252 { Count
= len
- nread
;
1253 if (Count
> MAXDATA
) Count
= MAXDATA
;
1254 From
.Offset
= memaddr
+ nread
;
1255 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1256 { error("UDIRead() failed in udi_read_inferrior_memory");
1260 { nread
+= CountDone
;
1267 /********************************************************************* WARNING
1272 error ("ERROR while loading program into remote TIP: $d\n", num
);
1276 /*****************************************************************************/
1277 /* Fetch a single register indicatated by 'regno'.
1278 * Returns 0/-1 on success/failure.
1281 fetch_register (regno
)
1289 UDIBool HostEndian
= 0;
1293 if (regno
== GR1_REGNUM
)
1295 From
.Space
= UDI29KGlobalRegs
;
1298 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1300 From
.Space
= UDI29KGlobalRegs
;
1301 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1304 #if defined(GR64_REGNUM)
1306 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1308 From
.Space
= UDI29KGlobalRegs
;
1309 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1312 #endif /* GR64_REGNUM */
1314 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1316 From
.Space
= UDI29KLocalRegs
;
1317 From
.Offset
= (regno
- LR0_REGNUM
);
1319 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1322 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1323 return; /* Pretend Success */
1327 From
.Space
= UDI29KSpecialRegs
;
1328 From
.Offset
= regnum_to_srnum(regno
);
1331 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1332 error("UDIRead() failed in udi_fetch_registers");
1334 supply_register(regno
, (char *) &To
);
1337 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1339 /*****************************************************************************/
1340 /* Store a single register indicated by 'regno'.
1341 * Returns 0/-1 on success/failure.
1344 store_register (regno
)
1353 UDIBool HostEndian
= 0;
1355 From
= read_register (regno
); /* get data value */
1358 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1360 if (regno
== GR1_REGNUM
)
1361 { To
.Space
= UDI29KGlobalRegs
;
1363 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1364 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1365 * register cache. Do this *after* calling read_register, because we want
1366 * read_register to return the value that write_register has just stuffed
1367 * into the registers array, not the value of the register fetched from
1370 registers_changed ();
1372 #if defined(GR64_REGNUM)
1373 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1374 { To
.Space
= UDI29KGlobalRegs
;
1375 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1376 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1378 #endif /* GR64_REGNUM */
1379 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1380 { To
.Space
= UDI29KGlobalRegs
;
1381 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1382 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1384 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1385 { To
.Space
= UDI29KLocalRegs
;
1386 To
.Offset
= (regno
- LR0_REGNUM
);
1387 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1389 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1391 return 0; /* Pretend Success */
1393 else /* An unprotected or protected special register */
1394 { To
.Space
= UDI29KSpecialRegs
;
1395 To
.Offset
= regnum_to_srnum(regno
);
1396 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1401 error("UDIWrite() failed in store_registers");
1405 /********************************************************** REGNUM_TO_SRNUM */
1407 * Convert a gdb special register number to a 29000 special register number.
1410 regnum_to_srnum(regno
)
1414 case VAB_REGNUM
: return(0);
1415 case OPS_REGNUM
: return(1);
1416 case CPS_REGNUM
: return(2);
1417 case CFG_REGNUM
: return(3);
1418 case CHA_REGNUM
: return(4);
1419 case CHD_REGNUM
: return(5);
1420 case CHC_REGNUM
: return(6);
1421 case RBP_REGNUM
: return(7);
1422 case TMC_REGNUM
: return(8);
1423 case TMR_REGNUM
: return(9);
1424 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1425 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1426 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1427 case MMU_REGNUM
: return(13);
1428 case LRU_REGNUM
: return(14);
1429 case IPC_REGNUM
: return(128);
1430 case IPA_REGNUM
: return(129);
1431 case IPB_REGNUM
: return(130);
1432 case Q_REGNUM
: return(131);
1433 case ALU_REGNUM
: return(132);
1434 case BP_REGNUM
: return(133);
1435 case FC_REGNUM
: return(134);
1436 case CR_REGNUM
: return(135);
1437 case FPE_REGNUM
: return(160);
1438 case INTE_REGNUM
: return(161);
1439 case FPS_REGNUM
: return(162);
1440 case EXO_REGNUM
:return(164);
1442 return(255); /* Failure ? */
1445 /****************************************************************************/
1447 * Determine the Target memory space qualifier based on the addr.
1448 * FIXME: Can't distinguis I_ROM/D_ROM.
1449 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1452 udi_memory_space(addr
)
1455 UDIUInt32 tstart
= IMemStart
;
1456 UDIUInt32 tend
= tstart
+ IMemSize
;
1457 UDIUInt32 dstart
= DMemStart
;
1458 UDIUInt32 dend
= tstart
+ DMemSize
;
1459 UDIUInt32 rstart
= RMemStart
;
1460 UDIUInt32 rend
= tstart
+ RMemSize
;
1462 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1463 return UDI29KIRAMSpace
;
1464 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1465 return UDI29KDRAMSpace
;
1466 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1467 /* FIXME: how do we determine between D_ROM and I_ROM */
1468 return UDI29KIROMSpace
;
1469 } else /* FIXME: what do me do now? */
1470 return UDI29KDRAMSpace
; /* Hmmm! */
1472 /*********************************************************************** STUBS
1475 void convert16() {;}
1476 void convert32() {;}
1477 FILE* EchoFile
= 0; /* used for debugging */
1478 int QuietMode
= 0; /* used for debugging */
1480 /****************************************************************************/
1482 * Define the target subroutine names
1484 static struct target_ops udi_ops
= {
1486 "Remote UDI connected TIP",
1487 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1489 `configuration-id AF_INET hostname port-number'\n\
1490 To connect via the network, where hostname and port-number specify the\n\
1491 host and port where you can connect via UDI.\n\
1492 configuration-id is unused.\n\
1494 `configuration-id AF_UNIX socket-name tip-program'\n\
1495 To connect using a local connection to the \"tip.exe\" program which is\n\
1496 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1497 tip program must already be started; connect to it using that socket.\n\
1498 If not, start up tip-program, which should be the name of the tip\n\
1499 program. If appropriate, the PATH environment variable is searched.\n\
1500 configuration-id is unused.\n\
1502 `configuration-id'\n\
1503 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1504 are files containing lines in the above formats. configuration-id is\n\
1505 used to pick which line of the file to use.",
1512 udi_fetch_registers
,
1513 udi_store_registers
,
1514 udi_prepare_to_store
,
1515 udi_xfer_inferior_memory
,
1517 udi_insert_breakpoint
,
1518 udi_remove_breakpoint
,
1519 0, /* termial_init */
1520 0, /* terminal_inferior */
1521 0, /* terminal_ours_for_output */
1522 0, /* terminal_ours */
1523 0, /* terminal_info */
1524 udi_kill
, /* FIXME, kill */
1526 0, /* lookup_symbol */
1527 udi_create_inferior
,
1528 udi_mourn
, /* mourn_inferior FIXME */
1530 0, /* notice_signals */
1533 1, /* has_all_memory */
1536 1, /* has_registers */
1537 1, /* has_execution */
1539 0, /* sections_end */
1540 OPS_MAGIC
, /* Always the last thing */
1543 void _initialize_remote_udi()
1545 add_target (&udi_ops
);
1547 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1549 "Set debugging of UDI I/O.\n\
1550 When enabled, debugging info is displayed.",
1555 #ifdef NO_HIF_SUPPORT
1559 return(0); /* Emulate a failure */