diff options
Diffstat (limited to 'sim/arm/wrapper.c')
-rw-r--r-- | sim/arm/wrapper.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c new file mode 100644 index 0000000..4038004 --- /dev/null +++ b/sim/arm/wrapper.c @@ -0,0 +1,467 @@ +/* run front end support for arm + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + +This file is part of ARM SIM. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* This file provides the interface between the simulator and run.c and gdb + (when the simulator is linked with gdb). + All simulator interaction should go through this file. */ + +#include <stdio.h> +#include <stdarg.h> +#include <bfd.h> +#include <signal.h> +#include "callback.h" +#include "remote-sim.h" +#include "armdefs.h" +#include "armemu.h" +#include "dbg_rdi.h" + +host_callback *sim_callback; + +static struct ARMul_State *state; + +/* Who is using the simulator. */ +static SIM_OPEN_KIND sim_kind; + +/* argv[0] */ +static char *myname; + +/* Memory size in bytes. */ +static int mem_size = (1 << 21); + +/* Non-zero to display start up banner, and maybe other things. */ +static int verbosity; + +/* Non-zero to set big endian mode. */ +static int big_endian; + +static void +init () +{ + static int done; + + if (!done) + { + ARMul_EmulateInit(); + state = ARMul_NewState (); + state->bigendSig = (big_endian ? HIGH : LOW); + ARMul_MemoryInit(state, mem_size); + ARMul_OSInit(state); + ARMul_CoProInit(state); + state->verbose = verbosity; + done = 1; + } +} + +/* Set verbosity level of simulator. + This is not intended to produce detailed tracing or debugging information. + Just summaries. */ +/* FIXME: common/run.c doesn't do this yet. */ + +void +sim_set_verbose (v) + int v; +{ + verbosity = v; +} + +/* Set the memory size to SIZE bytes. + Must be called before initializing simulator. */ +/* FIXME: Rename to sim_set_mem_size. */ + +void +sim_size (size) + int size; +{ + mem_size = size; +} + +void +ARMul_ConsolePrint (ARMul_State * state, const char *format,...) +{ + va_list ap; + + if (state->verbose) + { + va_start (ap, format); + vprintf (format, ap); + va_end (ap); + } +} + +ARMword +ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr) +{ + +} + +int +sim_write (sd, addr, buffer, size) + SIM_DESC sd; + SIM_ADDR addr; + unsigned char *buffer; + int size; +{ + int i; + init (); + for (i = 0; i < size; i++) + { + ARMul_WriteByte (state, addr+i, buffer[i]); + } + return size; +} + +int +sim_read (sd, addr, buffer, size) + SIM_DESC sd; + SIM_ADDR addr; + unsigned char *buffer; + int size; +{ + int i; + init (); + for (i = 0; i < size; i++) + { + buffer[i] = ARMul_ReadByte (state, addr + i); + } + return size; +} + +int +sim_trace (sd) + SIM_DESC sd; +{ + (*sim_callback->printf_filtered) (sim_callback, "This simulator does not support tracing\n"); + return 1; +} + +int +sim_stop (sd) + SIM_DESC sd; +{ + return 0; +} + +void +sim_resume (sd, step, siggnal) + SIM_DESC sd; + int step, siggnal; +{ + state->EndCondition = 0; + + if (step) + { + state->Reg[15] = ARMul_DoInstr (state); + if (state->EndCondition == 0) + state->EndCondition = RDIError_BreakpointReached; + } + else + { +#if 1 /* JGS */ + state->NextInstr = RESUME; /* treat as PC change */ +#endif + state->Reg[15] = ARMul_DoProg (state); + } + + FLUSHPIPE; +} + +SIM_RC +sim_create_inferior (sd, abfd, argv, env) + SIM_DESC sd; + struct _bfd *abfd; + char **argv; + char **env; +{ + int argvlen=0; + char **arg; + + if (abfd != NULL) + ARMul_SetPC (state, bfd_get_start_address (abfd)); + else + ARMul_SetPC (state, 0); /* ??? */ + +#if 1 /* JGS */ + /* We explicitly select a processor capable of supporting the ARM + 32bit mode, and then we force the simulated CPU into the 32bit + User mode: */ + ARMul_SelectProcessor(state, ARM600); + ARMul_SetCPSR(state, USER32MODE); +#endif + + if (argv != NULL) + { + /* + ** Set up the command line (by laboriously stringing together the + ** environment carefully picked apart by our caller...) + */ + /* Free any old stuff */ + if (state->CommandLine != NULL) + { + free(state->CommandLine); + state->CommandLine = NULL; + } + + /* See how much we need */ + for (arg = argv; *arg != NULL; arg++) + argvlen += strlen(*arg)+1; + + /* allocate it... */ + state->CommandLine = malloc(argvlen+1); + if (state->CommandLine != NULL) + { + arg = argv; + state->CommandLine[0]='\0'; + for (arg = argv; *arg != NULL; arg++) + { + strcat(state->CommandLine, *arg); + strcat(state->CommandLine, " "); + } + } + } + + if (env != NULL) + { + /* Now see if there's a MEMSIZE spec in the environment */ + while (*env) + { + if (strncmp(*env, "MEMSIZE=", sizeof("MEMSIZE=")-1)==0) + { + unsigned long top_of_memory; + char *end_of_num; + + /* Set up memory limit */ + state->MemSize = strtoul(*env + sizeof("MEMSIZE=")-1, &end_of_num, 0); + } + env++; + } + } + + return SIM_RC_OK; +} + +void +sim_info (sd, verbose) + SIM_DESC sd; + int verbose; +{ +} + + +static int +frommem (state, memory) + struct ARMul_State *state; + unsigned char *memory; +{ + if (state->bigendSig == HIGH) + { + return (memory[0] << 24) + | (memory[1] << 16) + | (memory[2] << 8) + | (memory[3] << 0); + } + else + { + return (memory[3] << 24) + | (memory[2] << 16) + | (memory[1] << 8) + | (memory[0] << 0); + } +} + + +static void +tomem (state, memory, val) + struct ARMul_State *state; + unsigned char *memory; + int val; +{ + if (state->bigendSig == HIGH) + { + memory[0] = val >> 24; + memory[1] = val >> 16; + memory[2] = val >> 8; + memory[3] = val >> 0; + } + else + { + memory[3] = val >> 24; + memory[2] = val >> 16; + memory[1] = val >> 8; + memory[0] = val >> 0; + } +} + +int +sim_store_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + init (); + ARMul_SetReg(state, state->Mode, rn, frommem (state, memory)); + return -1; +} + +int +sim_fetch_register (sd, rn, memory, length) + SIM_DESC sd; + int rn; + unsigned char *memory; + int length; +{ + ARMword regval; + + init (); + if (rn < 16) + regval = ARMul_GetReg(state, state->Mode, rn); + else if (rn == 25) /* FIXME: use PS_REGNUM from gdb/config/arm/tm-arm.h */ + regval = ARMul_GetCPSR(state); + else + regval = 0; /* FIXME: should report an error */ + tomem (state, memory, regval); + return -1; +} + +SIM_DESC +sim_open (kind, ptr, abfd, argv) + SIM_OPEN_KIND kind; + host_callback *ptr; + struct _bfd *abfd; + char **argv; +{ + sim_kind = kind; + myname = argv[0]; + sim_callback = ptr; + + /* Decide upon the endian-ness of the processor. + If we can, get the information from the bfd itself. + Otherwise look to see if we have been given a command + line switch that tells us. Otherwise default to little endian. */ + if (abfd != NULL) + big_endian = bfd_big_endian (abfd); + else if (argv[1] != NULL) + { + int i; + + /* Scan for endian-ness switch. */ + for (i = 0; (argv[i] != NULL) && (argv[i][0] != 0); i++) + if (argv[i][0] == '-' && argv[i][1] == 'E') + { + char c; + + if ((c = argv[i][2]) == 0) + { + ++i; + c = argv[i][0]; + } + + switch (c) + { + case 0: + sim_callback->printf_filtered + (sim_callback, "No argument to -E option provided\n"); + break; + + case 'b': + case 'B': + big_endian = 1; + break; + + case 'l': + case 'L': + big_endian = 0; + break; + + default: + sim_callback->printf_filtered + (sim_callback, "Unrecognised argument to -E option\n"); + break; + } + } + } + + return (SIM_DESC) 1; +} + +void +sim_close (sd, quitting) + SIM_DESC sd; + int quitting; +{ + /* nothing to do */ +} + +SIM_RC +sim_load (sd, prog, abfd, from_tty) + SIM_DESC sd; + char *prog; + bfd *abfd; + int from_tty; +{ + extern bfd *sim_load_file (); /* ??? Don't know where this should live. */ + bfd *prog_bfd; + + prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd, + sim_kind == SIM_OPEN_DEBUG, + 0, sim_write); + if (prog_bfd == NULL) + return SIM_RC_FAIL; + ARMul_SetPC (state, bfd_get_start_address (prog_bfd)); + if (abfd == NULL) + bfd_close (prog_bfd); + return SIM_RC_OK; +} + +void +sim_stop_reason (sd, reason, sigrc) + SIM_DESC sd; + enum sim_stop *reason; + int *sigrc; +{ + if (state->EndCondition == 0) + { + *reason = sim_exited; + *sigrc = state->Reg[0] & 255; + } + else + { + *reason = sim_stopped; + if (state->EndCondition == RDIError_BreakpointReached) + *sigrc = SIGTRAP; + else + *sigrc = 0; + } +} + +void +sim_do_command (sd, cmd) + SIM_DESC sd; + char *cmd; +{ + (*sim_callback->printf_filtered) (sim_callback, "This simulator does not accept any commands.\n"); +} + + +void +sim_set_callbacks (ptr) + host_callback *ptr; +{ + sim_callback = ptr; +} |