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"
39 #include "gdb/sim-arm.h"
41 host_callback
*sim_callback
;
43 static struct ARMul_State
*state
;
45 /* Who is using the simulator. */
46 static SIM_OPEN_KIND sim_kind
;
51 /* Memory size in bytes. */
52 static int mem_size
= (1 << 21);
54 /* Non-zero to display start up banner, and maybe other things. */
57 /* Non-zero to set big endian mode. */
58 static int big_endian
;
62 /* Cirrus DSP registers.
64 We need to define these registers outside of maverick.c because
65 maverick.c might not be linked in unless --target=arm9e-* in which
66 case wrapper.c will not compile because it tries to access Cirrus
67 registers. This should all go away once we get the Cirrus and ARM
68 Coprocessor to coexist in armcopro.c-- aldyh. */
85 union maverick_acc_regs
87 long double ld
; /* Acc registers are 72-bits. */
90 struct maverick_regs DSPregs
[16];
91 union maverick_acc_regs DSPacc
[4];
101 ARMul_EmulateInit ();
102 state
= ARMul_NewState ();
103 state
->bigendSig
= (big_endian
? HIGH
: LOW
);
104 ARMul_MemoryInit (state
, mem_size
);
105 ARMul_OSInit (state
);
106 state
->verbose
= verbosity
;
111 /* Set verbosity level of simulator.
112 This is not intended to produce detailed tracing or debugging information.
114 /* FIXME: common/run.c doesn't do this yet. */
123 /* Set the memory size to SIZE bytes.
124 Must be called before initializing simulator. */
125 /* FIXME: Rename to sim_set_mem_size. */
135 ARMul_ConsolePrint
VPARAMS ((ARMul_State
* state
,
143 va_start (ap
, format
);
144 vprintf (format
, ap
);
150 ARMul_Debug (state
, pc
, instr
)
151 ARMul_State
* state ATTRIBUTE_UNUSED
;
152 ARMword pc ATTRIBUTE_UNUSED
;
153 ARMword instr ATTRIBUTE_UNUSED
;
159 sim_write (sd
, addr
, buffer
, size
)
160 SIM_DESC sd ATTRIBUTE_UNUSED
;
162 unsigned char * buffer
;
169 for (i
= 0; i
< size
; i
++)
170 ARMul_SafeWriteByte (state
, addr
+ i
, buffer
[i
]);
176 sim_read (sd
, addr
, buffer
, size
)
177 SIM_DESC sd ATTRIBUTE_UNUSED
;
179 unsigned char * buffer
;
186 for (i
= 0; i
< size
; i
++)
187 buffer
[i
] = ARMul_SafeReadByte (state
, addr
+ i
);
194 SIM_DESC sd ATTRIBUTE_UNUSED
;
196 (*sim_callback
->printf_filtered
)
198 "This simulator does not support tracing\n");
204 SIM_DESC sd ATTRIBUTE_UNUSED
;
206 state
->Emulate
= STOP
;
212 sim_resume (sd
, step
, siggnal
)
213 SIM_DESC sd ATTRIBUTE_UNUSED
;
215 int siggnal ATTRIBUTE_UNUSED
;
217 state
->EndCondition
= 0;
222 state
->Reg
[15] = ARMul_DoInstr (state
);
223 if (state
->EndCondition
== 0)
224 state
->EndCondition
= RDIError_BreakpointReached
;
228 state
->NextInstr
= RESUME
; /* treat as PC change */
229 state
->Reg
[15] = ARMul_DoProg (state
);
236 sim_create_inferior (sd
, abfd
, argv
, env
)
237 SIM_DESC sd ATTRIBUTE_UNUSED
;
247 ARMul_SetPC (state
, bfd_get_start_address (abfd
));
249 ARMul_SetPC (state
, 0); /* ??? */
251 mach
= bfd_get_mach (abfd
);
256 (*sim_callback
->printf_filtered
)
258 "Unknown machine type '%d'; please update sim_create_inferior.\n",
263 /* We wouldn't set the machine type with earlier toolchains, so we
264 explicitly select a processor capable of supporting all ARMs in
266 case bfd_mach_arm_XScale
:
267 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
| ARM_XScale_Prop
);
270 case bfd_mach_arm_ep9312
:
271 ARMul_SelectProcessor (state
, ARM_v4_Prop
| ARM_ep9312_Prop
);
275 if (bfd_family_coff (abfd
))
277 /* This is a special case in order to support COFF based ARM toolchains.
278 The COFF header does not have enough room to store all the different
279 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
280 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
281 machine type here, we assume it could be any of the above architectures
282 and so select the most feature-full. */
283 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
| ARM_XScale_Prop
);
286 /* Otherwise drop through. */
288 case bfd_mach_arm_5T
:
289 ARMul_SelectProcessor (state
, ARM_v5_Prop
);
292 case bfd_mach_arm_5TE
:
293 ARMul_SelectProcessor (state
, ARM_v5_Prop
| ARM_v5e_Prop
);
297 case bfd_mach_arm_4T
:
298 ARMul_SelectProcessor (state
, ARM_v4_Prop
);
302 case bfd_mach_arm_3M
:
303 ARMul_SelectProcessor (state
, ARM_Lock_Prop
);
307 case bfd_mach_arm_2a
:
308 ARMul_SelectProcessor (state
, ARM_Fix26_Prop
);
312 if ( mach
!= bfd_mach_arm_3
313 && mach
!= bfd_mach_arm_3M
314 && mach
!= bfd_mach_arm_2
315 && mach
!= bfd_mach_arm_2a
)
317 /* Reset mode to ARM. A gdb user may rerun a program that had entered
318 THUMB mode from the start and cause the ARM-mode startup code to be
319 executed in THUMB mode. */
320 ARMul_SetCPSR (state
, SVC32MODE
);
325 /* Set up the command line by laboriously stringing together
326 the environment carefully picked apart by our caller. */
328 /* Free any old stuff. */
329 if (state
->CommandLine
!= NULL
)
331 free (state
->CommandLine
);
332 state
->CommandLine
= NULL
;
335 /* See how much we need. */
336 for (arg
= argv
; *arg
!= NULL
; arg
++)
337 argvlen
+= strlen (*arg
) + 1;
340 state
->CommandLine
= malloc (argvlen
+ 1);
341 if (state
->CommandLine
!= NULL
)
344 state
->CommandLine
[0] = '\0';
346 for (arg
= argv
; *arg
!= NULL
; arg
++)
348 strcat (state
->CommandLine
, *arg
);
349 strcat (state
->CommandLine
, " ");
356 /* Now see if there's a MEMSIZE spec in the environment. */
359 if (strncmp (*env
, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
363 /* Set up memory limit. */
365 strtoul (*env
+ sizeof ("MEMSIZE=") - 1, &end_of_num
, 0);
375 sim_info (sd
, verbose
)
376 SIM_DESC sd ATTRIBUTE_UNUSED
;
377 int verbose ATTRIBUTE_UNUSED
;
382 frommem (state
, memory
)
383 struct ARMul_State
*state
;
384 unsigned char *memory
;
386 if (state
->bigendSig
== HIGH
)
387 return (memory
[0] << 24) | (memory
[1] << 16)
388 | (memory
[2] << 8) | (memory
[3] << 0);
390 return (memory
[3] << 24) | (memory
[2] << 16)
391 | (memory
[1] << 8) | (memory
[0] << 0);
395 tomem (state
, memory
, val
)
396 struct ARMul_State
*state
;
397 unsigned char *memory
;
400 if (state
->bigendSig
== HIGH
)
402 memory
[0] = val
>> 24;
403 memory
[1] = val
>> 16;
404 memory
[2] = val
>> 8;
405 memory
[3] = val
>> 0;
409 memory
[3] = val
>> 24;
410 memory
[2] = val
>> 16;
411 memory
[1] = val
>> 8;
412 memory
[0] = val
>> 0;
417 sim_store_register (sd
, rn
, memory
, length
)
418 SIM_DESC sd ATTRIBUTE_UNUSED
;
420 unsigned char *memory
;
421 int length ATTRIBUTE_UNUSED
;
425 switch ((enum sim_arm_regs
) rn
)
427 case SIM_ARM_R0_REGNUM
:
428 case SIM_ARM_R1_REGNUM
:
429 case SIM_ARM_R2_REGNUM
:
430 case SIM_ARM_R3_REGNUM
:
431 case SIM_ARM_R4_REGNUM
:
432 case SIM_ARM_R5_REGNUM
:
433 case SIM_ARM_R6_REGNUM
:
434 case SIM_ARM_R7_REGNUM
:
435 case SIM_ARM_R8_REGNUM
:
436 case SIM_ARM_R9_REGNUM
:
437 case SIM_ARM_R10_REGNUM
:
438 case SIM_ARM_R11_REGNUM
:
439 case SIM_ARM_R12_REGNUM
:
440 case SIM_ARM_R13_REGNUM
:
441 case SIM_ARM_R14_REGNUM
:
442 case SIM_ARM_R15_REGNUM
: /* PC */
443 case SIM_ARM_FP0_REGNUM
:
444 case SIM_ARM_FP1_REGNUM
:
445 case SIM_ARM_FP2_REGNUM
:
446 case SIM_ARM_FP3_REGNUM
:
447 case SIM_ARM_FP4_REGNUM
:
448 case SIM_ARM_FP5_REGNUM
:
449 case SIM_ARM_FP6_REGNUM
:
450 case SIM_ARM_FP7_REGNUM
:
451 case SIM_ARM_FPS_REGNUM
:
452 ARMul_SetReg (state
, state
->Mode
, rn
, frommem (state
, memory
));
455 case SIM_ARM_PS_REGNUM
:
456 state
->Cpsr
= frommem (state
, memory
);
457 ARMul_CPSRAltered (state
);
460 case SIM_ARM_MAVERIC_COP0R0_REGNUM
:
461 case SIM_ARM_MAVERIC_COP0R1_REGNUM
:
462 case SIM_ARM_MAVERIC_COP0R2_REGNUM
:
463 case SIM_ARM_MAVERIC_COP0R3_REGNUM
:
464 case SIM_ARM_MAVERIC_COP0R4_REGNUM
:
465 case SIM_ARM_MAVERIC_COP0R5_REGNUM
:
466 case SIM_ARM_MAVERIC_COP0R6_REGNUM
:
467 case SIM_ARM_MAVERIC_COP0R7_REGNUM
:
468 case SIM_ARM_MAVERIC_COP0R8_REGNUM
:
469 case SIM_ARM_MAVERIC_COP0R9_REGNUM
:
470 case SIM_ARM_MAVERIC_COP0R10_REGNUM
:
471 case SIM_ARM_MAVERIC_COP0R11_REGNUM
:
472 case SIM_ARM_MAVERIC_COP0R12_REGNUM
:
473 case SIM_ARM_MAVERIC_COP0R13_REGNUM
:
474 case SIM_ARM_MAVERIC_COP0R14_REGNUM
:
475 case SIM_ARM_MAVERIC_COP0R15_REGNUM
:
476 memcpy (& DSPregs
[rn
- SIM_ARM_MAVERIC_COP0R0_REGNUM
],
477 memory
, sizeof (struct maverick_regs
));
478 return sizeof (struct maverick_regs
);
480 case SIM_ARM_MAVERIC_DSPSC_REGNUM
:
481 memcpy (&DSPsc
, memory
, sizeof DSPsc
);
492 sim_fetch_register (sd
, rn
, memory
, length
)
493 SIM_DESC sd ATTRIBUTE_UNUSED
;
495 unsigned char *memory
;
496 int length ATTRIBUTE_UNUSED
;
502 switch ((enum sim_arm_regs
) rn
)
504 case SIM_ARM_R0_REGNUM
:
505 case SIM_ARM_R1_REGNUM
:
506 case SIM_ARM_R2_REGNUM
:
507 case SIM_ARM_R3_REGNUM
:
508 case SIM_ARM_R4_REGNUM
:
509 case SIM_ARM_R5_REGNUM
:
510 case SIM_ARM_R6_REGNUM
:
511 case SIM_ARM_R7_REGNUM
:
512 case SIM_ARM_R8_REGNUM
:
513 case SIM_ARM_R9_REGNUM
:
514 case SIM_ARM_R10_REGNUM
:
515 case SIM_ARM_R11_REGNUM
:
516 case SIM_ARM_R12_REGNUM
:
517 case SIM_ARM_R13_REGNUM
:
518 case SIM_ARM_R14_REGNUM
:
519 case SIM_ARM_R15_REGNUM
: /* PC */
520 regval
= ARMul_GetReg (state
, state
->Mode
, rn
);
523 case SIM_ARM_FP0_REGNUM
:
524 case SIM_ARM_FP1_REGNUM
:
525 case SIM_ARM_FP2_REGNUM
:
526 case SIM_ARM_FP3_REGNUM
:
527 case SIM_ARM_FP4_REGNUM
:
528 case SIM_ARM_FP5_REGNUM
:
529 case SIM_ARM_FP6_REGNUM
:
530 case SIM_ARM_FP7_REGNUM
:
531 case SIM_ARM_FPS_REGNUM
:
532 memset (memory
, 0, length
);
535 case SIM_ARM_PS_REGNUM
:
536 regval
= ARMul_GetCPSR (state
);
539 case SIM_ARM_MAVERIC_COP0R0_REGNUM
:
540 case SIM_ARM_MAVERIC_COP0R1_REGNUM
:
541 case SIM_ARM_MAVERIC_COP0R2_REGNUM
:
542 case SIM_ARM_MAVERIC_COP0R3_REGNUM
:
543 case SIM_ARM_MAVERIC_COP0R4_REGNUM
:
544 case SIM_ARM_MAVERIC_COP0R5_REGNUM
:
545 case SIM_ARM_MAVERIC_COP0R6_REGNUM
:
546 case SIM_ARM_MAVERIC_COP0R7_REGNUM
:
547 case SIM_ARM_MAVERIC_COP0R8_REGNUM
:
548 case SIM_ARM_MAVERIC_COP0R9_REGNUM
:
549 case SIM_ARM_MAVERIC_COP0R10_REGNUM
:
550 case SIM_ARM_MAVERIC_COP0R11_REGNUM
:
551 case SIM_ARM_MAVERIC_COP0R12_REGNUM
:
552 case SIM_ARM_MAVERIC_COP0R13_REGNUM
:
553 case SIM_ARM_MAVERIC_COP0R14_REGNUM
:
554 case SIM_ARM_MAVERIC_COP0R15_REGNUM
:
555 memcpy (memory
, & DSPregs
[rn
- SIM_ARM_MAVERIC_COP0R0_REGNUM
],
556 sizeof (struct maverick_regs
));
557 return sizeof (struct maverick_regs
);
559 case SIM_ARM_MAVERIC_DSPSC_REGNUM
:
560 memcpy (memory
, & DSPsc
, sizeof DSPsc
);
569 tomem (state
, memory
, regval
);
579 #ifdef SIM_TARGET_SWITCHES
581 static void sim_target_parse_arg_array
PARAMS ((char **));
586 unsigned int swi_mask
;
589 #define SWI_SWITCH "--swi-support"
591 static swi_options options
[] =
594 { "demon", SWI_MASK_DEMON
},
595 { "angel", SWI_MASK_ANGEL
},
596 { "redboot", SWI_MASK_REDBOOT
},
599 { "DEMON", SWI_MASK_DEMON
},
600 { "ANGEL", SWI_MASK_ANGEL
},
601 { "REDBOOT", SWI_MASK_REDBOOT
},
607 sim_target_parse_command_line (argc
, argv
)
613 for (i
= 1; i
< argc
; i
++)
615 char * ptr
= argv
[i
];
618 if ((ptr
== NULL
) || (* ptr
!= '-'))
621 if (strncmp (ptr
, SWI_SWITCH
, sizeof SWI_SWITCH
- 1) != 0)
624 if (ptr
[sizeof SWI_SWITCH
- 1] == 0)
626 /* Remove this option from the argv array. */
627 for (arg
= i
; arg
< argc
; arg
++)
628 argv
[arg
] = argv
[arg
+ 1];
634 ptr
+= sizeof SWI_SWITCH
;
642 for (i
= sizeof options
/ sizeof options
[0]; i
--;)
643 if (strncmp (ptr
, options
[i
].swi_option
,
644 strlen (options
[i
].swi_option
)) == 0)
646 swi_mask
|= options
[i
].swi_mask
;
647 ptr
+= strlen (options
[i
].swi_option
);
660 fprintf (stderr
, "Ignoring swi options: %s\n", ptr
);
662 /* Remove this option from the argv array. */
663 for (arg
= i
; arg
< argc
; arg
++)
664 argv
[arg
] = argv
[arg
+ 1];
672 sim_target_parse_arg_array (argv
)
677 for (i
= 0; argv
[i
]; i
++)
680 return (void) sim_target_parse_command_line (i
, argv
);
684 sim_target_display_usage ()
686 fprintf (stderr
, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
687 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
693 sim_open (kind
, ptr
, abfd
, argv
)
700 if (myname
) free (myname
);
701 myname
= (char *) xstrdup (argv
[0]);
704 #ifdef SIM_TARGET_SWITCHES
705 sim_target_parse_arg_array (argv
);
708 /* Decide upon the endian-ness of the processor.
709 If we can, get the information from the bfd itself.
710 Otherwise look to see if we have been given a command
711 line switch that tells us. Otherwise default to little endian. */
713 big_endian
= bfd_big_endian (abfd
);
714 else if (argv
[1] != NULL
)
718 /* Scan for endian-ness and memory-size switches. */
719 for (i
= 0; (argv
[i
] != NULL
) && (argv
[i
][0] != 0); i
++)
720 if (argv
[i
][0] == '-' && argv
[i
][1] == 'E')
724 if ((c
= argv
[i
][2]) == 0)
733 sim_callback
->printf_filtered
734 (sim_callback
, "No argument to -E option provided\n");
748 sim_callback
->printf_filtered
749 (sim_callback
, "Unrecognised argument to -E option\n");
753 else if (argv
[i
][0] == '-' && argv
[i
][1] == 'm')
755 if (argv
[i
][2] != '\0')
756 sim_size (atoi (&argv
[i
][2]));
757 else if (argv
[i
+ 1] != NULL
)
759 sim_size (atoi (argv
[i
+ 1]));
764 sim_callback
->printf_filtered (sim_callback
,
765 "Missing argument to -m option\n");
776 sim_close (sd
, quitting
)
777 SIM_DESC sd ATTRIBUTE_UNUSED
;
778 int quitting ATTRIBUTE_UNUSED
;
786 sim_load (sd
, prog
, abfd
, from_tty
)
790 int from_tty ATTRIBUTE_UNUSED
;
794 prog_bfd
= sim_load_file (sd
, myname
, sim_callback
, prog
, abfd
,
795 sim_kind
== SIM_OPEN_DEBUG
, 0, sim_write
);
796 if (prog_bfd
== NULL
)
798 ARMul_SetPC (state
, bfd_get_start_address (prog_bfd
));
800 bfd_close (prog_bfd
);
805 sim_stop_reason (sd
, reason
, sigrc
)
806 SIM_DESC sd ATTRIBUTE_UNUSED
;
807 enum sim_stop
*reason
;
812 *reason
= sim_stopped
;
815 else if (state
->EndCondition
== 0)
817 *reason
= sim_exited
;
818 *sigrc
= state
->Reg
[0] & 255;
822 *reason
= sim_stopped
;
823 if (state
->EndCondition
== RDIError_BreakpointReached
)
831 sim_do_command (sd
, cmd
)
832 SIM_DESC sd ATTRIBUTE_UNUSED
;
833 char *cmd ATTRIBUTE_UNUSED
;
835 (*sim_callback
->printf_filtered
)
837 "This simulator does not accept any commands.\n");
841 sim_set_callbacks (ptr
)