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"
39 host_callback *sim_callback;
41 static struct ARMul_State *state;
43 /* Who is using the simulator. */
44 static SIM_OPEN_KIND sim_kind;
49 /* Memory size in bytes. */
50 static int mem_size = (1 << 21);
52 /* Non-zero to display start up banner, and maybe other things. */
55 /* Non-zero to set big endian mode. */
56 static int big_endian;
68 state = ARMul_NewState ();
69 state->bigendSig = (big_endian ? HIGH : LOW);
70 ARMul_MemoryInit (state, mem_size);
72 ARMul_CoProInit (state);
73 state->verbose = verbosity;
78 /* Set verbosity level of simulator.
79 This is not intended to produce detailed tracing or debugging information.
81 /* FIXME: common/run.c doesn't do this yet. */
90 /* Set the memory size to SIZE bytes.
91 Must be called before initializing simulator. */
92 /* FIXME: Rename to sim_set_mem_size. */
102 ARMul_ConsolePrint VPARAMS ((ARMul_State * state,
110 va_start (ap, format);
111 vprintf (format, ap);
117 ARMul_Debug (state, pc, instr)
118 ARMul_State * state ATTRIBUTE_UNUSED;
119 ARMword pc ATTRIBUTE_UNUSED;
120 ARMword instr ATTRIBUTE_UNUSED;
126 sim_write (sd, addr, buffer, size)
127 SIM_DESC sd ATTRIBUTE_UNUSED;
129 unsigned char * buffer;
136 for (i = 0; i < size; i++)
137 ARMul_SafeWriteByte (state, addr + i, buffer[i]);
143 sim_read (sd, addr, buffer, size)
144 SIM_DESC sd ATTRIBUTE_UNUSED;
146 unsigned char * buffer;
153 for (i = 0; i < size; i++)
154 buffer[i] = ARMul_SafeReadByte (state, addr + i);
161 SIM_DESC sd ATTRIBUTE_UNUSED;
163 (*sim_callback->printf_filtered)
165 "This simulator does not support tracing\n");
171 SIM_DESC sd ATTRIBUTE_UNUSED;
173 state->Emulate = STOP;
179 sim_resume (sd, step, siggnal)
180 SIM_DESC sd ATTRIBUTE_UNUSED;
182 int siggnal ATTRIBUTE_UNUSED;
184 state->EndCondition = 0;
189 state->Reg[15] = ARMul_DoInstr (state);
190 if (state->EndCondition == 0)
191 state->EndCondition = RDIError_BreakpointReached;
195 state->NextInstr = RESUME; /* treat as PC change */
196 state->Reg[15] = ARMul_DoProg (state);
203 sim_create_inferior (sd, abfd, argv, env)
204 SIM_DESC sd ATTRIBUTE_UNUSED;
214 ARMul_SetPC (state, bfd_get_start_address (abfd));
216 ARMul_SetPC (state, 0); /* ??? */
218 mach = bfd_get_mach (abfd);
223 (*sim_callback->printf_filtered)
225 "Unknown machine type; please update sim_create_inferior.\n");
229 /* We wouldn't set the machine type with earlier toolchains, so we
230 explicitly select a processor capable of supporting all ARMs in
232 case bfd_mach_arm_XScale:
233 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
237 /* This is a special case in order to support COFF based ARM toolchains.
238 The COFF header does not have enough room to store all the different
239 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
240 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
241 machine type here, we assume it could be any of the above architectures
242 and so select the most feature-full. */
243 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
246 case bfd_mach_arm_5T:
247 ARMul_SelectProcessor (state, ARM_v5_Prop);
250 case bfd_mach_arm_5TE:
251 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
255 case bfd_mach_arm_4T:
256 ARMul_SelectProcessor (state, ARM_v4_Prop);
260 case bfd_mach_arm_3M:
261 ARMul_SelectProcessor (state, ARM_Lock_Prop);
265 case bfd_mach_arm_2a:
266 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
270 if ( mach != bfd_mach_arm_3
271 && mach != bfd_mach_arm_3M
272 && mach != bfd_mach_arm_2
273 && mach != bfd_mach_arm_2a)
275 /* Reset mode to ARM. A gdb user may rerun a program that had entered
276 THUMB mode from the start and cause the ARM-mode startup code to be
277 executed in THUMB mode. */
278 ARMul_SetCPSR (state, SVC32MODE);
283 /* Set up the command line by laboriously stringing together
284 the environment carefully picked apart by our caller. */
286 /* Free any old stuff. */
287 if (state->CommandLine != NULL)
289 free (state->CommandLine);
290 state->CommandLine = NULL;
293 /* See how much we need. */
294 for (arg = argv; *arg != NULL; arg++)
295 argvlen += strlen (*arg) + 1;
298 state->CommandLine = malloc (argvlen + 1);
299 if (state->CommandLine != NULL)
302 state->CommandLine[0] = '\0';
304 for (arg = argv; *arg != NULL; arg++)
306 strcat (state->CommandLine, *arg);
307 strcat (state->CommandLine, " ");
314 /* Now see if there's a MEMSIZE spec in the environment. */
317 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
321 /* Set up memory limit. */
323 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
333 sim_info (sd, verbose)
334 SIM_DESC sd ATTRIBUTE_UNUSED;
335 int verbose ATTRIBUTE_UNUSED;
340 frommem (state, memory)
341 struct ARMul_State *state;
342 unsigned char *memory;
344 if (state->bigendSig == HIGH)
345 return (memory[0] << 24) | (memory[1] << 16)
346 | (memory[2] << 8) | (memory[3] << 0);
348 return (memory[3] << 24) | (memory[2] << 16)
349 | (memory[1] << 8) | (memory[0] << 0);
353 tomem (state, memory, val)
354 struct ARMul_State *state;
355 unsigned char *memory;
358 if (state->bigendSig == HIGH)
360 memory[0] = val >> 24;
361 memory[1] = val >> 16;
362 memory[2] = val >> 8;
363 memory[3] = val >> 0;
367 memory[3] = val >> 24;
368 memory[2] = val >> 16;
369 memory[1] = val >> 8;
370 memory[0] = val >> 0;
375 sim_store_register (sd, rn, memory, length)
376 SIM_DESC sd ATTRIBUTE_UNUSED;
378 unsigned char *memory;
379 int length ATTRIBUTE_UNUSED;
385 state->Cpsr = frommem (state, memory);
386 ARMul_CPSRAltered (state);
389 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
394 sim_fetch_register (sd, rn, memory, length)
395 SIM_DESC sd ATTRIBUTE_UNUSED;
397 unsigned char *memory;
398 int length ATTRIBUTE_UNUSED;
405 regval = ARMul_GetReg (state, state->Mode, rn);
407 /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h. */
408 regval = ARMul_GetCPSR (state);
410 /* FIXME: should report an error. */
415 tomem (state, memory, regval);
426 sim_open (kind, ptr, abfd, argv)
433 if (myname) free (myname);
434 myname = (char *) xstrdup (argv[0]);
437 /* Decide upon the endian-ness of the processor.
438 If we can, get the information from the bfd itself.
439 Otherwise look to see if we have been given a command
440 line switch that tells us. Otherwise default to little endian. */
442 big_endian = bfd_big_endian (abfd);
443 else if (argv[1] != NULL)
447 /* Scan for endian-ness switch. */
448 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
449 if (argv[i][0] == '-' && argv[i][1] == 'E')
453 if ((c = argv[i][2]) == 0)
462 sim_callback->printf_filtered
463 (sim_callback, "No argument to -E option provided\n");
477 sim_callback->printf_filtered
478 (sim_callback, "Unrecognised argument to -E option\n");
488 sim_close (sd, quitting)
489 SIM_DESC sd ATTRIBUTE_UNUSED;
490 int quitting ATTRIBUTE_UNUSED;
498 sim_load (sd, prog, abfd, from_tty)
502 int from_tty ATTRIBUTE_UNUSED;
506 prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
507 sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
508 if (prog_bfd == NULL)
510 ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
512 bfd_close (prog_bfd);
517 sim_stop_reason (sd, reason, sigrc)
518 SIM_DESC sd ATTRIBUTE_UNUSED;
519 enum sim_stop *reason;
524 *reason = sim_stopped;
527 else if (state->EndCondition == 0)
529 *reason = sim_exited;
530 *sigrc = state->Reg[0] & 255;
534 *reason = sim_stopped;
535 if (state->EndCondition == RDIError_BreakpointReached)
543 sim_do_command (sd, cmd)
544 SIM_DESC sd ATTRIBUTE_UNUSED;
545 char *cmd ATTRIBUTE_UNUSED;
547 (*sim_callback->printf_filtered)
549 "This simulator does not accept any commands.\n");
553 sim_set_callbacks (ptr)