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 /* Called when SIGALRM signal sent due to alarm() timeout. */
131 volatile int n_alarms
;
138 printf ("udi_timer called\n");
142 #endif /* HAVE_TERMIO */
144 /* malloc'd name of the program on the remote system. */
145 static char *prog_name
= NULL
;
147 /* Number of SIGTRAPs we need to simulate. That is, the next
148 NEED_ARTIFICIAL_TRAP calls to udi_wait should just return
149 SIGTRAP without actually waiting for anything. */
151 /* This is called not only when we first attach, but also when the
152 user types "run" after having attached. */
155 udi_create_inferior (execfile
, args
, env
)
164 if (prog_name
!= NULL
)
166 prog_name
= savestring (execfile
, strlen (execfile
));
168 else if (entry
.Offset
)
171 error ("No image loaded into target.");
173 if (udi_session_id
< 0)
175 printf("UDI connection not open yet.\n");
179 inferior_pid
= 40000;
182 download(execfile
, 0);
184 args1
= alloca (strlen(execfile
) + strlen(args
) + 2);
186 strcpy (args1
, execfile
);
188 strcat (args1
, args
);
190 UDIInitializeProcess (address_ranges
, /* ProcessMemory[] */
191 (UDIInt
)2, /* NumberOfRanges */
192 entry
, /* EntryPoint */
193 stack_sizes
, /* *StackSizes */
194 (UDIInt
)2, /* NumberOfStacks */
195 args1
); /* ArgString */
197 init_wait_for_inferior ();
198 clear_proceed_status ();
205 pop_target (); /* Pop back to no-child state */
206 generic_mourn_inferior ();
209 /******************************************************************** UDI_OPEN
210 ** Open a connection to remote TIP.
211 NAME is the socket domain used for communication with the TIP,
212 then a space and the socket name or TIP-host name.
213 '<udi_udi_config_id>' for example.
216 /* XXX - need cleanups for udiconnect for various failures!!! */
218 static char *udi_config_id
;
220 udi_open (name
, from_tty
)
227 UDIMemoryRange KnownMemory
[10];
228 UDIUInt32 ChipVersions
[10];
229 UDIInt NumberOfRanges
= 10;
230 UDIInt NumberOfChips
= 10;
232 UDIUInt32 TIPId
, TargetId
, DFEId
, DFE
, TIP
, DFEIPCId
, TIPIPCId
;
234 target_preopen(from_tty
);
238 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
239 bkpt_table
[cnt
].Type
= 0;
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;
396 if (udi_session_id
< 0)
397 error ("UDI connection not opened yet, use the 'target udi' command.\n");
400 printf ("Attaching to remote program %s...\n", prog_name
);
403 From
.Space
= UDI29KSpecialRegs
;
405 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
406 error ("UDIRead failed in udi_attach");
407 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
409 /************************************************************* UDI_DETACH */
410 /* Terminate the open connection to the TIP process.
411 Use this when you want to detach and do something else
412 with your gdb. Leave remote process running (with no breakpoints set). */
414 udi_detach (args
,from_tty
)
419 remove_breakpoints(); /* Just in case there were any left in */
421 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
422 error ("UDIDisconnect() failed in udi_detach");
424 pop_target(); /* calls udi_close to do the real work */
427 printf ("Ending remote debugging\n");
431 /****************************************************************** UDI_RESUME
432 ** Tell the remote machine to resume. */
435 udi_resume (step
, sig
)
440 UDIStepType StepType
= UDIStepNatural
;
443 if (step
) /* step 1 instruction */
445 tip_error
= UDIStep (Steps
, StepType
, Range
);
449 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
450 error ("failed in udi_resume");
454 error ("UDIExecute() failed in udi_resume");
457 /******************************************************************** UDI_WAIT
458 ** Wait until the remote machine stops, then return,
459 storing status in STATUS just as `wait' would. */
469 int old_timeout
= timeout
;
470 int old_immediate_quit
= immediate_quit
;
473 WSETEXIT ((*status
), 0);
475 /* wait for message to arrive. It should be:
476 If the target stops executing, udi_wait() should return.
478 timeout
= 0; /* Wait indefinetly for a message */
479 immediate_quit
= 1; /* Helps ability to QUIT */
484 MaxTime
= UDIWaitForever
;
485 UDIWait(MaxTime
, &PId
, &StopReason
);
486 QUIT
; /* Let user quit if they want */
488 switch (StopReason
& UDIGrossState
)
491 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
492 error ("UDIGetStdout() failed in udi_wait");
493 fwrite (sbuf
, 1, CountDone
, stdout
);
497 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
498 fwrite (sbuf
, 1, CountDone
, stderr
);
504 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
507 /* In spite of the fact that we told UDIWait to wait forever, it will
508 return spuriously sometimes. */
517 switch (StopReason
& UDIGrossState
)
520 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
522 switch (StopReason
>> 8)
524 case 0: /* Illegal opcode */
525 printf(" (break point)\n");
526 WSETSTOP ((*status
), SIGTRAP
);
528 case 1: /* Unaligned Access */
529 WSETSTOP ((*status
), SIGBUS
);
533 WSETSTOP ((*status
), SIGFPE
);
535 case 5: /* Protection Violation */
536 WSETSTOP ((*status
), SIGILL
);
540 case 8: /* User Instruction Mapping Miss */
541 case 9: /* User Data Mapping Miss */
542 case 10: /* Supervisor Instruction Mapping Miss */
543 case 11: /* Supervisor Data Mapping Miss */
544 WSETSTOP ((*status
), SIGSEGV
);
548 WSETSTOP ((*status
), SIGILL
);
551 WSETSTOP ((*status
), SIGALRM
);
554 WSETSTOP ((*status
), SIGTRAP
);
559 case 19: /* INTR3/Internal */
562 WSETSTOP ((*status
), SIGINT
);
564 case 22: /* Floating-Point Exception */
565 WSETSTOP ((*status
), SIGILL
);
567 case 77: /* assert 77 */
568 WSETSTOP ((*status
), SIGTRAP
);
571 WSETEXIT ((*status
), 0);
574 case UDINotExecuting
:
575 WSETSTOP ((*status
), SIGTERM
);
578 WSETSTOP ((*status
), SIGTSTP
);
581 WSETSTOP ((*status
), SIGURG
);
585 WSETSTOP ((*status
), SIGTRAP
);
588 WSETSTOP ((*status
), SIGSTOP
);
591 WSETSTOP ((*status
), SIGKILL
);
595 WSETEXIT ((*status
), 0);
598 timeout
= old_timeout
; /* Restore original timeout value */
599 immediate_quit
= old_immediate_quit
;
603 /********************************************************** UDI_FETCH_REGISTERS
604 * Read a remote register 'regno'.
605 * If regno==-1 then read all the registers.
608 udi_fetch_registers (regno
)
616 UDIBool HostEndian
= 0;
621 fetch_register(regno
);
627 From
.Space
= UDI29KGlobalRegs
;
629 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
631 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
632 error("UDIRead() failed in udi_fetch_registers");
634 register_valid
[GR1_REGNUM
] = 1;
636 #if defined(GR64_REGNUM) /* Read gr64-127 */
638 /* Global Registers gr64-gr95 */
640 From
.Space
= UDI29KGlobalRegs
;
642 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
644 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
645 error("UDIRead() failed in udi_fetch_registers");
647 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
648 register_valid
[i
] = 1;
650 #endif /* GR64_REGNUM */
652 /* Global Registers gr96-gr127 */
654 From
.Space
= UDI29KGlobalRegs
;
656 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
658 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
659 error("UDIRead() failed in udi_fetch_registers");
661 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
662 register_valid
[i
] = 1;
664 /* Local Registers */
666 From
.Space
= UDI29KLocalRegs
;
668 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
670 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
671 error("UDIRead() failed in udi_fetch_registers");
673 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
674 register_valid
[i
] = 1;
676 /* Protected Special Registers */
678 From
.Space
= UDI29KSpecialRegs
;
680 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
682 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
683 error("UDIRead() failed in udi_fetch_registers");
685 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
686 register_valid
[i
] = 1;
688 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
689 fetch_register(NPC_REGNUM
);
690 fetch_register(PC_REGNUM
);
691 fetch_register(PC2_REGNUM
);
693 /* Unprotected Special Registers sr128-sr135 */
695 From
.Space
= UDI29KSpecialRegs
;
697 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
699 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
700 error("UDIRead() failed in udi_fetch_registers");
702 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
703 register_valid
[i
] = 1;
708 printf("Fetching all registers\n");
709 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
710 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
711 read_register(PC2_REGNUM
));
714 /* There doesn't seem to be any way to get these. */
717 supply_register (FPE_REGNUM
, (char *) &val
);
718 supply_register (INTE_REGNUM
, (char *) &val
);
719 supply_register (FPS_REGNUM
, (char *) &val
);
720 supply_register (EXO_REGNUM
, (char *) &val
);
725 /********************************************************* UDI_STORE_REGISTERS
726 ** Store register regno into the target.
727 * If regno==-1 then store all the registers.
731 udi_store_registers (regno
)
739 UDIBool HostEndian
= 0;
743 store_register(regno
);
749 printf("Storing all registers\n");
750 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
751 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
756 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
757 To
.Space
= UDI29KGlobalRegs
;
760 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
761 error("UDIWrite() failed in udi_store_regisetrs");
763 #if defined(GR64_REGNUM)
765 /* Global registers gr64-gr95 */
767 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
768 To
.Space
= UDI29KGlobalRegs
;
771 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
772 error("UDIWrite() failed in udi_store_regisetrs");
774 #endif /* GR64_REGNUM */
776 /* Global registers gr96-gr127 */
778 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
779 To
.Space
= UDI29KGlobalRegs
;
782 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
783 error("UDIWrite() failed in udi_store_regisetrs");
785 /* Local Registers */
787 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
788 To
.Space
= UDI29KLocalRegs
;
791 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
792 error("UDIWrite() failed in udi_store_regisetrs");
795 /* Protected Special Registers */ /* VAB through TMR */
797 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
798 To
.Space
= UDI29KSpecialRegs
;
801 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
802 error("UDIWrite() failed in udi_store_regisetrs");
804 /* PC0, PC1, PC2 possibly as shadow registers */
806 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
807 To
.Space
= UDI29KSpecialRegs
;
810 To
.Offset
= 20; /* SPC0 */
812 To
.Offset
= 10; /* PC0 */
813 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
814 error("UDIWrite() failed in udi_store_regisetrs");
818 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
819 To
.Space
= UDI29KSpecialRegs
;
822 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
823 error("UDIWrite() failed in udi_store_regisetrs");
825 /* Unprotected Special Registers */
827 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
828 To
.Space
= UDI29KSpecialRegs
;
831 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
832 error("UDIWrite() failed in udi_store_regisetrs");
834 registers_changed ();
837 /****************************************************** UDI_PREPARE_TO_STORE */
838 /* Get ready to modify the registers array. On machines which store
839 individual registers, this doesn't need to do anything. On machines
840 which store all the registers in one fell swoop, this makes sure
841 that registers contains all the registers from the program being
845 udi_prepare_to_store ()
847 /* Do nothing, since we can store individual regs */
850 /********************************************************** TRANSLATE_ADDR */
855 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
856 /* Check for a virtual address in the kernel */
857 /* Assume physical address of ublock is in paddr_u register */
858 /* FIXME: doesn't work for user virtual addresses */
859 if (addr
>= UVADDR
) {
860 /* PADDR_U register holds the physical address of the ublock */
861 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
862 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
870 /************************************************* UDI_XFER_INFERIOR_MEMORY */
871 /* FIXME! Merge these two. */
873 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
880 memaddr
= translate_addr(memaddr
);
883 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
885 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
888 /********************************************************** UDI_FILES_INFO */
892 printf ("\tAttached to UDI socket to %s and running program %s.\n",
893 udi_config_id
, prog_name
);
896 /**************************************************** UDI_INSERT_BREAKPOINT */
898 udi_insert_breakpoint (addr
, contents_cache
)
900 char *contents_cache
;
905 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
906 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
909 if(cnt
>= BKPT_TABLE_SIZE
)
910 error("Too many breakpoints set");
912 bkpt_table
[cnt
].Addr
.Offset
= addr
;
913 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
914 bkpt_table
[cnt
].PassCount
= 1;
915 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
917 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
918 bkpt_table
[cnt
].PassCount
,
919 bkpt_table
[cnt
].Type
,
920 &bkpt_table
[cnt
].BreakId
);
922 if (err
== 0) return 0; /* Success */
924 bkpt_table
[cnt
].Type
= 0;
925 error("UDISetBreakpoint returned error code %d\n", err
);
928 /**************************************************** UDI_REMOVE_BREAKPOINT */
930 udi_remove_breakpoint (addr
, contents_cache
)
932 char *contents_cache
;
937 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
938 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
941 if(cnt
>= BKPT_TABLE_SIZE
)
942 error("Can't find breakpoint in table");
944 bkpt_table
[cnt
].Type
= 0;
946 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
947 if (err
== 0) return 0; /* Success */
949 error("UDIClearBreakpoint returned error code %d\n", err
);
953 udi_kill(arg
,from_tty
)
960 UDIStop does not really work as advertised. It causes the TIP to close it's
961 connection, which usually results in GDB dying with a SIGPIPE. For now, we
962 just invoke udi_close, which seems to get things right.
970 printf("Target has been stopped.");
978 Load a program into the target. Args are: `program {options}'. The options
979 are used to control loading of the program, and are NOT passed onto the
980 loaded code as arguments. (You need to use the `run' command to do that.)
983 -ms %d Set mem stack size to %d
984 -rs %d Set regular stack size to %d
985 -i send init info (default)
986 -noi don't send init info
987 -[tT] Load Text section
988 -[dD] Load Data section
989 -[bB] Load BSS section
990 -[lL] Load Lit section
994 download(load_arg_string
, from_tty
)
995 char *load_arg_string
;
998 #define DEFAULT_MEM_STACK_SIZE 0x6000
999 #define DEFAULT_REG_STACK_SIZE 0x2000
1006 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1008 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1009 address_ranges
[0].Offset
= 0xffffffff;
1010 address_ranges
[0].Size
= 0;
1012 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1013 address_ranges
[1].Offset
= 0xffffffff;
1014 address_ranges
[1].Size
= 0;
1016 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1017 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1021 filename
= strtok(load_arg_string
, " \t");
1023 error ("Must specify at least a file name with the load command");
1025 filename
= tilde_expand (filename
);
1026 make_cleanup (free
, filename
);
1028 while (token
= strtok (NULL
, " \t"))
1030 if (token
[0] == '-')
1034 if (STREQ (token
, "ms"))
1035 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1036 else if (STREQ (token
, "rs"))
1037 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1040 load_text
= load_data
= load_bss
= load_lit
= 0;
1063 error ("Unknown UDI load option -%s", token
-1);
1070 pbfd
= bfd_openr (filename
, 0);
1073 perror_with_name (filename
);
1075 make_cleanup (bfd_close
, pbfd
);
1080 if (!bfd_check_format (pbfd
, bfd_object
))
1081 error ("It doesn't seem to be an object file");
1083 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1085 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1089 unsigned long section_size
, section_end
;
1090 const char *section_name
;
1092 section_name
= bfd_get_section_name (pbfd
, section
);
1093 if (STREQ (section_name
, ".text") && !load_text
)
1095 else if (STREQ (section_name
, ".data") && !load_data
)
1097 else if (STREQ (section_name
, ".bss") && !load_bss
)
1099 else if (STREQ (section_name
, ".lit") && !load_lit
)
1102 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1103 section_size
= bfd_section_size (pbfd
, section
);
1104 section_end
= To
.Offset
+ section_size
;
1106 printf("[Loading section %s at %x (%d bytes)]\n",
1111 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1113 To
.Space
= UDI29KIRAMSpace
;
1115 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1117 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1119 - address_ranges
[0].Offset
);
1123 To
.Space
= UDI29KDRAMSpace
;
1125 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1127 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1129 - address_ranges
[1].Offset
);
1132 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1138 while (section_size
> 0)
1142 Count
= min (section_size
, 1024);
1144 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1147 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1150 (UDISizeT
)1, /* Size */
1151 &Count
, /* CountDone */
1152 (UDIBool
)0); /* HostEndian */
1154 error ("UDIWrite failed, error = %d", err
);
1158 section_size
-= Count
;
1164 unsigned long zero
= 0;
1166 /* Write a zero byte at the vma */
1167 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1169 (UDICount
)1, /* Count */
1170 (UDISizeT
)4, /* Size */
1171 &Count
, /* CountDone */
1172 (UDIBool
)0); /* HostEndian */
1174 error ("UDIWrite failed, error = %d", err
);
1179 /* Now, duplicate it for the length of the BSS */
1180 err
= UDICopy (From
, /* From */
1182 (UDICount
)(section_size
/4 - 1), /* Count */
1183 (UDISizeT
)4, /* Size */
1184 &Count
, /* CountDone */
1185 (UDIBool
)1); /* Direction */
1191 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1193 fprintf (stderr
, "Error is %s\n", message
);
1195 fprintf (stderr
, "xerr is %d\n", xerr
);
1196 error ("UDICopy failed, error = %d", err
);
1203 entry
.Space
= UDI29KIRAMSpace
;
1204 entry
.Offset
= bfd_get_start_address (pbfd
);
1209 /* User interface to download an image into the remote target. See download()
1210 * for details on args.
1214 udi_load(args
, from_tty
)
1218 download (args
, from_tty
);
1220 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1223 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1224 ** Copy LEN bytes of data from debugger memory at MYADDR
1225 to inferior's memory at MEMADDR. Returns number of bytes written. */
1227 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1237 UDICount CountDone
= 0;
1238 UDIBool HostEndian
= 0;
1240 To
.Space
= udi_memory_space(memaddr
);
1241 From
= (UDIUInt32
*)myaddr
;
1243 while (nwritten
< len
)
1244 { Count
= len
- nwritten
;
1245 if (Count
> MAXDATA
) Count
= MAXDATA
;
1246 To
.Offset
= memaddr
+ nwritten
;
1247 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1248 { error("UDIWrite() failed in udi_write_inferrior_memory");
1252 { nwritten
+= CountDone
;
1259 /**************************************************** UDI_READ_INFERIOR_MEMORY
1260 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1261 at debugger address MYADDR. Returns number of bytes read. */
1263 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1273 UDICount CountDone
= 0;
1274 UDIBool HostEndian
= 0;
1277 From
.Space
= udi_memory_space(memaddr
);
1278 To
= (UDIUInt32
*)myaddr
;
1281 { Count
= len
- nread
;
1282 if (Count
> MAXDATA
) Count
= MAXDATA
;
1283 From
.Offset
= memaddr
+ nread
;
1284 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1285 { error("UDIRead() failed in udi_read_inferrior_memory");
1289 { nread
+= CountDone
;
1296 /********************************************************************* WARNING
1301 error ("ERROR while loading program into remote TIP: $d\n", num
);
1305 /*****************************************************************************/
1306 /* Fetch a single register indicatated by 'regno'.
1307 * Returns 0/-1 on success/failure.
1310 fetch_register (regno
)
1318 UDIBool HostEndian
= 0;
1322 if (regno
== GR1_REGNUM
)
1324 From
.Space
= UDI29KGlobalRegs
;
1327 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1329 From
.Space
= UDI29KGlobalRegs
;
1330 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1333 #if defined(GR64_REGNUM)
1335 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1337 From
.Space
= UDI29KGlobalRegs
;
1338 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1341 #endif /* GR64_REGNUM */
1343 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1345 From
.Space
= UDI29KLocalRegs
;
1346 From
.Offset
= (regno
- LR0_REGNUM
);
1348 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1351 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1352 return; /* Pretend Success */
1356 From
.Space
= UDI29KSpecialRegs
;
1357 From
.Offset
= regnum_to_srnum(regno
);
1360 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1361 error("UDIRead() failed in udi_fetch_registers");
1363 supply_register(regno
, (char *) &To
);
1366 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1368 /*****************************************************************************/
1369 /* Store a single register indicated by 'regno'.
1370 * Returns 0/-1 on success/failure.
1373 store_register (regno
)
1382 UDIBool HostEndian
= 0;
1384 From
= read_register (regno
); /* get data value */
1387 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1389 if (regno
== GR1_REGNUM
)
1390 { To
.Space
= UDI29KGlobalRegs
;
1392 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1393 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1394 * register cache. Do this *after* calling read_register, because we want
1395 * read_register to return the value that write_register has just stuffed
1396 * into the registers array, not the value of the register fetched from
1399 registers_changed ();
1401 #if defined(GR64_REGNUM)
1402 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1403 { To
.Space
= UDI29KGlobalRegs
;
1404 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1405 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1407 #endif /* GR64_REGNUM */
1408 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1409 { To
.Space
= UDI29KGlobalRegs
;
1410 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1411 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1413 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1414 { To
.Space
= UDI29KLocalRegs
;
1415 To
.Offset
= (regno
- LR0_REGNUM
);
1416 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1418 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1420 return 0; /* Pretend Success */
1422 else /* An unprotected or protected special register */
1423 { To
.Space
= UDI29KSpecialRegs
;
1424 To
.Offset
= regnum_to_srnum(regno
);
1425 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1430 error("UDIWrite() failed in store_registers");
1434 /********************************************************** REGNUM_TO_SRNUM */
1436 * Convert a gdb special register number to a 29000 special register number.
1439 regnum_to_srnum(regno
)
1443 case VAB_REGNUM
: return(0);
1444 case OPS_REGNUM
: return(1);
1445 case CPS_REGNUM
: return(2);
1446 case CFG_REGNUM
: return(3);
1447 case CHA_REGNUM
: return(4);
1448 case CHD_REGNUM
: return(5);
1449 case CHC_REGNUM
: return(6);
1450 case RBP_REGNUM
: return(7);
1451 case TMC_REGNUM
: return(8);
1452 case TMR_REGNUM
: return(9);
1453 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1454 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1455 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1456 case MMU_REGNUM
: return(13);
1457 case LRU_REGNUM
: return(14);
1458 case IPC_REGNUM
: return(128);
1459 case IPA_REGNUM
: return(129);
1460 case IPB_REGNUM
: return(130);
1461 case Q_REGNUM
: return(131);
1462 case ALU_REGNUM
: return(132);
1463 case BP_REGNUM
: return(133);
1464 case FC_REGNUM
: return(134);
1465 case CR_REGNUM
: return(135);
1466 case FPE_REGNUM
: return(160);
1467 case INTE_REGNUM
: return(161);
1468 case FPS_REGNUM
: return(162);
1469 case EXO_REGNUM
:return(164);
1471 return(255); /* Failure ? */
1474 /****************************************************************************/
1476 * Determine the Target memory space qualifier based on the addr.
1477 * FIXME: Can't distinguis I_ROM/D_ROM.
1478 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1481 udi_memory_space(addr
)
1484 UDIUInt32 tstart
= IMemStart
;
1485 UDIUInt32 tend
= tstart
+ IMemSize
;
1486 UDIUInt32 dstart
= DMemStart
;
1487 UDIUInt32 dend
= tstart
+ DMemSize
;
1488 UDIUInt32 rstart
= RMemStart
;
1489 UDIUInt32 rend
= tstart
+ RMemSize
;
1491 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1492 return UDI29KIRAMSpace
;
1493 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1494 return UDI29KDRAMSpace
;
1495 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1496 /* FIXME: how do we determine between D_ROM and I_ROM */
1497 return UDI29KIROMSpace
;
1498 } else /* FIXME: what do me do now? */
1499 return UDI29KDRAMSpace
; /* Hmmm! */
1501 /*********************************************************************** STUBS
1504 void convert16() {;}
1505 void convert32() {;}
1506 FILE* EchoFile
= 0; /* used for debugging */
1507 int QuietMode
= 0; /* used for debugging */
1509 /****************************************************************************/
1511 * Define the target subroutine names
1513 static struct target_ops udi_ops
= {
1515 "Remote UDI connected TIP",
1516 "Remote debug an AMD 29k using UDI socket connection to TIP process.\n\
1518 `configuration-id AF_INET hostname port-number'\n\
1519 To connect via the network, where hostname and port-number specify the\n\
1520 host and port where you can connect via UDI.\n\
1521 configuration-id is unused.\n\
1523 `configuration-id AF_UNIX socket-name tip-program'\n\
1524 To connect using a local connection to the \"tip.exe\" program which is\n\
1525 supplied by AMD. If socket-name specifies an AF_UNIX socket then the\n\
1526 tip program must already be started; connect to it using that socket.\n\
1527 If not, start up tip-program, which should be the name of the tip\n\
1528 program. If appropriate, the PATH environment variable is searched.\n\
1529 configuration-id is unused.\n\
1531 `configuration-id'\n\
1532 Look up the configuration in ./udi_soc or /etc/udi_soc, which\n\
1533 are files containing lines in the above formats. configuration-id is\n\
1534 used to pick which line of the file to use.",
1541 udi_fetch_registers
,
1542 udi_store_registers
,
1543 udi_prepare_to_store
,
1544 udi_xfer_inferior_memory
,
1546 udi_insert_breakpoint
,
1547 udi_remove_breakpoint
,
1548 0, /* termial_init */
1549 0, /* terminal_inferior */
1550 0, /* terminal_ours_for_output */
1551 0, /* terminal_ours */
1552 0, /* terminal_info */
1553 udi_kill
, /* FIXME, kill */
1555 0, /* lookup_symbol */
1556 udi_create_inferior
,
1557 udi_mourn
, /* mourn_inferior FIXME */
1559 0, /* notice_signals */
1562 1, /* has_all_memory */
1565 1, /* has_registers */
1566 1, /* has_execution */
1568 0, /* sections_end */
1569 OPS_MAGIC
, /* Always the last thing */
1572 void _initialize_remote_udi()
1574 add_target (&udi_ops
);
1576 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1578 "Set debugging of UDI I/O.\n\
1579 When enabled, debugging info is displayed.",
1584 #ifdef NO_HIF_SUPPORT
1588 return(0); /* Emulate a failure */