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
);
243 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
244 bkpt_table
[cnt
].Type
= 0;
247 free (udi_config_id
);
250 error("Usage: target udi config_id, where config_id appears in udi_soc file");
252 udi_config_id
= strdup (strtok (name
, " \t"));
254 if (UDIConnect (udi_config_id
, &udi_session_id
))
255 error("UDIConnect() failed: %s\n", dfe_errmsg
);
257 push_target (&udi_ops
);
260 #ifndef NO_SIGINTERRUPT
261 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
263 if (siginterrupt (SIGALRM
, 1) != 0)
264 error ("udi_open: siginterrupt() %s", safe_strerror(errno
));
267 /* Set up read timeout timer. */
268 if ((void (*)) signal (SIGALRM
, udi_timer
) == (void (*)) -1)
269 error ("udi_open: signal() %s", safe_strerror(errno
));
272 #if defined (LOG_FILE)
273 log_file
= fopen (LOG_FILE
, "w");
274 if (log_file
== NULL
)
275 error ("udi_open: fopen(%s) %s", LOG_FILE
, safe_strerror(errno
));
278 ** Initialize target configuration structure (global)
280 if (UDIGetTargetConfig (KnownMemory
, &NumberOfRanges
,
281 ChipVersions
, &NumberOfChips
))
282 error ("UDIGetTargetConfig() failed");
283 if (NumberOfChips
> 2)
284 fprintf(stderr
,"Target has more than one processor\n");
285 for (cnt
=0; cnt
< NumberOfRanges
; cnt
++)
287 switch(KnownMemory
[cnt
].Space
)
290 fprintf(stderr
, "UDIGetTargetConfig() unknown memory space\n");
294 case UDI29KIROMSpace
:
295 RMemStart
= KnownMemory
[cnt
].Offset
;
296 RMemSize
= KnownMemory
[cnt
].Size
;
298 case UDI29KIRAMSpace
:
299 IMemStart
= KnownMemory
[cnt
].Offset
;
300 IMemSize
= KnownMemory
[cnt
].Size
;
302 case UDI29KDRAMSpace
:
303 DMemStart
= KnownMemory
[cnt
].Offset
;
304 DMemSize
= KnownMemory
[cnt
].Size
;
309 /* Determine the processor revision level */
310 prl
= (unsigned int)read_register (CFG_REGNUM
) >> 24;
313 fprintf_filtered (stderr
,
314 "Remote debugging Am29000 rev %c\n",'A'+(prl
&0x1f));
315 processor_type
= TYPE_A29000
;
317 else if ((prl
&0xe0) == 0x40) /* 29030 = 0x4* */
319 fprintf_filtered (stderr
,
320 "Remote debugging Am2903* rev %c\n",'A'+(prl
&0x1f));
321 processor_type
= TYPE_A29030
;
323 else if ((prl
&0xe0) == 0x20) /* 29050 = 0x2* */
325 fprintf_filtered (stderr
,
326 "Remote debugging Am29050 rev %c\n",'A'+(prl
&0x1f));
327 processor_type
= TYPE_A29050
;
331 processor_type
= TYPE_UNKNOWN
;
332 fprintf_filtered (stderr
,"WARNING: processor type unknown.\n");
334 if (UDICreateProcess (&PId
))
335 fprintf(stderr
, "UDICreateProcess() failed\n");
337 /* Print out some stuff, letting the user now what's going on */
338 if (UDICapabilities (&TIPId
, &TargetId
, DFEId
, DFE
, &TIP
, &DFEIPCId
,
340 error ("UDICapabilities() failed");
343 printf_filtered ("Remote debugging an %s connected via UDI socket,\n\
344 DFE-IPC version %x.%x.%x TIP-IPC version %x.%x.%x TIP version %x.%x.%x\n %s\n",
345 processor_name
[processor_type
],
346 (DFEIPCId
>>8)&0xf, (DFEIPCId
>>4)&0xf, DFEIPCId
&0xf,
347 (TIPIPCId
>>8)&0xf, (TIPIPCId
>>4)&0xf, TIPIPCId
&0xf,
348 (TargetId
>>8)&0xf, (TargetId
>>4)&0xf, TargetId
&0xf,
353 /******************************************************************* UDI_CLOSE
354 Close the open connection to the TIP process.
355 Use this when you want to detach and do something else
358 udi_close (quitting
) /*FIXME: how is quitting used */
361 if (udi_session_id
< 0)
364 /* We should never get here if there isn't something valid in
367 if (UDIDisconnect (udi_session_id
, UDITerminateSession
))
368 error ("UDIDisconnect() failed in udi_close");
370 /* Do not try to close udi_session_id again, later in the program. */
374 #if defined (LOG_FILE)
375 if (ferror (log_file
))
376 printf ("Error writing log file.\n");
377 if (fclose (log_file
) != 0)
378 printf ("Error closing log file.\n");
381 printf_filtered (" Ending remote debugging\n");
384 /**************************************************************** UDI_ATACH */
385 /* Attach to a program that is already loaded and running
386 * Upon exiting the process's execution is stopped.
389 udi_attach (args
, from_tty
)
398 UDIBool HostEndian
= 0;
401 if (udi_session_id
< 0)
402 error ("UDI connection not opened yet, use the 'target udi' command.\n");
405 printf ("Attaching to remote program %s...\n", prog_name
);
408 From
.Space
= UDI29KSpecialRegs
;
410 if (err
= UDIRead(From
, &PC_adds
, Count
, Size
, &CountDone
, HostEndian
))
411 error ("UDIRead failed in udi_attach");
412 printf ("Remote process is now halted, pc1 = 0x%x.\n", PC_adds
);
414 /************************************************************* UDI_DETACH */
415 /* Terminate the open connection to the TIP process.
416 Use this when you want to detach and do something else
417 with your gdb. Leave remote process running (with no breakpoints set). */
419 udi_detach (args
,from_tty
)
424 remove_breakpoints(); /* Just in case there were any left in */
426 if (UDIDisconnect (udi_session_id
, UDIContinueSession
))
427 error ("UDIDisconnect() failed in udi_detach");
429 pop_target(); /* calls udi_close to do the real work */
432 printf ("Ending remote debugging\n");
436 /****************************************************************** UDI_RESUME
437 ** Tell the remote machine to resume. */
440 udi_resume (step
, sig
)
445 UDIStepType StepType
= UDIStepNatural
;
448 if (step
) /* step 1 instruction */
450 tip_error
= UDIStep (Steps
, StepType
, Range
);
454 fprintf (stderr
, "UDIStep() error = %d\n", tip_error
);
455 error ("failed in udi_resume");
459 error ("UDIExecute() failed in udi_resume");
462 /******************************************************************** UDI_WAIT
463 ** Wait until the remote machine stops, then return,
464 storing status in STATUS just as `wait' would. */
474 int old_timeout
= timeout
;
475 int old_immediate_quit
= immediate_quit
;
478 WSETEXIT ((*status
), 0);
480 /* wait for message to arrive. It should be:
481 If the target stops executing, udi_wait() should return.
483 timeout
= 0; /* Wait indefinetly for a message */
484 immediate_quit
= 1; /* Helps ability to QUIT */
489 MaxTime
= UDIWaitForever
;
490 UDIWait(MaxTime
, &PId
, &StopReason
);
491 QUIT
; /* Let user quit if they want */
493 switch (StopReason
& UDIGrossState
)
496 if (UDIGetStdout (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
))
497 error ("UDIGetStdout() failed in udi_wait");
498 fwrite (sbuf
, 1, CountDone
, stdout
);
502 UDIGetStderr (sbuf
, (UDISizeT
)SBUF_MAX
, &CountDone
);
503 fwrite (sbuf
, 1, CountDone
, stderr
);
509 UDIPutStdin (sbuf
, (UDISizeT
)i
, &CountDone
);
512 /* In spite of the fact that we told UDIWait to wait forever, it will
513 return spuriously sometimes. */
522 switch (StopReason
& UDIGrossState
)
525 printf("Am290*0 received vector number %d\n", StopReason
>> 24);
527 switch (StopReason
>> 8)
529 case 0: /* Illegal opcode */
530 printf(" (break point)\n");
531 WSETSTOP ((*status
), SIGTRAP
);
533 case 1: /* Unaligned Access */
534 WSETSTOP ((*status
), SIGBUS
);
538 WSETSTOP ((*status
), SIGFPE
);
540 case 5: /* Protection Violation */
541 WSETSTOP ((*status
), SIGILL
);
545 case 8: /* User Instruction Mapping Miss */
546 case 9: /* User Data Mapping Miss */
547 case 10: /* Supervisor Instruction Mapping Miss */
548 case 11: /* Supervisor Data Mapping Miss */
549 WSETSTOP ((*status
), SIGSEGV
);
553 WSETSTOP ((*status
), SIGILL
);
556 WSETSTOP ((*status
), SIGALRM
);
559 WSETSTOP ((*status
), SIGTRAP
);
564 case 19: /* INTR3/Internal */
567 WSETSTOP ((*status
), SIGINT
);
569 case 22: /* Floating-Point Exception */
570 WSETSTOP ((*status
), SIGILL
);
572 case 77: /* assert 77 */
573 WSETSTOP ((*status
), SIGTRAP
);
576 WSETEXIT ((*status
), 0);
579 case UDINotExecuting
:
580 WSETSTOP ((*status
), SIGTERM
);
583 WSETSTOP ((*status
), SIGTSTP
);
586 WSETSTOP ((*status
), SIGLOST
);
590 WSETSTOP ((*status
), SIGTRAP
);
593 WSETSTOP ((*status
), SIGSTOP
);
596 WSETSTOP ((*status
), SIGKILL
);
600 WSETEXIT ((*status
), 0);
603 timeout
= old_timeout
; /* Restore original timeout value */
604 immediate_quit
= old_immediate_quit
;
608 /********************************************************** UDI_FETCH_REGISTERS
609 * Read a remote register 'regno'.
610 * If regno==-1 then read all the registers.
613 udi_fetch_registers (regno
)
621 UDIBool HostEndian
= 0;
626 fetch_register(regno
);
632 From
.Space
= UDI29KGlobalRegs
;
634 To
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
636 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
637 error("UDIRead() failed in udi_fetch_registers");
639 register_valid
[GR1_REGNUM
] = 1;
641 #if defined(GR64_REGNUM) /* Read gr64-127 */
643 /* Global Registers gr64-gr95 */
645 From
.Space
= UDI29KGlobalRegs
;
647 To
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
649 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
650 error("UDIRead() failed in udi_fetch_registers");
652 for (i
= GR64_REGNUM
; i
< GR64_REGNUM
+ 32; i
++)
653 register_valid
[i
] = 1;
655 #endif /* GR64_REGNUM */
657 /* Global Registers gr96-gr127 */
659 From
.Space
= UDI29KGlobalRegs
;
661 To
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
663 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
664 error("UDIRead() failed in udi_fetch_registers");
666 for (i
= GR96_REGNUM
; i
< GR96_REGNUM
+ 32; i
++)
667 register_valid
[i
] = 1;
669 /* Local Registers */
671 From
.Space
= UDI29KLocalRegs
;
673 To
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
675 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
676 error("UDIRead() failed in udi_fetch_registers");
678 for (i
= LR0_REGNUM
; i
< LR0_REGNUM
+ 128; i
++)
679 register_valid
[i
] = 1;
681 /* Protected Special Registers */
683 From
.Space
= UDI29KSpecialRegs
;
685 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
687 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
688 error("UDIRead() failed in udi_fetch_registers");
690 for (i
= SR_REGNUM(0); i
< SR_REGNUM(0) + 15; i
++)
691 register_valid
[i
] = 1;
693 if (USE_SHADOW_PC
) { /* Let regno_to_srnum() handle the register number */
694 fetch_register(NPC_REGNUM
);
695 fetch_register(PC_REGNUM
);
696 fetch_register(PC2_REGNUM
);
698 /* Unprotected Special Registers sr128-sr135 */
700 From
.Space
= UDI29KSpecialRegs
;
702 To
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
704 if (err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
705 error("UDIRead() failed in udi_fetch_registers");
707 for (i
= SR_REGNUM(128); i
< SR_REGNUM(128) + 135-128+1; i
++)
708 register_valid
[i
] = 1;
713 printf("Fetching all registers\n");
714 printf("Fetching PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n",
715 read_register(NPC_REGNUM
), read_register(PC_REGNUM
),
716 read_register(PC2_REGNUM
));
719 /* There doesn't seem to be any way to get these. */
722 supply_register (FPE_REGNUM
, (char *) &val
);
723 supply_register (INTE_REGNUM
, (char *) &val
);
724 supply_register (FPS_REGNUM
, (char *) &val
);
725 supply_register (EXO_REGNUM
, (char *) &val
);
730 /********************************************************* UDI_STORE_REGISTERS
731 ** Store register regno into the target.
732 * If regno==-1 then store all the registers.
736 udi_store_registers (regno
)
744 UDIBool HostEndian
= 0;
748 store_register(regno
);
754 printf("Storing all registers\n");
755 printf("PC0 = 0x%x, PC1 = 0x%x, PC2 = 0x%x\n", read_register(NPC_REGNUM
),
756 read_register(PC_REGNUM
), read_register(PC2_REGNUM
));
761 From
= (UDIUInt32
*)®isters
[4 * GR1_REGNUM
];
762 To
.Space
= UDI29KGlobalRegs
;
765 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
766 error("UDIWrite() failed in udi_store_regisetrs");
768 #if defined(GR64_REGNUM)
770 /* Global registers gr64-gr95 */
772 From
= (UDIUInt32
*)®isters
[4 * GR64_REGNUM
];
773 To
.Space
= UDI29KGlobalRegs
;
776 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
777 error("UDIWrite() failed in udi_store_regisetrs");
779 #endif /* GR64_REGNUM */
781 /* Global registers gr96-gr127 */
783 From
= (UDIUInt32
*)®isters
[4 * GR96_REGNUM
];
784 To
.Space
= UDI29KGlobalRegs
;
787 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
788 error("UDIWrite() failed in udi_store_regisetrs");
790 /* Local Registers */
792 From
= (UDIUInt32
*)®isters
[4 * LR0_REGNUM
];
793 To
.Space
= UDI29KLocalRegs
;
796 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
797 error("UDIWrite() failed in udi_store_regisetrs");
800 /* Protected Special Registers */ /* VAB through TMR */
802 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(0)];
803 To
.Space
= UDI29KSpecialRegs
;
806 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
807 error("UDIWrite() failed in udi_store_regisetrs");
809 /* PC0, PC1, PC2 possibly as shadow registers */
811 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(10)];
812 To
.Space
= UDI29KSpecialRegs
;
815 To
.Offset
= 20; /* SPC0 */
817 To
.Offset
= 10; /* PC0 */
818 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
819 error("UDIWrite() failed in udi_store_regisetrs");
823 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(13)];
824 To
.Space
= UDI29KSpecialRegs
;
827 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
828 error("UDIWrite() failed in udi_store_regisetrs");
830 /* Unprotected Special Registers */
832 From
= (UDIUInt32
*)®isters
[4 * SR_REGNUM(128)];
833 To
.Space
= UDI29KSpecialRegs
;
836 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
837 error("UDIWrite() failed in udi_store_regisetrs");
839 registers_changed ();
842 /****************************************************** UDI_PREPARE_TO_STORE */
843 /* Get ready to modify the registers array. On machines which store
844 individual registers, this doesn't need to do anything. On machines
845 which store all the registers in one fell swoop, this makes sure
846 that registers contains all the registers from the program being
850 udi_prepare_to_store ()
852 /* Do nothing, since we can store individual regs */
855 /********************************************************** TRANSLATE_ADDR */
860 #if defined(ULTRA3) && defined(KERNEL_DEBUGGING)
861 /* Check for a virtual address in the kernel */
862 /* Assume physical address of ublock is in paddr_u register */
863 /* FIXME: doesn't work for user virtual addresses */
864 if (addr
>= UVADDR
) {
865 /* PADDR_U register holds the physical address of the ublock */
866 CORE_ADDR i
= (CORE_ADDR
)read_register(PADDR_U_REGNUM
);
867 return(i
+ addr
- (CORE_ADDR
)UVADDR
);
875 /************************************************* UDI_XFER_INFERIOR_MEMORY */
876 /* FIXME! Merge these two. */
878 udi_xfer_inferior_memory (memaddr
, myaddr
, len
, write
)
885 memaddr
= translate_addr(memaddr
);
888 return udi_write_inferior_memory (memaddr
, myaddr
, len
);
890 return udi_read_inferior_memory (memaddr
, myaddr
, len
);
893 /********************************************************** UDI_FILES_INFO */
897 printf ("\tAttached to UDI socket to %s and running program %s.\n",
898 udi_config_id
, prog_name
);
901 /**************************************************** UDI_INSERT_BREAKPOINT */
903 udi_insert_breakpoint (addr
, contents_cache
)
905 char *contents_cache
;
910 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
911 if (bkpt_table
[cnt
].Type
== 0) /* Find first free slot */
914 if(cnt
>= BKPT_TABLE_SIZE
)
915 error("Too many breakpoints set");
917 bkpt_table
[cnt
].Addr
.Offset
= addr
;
918 bkpt_table
[cnt
].Addr
.Space
= UDI29KIRAMSpace
;
919 bkpt_table
[cnt
].PassCount
= 1;
920 bkpt_table
[cnt
].Type
= UDIBreakFlagExecute
;
922 err
= UDISetBreakpoint(bkpt_table
[cnt
].Addr
,
923 bkpt_table
[cnt
].PassCount
,
924 bkpt_table
[cnt
].Type
,
925 &bkpt_table
[cnt
].BreakId
);
927 if (err
== 0) return 0; /* Success */
929 bkpt_table
[cnt
].Type
= 0;
930 error("UDISetBreakpoint returned error code %d\n", err
);
933 /**************************************************** UDI_REMOVE_BREAKPOINT */
935 udi_remove_breakpoint (addr
, contents_cache
)
937 char *contents_cache
;
942 for (cnt
= 0; cnt
< BKPT_TABLE_SIZE
; cnt
++)
943 if (bkpt_table
[cnt
].Addr
.Offset
== addr
) /* Find matching breakpoint */
946 if(cnt
>= BKPT_TABLE_SIZE
)
947 error("Can't find breakpoint in table");
949 bkpt_table
[cnt
].Type
= 0;
951 err
= UDIClearBreakpoint(bkpt_table
[cnt
].BreakId
);
952 if (err
== 0) return 0; /* Success */
954 error("UDIClearBreakpoint returned error code %d\n", err
);
958 udi_kill(arg
,from_tty
)
965 UDIStop does not really work as advertised. It causes the TIP to close it's
966 connection, which usually results in GDB dying with a SIGPIPE. For now, we
967 just invoke udi_close, which seems to get things right.
975 printf("Target has been stopped.");
983 Load a program into the target. Args are: `program {options}'. The options
984 are used to control loading of the program, and are NOT passed onto the
985 loaded code as arguments. (You need to use the `run' command to do that.)
988 -ms %d Set mem stack size to %d
989 -rs %d Set regular stack size to %d
990 -i send init info (default)
991 -noi don't send init info
992 -[tT] Load Text section
993 -[dD] Load Data section
994 -[bB] Load BSS section
995 -[lL] Load Lit section
999 download(load_arg_string
, from_tty
)
1000 char *load_arg_string
;
1003 #define DEFAULT_MEM_STACK_SIZE 0x6000
1004 #define DEFAULT_REG_STACK_SIZE 0x2000
1011 int load_text
= 1, load_data
= 1, load_bss
= 1, load_lit
= 1;
1013 address_ranges
[0].Space
= UDI29KIRAMSpace
;
1014 address_ranges
[0].Offset
= 0xffffffff;
1015 address_ranges
[0].Size
= 0;
1017 address_ranges
[1].Space
= UDI29KDRAMSpace
;
1018 address_ranges
[1].Offset
= 0xffffffff;
1019 address_ranges
[1].Size
= 0;
1021 stack_sizes
[0] = DEFAULT_REG_STACK_SIZE
;
1022 stack_sizes
[1] = DEFAULT_MEM_STACK_SIZE
;
1026 filename
= strtok(load_arg_string
, " \t");
1028 error ("Must specify at least a file name with the load command");
1030 filename
= tilde_expand (filename
);
1031 make_cleanup (free
, filename
);
1033 while (token
= strtok (NULL
, " \t"))
1035 if (token
[0] == '-')
1039 if (STREQ (token
, "ms"))
1040 stack_sizes
[1] = atol (strtok (NULL
, " \t"));
1041 else if (STREQ (token
, "rs"))
1042 stack_sizes
[0] = atol (strtok (NULL
, " \t"));
1045 load_text
= load_data
= load_bss
= load_lit
= 0;
1068 error ("Unknown UDI load option -%s", token
-1);
1075 pbfd
= bfd_openr (filename
, 0);
1078 perror_with_name (filename
);
1080 make_cleanup (bfd_close
, pbfd
);
1085 if (!bfd_check_format (pbfd
, bfd_object
))
1086 error ("It doesn't seem to be an object file");
1088 for (section
= pbfd
->sections
; section
; section
= section
->next
)
1090 if (bfd_get_section_flags (pbfd
, section
) & SEC_ALLOC
)
1094 unsigned long section_size
, section_end
;
1095 const char *section_name
;
1097 section_name
= bfd_get_section_name (pbfd
, section
);
1098 if (STREQ (section_name
, ".text") && !load_text
)
1100 else if (STREQ (section_name
, ".data") && !load_data
)
1102 else if (STREQ (section_name
, ".bss") && !load_bss
)
1104 else if (STREQ (section_name
, ".lit") && !load_lit
)
1107 To
.Offset
= bfd_get_section_vma (pbfd
, section
);
1108 section_size
= bfd_section_size (pbfd
, section
);
1109 section_end
= To
.Offset
+ section_size
;
1111 printf("[Loading section %s at %x (%d bytes)]\n",
1116 if (bfd_get_section_flags (pbfd
, section
) & SEC_CODE
)
1118 To
.Space
= UDI29KIRAMSpace
;
1120 address_ranges
[0].Offset
= min (address_ranges
[0].Offset
,
1122 address_ranges
[0].Size
= max (address_ranges
[0].Size
,
1124 - address_ranges
[0].Offset
);
1128 To
.Space
= UDI29KDRAMSpace
;
1130 address_ranges
[1].Offset
= min (address_ranges
[1].Offset
,
1132 address_ranges
[1].Size
= max (address_ranges
[1].Size
,
1134 - address_ranges
[1].Offset
);
1137 if (bfd_get_section_flags (pbfd
, section
) & SEC_LOAD
) /* Text, data or lit */
1143 while (section_size
> 0)
1147 Count
= min (section_size
, 1024);
1149 bfd_get_section_contents (pbfd
, section
, buffer
, fptr
,
1152 err
= UDIWrite ((UDIHostMemPtr
)buffer
, /* From */
1155 (UDISizeT
)1, /* Size */
1156 &Count
, /* CountDone */
1157 (UDIBool
)0); /* HostEndian */
1159 error ("UDIWrite failed, error = %d", err
);
1163 section_size
-= Count
;
1169 unsigned long zero
= 0;
1171 /* Write a zero byte at the vma */
1172 err
= UDIWrite ((UDIHostMemPtr
)&zero
, /* From */
1174 (UDICount
)1, /* Count */
1175 (UDISizeT
)4, /* Size */
1176 &Count
, /* CountDone */
1177 (UDIBool
)0); /* HostEndian */
1179 error ("UDIWrite failed, error = %d", err
);
1184 /* Now, duplicate it for the length of the BSS */
1185 err
= UDICopy (From
, /* From */
1187 (UDICount
)(section_size
/4 - 1), /* Count */
1188 (UDISizeT
)4, /* Size */
1189 &Count
, /* CountDone */
1190 (UDIBool
)1); /* Direction */
1196 xerr
= UDIGetErrorMsg(err
, 100, message
, &Count
);
1198 fprintf (stderr
, "Error is %s\n", message
);
1200 fprintf (stderr
, "xerr is %d\n", xerr
);
1201 error ("UDICopy failed, error = %d", err
);
1208 entry
.Space
= UDI29KIRAMSpace
;
1209 entry
.Offset
= bfd_get_start_address (pbfd
);
1214 /* User interface to download an image into the remote target. See download()
1215 * for details on args.
1219 udi_load(args
, from_tty
)
1223 download (args
, from_tty
);
1225 symbol_file_add (strtok (args
, " \t"), from_tty
, 0, 0, 0, 0);
1228 /*************************************************** UDI_WRITE_INFERIOR_MEMORY
1229 ** Copy LEN bytes of data from debugger memory at MYADDR
1230 to inferior's memory at MEMADDR. Returns number of bytes written. */
1232 udi_write_inferior_memory (memaddr
, myaddr
, len
)
1242 UDICount CountDone
= 0;
1243 UDIBool HostEndian
= 0;
1245 To
.Space
= udi_memory_space(memaddr
);
1246 From
= (UDIUInt32
*)myaddr
;
1248 while (nwritten
< len
)
1249 { Count
= len
- nwritten
;
1250 if (Count
> MAXDATA
) Count
= MAXDATA
;
1251 To
.Offset
= memaddr
+ nwritten
;
1252 if(UDIWrite(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1253 { error("UDIWrite() failed in udi_write_inferrior_memory");
1257 { nwritten
+= CountDone
;
1264 /**************************************************** UDI_READ_INFERIOR_MEMORY
1265 ** Read LEN bytes from inferior memory at MEMADDR. Put the result
1266 at debugger address MYADDR. Returns number of bytes read. */
1268 udi_read_inferior_memory(memaddr
, myaddr
, len
)
1278 UDICount CountDone
= 0;
1279 UDIBool HostEndian
= 0;
1282 From
.Space
= udi_memory_space(memaddr
);
1283 To
= (UDIUInt32
*)myaddr
;
1286 { Count
= len
- nread
;
1287 if (Count
> MAXDATA
) Count
= MAXDATA
;
1288 From
.Offset
= memaddr
+ nread
;
1289 if(err
= UDIRead(From
, To
, Count
, Size
, &CountDone
, HostEndian
))
1290 { error("UDIRead() failed in udi_read_inferrior_memory");
1294 { nread
+= CountDone
;
1301 /********************************************************************* WARNING
1306 error ("ERROR while loading program into remote TIP: $d\n", num
);
1310 /*****************************************************************************/
1311 /* Fetch a single register indicatated by 'regno'.
1312 * Returns 0/-1 on success/failure.
1315 fetch_register (regno
)
1323 UDIBool HostEndian
= 0;
1327 if (regno
== GR1_REGNUM
)
1329 From
.Space
= UDI29KGlobalRegs
;
1332 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1334 From
.Space
= UDI29KGlobalRegs
;
1335 From
.Offset
= (regno
- GR96_REGNUM
) + 96;;
1338 #if defined(GR64_REGNUM)
1340 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1342 From
.Space
= UDI29KGlobalRegs
;
1343 From
.Offset
= (regno
- GR64_REGNUM
) + 64;
1346 #endif /* GR64_REGNUM */
1348 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1350 From
.Space
= UDI29KLocalRegs
;
1351 From
.Offset
= (regno
- LR0_REGNUM
);
1353 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1356 supply_register(160 + (regno
- FPE_REGNUM
),(char *) &val
);
1357 return; /* Pretend Success */
1361 From
.Space
= UDI29KSpecialRegs
;
1362 From
.Offset
= regnum_to_srnum(regno
);
1365 if (err
= UDIRead(From
, &To
, Count
, Size
, &CountDone
, HostEndian
))
1366 error("UDIRead() failed in udi_fetch_registers");
1368 supply_register(regno
, (char *) &To
);
1371 printf("Fetching register %s = 0x%x\n", reg_names
[regno
], To
);
1373 /*****************************************************************************/
1374 /* Store a single register indicated by 'regno'.
1375 * Returns 0/-1 on success/failure.
1378 store_register (regno
)
1387 UDIBool HostEndian
= 0;
1389 From
= read_register (regno
); /* get data value */
1392 printf("Storing register %s = 0x%x\n", reg_names
[regno
], From
);
1394 if (regno
== GR1_REGNUM
)
1395 { To
.Space
= UDI29KGlobalRegs
;
1397 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1398 /* Setting GR1 changes the numbers of all the locals, so invalidate the
1399 * register cache. Do this *after* calling read_register, because we want
1400 * read_register to return the value that write_register has just stuffed
1401 * into the registers array, not the value of the register fetched from
1404 registers_changed ();
1406 #if defined(GR64_REGNUM)
1407 else if (regno
>= GR64_REGNUM
&& regno
< GR64_REGNUM
+ 32 )
1408 { To
.Space
= UDI29KGlobalRegs
;
1409 To
.Offset
= (regno
- GR64_REGNUM
) + 64;
1410 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1412 #endif /* GR64_REGNUM */
1413 else if (regno
>= GR96_REGNUM
&& regno
< GR96_REGNUM
+ 32)
1414 { To
.Space
= UDI29KGlobalRegs
;
1415 To
.Offset
= (regno
- GR96_REGNUM
) + 96;
1416 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1418 else if (regno
>= LR0_REGNUM
&& regno
< LR0_REGNUM
+ 128)
1419 { To
.Space
= UDI29KLocalRegs
;
1420 To
.Offset
= (regno
- LR0_REGNUM
);
1421 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1423 else if (regno
>=FPE_REGNUM
&& regno
<=EXO_REGNUM
)
1425 return 0; /* Pretend Success */
1427 else /* An unprotected or protected special register */
1428 { To
.Space
= UDI29KSpecialRegs
;
1429 To
.Offset
= regnum_to_srnum(regno
);
1430 result
= UDIWrite(&From
, To
, Count
, Size
, &CountDone
, HostEndian
);
1435 error("UDIWrite() failed in store_registers");
1439 /********************************************************** REGNUM_TO_SRNUM */
1441 * Convert a gdb special register number to a 29000 special register number.
1444 regnum_to_srnum(regno
)
1448 case VAB_REGNUM
: return(0);
1449 case OPS_REGNUM
: return(1);
1450 case CPS_REGNUM
: return(2);
1451 case CFG_REGNUM
: return(3);
1452 case CHA_REGNUM
: return(4);
1453 case CHD_REGNUM
: return(5);
1454 case CHC_REGNUM
: return(6);
1455 case RBP_REGNUM
: return(7);
1456 case TMC_REGNUM
: return(8);
1457 case TMR_REGNUM
: return(9);
1458 case NPC_REGNUM
: return(USE_SHADOW_PC
? (20) : (10));
1459 case PC_REGNUM
: return(USE_SHADOW_PC
? (21) : (11));
1460 case PC2_REGNUM
: return(USE_SHADOW_PC
? (22) : (12));
1461 case MMU_REGNUM
: return(13);
1462 case LRU_REGNUM
: return(14);
1463 case IPC_REGNUM
: return(128);
1464 case IPA_REGNUM
: return(129);
1465 case IPB_REGNUM
: return(130);
1466 case Q_REGNUM
: return(131);
1467 case ALU_REGNUM
: return(132);
1468 case BP_REGNUM
: return(133);
1469 case FC_REGNUM
: return(134);
1470 case CR_REGNUM
: return(135);
1471 case FPE_REGNUM
: return(160);
1472 case INTE_REGNUM
: return(161);
1473 case FPS_REGNUM
: return(162);
1474 case EXO_REGNUM
:return(164);
1476 return(255); /* Failure ? */
1479 /****************************************************************************/
1481 * Determine the Target memory space qualifier based on the addr.
1482 * FIXME: Can't distinguis I_ROM/D_ROM.
1483 * FIXME: Doesn't know anything about I_CACHE/D_CACHE.
1486 udi_memory_space(addr
)
1489 UDIUInt32 tstart
= IMemStart
;
1490 UDIUInt32 tend
= tstart
+ IMemSize
;
1491 UDIUInt32 dstart
= DMemStart
;
1492 UDIUInt32 dend
= tstart
+ DMemSize
;
1493 UDIUInt32 rstart
= RMemStart
;
1494 UDIUInt32 rend
= tstart
+ RMemSize
;
1496 if (((UDIUInt32
)addr
>= tstart
) && ((UDIUInt32
)addr
< tend
)) {
1497 return UDI29KIRAMSpace
;
1498 } else if (((UDIUInt32
)addr
>= dstart
) && ((UDIUInt32
)addr
< dend
)) {
1499 return UDI29KDRAMSpace
;
1500 } else if (((UDIUInt32
)addr
>= rstart
) && ((UDIUInt32
)addr
< rend
)) {
1501 /* FIXME: how do we determine between D_ROM and I_ROM */
1502 return UDI29KIROMSpace
;
1503 } else /* FIXME: what do me do now? */
1504 return UDI29KDRAMSpace
; /* Hmmm! */
1506 /*********************************************************************** STUBS
1509 void convert16() {;}
1510 void convert32() {;}
1511 FILE* EchoFile
= 0; /* used for debugging */
1512 int QuietMode
= 0; /* used for debugging */
1514 /****************************************************************************/
1516 * Define the target subroutine names
1518 static struct target_ops udi_ops
= {
1520 "Remote UDI connected TIP",
1521 "Remote debug an AMD 29k using UDI socket connection to TIP process",
1528 udi_fetch_registers
,
1529 udi_store_registers
,
1530 udi_prepare_to_store
,
1531 udi_xfer_inferior_memory
,
1533 udi_insert_breakpoint
,
1534 udi_remove_breakpoint
,
1535 0, /* termial_init */
1536 0, /* terminal_inferior */
1537 0, /* terminal_ours_for_output */
1538 0, /* terminal_ours */
1539 0, /* terminal_info */
1540 udi_kill
, /* FIXME, kill */
1542 0, /* lookup_symbol */
1543 udi_create_inferior
,
1544 udi_mourn
, /* mourn_inferior FIXME */
1546 0, /* notice_signals */
1549 1, /* has_all_memory */
1552 1, /* has_registers */
1553 1, /* has_execution */
1555 0, /* sections_end */
1556 OPS_MAGIC
, /* Always the last thing */
1559 void _initialize_remote_udi()
1561 add_target (&udi_ops
);
1563 add_set_cmd ("remotedebug", no_class
, var_boolean
,
1565 "Set debugging of UDI I/O.\n\
1566 When enabled, debugging info is displayed.",
1571 #ifdef NO_HIF_SUPPORT
1575 return(0); /* Emulate a failure */