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 << 23);
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 if (bfd_family_coff (abfd))
239 /* This is a special case in order to support COFF based ARM toolchains.
240 The COFF header does not have enough room to store all the different
241 kinds of ARM cpu, so the XScale, v5T and v5TE architectures all default
242 to v5. (See coff_set_flags() in bdf/coffcode.h). So if we see a v5
243 machine type here, we assume it could be any of the above architectures
244 and so select the most feature-full. */
245 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop);
248 /* Otherwise drop through. */
250 case bfd_mach_arm_5T:
251 ARMul_SelectProcessor (state, ARM_v5_Prop);
254 case bfd_mach_arm_5TE:
255 ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop);
259 case bfd_mach_arm_4T:
260 ARMul_SelectProcessor (state, ARM_v4_Prop);
264 case bfd_mach_arm_3M:
265 ARMul_SelectProcessor (state, ARM_Lock_Prop);
269 case bfd_mach_arm_2a:
270 ARMul_SelectProcessor (state, ARM_Fix26_Prop);
274 if ( mach != bfd_mach_arm_3
275 && mach != bfd_mach_arm_3M
276 && mach != bfd_mach_arm_2
277 && mach != bfd_mach_arm_2a)
279 /* Reset mode to ARM. A gdb user may rerun a program that had entered
280 THUMB mode from the start and cause the ARM-mode startup code to be
281 executed in THUMB mode. */
282 ARMul_SetCPSR (state, SVC32MODE);
287 /* Set up the command line by laboriously stringing together
288 the environment carefully picked apart by our caller. */
290 /* Free any old stuff. */
291 if (state->CommandLine != NULL)
293 free (state->CommandLine);
294 state->CommandLine = NULL;
297 /* See how much we need. */
298 for (arg = argv; *arg != NULL; arg++)
299 argvlen += strlen (*arg) + 1;
302 state->CommandLine = malloc (argvlen + 1);
303 if (state->CommandLine != NULL)
306 state->CommandLine[0] = '\0';
308 for (arg = argv; *arg != NULL; arg++)
310 strcat (state->CommandLine, *arg);
311 strcat (state->CommandLine, " ");
318 /* Now see if there's a MEMSIZE spec in the environment. */
321 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0)
325 /* Set up memory limit. */
327 strtoul (*env + sizeof ("MEMSIZE=") - 1, &end_of_num, 0);
337 sim_info (sd, verbose)
338 SIM_DESC sd ATTRIBUTE_UNUSED;
339 int verbose ATTRIBUTE_UNUSED;
344 frommem (state, memory)
345 struct ARMul_State *state;
346 unsigned char *memory;
348 if (state->bigendSig == HIGH)
349 return (memory[0] << 24) | (memory[1] << 16)
350 | (memory[2] << 8) | (memory[3] << 0);
352 return (memory[3] << 24) | (memory[2] << 16)
353 | (memory[1] << 8) | (memory[0] << 0);
357 tomem (state, memory, val)
358 struct ARMul_State *state;
359 unsigned char *memory;
362 if (state->bigendSig == HIGH)
364 memory[0] = val >> 24;
365 memory[1] = val >> 16;
366 memory[2] = val >> 8;
367 memory[3] = val >> 0;
371 memory[3] = val >> 24;
372 memory[2] = val >> 16;
373 memory[1] = val >> 8;
374 memory[0] = val >> 0;
379 sim_store_register (sd, rn, memory, length)
380 SIM_DESC sd ATTRIBUTE_UNUSED;
382 unsigned char *memory;
383 int length ATTRIBUTE_UNUSED;
389 state->Cpsr = frommem (state, memory);
390 ARMul_CPSRAltered (state);
393 ARMul_SetReg (state, state->Mode, rn, frommem (state, memory));
398 sim_fetch_register (sd, rn, memory, length)
399 SIM_DESC sd ATTRIBUTE_UNUSED;
401 unsigned char *memory;
402 int length ATTRIBUTE_UNUSED;
409 regval = ARMul_GetReg (state, state->Mode, rn);
411 /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h. */
412 regval = ARMul_GetCPSR (state);
414 /* FIXME: should report an error. */
419 tomem (state, memory, regval);
430 sim_open (kind, ptr, abfd, argv)
437 if (myname) free (myname);
438 myname = (char *) xstrdup (argv[0]);
441 /* Decide upon the endian-ness of the processor.
442 If we can, get the information from the bfd itself.
443 Otherwise look to see if we have been given a command
444 line switch that tells us. Otherwise default to little endian. */
446 big_endian = bfd_big_endian (abfd);
447 else if (argv[1] != NULL)
451 /* Scan for endian-ness switch. */
452 for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++)
453 if (argv[i][0] == '-' && argv[i][1] == 'E')
457 if ((c = argv[i][2]) == 0)
466 sim_callback->printf_filtered
467 (sim_callback, "No argument to -E option provided\n");
481 sim_callback->printf_filtered
482 (sim_callback, "Unrecognised argument to -E option\n");
492 sim_close (sd, quitting)
493 SIM_DESC sd ATTRIBUTE_UNUSED;
494 int quitting ATTRIBUTE_UNUSED;
502 sim_load (sd, prog, abfd, from_tty)
506 int from_tty ATTRIBUTE_UNUSED;
510 prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
511 sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
512 if (prog_bfd == NULL)
514 ARMul_SetPC (state, bfd_get_start_address (prog_bfd));
516 bfd_close (prog_bfd);
521 sim_stop_reason (sd, reason, sigrc)
522 SIM_DESC sd ATTRIBUTE_UNUSED;
523 enum sim_stop *reason;
528 *reason = sim_stopped;
531 else if (state->EndCondition == 0)
533 *reason = sim_exited;
534 *sigrc = state->Reg[0] & 255;
538 *reason = sim_stopped;
539 if (state->EndCondition == RDIError_BreakpointReached)
547 sim_do_command (sd, cmd)
548 SIM_DESC sd ATTRIBUTE_UNUSED;
549 char *cmd ATTRIBUTE_UNUSED;
551 (*sim_callback->printf_filtered)
553 "This simulator does not accept any commands.\n");
557 sim_set_callbacks (ptr)