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 << 23);
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;
70 state = ARMul_NewState ();
71 state->bigendSig = (big_endian ? HIGH : LOW);
72 ARMul_MemoryInit (state, mem_size);
74 ARMul_CoProInit (state);
75 state->verbose = verbosity;
80 /* Set verbosity level of simulator.
81 This is not intended to produce detailed tracing or debugging information.
83 /* FIXME: common/run.c doesn't do this yet. */
92 /* Set the memory size to SIZE bytes.
93 Must be called before initializing simulator. */
94 /* FIXME: Rename to sim_set_mem_size. */
104 ARMul_ConsolePrint VPARAMS ((ARMul_State * state,
112 va_start (ap, format);
113 vprintf (format, ap);
119 ARMul_Debug (state, pc, instr)
120 ARMul_State * state ATTRIBUTE_UNUSED;
121 ARMword pc ATTRIBUTE_UNUSED;
122 ARMword instr ATTRIBUTE_UNUSED;
128 sim_write (sd, addr, buffer, size)
129 SIM_DESC sd ATTRIBUTE_UNUSED;
131 unsigned char * buffer;
138 for (i = 0; i < size; i++)
139 ARMul_SafeWriteByte (state, addr + i, buffer[i]);
145 sim_read (sd, addr, buffer, size)
146 SIM_DESC sd ATTRIBUTE_UNUSED;
148 unsigned char * buffer;
155 for (i = 0; i < size; i++)
156 buffer[i] = ARMul_SafeReadByte (state, addr + i);
163 SIM_DESC sd ATTRIBUTE_UNUSED;
165 (*sim_callback->printf_filtered)
167 "This simulator does not support tracing\n");
173 SIM_DESC sd ATTRIBUTE_UNUSED;
175 state->Emulate = STOP;
181 sim_resume (sd, step, siggnal)
182 SIM_DESC sd ATTRIBUTE_UNUSED;
184 int siggnal ATTRIBUTE_UNUSED;
186 state->EndCondition = 0;
191 state->Reg[15] = ARMul_DoInstr (state);
192 if (state->EndCondition == 0)
193 state->EndCondition = RDIError_BreakpointReached;
197 state->NextInstr = RESUME; /* treat as PC change */
198 state->Reg[15] = ARMul_DoProg (state);
205 sim_create_inferior (sd, abfd, argv, env)
206 SIM_DESC sd ATTRIBUTE_UNUSED;
216 ARMul_SetPC (state, bfd_get_start_address (abfd));
218 ARMul_SetPC (state, 0); /* ??? */
220 mach = bfd_get_mach (abfd);
225 (*sim_callback->printf_filtered)
227 "Unknown machine type '%d'; please update sim_create_inferior.\n",
232 /* We wouldn't set the machine type with earlier toolchains, so we
233 explicitly select a processor capable of supporting all ARMs in
235 case bfd_mach_arm_XScale:
236 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
240 if (bfd_family_coff (abfd))
242 /* This is a special case in order to support COFF based ARM toolchains.
243 The COFF header does not have enough room to store all the different
244 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
245 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
246 machine type here, we assume it could be any of the above architectures
247 and so select the most feature-full. */
248 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
251 /* Otherwise drop through. */
253 case bfd_mach_arm_5T:
254 ARMul_SelectProcessor (state, ARM_v5_Prop);
257 case bfd_mach_arm_5TE:
258 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
262 case bfd_mach_arm_4T:
263 ARMul_SelectProcessor (state, ARM_v4_Prop);
267 case bfd_mach_arm_3M:
268 ARMul_SelectProcessor (state, ARM_Lock_Prop);
272 case bfd_mach_arm_2a:
273 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
277 if ( mach != bfd_mach_arm_3
278 && mach != bfd_mach_arm_3M
279 && mach != bfd_mach_arm_2
280 && mach != bfd_mach_arm_2a)
282 /* Reset mode to ARM. A gdb user may rerun a program that had entered
283 THUMB mode from the start and cause the ARM-mode startup code to be
284 executed in THUMB mode. */
285 ARMul_SetCPSR (state, SVC32MODE);
290 /* Set up the command line by laboriously stringing together
291 the environment carefully picked apart by our caller. */
293 /* Free any old stuff. */
294 if (state->CommandLine != NULL)
296 free (state->CommandLine);
297 state->CommandLine = NULL;
300 /* See how much we need. */
301 for (arg = argv; *arg != NULL; arg++)
302 argvlen += strlen (*arg) + 1;
305 state->CommandLine = malloc (argvlen + 1);
306 if (state->CommandLine != NULL)
309 state->CommandLine[0] = '\0';
311 for (arg = argv; *arg != NULL; arg++)
313 strcat (state->CommandLine, *arg);
314 strcat (state->CommandLine, " ");
321 /* Now see if there's a MEMSIZE spec in the environment. */
324 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
328 /* Set up memory limit. */
330 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
340 sim_info (sd, verbose)
341 SIM_DESC sd ATTRIBUTE_UNUSED;
342 int verbose ATTRIBUTE_UNUSED;
347 frommem (state, memory)
348 struct ARMul_State *state;
349 unsigned char *memory;
351 if (state->bigendSig == HIGH)
352 return (memory[0] << 24) | (memory[1] << 16)
353 | (memory[2] << 8) | (memory[3] << 0);
355 return (memory[3] << 24) | (memory[2] << 16)
356 | (memory[1] << 8) | (memory[0] << 0);
360 tomem (state, memory, val)
361 struct ARMul_State *state;
362 unsigned char *memory;
365 if (state->bigendSig == HIGH)
367 memory[0] = val >> 24;
368 memory[1] = val >> 16;
369 memory[2] = val >> 8;
370 memory[3] = val >> 0;
374 memory[3] = val >> 24;
375 memory[2] = val >> 16;
376 memory[1] = val >> 8;
377 memory[0] = val >> 0;
382 sim_store_register (sd, rn, memory, length)
383 SIM_DESC sd ATTRIBUTE_UNUSED;
385 unsigned char *memory;
386 int length ATTRIBUTE_UNUSED;
390 switch ((enum sim_arm_regs) rn)
392 case SIM_ARM_R0_REGNUM:
393 case SIM_ARM_R1_REGNUM:
394 case SIM_ARM_R2_REGNUM:
395 case SIM_ARM_R3_REGNUM:
396 case SIM_ARM_R4_REGNUM:
397 case SIM_ARM_R5_REGNUM:
398 case SIM_ARM_R6_REGNUM:
399 case SIM_ARM_R7_REGNUM:
400 case SIM_ARM_R8_REGNUM:
401 case SIM_ARM_R9_REGNUM:
402 case SIM_ARM_R10_REGNUM:
403 case SIM_ARM_R11_REGNUM:
404 case SIM_ARM_R12_REGNUM:
405 case SIM_ARM_R13_REGNUM:
406 case SIM_ARM_R14_REGNUM:
407 case SIM_ARM_R15_REGNUM: /* PC */
408 case SIM_ARM_FP0_REGNUM:
409 case SIM_ARM_FP1_REGNUM:
410 case SIM_ARM_FP2_REGNUM:
411 case SIM_ARM_FP3_REGNUM:
412 case SIM_ARM_FP4_REGNUM:
413 case SIM_ARM_FP5_REGNUM:
414 case SIM_ARM_FP6_REGNUM:
415 case SIM_ARM_FP7_REGNUM:
416 case SIM_ARM_FPS_REGNUM:
417 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
420 case SIM_ARM_PS_REGNUM:
421 state->Cpsr = frommem (state, memory);
422 ARMul_CPSRAltered (state);
433 sim_fetch_register (sd, rn, memory, length)
434 SIM_DESC sd ATTRIBUTE_UNUSED;
436 unsigned char *memory;
437 int length ATTRIBUTE_UNUSED;
443 switch ((enum sim_arm_regs) rn)
445 case SIM_ARM_R0_REGNUM:
446 case SIM_ARM_R1_REGNUM:
447 case SIM_ARM_R2_REGNUM:
448 case SIM_ARM_R3_REGNUM:
449 case SIM_ARM_R4_REGNUM:
450 case SIM_ARM_R5_REGNUM:
451 case SIM_ARM_R6_REGNUM:
452 case SIM_ARM_R7_REGNUM:
453 case SIM_ARM_R8_REGNUM:
454 case SIM_ARM_R9_REGNUM:
455 case SIM_ARM_R10_REGNUM:
456 case SIM_ARM_R11_REGNUM:
457 case SIM_ARM_R12_REGNUM:
458 case SIM_ARM_R13_REGNUM:
459 case SIM_ARM_R14_REGNUM:
460 case SIM_ARM_R15_REGNUM: /* PC */
461 regval = ARMul_GetReg (state, state->Mode, rn);
464 case SIM_ARM_FP0_REGNUM:
465 case SIM_ARM_FP1_REGNUM:
466 case SIM_ARM_FP2_REGNUM:
467 case SIM_ARM_FP3_REGNUM:
468 case SIM_ARM_FP4_REGNUM:
469 case SIM_ARM_FP5_REGNUM:
470 case SIM_ARM_FP6_REGNUM:
471 case SIM_ARM_FP7_REGNUM:
472 case SIM_ARM_FPS_REGNUM:
473 memset (memory, 0, length);
476 case SIM_ARM_PS_REGNUM:
477 regval = ARMul_GetCPSR (state);
486 tomem (state, memory, regval);
496 #ifdef SIM_TARGET_SWITCHES
498 static void sim_target_parse_arg_array PARAMS ((char **));
503 unsigned int swi_mask;
506 #define SWI_SWITCH "--swi-support"
508 static swi_options options[] =
511 { "demon", SWI_MASK_DEMON },
512 { "angel", SWI_MASK_ANGEL },
513 { "redboot", SWI_MASK_REDBOOT },
516 { "DEMON", SWI_MASK_DEMON },
517 { "ANGEL", SWI_MASK_ANGEL },
518 { "REDBOOT", SWI_MASK_REDBOOT },
524 sim_target_parse_command_line (argc, argv)
530 for (i = 1; i < argc; i++)
532 char * ptr = argv[i];
535 if ((ptr == NULL) || (* ptr != '-'))
538 if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
541 if (ptr[sizeof SWI_SWITCH - 1] == 0)
543 /* Remove this option from the argv array. */
544 for (arg = i; arg < argc; arg ++)
545 argv[arg] = argv[arg + 1];
551 ptr += sizeof SWI_SWITCH;
559 for (i = sizeof options / sizeof options[0]; i--;)
560 if (strncmp (ptr, options[i].swi_option,
561 strlen (options[i].swi_option)) == 0)
563 swi_mask |= options[i].swi_mask;
564 ptr += strlen (options[i].swi_option);
577 fprintf (stderr, "Ignoring swi options: %s\n", ptr);
579 /* Remove this option from the argv array. */
580 for (arg = i; arg < argc; arg ++)
581 argv[arg] = argv[arg + 1];
589 sim_target_parse_arg_array (argv)
594 for (i = 0; argv[i]; i++)
597 return (void) sim_target_parse_command_line (i, argv);
601 sim_target_display_usage ()
603 fprintf (stderr, "%s=<list> Comma seperated list of SWI protocols to supoport.\n\
604 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
610 sim_open (kind, ptr, abfd, argv)
617 if (myname) free (myname);
618 myname = (char *) xstrdup (argv[0]);
621 #ifdef SIM_TARGET_SWITCHES
622 sim_target_parse_arg_array (argv);
625 /* Decide upon the endian-ness of the processor.
626 If we can, get the information from the bfd itself.
627 Otherwise look to see if we have been given a command
628 line switch that tells us. Otherwise default to little endian. */
630 big_endian = bfd_big_endian (abfd);
631 else if (argv[1] != NULL)
635 /* Scan for endian-ness switch. */
636 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
637 if (argv[i][0] == '-' && argv[i][1] == 'E')
641 if ((c = argv[i][2]) == 0)
650 sim_callback->printf_filtered
651 (sim_callback, "No argument to -E option provided\n");
665 sim_callback->printf_filtered
666 (sim_callback, "Unrecognised argument to -E option\n");
676 sim_close (sd, quitting)
677 SIM_DESC sd ATTRIBUTE_UNUSED;
678 int quitting ATTRIBUTE_UNUSED;
686 sim_load (sd, prog, abfd, from_tty)
690 int from_tty ATTRIBUTE_UNUSED;
694 prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
695 sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
696 if (prog_bfd == NULL)
698 ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
700 bfd_close (prog_bfd);
705 sim_stop_reason (sd, reason, sigrc)
706 SIM_DESC sd ATTRIBUTE_UNUSED;
707 enum sim_stop *reason;
712 *reason = sim_stopped;
715 else if (state->EndCondition == 0)
717 *reason = sim_exited;
718 *sigrc = state->Reg[0] & 255;
722 *reason = sim_stopped;
723 if (state->EndCondition == RDIError_BreakpointReached)
731 sim_do_command (sd, cmd)
732 SIM_DESC sd ATTRIBUTE_UNUSED;
733 char *cmd ATTRIBUTE_UNUSED;
735 (*sim_callback->printf_filtered)
737 "This simulator does not accept any commands.\n");
741 sim_set_callbacks (ptr)