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. */
32 #include "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; please update sim_create_inferior.\n");
230 /* We wouldn't set the machine type with earlier toolchains, so we
231 explicitly select a processor capable of supporting all ARMs in
233 case bfd_mach_arm_XScale:
234 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
238 if (bfd_family_coff (abfd))
240 /* This is a special case in order to support COFF based ARM toolchains.
241 The COFF header does not have enough room to store all the different
242 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
243 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
244 machine type here, we assume it could be any of the above architectures
245 and so select the most feature-full. */
246 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
249 /* Otherwise drop through. */
251 case bfd_mach_arm_5T:
252 ARMul_SelectProcessor (state, ARM_v5_Prop);
255 case bfd_mach_arm_5TE:
256 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
260 case bfd_mach_arm_4T:
261 ARMul_SelectProcessor (state, ARM_v4_Prop);
265 case bfd_mach_arm_3M:
266 ARMul_SelectProcessor (state, ARM_Lock_Prop);
270 case bfd_mach_arm_2a:
271 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
275 if ( mach != bfd_mach_arm_3
276 && mach != bfd_mach_arm_3M
277 && mach != bfd_mach_arm_2
278 && mach != bfd_mach_arm_2a)
280 /* Reset mode to ARM. A gdb user may rerun a program that had entered
281 THUMB mode from the start and cause the ARM-mode startup code to be
282 executed in THUMB mode. */
283 ARMul_SetCPSR (state, SVC32MODE);
288 /* Set up the command line by laboriously stringing together
289 the environment carefully picked apart by our caller. */
291 /* Free any old stuff. */
292 if (state->CommandLine != NULL)
294 free (state->CommandLine);
295 state->CommandLine = NULL;
298 /* See how much we need. */
299 for (arg = argv; *arg != NULL; arg++)
300 argvlen += strlen (*arg) + 1;
303 state->CommandLine = malloc (argvlen + 1);
304 if (state->CommandLine != NULL)
307 state->CommandLine[0] = '\0';
309 for (arg = argv; *arg != NULL; arg++)
311 strcat (state->CommandLine, *arg);
312 strcat (state->CommandLine, " ");
319 /* Now see if there's a MEMSIZE spec in the environment. */
322 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
326 /* Set up memory limit. */
328 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
338 sim_info (sd, verbose)
339 SIM_DESC sd ATTRIBUTE_UNUSED;
340 int verbose ATTRIBUTE_UNUSED;
345 frommem (state, memory)
346 struct ARMul_State *state;
347 unsigned char *memory;
349 if (state->bigendSig == HIGH)
350 return (memory[0] << 24) | (memory[1] << 16)
351 | (memory[2] << 8) | (memory[3] << 0);
353 return (memory[3] << 24) | (memory[2] << 16)
354 | (memory[1] << 8) | (memory[0] << 0);
358 tomem (state, memory, val)
359 struct ARMul_State *state;
360 unsigned char *memory;
363 if (state->bigendSig == HIGH)
365 memory[0] = val >> 24;
366 memory[1] = val >> 16;
367 memory[2] = val >> 8;
368 memory[3] = val >> 0;
372 memory[3] = val >> 24;
373 memory[2] = val >> 16;
374 memory[1] = val >> 8;
375 memory[0] = val >> 0;
380 sim_store_register (sd, rn, memory, length)
381 SIM_DESC sd ATTRIBUTE_UNUSED;
383 unsigned char *memory;
384 int length ATTRIBUTE_UNUSED;
390 state->Cpsr = frommem (state, memory);
391 ARMul_CPSRAltered (state);
394 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
399 sim_fetch_register (sd, rn, memory, length)
400 SIM_DESC sd ATTRIBUTE_UNUSED;
402 unsigned char *memory;
403 int length ATTRIBUTE_UNUSED;
410 regval = ARMul_GetReg (state, state->Mode, rn);
412 /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h. */
413 regval = ARMul_GetCPSR (state);
415 /* FIXME: should report an error. */
420 tomem (state, memory, regval);
430 #ifdef SIM_TARGET_SWITCHES
432 static void sim_target_parse_arg_array PARAMS ((char **));
437 unsigned int swi_mask;
440 #define SWI_SWITCH "--swi-support"
442 static swi_options options[] =
445 { "demon", SWI_MASK_DEMON },
446 { "angel", SWI_MASK_ANGEL },
447 { "redboot", SWI_MASK_REDBOOT },
450 { "DEMON", SWI_MASK_DEMON },
451 { "ANGEL", SWI_MASK_ANGEL },
452 { "REDBOOT", SWI_MASK_REDBOOT },
458 sim_target_parse_command_line (argc, argv)
464 for (i = 1; i < argc; i++)
466 char * ptr = argv[i];
469 if ((ptr == NULL) || (* ptr != '-'))
472 if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
475 if (ptr[sizeof SWI_SWITCH - 1] == 0)
477 /* Remove this option from the argv array. */
478 for (arg = i; arg < argc; arg ++)
479 argv[arg] = argv[arg + 1];
485 ptr += sizeof SWI_SWITCH;
493 for (i = sizeof options / sizeof options[0]; i--;)
494 if (strncmp (ptr, options[i].swi_option,
495 strlen (options[i].swi_option)) == 0)
497 swi_mask |= options[i].swi_mask;
498 ptr += strlen (options[i].swi_option);
511 fprintf (stderr, "Ignoring swi options: %s\n", ptr);
513 /* Remove this option from the argv array. */
514 for (arg = i; arg < argc; arg ++)
515 argv[arg] = argv[arg + 1];
523 sim_target_parse_arg_array (argv)
528 for (i = 0; argv[i]; i++)
531 return (void) sim_target_parse_command_line (i, argv);
535 sim_target_display_usage ()
537 fprintf (stderr, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
538 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
544 sim_open (kind, ptr, abfd, argv)
551 if (myname) free (myname);
552 myname = (char *) xstrdup (argv[0]);
555 #ifdef SIM_TARGET_SWITCHES
556 sim_target_parse_arg_array (argv);
559 /* Decide upon the endian-ness of the processor.
560 If we can, get the information from the bfd itself.
561 Otherwise look to see if we have been given a command
562 line switch that tells us. Otherwise default to little endian. */
564 big_endian = bfd_big_endian (abfd);
565 else if (argv[1] != NULL)
569 /* Scan for endian-ness switch. */
570 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
571 if (argv[i][0] == '-' && argv[i][1] == 'E')
575 if ((c = argv[i][2]) == 0)
584 sim_callback->printf_filtered
585 (sim_callback, "No argument to -E option provided\n");
599 sim_callback->printf_filtered
600 (sim_callback, "Unrecognised argument to -E option\n");
610 sim_close (sd, quitting)
611 SIM_DESC sd ATTRIBUTE_UNUSED;
612 int quitting ATTRIBUTE_UNUSED;
620 sim_load (sd, prog, abfd, from_tty)
624 int from_tty ATTRIBUTE_UNUSED;
628 prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
629 sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
630 if (prog_bfd == NULL)
632 ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
634 bfd_close (prog_bfd);
639 sim_stop_reason (sd, reason, sigrc)
640 SIM_DESC sd ATTRIBUTE_UNUSED;
641 enum sim_stop *reason;
646 *reason = sim_stopped;
649 else if (state->EndCondition == 0)
651 *reason = sim_exited;
652 *sigrc = state->Reg[0] & 255;
656 *reason = sim_stopped;
657 if (state->EndCondition == RDIError_BreakpointReached)
665 sim_do_command (sd, cmd)
666 SIM_DESC sd ATTRIBUTE_UNUSED;
667 char *cmd ATTRIBUTE_UNUSED;
669 (*sim_callback->printf_filtered)
671 "This simulator does not accept any commands.\n");
675 sim_set_callbacks (ptr)