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. Because we are only attempting to
31 use this module to debug our kernel, which is already loaded when
32 gdb is started up, I did not code up the file downloading facilities.
33 As a result this module has only the stubs to download files.
34 You should get tagged at compile time if you need to make any
36 - Daniel Mann at AMD took the 3.95 adaptions above and replaced
37 MiniMON interface with UDI-p interface. */
50 #include "29k-share/udi/udiproc.h"
54 /* access the register store directly, without going through
55 the normal handler functions. This avoids an extra data copy. */
58 extern int stop_soon_quietly
; /* for wait_for_inferior */
59 extern struct value
*call_function_by_hand();
60 static void udi_resume
PARAMS ((int step
, int sig
));
61 static void udi_fetch_registers
PARAMS ((int regno
));
62 static void udi_load
PARAMS ((char *args
, int from_tty
));
63 static void fetch_register
PARAMS ((int regno
));
64 static void udi_store_registers
PARAMS ((int regno
));
65 static int store_register
PARAMS ((int regno
));
66 static int regnum_to_srnum
PARAMS ((int regno
));
67 static void udi_close
PARAMS ((int quitting
));
68 static CPUSpace udi_memory_space
PARAMS ((CORE_ADDR addr
));
69 static int udi_write_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
71 static int udi_read_inferior_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
73 static void download
PARAMS ((char *load_arg_string
, int from_tty
));
74 char CoffFileName
[100] = "";
78 #define TYPE_UNKNOWN 0
82 static char *processor_name
[] = { "Unknown", "Am29000", "Am29030", "Am29050" };
83 static int processor_type
=TYPE_UNKNOWN
;
84 #define FREEZE_MODE (read_register(CPS_REGNUM) && 0x400)
85 #define USE_SHADOW_PC ((processor_type == TYPE_A29050) && FREEZE_MODE)
87 #define LLOG_FILE "udi.log"
88 #if defined (LOG_FILE)
92 static int timeout
= 5;
93 extern struct target_ops udi_ops
; /* Forward declaration */
95 /* Special register enumeration.
98 /******************************************************************* UDI DATA*/
99 #define MAXDATA 2*1024 /* max UDI[read/write] byte size */
100 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
101 udi_open knows that we don't have a file open when the program
104 UDISessionId udi_session_id
= -1;
106 CPUOffset IMemStart
= 0;
107 CPUSizeT IMemSize
= 0;
108 CPUOffset DMemStart
= 0;
109 CPUSizeT DMemSize
= 0;
110 CPUOffset RMemStart
= 0;
111 CPUSizeT RMemSize
= 0;
115 UDIMemoryRange address_ranges
[2]; /* Text and data */
116 UDIResource entry
= {0, 0}; /* Entry point */
117 CPUSizeT stack_sizes
[2]; /* Regular and memory stacks */
119 #define SBUF_MAX 1024 /* maximum size of string handling buffer */
122 typedef struct bkpt_entry_str
127 unsigned int BreakId
;
129 #define BKPT_TABLE_SIZE 40
130 static bkpt_entry_t bkpt_table
[BKPT_TABLE_SIZE
];
131 extern char dfe_errmsg
[]; /* error string */
133 /* Called when SIGALRM signal sent due to alarm() timeout. */
136 volatile int n_alarms
;
143 printf ("udi_timer called\n");
147 #endif /* HAVE_TERMIO */
149 /* malloc'd name of the program on the remote system. */
150 static char *prog_name
= NULL
;
152 /* Number of SIGTRAPs we need to simulate. That is, the next
153 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
154 SIGTRAP without actually waiting for anything. */
156 /* This is called not only when we first attach, but also when the
157 user types "run" after having attached. */
160 udi_create_inferior (execfile
, args
, env
)
169 if (prog_name
!= NULL
)
171 prog_name
= savestring (execfile
, strlen (execfile
));
173 else if (entry
.Offset
)
176 error ("No image loaded into target.");
178 if (udi_session_id
< 0)
180 printf("UDI connection not open yet.\n");
184 inferior_pid
= 40000;
187 download(execfile
, 0);
189 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
191 strcpy (args1
, execfile
);
193 strcat (args1
, args
);
195 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
196 (UDIInt
)2, /* NumberOfRanges */
197 entry
, /* EntryPoint */
198 stack_sizes
, /* *StackSizes */
199 (UDIInt
)2, /* NumberOfStacks */
200 args1
); /* ArgString */
202 init_wait_for_inferior ();
203 clear_proceed_status ();
210 pop_target (); /* Pop back to no-child state */
211 generic_mourn_inferior ();
214 /******************************************************************** UDI_OPEN
215 ** Open a connection to remote TIP.
216 NAME is the socket domain used for communication with the TIP,
217 then a space and the socket name or TIP-host name.
218 '<udi_udi_config_id>' for example.
221 /* XXX - need cleanups for udiconnect for various failures!!! */
223 static char *udi_config_id
;
225 udi_open (name
, from_tty
)
232 UDIMemoryRange KnownMemory
[10];
233 UDIUInt32 ChipVersions
[10];
234 UDIInt NumberOfRanges
= 10;
235 UDIInt NumberOfChips
= 10;
237 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
239 target_preopen(from_tty
);
242 free (udi_config_id
);
245 error("Usage: target udi config_id, where config_id appears in udi_soc file");
247 udi_config_id
= strdup (strtok (name
, " \t"));
249 if (UDIConnect (udi_config_id
, &udi_session_id
))
250 error("UDIConnect() failed: %s\n", dfe_errmsg
);
252 push_target (&udi_ops
);
255 #ifndef NO_SIGINTERRUPT
256 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
258 if (siginterrupt (SIGALRM
, 1) != 0)
259 error ("udi_open: siginterrupt() %s", safe_strerror(errno
));
262 /* Set up read timeout timer. */
263 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
264 error ("udi_open: signal() %s", safe_strerror(errno
));
267 #if defined (LOG_FILE)
268 log_file
= fopen (LOG_FILE
, "w");
269 if (log_file
== NULL
)
270 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
273 ** Initialize target configuration structure (global)
275 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
276 ChipVersions
, &NumberOfChips
))
277 error ("UDIGetTargetConfig() failed");
278 if (NumberOfChips
> 2)
279 fprintf(stderr
,"Target has more than one processor\n");
280 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
282 switch(KnownMemory
[cnt
].Space
)
285 fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
289 case UDI29KIROMSpace
:
290 RMemStart
= KnownMemory
[cnt
].Offset
;
291 RMemSize
= KnownMemory
[cnt
].Size
;
293 case UDI29KIRAMSpace
:
294 IMemStart
= KnownMemory
[cnt
].Offset
;
295 IMemSize
= KnownMemory
[cnt
].Size
;
297 case UDI29KDRAMSpace
:
298 DMemStart
= KnownMemory
[cnt
].Offset
;
299 DMemSize
= KnownMemory
[cnt
].Size
;
304 /* Determine the processor revision level */
305 prl
= (unsigned int)read_register (CFG_REGNUM
) >> 24;
308 fprintf_filtered (stderr
,
309 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
310 processor_type
= TYPE_A29000
;
312 else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
314 fprintf_filtered (stderr
,
315 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
316 processor_type
= TYPE_A29030
;
318 else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
320 fprintf_filtered (stderr
,
321 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
322 processor_type
= TYPE_A29050
;
326 processor_type
= TYPE_UNKNOWN
;
327 fprintf_filtered (stderr
,"WARNING: processor type unknown.\n");
329 if (UDICreateProcess (&PId
))
330 fprintf(stderr
, "UDICreateProcess() failed\n");
332 /* Print out some stuff, letting the user now what's going on */
333 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
335 error ("UDICapabilities() failed");
338 printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
339 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
340 processor_name
[processor_type
],
341 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
342 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
343 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
348 /******************************************************************* UDI_CLOSE
349 Close the open connection to the TIP process.
350 Use this when you want to detach and do something else
353 udi_close (quitting
) /*FIXME: how is quitting used */
356 if (udi_session_id
< 0)
359 /* We should never get here if there isn't something valid in
362 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
363 error ("UDIDisconnect() failed in udi_close");
365 /* Do not try to close udi_session_id again, later in the program. */
369 #if defined (LOG_FILE)
370 if (ferror (log_file
))
371 printf ("Error writing log file.\n");
372 if (fclose (log_file
) != 0)
373 printf ("Error closing log file.\n");
376 printf_filtered (" Ending remote debugging\n");
379 /**************************************************************** UDI_ATACH */
380 /* Attach to a program that is already loaded and running
381 * Upon exiting the process's execution is stopped.
384 udi_attach (args
, from_tty
)
393 UDIBool HostEndian
= 0;
395 if (udi_session_id
< 0)
396 error ("UDI connection not opened yet, use the 'target udi' command.\n");
399 printf ("Attaching to remote program %s...\n", prog_name
);
403 From
.Offset
= UDI29KSpecialRegs
;
404 if(UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
405 error ("UDIRead failed in udi_attach");
406 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
408 /************************************************************* UDI_DETACH */
409 /* Terminate the open connection to the TIP process.
410 Use this when you want to detach and do something else
411 with your gdb. Leave remote process running (with no breakpoints set). */
413 udi_detach (args
,from_tty
)
418 remove_breakpoints(); /* Just in case there were any left in */
420 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
421 error ("UDIDisconnect() failed in udi_detach");
423 pop_target(); /* calls udi_close to do the real work */
426 printf ("Ending remote debugging\n");
430 /****************************************************************** UDI_RESUME
431 ** Tell the remote machine to resume. */
434 udi_resume (step
, sig
)
439 UDIStepType StepType
= UDIStepNatural
;
442 if (step
) /* step 1 instruction */
444 tip_error
= UDIStep (Steps
, StepType
, Range
);
448 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
449 error ("failed in udi_resume");
453 error ("UDIExecute() failed in udi_resume");
456 /******************************************************************** UDI_WAIT
457 ** Wait until the remote machine stops, then return,
458 storing status in STATUS just as `wait' would. */
468 int old_timeout
= timeout
;
469 int old_immediate_quit
= immediate_quit
;
472 WSETEXIT ((*status
), 0);
474 /* wait for message to arrive. It should be:
475 If the target stops executing, udi_wait() should return.
477 timeout
= 0; /* Wait indefinetly for a message */
478 immediate_quit
= 1; /* Helps ability to QUIT */
483 MaxTime
= UDIWaitForever
;
484 UDIWait(MaxTime
, &PId
, &StopReason
);
485 QUIT
; /* Let user quit if they want */
487 switch (StopReason
& UDIGrossState
)
490 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
491 error ("UDIGetStdin() failed in udi_wait");
492 fwrite (sbuf
, 1, CountDone
, stdout
);
496 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
497 fwrite (sbuf
, 1, CountDone
, stderr
);
501 printf("DEBUG: stdin requested ... continue\n");
502 /* UDIPutStdin(sbuf, (UDISizeT)i, &CountDone); */
512 switch (StopReason
& UDIGrossState
)
515 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
517 switch (StopReason
>> 8)
519 case 0: /* Illegal opcode */
520 printf(" (break point)\n");
521 WSETSTOP ((*status
), SIGTRAP
);
523 case 1: /* Unaligned Access */
524 WSETSTOP ((*status
), SIGBUS
);
528 WSETSTOP ((*status
), SIGFPE
);
530 case 5: /* Protection Violation */
531 WSETSTOP ((*status
), SIGILL
);
535 case 8: /* User Instruction Mapping Miss */
536 case 9: /* User Data Mapping Miss */
537 case 10: /* Supervisor Instruction Mapping Miss */
538 case 11: /* Supervisor Data Mapping Miss */
539 WSETSTOP ((*status
), SIGSEGV
);
543 WSETSTOP ((*status
), SIGILL
);
546 WSETSTOP ((*status
), SIGALRM
);
549 WSETSTOP ((*status
), SIGTRAP
);
554 case 19: /* INTR3/Internal */
557 WSETSTOP ((*status
), SIGINT
);
559 case 22: /* Floating-Point Exception */
560 WSETSTOP ((*status
), SIGILL
);
562 case 77: /* assert 77 */
563 WSETSTOP ((*status
), SIGTRAP
);
566 WSETEXIT ((*status
), 0);
569 case UDINotExecuting
:
570 WSETSTOP ((*status
), SIGTERM
);
573 WSETSTOP ((*status
), SIGILL
);
576 WSETSTOP ((*status
), SIGTSTP
);
579 WSETSTOP ((*status
), SIGLOST
);
583 WSETSTOP ((*status
), SIGTRAP
);
586 WSETSTOP ((*status
), SIGSTOP
);
589 WSETSTOP ((*status
), SIGKILL
);
593 WSETEXIT ((*status
), 0);
596 timeout
= old_timeout
; /* Restore original timeout value */
597 immediate_quit
= old_immediate_quit
;
601 /********************************************************** UDI_FETCH_REGISTERS
602 * Read a remote register 'regno'.
603 * If regno==-1 then read all the registers.
606 udi_fetch_registers (regno
)
614 UDIBool HostEndian
= 0;
618 fetch_register(regno
);
624 From
.Space
= UDI29KGlobalRegs
;
626 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
628 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
629 error("UDIRead() failed in udi_fetch_registers");
631 register_valid
[GR1_REGNUM
] = 1;
633 #if defined(GR64_REGNUM) /* Read gr64-127 */
635 /* Global Registers gr64-gr95 */
637 From
.Space
= UDI29KGlobalRegs
;
639 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
641 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
642 error("UDIRead() failed in udi_fetch_registers");
644 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
645 register_valid
[i
] = 1;
647 #endif /* GR64_REGNUM */
649 /* Global Registers gr96-gr127 */
651 From
.Space
= UDI29KGlobalRegs
;
653 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
655 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
656 error("UDIRead() failed in udi_fetch_registers");
658 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
659 register_valid
[i
] = 1;
661 /* Local Registers */
663 From
.Space
= UDI29KLocalRegs
;
665 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
667 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
668 error("UDIRead() failed in udi_fetch_registers");
670 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
671 register_valid
[i
] = 1;
673 /* Protected Special Registers */
675 From
.Space
= UDI29KSpecialRegs
;
677 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
679 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
680 error("UDIRead() failed in udi_fetch_registers");
682 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
683 register_valid
[i
] = 1;
685 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
686 fetch_register(NPC_REGNUM
);
687 fetch_register(PC_REGNUM
);
688 fetch_register(PC2_REGNUM
);
690 /* Unprotected Special Registers sr128-sr135 */
692 From
.Space
= UDI29KSpecialRegs
;
694 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
696 if (UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
697 error("UDIRead() failed in udi_fetch_registers");
699 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
700 register_valid
[i
] = 1;
705 printf("Fetching all registers\n");
706 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
707 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
708 read_register(PC2_REGNUM
));
711 /* There doesn't seem to be any way to get these. */
714 supply_register (FPE_REGNUM
, (char *) &val
);
715 supply_register (INTE_REGNUM
, (char *) &val
);
716 supply_register (FPS_REGNUM
, (char *) &val
);
717 supply_register (EXO_REGNUM
, (char *) &val
);
722 /********************************************************* UDI_STORE_REGISTERS
723 ** Store register regno into the target.
724 * If regno==-1 then store all the registers.
728 udi_store_registers (regno
)
736 UDIBool HostEndian
= 0;
740 store_register(regno
);
746 printf("Storing all registers\n");
747 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
748 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
753 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
754 To
.Space
= UDI29KGlobalRegs
;
757 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
758 error("UDIWrite() failed in udi_store_regisetrs");
760 #if defined(GR64_REGNUM)
762 /* Global registers gr64-gr95 */
764 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
765 To
.Space
= UDI29KGlobalRegs
;
768 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
769 error("UDIWrite() failed in udi_store_regisetrs");
771 #endif /* GR64_REGNUM */
773 /* Global registers gr96-gr127 */
775 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
776 To
.Space
= UDI29KGlobalRegs
;
779 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
780 error("UDIWrite() failed in udi_store_regisetrs");
782 /* Local Registers */
784 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
785 To
.Space
= UDI29KLocalRegs
;
788 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
789 error("UDIWrite() failed in udi_store_regisetrs");
792 /* Protected Special Registers */ /* VAB through TMR */
794 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
795 To
.Space
= UDI29KSpecialRegs
;
798 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
799 error("UDIWrite() failed in udi_store_regisetrs");
801 /* PC0, PC1, PC2 possibly as shadow registers */
803 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
804 To
.Space
= UDI29KSpecialRegs
;
807 To
.Offset
= 20; /* SPC0 */
809 To
.Offset
= 10; /* PC0 */
810 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
811 error("UDIWrite() failed in udi_store_regisetrs");
815 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
816 To
.Space
= UDI29KSpecialRegs
;
819 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
820 error("UDIWrite() failed in udi_store_regisetrs");
822 /* Unprotected Special Registers */
824 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
825 To
.Space
= UDI29KSpecialRegs
;
828 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
829 error("UDIWrite() failed in udi_store_regisetrs");
831 registers_changed ();
834 /****************************************************** UDI_PREPARE_TO_STORE */
835 /* Get ready to modify the registers array. On machines which store
836 individual registers, this doesn't need to do anything. On machines
837 which store all the registers in one fell swoop, this makes sure
838 that registers contains all the registers from the program being
842 udi_prepare_to_store ()
844 /* Do nothing, since we can store individual regs */
847 /********************************************************** TRANSLATE_ADDR */
852 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
853 /* Check for a virtual address in the kernel */
854 /* Assume physical address of ublock is in paddr_u register */
855 /* FIXME: doesn't work for user virtual addresses */
856 if (addr
>= UVADDR
) {
857 /* PADDR_U register holds the physical address of the ublock */
858 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
859 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
867 /************************************************* UDI_XFER_INFERIOR_MEMORY */
868 /* FIXME! Merge these two. */
870 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
877 memaddr
= translate_addr(memaddr
);
880 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
882 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
885 /********************************************************** UDI_FILES_INFO */
889 printf ("\tAttached to UDI socket to %s and running program %s.\n",
890 udi_config_id
, prog_name
);
893 /**************************************************** UDI_INSERT_BREAKPOINT */
895 udi_insert_breakpoint (addr
, contents_cache
)
897 char *contents_cache
;
902 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
903 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
906 if(cnt
>= BKPT_TABLE_SIZE
)
907 error("Too many breakpoints set");
909 bkpt_table
[cnt
].Addr
.Offset
= addr
;
910 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
911 bkpt_table
[cnt
].PassCount
= 1;
912 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
914 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
915 bkpt_table
[cnt
].PassCount
,
916 bkpt_table
[cnt
].Type
,
917 &bkpt_table
[cnt
].BreakId
);
919 if (err
== 0) return 0; /* Success */
921 bkpt_table
[cnt
].Type
= 0;
922 error("UDISetBreakpoint returned error code %d\n", err
);
925 /**************************************************** UDI_REMOVE_BREAKPOINT */
927 udi_remove_breakpoint (addr
, contents_cache
)
929 char *contents_cache
;
934 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
935 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
938 if(cnt
>= BKPT_TABLE_SIZE
)
939 error("Can't find breakpoint in table");
941 bkpt_table
[cnt
].Type
= 0;
943 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
944 if (err
== 0) return 0; /* Success */
946 error("UDIClearBreakpoint returned error code %d\n", err
);
950 udi_kill(arg
,from_tty
)
957 UDIStop does not really work as advertised. It causes the TIP to close it's
958 connection, which usually results in GDB dying with a SIGPIPE. For now, we
959 just invoke udi_close, which seems to get things right.
967 printf("Target has been stopped.");
975 Load a program into the target. Args are: `program {options}'. The options
976 are used to control loading of the program, and are NOT passed onto the
977 loaded code as arguments. (You need to use the `run' command to do that.)
980 -ms %d Set mem stack size to %d
981 -rs %d Set regular stack size to %d
982 -i send init info (default)
983 -noi don't send init info
984 -[tT] Load Text section
985 -[dD] Load Data section
986 -[bB] Load BSS section
987 -[lL] Load Lit section
991 download(load_arg_string
, from_tty
)
992 char *load_arg_string
;
995 #define DEFAULT_MEM_STACK_SIZE 0x6000
996 #define DEFAULT_REG_STACK_SIZE 0x2000
1003 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1005 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1006 address_ranges
[0].Offset
= 0xffffffff;
1007 address_ranges
[0].Size
= 0;
1009 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1010 address_ranges
[1].Offset
= 0xffffffff;
1011 address_ranges
[1].Size
= 0;
1013 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1014 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1018 filename
= strtok(load_arg_string
, " \t");
1020 error ("Must specify at least a file name with the load command");
1022 filename
= tilde_expand (filename
);
1023 make_cleanup (free
, filename
);
1025 while (token
= strtok (NULL
, " \t"))
1027 if (token
[0] == '-')
1031 if (strcmp (token
, "ms") == 0)
1032 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1033 else if (strcmp (token
, "rs") == 0)
1034 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1037 load_text
= load_data
= load_bss
= load_lit
= 0;
1060 error ("Unknown UDI load option -%s", token
-1);
1067 pbfd
= bfd_openr (filename
, 0);
1070 perror_with_name (filename
);
1072 make_cleanup (bfd_close
, pbfd
);
1077 if (!bfd_check_format (pbfd
, bfd_object
))
1078 error ("It doesn't seem to be an object file");
1080 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1082 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1086 unsigned long section_size
, section_end
;
1087 const char *section_name
;
1089 section_name
= bfd_get_section_name (pbfd
, section
);
1090 if (strcmp (section_name
, ".text") == 0 && !load_text
)
1092 else if (strcmp (section_name
, ".data") == 0 && !load_data
)
1094 else if (strcmp (section_name
, ".bss") == 0 && !load_bss
)
1096 else if (strcmp (section_name
, ".lit") == 0 && !load_lit
)
1099 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1100 section_size
= bfd_section_size (pbfd
, section
);
1101 section_end
= To
.Offset
+ section_size
;
1103 printf("[Loading section %s at %x (%d bytes)]\n",
1108 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1110 To
.Space
= UDI29KIRAMSpace
;
1112 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1114 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1116 - address_ranges
[0].Offset
);
1120 To
.Space
= UDI29KDRAMSpace
;
1122 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1124 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1126 - address_ranges
[1].Offset
);
1129 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1135 while (section_size
> 0)
1139 Count
= min (section_size
, 1024);
1141 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1144 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1147 (UDISizeT
)1, /* Size */
1148 &Count
, /* CountDone */
1149 (UDIBool
)0); /* HostEndian */
1151 error ("UDIWrite failed, error = %d", err
);
1155 section_size
-= Count
;
1163 /* Write a zero byte at the vma */
1164 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1166 (UDICount
)1, /* Count */
1167 (UDISizeT
)1, /* Size */
1168 &Count
, /* CountDone */
1169 (UDIBool
)0); /* HostEndian */
1171 error ("UDIWrite failed, error = %d", err
);
1176 /* Now, duplicate it for the length of the BSS */
1177 err
= UDICopy (From
, /* From */
1179 (UDICount
)section_size
- 1, /* Count */
1180 (UDISizeT
)1, /* Size */
1181 &Count
, /* CountDone */
1182 (UDIBool
)1); /* Direction */
1184 error ("UDICopy failed, error = %d", err
);
1190 entry
.Space
= UDI29KIRAMSpace
;
1191 entry
.Offset
= bfd_get_start_address (pbfd
);
1196 /* User interface to download an image into the remote target. See download()
1197 * for details on args.
1201 udi_load(args
, from_tty
)
1205 download (args
, from_tty
);
1207 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1210 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1211 ** Copy LEN bytes of data from debugger memory at MYADDR
1212 to inferior's memory at MEMADDR. Returns number of bytes written. */
1214 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1224 UDICount CountDone
= 0;
1225 UDIBool HostEndian
= 0;
1227 To
.Space
= udi_memory_space(memaddr
);
1228 From
= (UDIUInt32
*)myaddr
;
1230 while (nwritten
< len
)
1231 { Count
= len
- nwritten
;
1232 if (Count
> MAXDATA
) Count
= MAXDATA
;
1233 To
.Offset
= memaddr
+ nwritten
;
1234 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1235 { error("UDIWrite() failed in udi_write_inferrior_memory");
1239 { nwritten
+= CountDone
;
1246 /**************************************************** UDI_READ_INFERIOR_MEMORY
1247 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1248 at debugger address MYADDR. Returns number of bytes read. */
1250 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1260 UDICount CountDone
= 0;
1261 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(UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1271 { error("UDIWrite() 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;
1307 if (regno
== GR1_REGNUM
)
1309 From
.Space
= UDI29KGlobalRegs
;
1312 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1314 From
.Space
= UDI29KGlobalRegs
;
1315 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1318 #if defined(GR64_REGNUM)
1320 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1322 From
.Space
= UDI29KGlobalRegs
;
1323 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1326 #endif /* GR64_REGNUM */
1328 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1330 From
.Space
= UDI29KLocalRegs
;
1331 From
.Offset
= (regno
- LR0_REGNUM
);
1333 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1336 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1337 return; /* Pretend Success */
1341 From
.Space
= UDI29KSpecialRegs
;
1342 From
.Offset
= regnum_to_srnum(regno
);
1345 if (UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1346 error("UDIRead() failed in udi_fetch_registers");
1348 supply_register(regno
, (char *) &To
);
1351 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1353 /*****************************************************************************/
1354 /* Store a single register indicated by 'regno'.
1355 * Returns 0/-1 on success/failure.
1358 store_register (regno
)
1367 UDIBool HostEndian
= 0;
1369 From
= read_register (regno
); /* get data value */
1372 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1374 if (regno
== GR1_REGNUM
)
1375 { To
.Space
= UDI29KGlobalRegs
;
1377 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1378 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1379 * register cache. Do this *after* calling read_register, because we want
1380 * read_register to return the value that write_register has just stuffed
1381 * into the registers array, not the value of the register fetched from
1384 registers_changed ();
1386 #if defined(GR64_REGNUM)
1387 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1388 { To
.Space
= UDI29KGlobalRegs
;
1389 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1390 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1392 #endif /* GR64_REGNUM */
1393 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1394 { To
.Space
= UDI29KGlobalRegs
;
1395 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1396 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1398 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1399 { To
.Space
= UDI29KLocalRegs
;
1400 To
.Offset
= (regno
- LR0_REGNUM
);
1401 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1403 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1405 return 0; /* Pretend Success */
1407 else /* An unprotected or protected special register */
1408 { To
.Space
= UDI29KSpecialRegs
;
1409 To
.Offset
= regnum_to_srnum(regno
);
1410 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1415 error("UDIWrite() failed in store_registers");
1419 /********************************************************** REGNUM_TO_SRNUM */
1421 * Convert a gdb special register number to a 29000 special register number.
1424 regnum_to_srnum(regno
)
1428 case VAB_REGNUM
: return(0);
1429 case OPS_REGNUM
: return(1);
1430 case CPS_REGNUM
: return(2);
1431 case CFG_REGNUM
: return(3);
1432 case CHA_REGNUM
: return(4);
1433 case CHD_REGNUM
: return(5);
1434 case CHC_REGNUM
: return(6);
1435 case RBP_REGNUM
: return(7);
1436 case TMC_REGNUM
: return(8);
1437 case TMR_REGNUM
: return(9);
1438 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1439 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1440 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1441 case MMU_REGNUM
: return(13);
1442 case LRU_REGNUM
: return(14);
1443 case IPC_REGNUM
: return(128);
1444 case IPA_REGNUM
: return(129);
1445 case IPB_REGNUM
: return(130);
1446 case Q_REGNUM
: return(131);
1447 case ALU_REGNUM
: return(132);
1448 case BP_REGNUM
: return(133);
1449 case FC_REGNUM
: return(134);
1450 case CR_REGNUM
: return(135);
1451 case FPE_REGNUM
: return(160);
1452 case INTE_REGNUM
: return(161);
1453 case FPS_REGNUM
: return(162);
1454 case EXO_REGNUM
:return(164);
1456 return(255); /* Failure ? */
1459 /****************************************************************************/
1461 * Determine the Target memory space qualifier based on the addr.
1462 * FIXME: Can't distinguis I_ROM/D_ROM.
1463 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1466 udi_memory_space(addr
)
1469 UDIUInt32 tstart
= IMemStart
;
1470 UDIUInt32 tend
= tstart
+ IMemSize
;
1471 UDIUInt32 dstart
= DMemStart
;
1472 UDIUInt32 dend
= tstart
+ DMemSize
;
1473 UDIUInt32 rstart
= RMemStart
;
1474 UDIUInt32 rend
= tstart
+ RMemSize
;
1476 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1477 return UDI29KIRAMSpace
;
1478 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1479 return UDI29KDRAMSpace
;
1480 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1481 /* FIXME: how do we determine between D_ROM and I_ROM */
1482 return UDI29KIROMSpace
;
1483 } else /* FIXME: what do me do now? */
1484 return UDI29KDRAMSpace
; /* Hmmm! */
1486 /*********************************************************************** STUBS
1489 void convert16() {;}
1490 void convert32() {;}
1491 FILE* EchoFile
= 0; /* used for debugging */
1492 int QuietMode
= 0; /* used for debugging */
1494 /****************************************************************************/
1496 * Define the target subroutine names
1498 static struct target_ops udi_ops
= {
1500 "Remote UDI connected TIP",
1501 "Remote debug an AMD 29k using UDI socket connection to TIP process",
1508 udi_fetch_registers
,
1509 udi_store_registers
,
1510 udi_prepare_to_store
,
1511 udi_xfer_inferior_memory
,
1513 udi_insert_breakpoint
,
1514 udi_remove_breakpoint
,
1515 0, /* termial_init */
1516 0, /* terminal_inferior */
1517 0, /* terminal_ours_for_output */
1518 0, /* terminal_ours */
1519 0, /* terminal_info */
1520 udi_kill
, /* FIXME, kill */
1522 0, /* lookup_symbol */
1523 udi_create_inferior
,
1524 udi_mourn
, /* mourn_inferior FIXME */
1526 0, /* notice_signals */
1529 1, /* has_all_memory */
1532 1, /* has_registers */
1533 1, /* has_execution */
1535 0, /* sections_end */
1536 OPS_MAGIC
, /* Always the last thing */
1539 void _initialize_remote_udi()
1541 add_target (&udi_ops
);
1543 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1545 "Set debugging of UDI I/O.\n\
1546 When enabled, debugging info is displayed.",
1551 #ifdef NO_HIF_SUPPORT
1555 return(0); /* Emulate a failure */