1 /* run front end support for arm
2 Copyright (C) 1995, 1996, 1997, 2000, 2001, 2002
3 Free Software Foundation, Inc.
5 This file is part of ARM SIM.
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 2, or (at your
10 option) any later version.
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public
18 License along with this program; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This file provides the interface between the simulator and
23 run.c and gdb (when the simulator is linked with gdb).
24 All simulator interaction should go through this file. */
31 #include "gdb/callback.h"
32 #include "gdb/remote-sim.h"
37 #include "sim-utils.h"
40 host_callback
*sim_callback
;
42 static struct ARMul_State
*state
;
44 /* Who is using the simulator. */
45 static SIM_OPEN_KIND sim_kind
;
50 /* Memory size in bytes. */
51 static int mem_size
= (1 << 23);
53 /* Non-zero to display start up banner, and maybe other things. */
56 /* Non-zero to set big endian mode. */
57 static int big_endian
;
69 state
= ARMul_NewState ();
70 state
->bigendSig
= (big_endian
? HIGH
: LOW
);
71 ARMul_MemoryInit (state
, mem_size
);
73 ARMul_CoProInit (state
);
74 state
->verbose
= verbosity
;
79 /* Set verbosity level of simulator.
80 This is not intended to produce detailed tracing or debugging information.
82 /* FIXME: common/run.c doesn't do this yet. */
91 /* Set the memory size to SIZE bytes.
92 Must be called before initializing simulator. */
93 /* FIXME: Rename to sim_set_mem_size. */
103 ARMul_ConsolePrint
VPARAMS ((ARMul_State
* state
,
111 va_start (ap
, format
);
112 vprintf (format
, ap
);
118 ARMul_Debug (state
, pc
, instr
)
119 ARMul_State
* state ATTRIBUTE_UNUSED
;
120 ARMword pc ATTRIBUTE_UNUSED
;
121 ARMword instr ATTRIBUTE_UNUSED
;
127 sim_write (sd
, addr
, buffer
, size
)
128 SIM_DESC sd ATTRIBUTE_UNUSED
;
130 unsigned char * buffer
;
137 for (i
= 0; i
< size
; i
++)
138 ARMul_SafeWriteByte (state
, addr
+ i
, buffer
[i
]);
144 sim_read (sd
, addr
, buffer
, size
)
145 SIM_DESC sd ATTRIBUTE_UNUSED
;
147 unsigned char * buffer
;
154 for (i
= 0; i
< size
; i
++)
155 buffer
[i
] = ARMul_SafeReadByte (state
, addr
+ i
);
162 SIM_DESC sd ATTRIBUTE_UNUSED
;
164 (*sim_callback
->printf_filtered
)
166 "This simulator does not support tracing\n");
172 SIM_DESC sd ATTRIBUTE_UNUSED
;
174 state
->Emulate
= STOP
;
180 sim_resume (sd
, step
, siggnal
)
181 SIM_DESC sd ATTRIBUTE_UNUSED
;
183 int siggnal ATTRIBUTE_UNUSED
;
185 state
->EndCondition
= 0;
190 state
->Reg
[15] = ARMul_DoInstr (state
);
191 if (state
->EndCondition
== 0)
192 state
->EndCondition
= RDIError_BreakpointReached
;
196 state
->NextInstr
= RESUME
; /* treat as PC change */
197 state
->Reg
[15] = ARMul_DoProg (state
);
204 sim_create_inferior (sd
, abfd
, argv
, env
)
205 SIM_DESC sd ATTRIBUTE_UNUSED
;
215 ARMul_SetPC (state
, bfd_get_start_address (abfd
));
217 ARMul_SetPC (state
, 0); /* ??? */
219 mach
= bfd_get_mach (abfd
);
224 (*sim_callback
->printf_filtered
)
226 "Unknown machine type '%d'; please update sim_create_inferior.\n",
231 /* We wouldn't set the machine type with earlier toolchains, so we
232 explicitly select a processor capable of supporting all ARMs in
234 case bfd_mach_arm_XScale
:
235 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
| ARM_XScale_Prop
);
239 if (bfd_family_coff (abfd
))
241 /* This is a special case in order to support COFF based ARM toolchains.
242 The COFF header does not have enough room to store all the different
243 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
244 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
245 machine type here, we assume it could be any of the above architectures
246 and so select the most feature-full. */
247 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
| ARM_XScale_Prop
);
250 /* Otherwise drop through. */
252 case bfd_mach_arm_5T
:
253 ARMul_SelectProcessor (state
, ARM_v5_Prop
);
256 case bfd_mach_arm_5TE
:
257 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
);
261 case bfd_mach_arm_4T
:
262 ARMul_SelectProcessor (state
, ARM_v4_Prop
);
266 case bfd_mach_arm_3M
:
267 ARMul_SelectProcessor (state
, ARM_Lock_Prop
);
271 case bfd_mach_arm_2a
:
272 ARMul_SelectProcessor (state
, ARM_Fix26_Prop
);
276 if ( mach
!= bfd_mach_arm_3
277 && mach
!= bfd_mach_arm_3M
278 && mach
!= bfd_mach_arm_2
279 && mach
!= bfd_mach_arm_2a
)
281 /* Reset mode to ARM. A gdb user may rerun a program that had entered
282 THUMB mode from the start and cause the ARM-mode startup code to be
283 executed in THUMB mode. */
284 ARMul_SetCPSR (state
, SVC32MODE
);
289 /* Set up the command line by laboriously stringing together
290 the environment carefully picked apart by our caller. */
292 /* Free any old stuff. */
293 if (state
->CommandLine
!= NULL
)
295 free (state
->CommandLine
);
296 state
->CommandLine
= NULL
;
299 /* See how much we need. */
300 for (arg
= argv
; *arg
!= NULL
; arg
++)
301 argvlen
+= strlen (*arg
) + 1;
304 state
->CommandLine
= malloc (argvlen
+ 1);
305 if (state
->CommandLine
!= NULL
)
308 state
->CommandLine
[0] = '\0';
310 for (arg
= argv
; *arg
!= NULL
; arg
++)
312 strcat (state
->CommandLine
, *arg
);
313 strcat (state
->CommandLine
, " ");
320 /* Now see if there's a MEMSIZE spec in the environment. */
323 if (strncmp (*env
, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
327 /* Set up memory limit. */
329 strtoul (*env
+ sizeof ("MEMSIZE=") - 1, &end_of_num
, 0);
339 sim_info (sd
, verbose
)
340 SIM_DESC sd ATTRIBUTE_UNUSED
;
341 int verbose ATTRIBUTE_UNUSED
;
346 frommem (state
, memory
)
347 struct ARMul_State
*state
;
348 unsigned char *memory
;
350 if (state
->bigendSig
== HIGH
)
351 return (memory
[0] << 24) | (memory
[1] << 16)
352 | (memory
[2] << 8) | (memory
[3] << 0);
354 return (memory
[3] << 24) | (memory
[2] << 16)
355 | (memory
[1] << 8) | (memory
[0] << 0);
359 tomem (state
, memory
, val
)
360 struct ARMul_State
*state
;
361 unsigned char *memory
;
364 if (state
->bigendSig
== HIGH
)
366 memory
[0] = val
>> 24;
367 memory
[1] = val
>> 16;
368 memory
[2] = val
>> 8;
369 memory
[3] = val
>> 0;
373 memory
[3] = val
>> 24;
374 memory
[2] = val
>> 16;
375 memory
[1] = val
>> 8;
376 memory
[0] = val
>> 0;
381 sim_store_register (sd
, rn
, memory
, length
)
382 SIM_DESC sd ATTRIBUTE_UNUSED
;
384 unsigned char *memory
;
385 int length ATTRIBUTE_UNUSED
;
391 state
->Cpsr
= frommem (state
, memory
);
392 ARMul_CPSRAltered (state
);
395 ARMul_SetReg (state
, state
->Mode
, rn
, frommem (state
, memory
));
400 sim_fetch_register (sd
, rn
, memory
, length
)
401 SIM_DESC sd ATTRIBUTE_UNUSED
;
403 unsigned char *memory
;
404 int length ATTRIBUTE_UNUSED
;
411 regval
= ARMul_GetReg (state
, state
->Mode
, rn
);
413 /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h. */
414 regval
= ARMul_GetCPSR (state
);
416 /* FIXME: should report an error. */
421 tomem (state
, memory
, regval
);
431 #ifdef SIM_TARGET_SWITCHES
433 static void sim_target_parse_arg_array
PARAMS ((char **));
438 unsigned int swi_mask
;
441 #define SWI_SWITCH "--swi-support"
443 static swi_options options
[] =
446 { "demon", SWI_MASK_DEMON
},
447 { "angel", SWI_MASK_ANGEL
},
448 { "redboot", SWI_MASK_REDBOOT
},
451 { "DEMON", SWI_MASK_DEMON
},
452 { "ANGEL", SWI_MASK_ANGEL
},
453 { "REDBOOT", SWI_MASK_REDBOOT
},
459 sim_target_parse_command_line (argc
, argv
)
465 for (i
= 1; i
< argc
; i
++)
467 char * ptr
= argv
[i
];
470 if ((ptr
== NULL
) || (* ptr
!= '-'))
473 if (strncmp (ptr
, SWI_SWITCH
, sizeof SWI_SWITCH
- 1) != 0)
476 if (ptr
[sizeof SWI_SWITCH
- 1] == 0)
478 /* Remove this option from the argv array. */
479 for (arg
= i
; arg
< argc
; arg
++)
480 argv
[arg
] = argv
[arg
+ 1];
486 ptr
+= sizeof SWI_SWITCH
;
494 for (i
= sizeof options
/ sizeof options
[0]; i
--;)
495 if (strncmp (ptr
, options
[i
].swi_option
,
496 strlen (options
[i
].swi_option
)) == 0)
498 swi_mask
|= options
[i
].swi_mask
;
499 ptr
+= strlen (options
[i
].swi_option
);
512 fprintf (stderr
, "Ignoring swi options: %s\n", ptr
);
514 /* Remove this option from the argv array. */
515 for (arg
= i
; arg
< argc
; arg
++)
516 argv
[arg
] = argv
[arg
+ 1];
524 sim_target_parse_arg_array (argv
)
529 for (i
= 0; argv
[i
]; i
++)
532 return (void) sim_target_parse_command_line (i
, argv
);
536 sim_target_display_usage ()
538 fprintf (stderr
, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
539 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
545 sim_open (kind
, ptr
, abfd
, argv
)
552 if (myname
) free (myname
);
553 myname
= (char *) xstrdup (argv
[0]);
556 #ifdef SIM_TARGET_SWITCHES
557 sim_target_parse_arg_array (argv
);
560 /* Decide upon the endian-ness of the processor.
561 If we can, get the information from the bfd itself.
562 Otherwise look to see if we have been given a command
563 line switch that tells us. Otherwise default to little endian. */
565 big_endian
= bfd_big_endian (abfd
);
566 else if (argv
[1] != NULL
)
570 /* Scan for endian-ness switch. */
571 for (i
= 0; (argv
[i
] != NULL
) && (argv
[i
][0] != 0); i
++)
572 if (argv
[i
][0] == '-' && argv
[i
][1] == 'E')
576 if ((c
= argv
[i
][2]) == 0)
585 sim_callback
->printf_filtered
586 (sim_callback
, "No argument to -E option provided\n");
600 sim_callback
->printf_filtered
601 (sim_callback
, "Unrecognised argument to -E option\n");
611 sim_close (sd
, quitting
)
612 SIM_DESC sd ATTRIBUTE_UNUSED
;
613 int quitting ATTRIBUTE_UNUSED
;
621 sim_load (sd
, prog
, abfd
, from_tty
)
625 int from_tty ATTRIBUTE_UNUSED
;
629 prog_bfd
= sim_load_file (sd
, myname
, sim_callback
, prog
, abfd
,
630 sim_kind
== SIM_OPEN_DEBUG
, 0, sim_write
);
631 if (prog_bfd
== NULL
)
633 ARMul_SetPC (state
, bfd_get_start_address (prog_bfd
));
635 bfd_close (prog_bfd
);
640 sim_stop_reason (sd
, reason
, sigrc
)
641 SIM_DESC sd ATTRIBUTE_UNUSED
;
642 enum sim_stop
*reason
;
647 *reason
= sim_stopped
;
650 else if (state
->EndCondition
== 0)
652 *reason
= sim_exited
;
653 *sigrc
= state
->Reg
[0] & 255;
657 *reason
= sim_stopped
;
658 if (state
->EndCondition
== RDIError_BreakpointReached
)
666 sim_do_command (sd
, cmd
)
667 SIM_DESC sd ATTRIBUTE_UNUSED
;
668 char *cmd ATTRIBUTE_UNUSED
;
670 (*sim_callback
->printf_filtered
)
672 "This simulator does not accept any commands.\n");
676 sim_set_callbacks (ptr
)