@@ -765,7 +765,6 @@ with_pkgversion
with_bugurl
enable_sim_endian
enable_sim_alignment
-enable_sim_default_model
enable_sim_environment
enable_sim_inline
enable_werror
@@ -1427,8 +1426,6 @@ Optional Features:
--enable-sim-alignment=align
Specify strict, nonstrict or forced alignment of
memory accesses
- --enable-sim-default-model=model
- Specify default model to simulate
--enable-sim-environment=environment
Specify mixed, user, virtual or operating
environment
@@ -13132,7 +13129,7 @@ sim_link_links="${sim_link_links} targ-vals.def"
-wire_endian="LITTLE"
+wire_endian=""
default_endian=""
# Check whether --enable-sim-endian was given.
if test "${enable_sim_endian+set}" = set; then :
@@ -13223,22 +13220,6 @@ fi
fi
-default_sim_default_model="bf537"
-# Check whether --enable-sim-default-model was given.
-if test "${enable_sim_default_model+set}" = set; then :
- enableval=$enable_sim_default_model; case "${enableval}" in
- yes|no) as_fn_error "\"Missing argument to --enable-sim-default-model\"" "$LINENO" 5;;
- *) sim_default_model="-DWITH_DEFAULT_MODEL='\"${enableval}\"'";;
-esac
-if test x"$silent" != x"yes" && test x"$sim_default_model" != x""; then
- echo "Setting default model = $sim_default_model" 6>&1
-fi
-else
- sim_default_model="-DWITH_DEFAULT_MODEL='\"${default_sim_default_model}\"'"
-fi
-
-
-
# Check whether --enable-sim-environment was given.
if test "${enable_sim_environment+set}" = set; then :
enableval=$enable_sim_environment; case "${enableval}" in
@@ -5,9 +5,8 @@ sinclude(../common/acinclude.m4)
SIM_AC_COMMON
-SIM_AC_OPTION_ENDIAN(LITTLE)
+SIM_AC_OPTION_ENDIAN
SIM_AC_OPTION_ALIGNMENT(STRICT_ALIGNMENT,STRICT_ALIGNMENT)
-SIM_AC_OPTION_DEFAULT_MODEL(bf537)
SIM_AC_OPTION_ENVIRONMENT
SIM_AC_OPTION_INLINE
SIM_AC_OPTION_WARNINGS
@@ -657,8 +657,8 @@ step_once (SIM_CPU *cpu)
return oldpc;
}
-void
-sim_engine_run (SIM_DESC sd,
+static void
+bfin_engine_run (SIM_DESC sd,
int next_cpu_nr, /* ignore */
int nr_cpus, /* ignore */
int siggnal) /* ignore */
@@ -681,22 +681,11 @@ sim_engine_run (SIM_DESC sd,
}
}
-/* Cover function of sim_state_free to free the cpu buffers as well. */
-
static void
-free_state (SIM_DESC sd)
+bfin_cpu_init (SIM_CPU *cpu)
{
- if (STATE_MODULES (sd) != NULL)
- sim_module_uninstall (sd);
- sim_cpu_free_all (sd);
- sim_state_free (sd);
-}
-
-/* Create an instance of the simulator. */
+ SIM_DESC sd = CPU_STATE (cpu);
-static void
-bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
-{
memset (&cpu->state, 0, sizeof (cpu->state));
PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
@@ -712,56 +701,20 @@ bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
SET_SYSCFGREG (0x30);
}
-SIM_DESC
-sim_open (SIM_OPEN_KIND kind, host_callback *callback,
- struct bfd *abfd, char **argv)
+static void
+bfin_state_init (SIM_DESC sd)
{
char c;
- int i;
- SIM_DESC sd = sim_state_alloc (kind, callback);
-
- /* The cpu data is kept in a separately allocated chunk of memory. */
- if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
- {
- /* XXX: Only first core gets profiled ? */
- SIM_CPU *cpu = STATE_CPU (sd, 0);
- STATE_WATCHPOINTS (sd)->pc = &PCREG;
- STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
- }
-
- if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
+ /* XXX: Only first core gets profiled ? */
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ STATE_WATCHPOINTS (sd)->pc = &PCREG;
+ STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
/* XXX: Default to the Virtual environment. */
if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
- /* These options override any module options.
- Obviously ambiguity should be avoided, however the caller may wish to
- augment the meaning of an option. */
-#define e_sim_add_option_table(sd, options) \
- do { \
- extern const OPTION options[]; \
- sim_add_option_table (sd, NULL, options); \
- } while (0)
- e_sim_add_option_table (sd, bfin_mmu_options);
- e_sim_add_option_table (sd, bfin_mach_options);
-
- /* The parser will print an error message for us, so we silently return. */
- if (sim_parse_args (sd, argv) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
-
/* Allocate external memory if none specified by user.
Use address 4 here in case the user wanted address 0 unmapped. */
if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
@@ -770,38 +723,6 @@ sim_open (SIM_OPEN_KIND kind, host_callback *callback,
sim_do_commandf (sd, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE);
sim_write (sd, 0, (void *)&emuexcpt, 2);
}
-
- /* Check for/establish the a reference program image. */
- if (sim_analyze_program (sd,
- (STATE_PROG_ARGV (sd) != NULL
- ? *STATE_PROG_ARGV (sd)
- : NULL), abfd) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
-
- /* Establish any remaining configuration options. */
- if (sim_config (sd) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
-
- if (sim_post_argv_init (sd) != SIM_RC_OK)
- {
- free_state (sd);
- return 0;
- }
-
- /* CPU specific initialization. */
- for (i = 0; i < MAX_NR_PROCESSORS; ++i)
- {
- SIM_CPU *cpu = STATE_CPU (sd, i);
- bfin_initialize_cpu (sd, cpu);
- }
-
- return sd;
}
/* Some utils don't like having a NULL environ. */
@@ -962,7 +883,7 @@ bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
}
static void
-bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
+bfin_user_init (SIM_DESC sd, struct bfd *abfd,
const char * const *argv, const char * const *env)
{
/* XXX: Missing host -> target endian ... */
@@ -998,6 +919,9 @@ bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
host_callback *cb = STATE_CALLBACK (sd);
+ /* We only set up the first CPU. The others are left unlocked. */
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+
elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
@@ -1145,8 +1069,10 @@ bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
}
static void
-bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
+bfin_os_init (SIM_DESC sd, const char * const *argv)
{
+ /* We only set up the first CPU. The others are left unlocked. */
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
/* Pass the command line via a string in R0 like Linux expects. */
int i;
bu8 byte;
@@ -1172,7 +1098,7 @@ bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
}
static void
-bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
+bfin_virtual_init (SIM_DESC sd)
{
host_callback *cb = STATE_CALLBACK (sd);
@@ -1180,42 +1106,41 @@ bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
stat_map_64 = NULL;
}
-SIM_RC
-sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
- char **argv, char **env)
+static void
+bfin_inferior_init (SIM_DESC sd, struct bfd *abfd,
+ const char * const *argv, const char * const *envp)
{
- SIM_CPU *cpu = STATE_CPU (sd, 0);
- SIM_ADDR addr;
-
- /* Set the PC. */
- if (abfd != NULL)
- addr = bfd_get_start_address (abfd);
- else
- addr = 0;
- sim_pc_set (cpu, addr);
-
- /* Standalone mode (i.e. `run`) will take care of the argv for us in
- sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
- with `gdb`), we need to handle it because the user can change the
- argv on the fly via gdb's 'run'. */
- if (STATE_PROG_ARGV (sd) != argv)
- {
- freeargv (STATE_PROG_ARGV (sd));
- STATE_PROG_ARGV (sd) = dupargv (argv);
- }
-
switch (STATE_ENVIRONMENT (sd))
{
case USER_ENVIRONMENT:
- bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
+ bfin_user_init (sd, abfd, (void *)argv, (void *)envp);
break;
case OPERATING_ENVIRONMENT:
- bfin_os_init (sd, cpu, (void *)argv);
+ bfin_os_init (sd, (void *)argv);
break;
default:
- bfin_virtual_init (sd, cpu);
+ bfin_virtual_init (sd);
break;
}
+}
+
+static const simarch bfin_simarch =
+{
+ .engine_run = bfin_engine_run,
+ .state_init = bfin_state_init,
+ .cpu_init = bfin_cpu_init,
+ .inferior_init = bfin_inferior_init,
+ .default_environment = VIRTUAL_ENVIRONMENT,
+ .default_endian = BFD_ENDIAN_LITTLE,
+ .default_alignment = STRICT_ALIGNMENT,
+ .default_model = "bf537",
+ .machs = sim_machs,
+};
+
+extern SIM_SIMARCH_REGISTER_FN sim_simarch_register_bfin;
- return SIM_RC_OK;
+SIM_RC
+sim_simarch_register_bfin (void)
+{
+ return sim_simarch_register (bfd_arch_bfin, &bfin_simarch);
}
@@ -18,8 +18,6 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-/* First entry is the default model. */
-P(537)
P(504)
P(506)
P(512)
@@ -38,6 +36,7 @@ P(533)
P(534)
/*P(535)*/
P(536)
+P(537)
P(538)
P(539)
P(542)
@@ -21,6 +21,9 @@
#ifndef _BFIN_MAIN_SIM_H_
#define _BFIN_MAIN_SIM_H_
+/* We want to use the new simarch logic. */
+#define WITH_SIMARCH 1
+
#include "sim-basics.h"
#include "sim-signal.h"
@@ -185,17 +185,20 @@ SIM_NEW_COMMON_OBJS = \
sim-fpu.o \
sim-hload.o \
sim-hrw.o \
+ sim-inferior.o \
sim-io.o \
sim-info.o \
sim-load.o \
sim-memopt.o \
sim-model.o \
sim-module.o \
+ sim-open.o \
sim-options.o \
sim-profile.o \
sim-reason.o \
sim-reg.o \
sim-signal.o \
+ sim-simarch.o \
sim-stop.o \
sim-syscall.o \
sim-trace.o \
@@ -78,6 +78,7 @@ typedef struct _sim_cpu sim_cpu;
#include "sim-module.h"
+#include "sim-simarch.h"
#include "sim-trace.h"
#include "sim-core.h"
#include "sim-events.h"
@@ -113,6 +114,10 @@ typedef struct {
struct host_callback_struct *callback;
#define STATE_CALLBACK(sd) ((sd)->base.callback)
+ /* Target specific data. */
+ const simarch *simarch;
+#define STATE_SIMARCH(sd) ((sd)->base.simarch)
+
/* The type of simulation environment (user/operating). */
enum sim_environment environment;
#define STATE_ENVIRONMENT(sd) ((sd)->base.environment)
@@ -147,8 +152,7 @@ typedef struct {
const char *target;
#define STATE_TARGET(sd) ((sd)->base.target)
- /* In standalone simulator, this is the program's arguments passed
- on the command line. */
+ /* The program's arguments passed on the command line. */
char **prog_argv;
#define STATE_PROG_ARGV(sd) ((sd)->base.prog_argv)
@@ -169,6 +169,8 @@ sim_config (SIM_DESC sd)
current_target_byte_order = WITH_TARGET_BYTE_ORDER;
if (current_target_byte_order == BFD_ENDIAN_UNKNOWN)
current_target_byte_order = WITH_DEFAULT_TARGET_BYTE_ORDER;
+ if (current_target_byte_order == BFD_ENDIAN_UNKNOWN && WITH_SIMARCH)
+ current_target_byte_order = STATE_SIMARCH (sd)->default_endian;
/* verify the target byte order */
if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_UNKNOWN)
@@ -237,8 +239,9 @@ sim_config (SIM_DESC sd)
}
#endif
if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
- STATE_ENVIRONMENT (sd) = DEFAULT_ENVIRONMENT;
-
+ STATE_ENVIRONMENT (sd) =
+ WITH_SIMARCH ? STATE_SIMARCH (sd)->default_environment
+ : DEFAULT_ENVIRONMENT;
/* set the alignment */
#if (WITH_TREE_PROPERTIES)
@@ -252,6 +255,8 @@ sim_config (SIM_DESC sd)
current_alignment = WITH_ALIGNMENT;
if (current_alignment == 0)
current_alignment = WITH_DEFAULT_ALIGNMENT;
+ if (current_alignment == 0 && WITH_SIMARCH)
+ current_alignment = STATE_SIMARCH (sd)->default_alignment;
/* verify the alignment */
if (CURRENT_ALIGNMENT == 0)
new file mode 100644
@@ -0,0 +1,64 @@
+/* Miscellaneous simulator utilities.
+
+ Copyright (C) 2005-2015 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc. and Stephane Carrez.
+
+ This file is part of simulators.
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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, see <http://www.gnu.org/licenses/>. */
+
+#include "sim-main.h"
+#include "gdb/remote-sim.h"
+
+#if WITH_SIMARCH
+
+SIM_RC
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char **argv, char **envp)
+{
+ size_t i;
+ sim_cia pc;
+ const simarch *simarch;
+
+ /* Set the PC. */
+ if (abfd != NULL)
+ pc = bfd_get_start_address (abfd);
+ else
+ pc = 0;
+
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, i);
+
+ sim_pc_set (cpu, pc);
+ }
+
+ /* Standalone mode (i.e. `run`) will take care of the argv for us in
+ sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
+ with `gdb`), we need to handle it because the user can change the
+ argv on the fly via gdb's 'run'. */
+ if (STATE_PROG_ARGV (sd) != argv)
+ {
+ freeargv (STATE_PROG_ARGV (sd));
+ STATE_PROG_ARGV (sd) = dupargv (argv);
+ }
+
+ simarch = STATE_SIMARCH (sd);
+ if (simarch->inferior_init)
+ simarch->inferior_init (sd, abfd, (void *)argv, (void *)envp);
+
+ return SIM_RC_OK;
+}
+
+#endif
@@ -25,79 +25,39 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sim-assert.h"
#include "bfd.h"
-static void model_set (sim_cpu *, const SIM_MODEL *);
+#define MODEL_ACTION_LIST (void *)-1
-static DECLARE_OPTION_HANDLER (model_option_handler);
+/* Find where the list of models are maintained. */
-static MODULE_INIT_FN sim_model_init;
-
-enum {
- OPTION_MODEL = OPTION_START,
- OPTION_MODEL_INFO,
-};
-
-static const OPTION model_options[] = {
- { {"model", required_argument, NULL, OPTION_MODEL},
- '\0', "MODEL", "Specify model to simulate",
- model_option_handler, NULL },
-
- { {"model-info", no_argument, NULL, OPTION_MODEL_INFO},
- '\0', NULL, "List selectable models",
- model_option_handler, NULL },
- { {"info-model", no_argument, NULL, OPTION_MODEL_INFO},
- '\0', NULL, NULL,
- model_option_handler, NULL },
-
- { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
-};
-
-static SIM_RC
-model_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
- char *arg, int is_command)
+static const SIM_MACH **
+sim_model_machs (SIM_DESC sd)
{
- switch (opt)
- {
- case OPTION_MODEL :
- {
- const SIM_MODEL *model = sim_model_lookup (arg);
- if (! model)
- {
- sim_io_eprintf (sd, "unknown model `%s'\n", arg);
- return SIM_RC_FAIL;
- }
- sim_model_set (sd, cpu, model);
- break;
- }
-
- case OPTION_MODEL_INFO :
- {
- const SIM_MACH **machp;
- const SIM_MODEL *model;
- for (machp = & sim_machs[0]; *machp != NULL; ++machp)
- {
- sim_io_printf (sd, "Models for architecture `%s':\n",
- MACH_NAME (*machp));
- for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL;
- ++model)
- sim_io_printf (sd, " %s", MODEL_NAME (model));
- sim_io_printf (sd, "\n");
- }
- break;
- }
- }
-
- return SIM_RC_OK;
+#if WITH_SIMARCH
+ return STATE_SIMARCH (sd)->machs;
+#else
+# if !WITH_MODEL_P
+ /* Set up basic model support. This is a stub for ports that do not define
+ models. See sim-model.h for more details. */
+ static const SIM_MACH *sim_machs[] = { NULL };
+# endif
+ return &sim_machs[0];
+#endif
}
-SIM_RC
-sim_model_install (SIM_DESC sd)
+static void
+model_list (SIM_DESC sd)
{
- SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-
- sim_add_option_table (sd, NULL, model_options);
- sim_module_add_init_fn (sd, sim_model_init);
+ const SIM_MACH **machp;
+ const SIM_MODEL *model;
- return SIM_RC_OK;
+ for (machp = sim_model_machs (sd); *machp != NULL; ++machp)
+ {
+ sim_io_printf (sd, "Models for architecture `%s':\n",
+ MACH_NAME (*machp));
+ for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL; ++model)
+ sim_io_printf (sd, " %s", MODEL_NAME (model));
+ sim_io_printf (sd, "\n");
+ }
}
/* Subroutine of sim_model_set to set the model for one cpu. */
@@ -135,12 +95,12 @@ sim_model_set (SIM_DESC sd, sim_cpu *cpu, const SIM_MODEL *model)
Result is pointer to MODEL entry or NULL if not found. */
const SIM_MODEL *
-sim_model_lookup (const char *name)
+sim_model_lookup (SIM_DESC sd, const char *name)
{
const SIM_MACH **machp;
const SIM_MODEL *model;
- for (machp = & sim_machs[0]; *machp != NULL; ++machp)
+ for (machp = sim_model_machs (sd); *machp != NULL; ++machp)
{
for (model = MACH_MODELS (*machp); MODEL_NAME (model) != NULL; ++model)
{
@@ -151,15 +111,30 @@ sim_model_lookup (const char *name)
return NULL;
}
+static SIM_RC
+model_set_name (SIM_DESC sd, sim_cpu *cpu, const char *name)
+{
+ const SIM_MODEL *model = sim_model_lookup (sd, name);
+
+ if (model == NULL)
+ {
+ sim_io_eprintf (sd, "unknown model `%s'\n", name);
+ return SIM_RC_FAIL;
+ }
+
+ sim_model_set (sd, cpu, model);
+ return SIM_RC_OK;
+}
+
/* Look up machine named NAME.
Result is pointer to MACH entry or NULL if not found. */
const SIM_MACH *
-sim_mach_lookup (const char *name)
+sim_mach_lookup (SIM_DESC sd, const char *name)
{
const SIM_MACH **machp;
- for (machp = & sim_machs[0]; *machp != NULL; ++machp)
+ for (machp = sim_model_machs (sd); *machp != NULL; ++machp)
{
if (strcmp (MACH_NAME (*machp), name) == 0)
return *machp;
@@ -171,11 +146,11 @@ sim_mach_lookup (const char *name)
Result is pointer to MACH entry or NULL if not found. */
const SIM_MACH *
-sim_mach_lookup_bfd_name (const char *name)
+sim_mach_lookup_bfd_name (SIM_DESC sd, const char *name)
{
const SIM_MACH **machp;
- for (machp = & sim_machs[0]; *machp != NULL; ++machp)
+ for (machp = sim_model_machs (sd); *machp != NULL; ++machp)
{
if (strcmp (MACH_BFD_NAME (*machp), name) == 0)
return *machp;
@@ -202,11 +177,26 @@ sim_model_init (SIM_DESC sd)
/* ??? At present this only supports homogeneous multiprocessors. */
cpu = STATE_CPU (sd, 0);
+ /* Process any actions requested by the command line. */
+ if (CPU_MODEL_DATA (cpu) == MODEL_ACTION_LIST)
+ model_list (sd);
+ else if (CPU_MODEL_DATA (cpu) != NULL)
+ {
+ const char *model_name = CPU_MODEL_DATA (cpu);
+
+ if (model_set_name (sd, cpu, model_name) != SIM_RC_OK)
+ return SIM_RC_FAIL;
+ }
+ CPU_MODEL_DATA (cpu) = NULL;
+
if (! STATE_ARCHITECTURE (sd)
&& ! CPU_MACH (cpu))
{
+#if WITH_SIMARCH
+# define WITH_DEFAULT_MODEL STATE_SIMARCH (sd)->default_model
+#endif
/* Set the default model. */
- const SIM_MODEL *model = sim_model_lookup (WITH_DEFAULT_MODEL);
+ const SIM_MODEL *model = sim_model_lookup (sd, WITH_DEFAULT_MODEL);
SIM_ASSERT (model != NULL);
sim_model_set (sd, NULL, model);
}
@@ -227,7 +217,7 @@ sim_model_init (SIM_DESC sd)
{
/* Use the default model for the selected machine.
The default model is the first one in the list. */
- const SIM_MACH *mach = sim_mach_lookup_bfd_name (STATE_ARCHITECTURE (sd)->printable_name);
+ const SIM_MACH *mach = sim_mach_lookup_bfd_name (sd, STATE_ARCHITECTURE (sd)->printable_name);
if (mach == NULL)
{
@@ -245,11 +235,77 @@ sim_model_init (SIM_DESC sd)
return SIM_RC_OK;
}
-#if !WITH_MODEL_P
-/* Set up basic model support. This is a stub for ports that do not define
- models. See sim-model.h for more details. */
-const SIM_MACH *sim_machs[] =
+/* We need to delay actions from option parsing to the init phase.
+ This way we can load the simarch properly which provides models. */
+static void
+model_queue_action (SIM_DESC sd, sim_cpu *cpu, void *act)
{
- NULL
+ if (cpu == NULL)
+ {
+ size_t c;
+
+ for (c = 0; c < MAX_NR_PROCESSORS; ++c)
+ {
+ cpu = STATE_CPU (sd, c);
+ if (cpu)
+ CPU_MODEL_DATA (cpu) = act;
+ }
+ }
+ else
+ CPU_MODEL_DATA (cpu) = act;
+}
+
+enum {
+ OPTION_MODEL = OPTION_START,
+ OPTION_MODEL_INFO,
};
-#endif
+
+static SIM_RC
+model_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
+ char *arg, int is_command)
+{
+ switch (opt)
+ {
+ case OPTION_MODEL :
+ if (STATE_SIMARCH (sd))
+ return model_set_name (sd, cpu, arg);
+ else
+ model_queue_action (sd, cpu, arg);
+ break;
+
+ case OPTION_MODEL_INFO :
+ if (STATE_SIMARCH (sd))
+ model_list (sd);
+ else
+ model_queue_action (sd, cpu, MODEL_ACTION_LIST);
+ break;
+ }
+
+ return SIM_RC_OK;
+}
+
+static const OPTION model_options[] = {
+ { {"model", required_argument, NULL, OPTION_MODEL},
+ '\0', "MODEL", "Specify model to simulate",
+ model_option_handler, NULL },
+
+ { {"model-info", no_argument, NULL, OPTION_MODEL_INFO},
+ '\0', NULL, "List selectable models",
+ model_option_handler, NULL },
+ { {"info-model", no_argument, NULL, OPTION_MODEL_INFO},
+ '\0', NULL, NULL,
+ model_option_handler, NULL },
+
+ { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
+};
+
+SIM_RC
+sim_model_install (SIM_DESC sd)
+{
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ sim_add_option_table (sd, NULL, model_options);
+ sim_module_add_init_fn (sd, sim_model_init);
+
+ return SIM_RC_OK;
+}
@@ -47,9 +47,8 @@ typedef struct {
#define MAX_UNITS 1
#endif
-#ifndef WITH_DEFAULT_MODEL
+#if !defined(WITH_DEFAULT_MODEL) && !WITH_SIMARCH
/* Just a stub for ports that do not define models. */
-enum mach_attr { _MACH_NONE };
# define WITH_DEFAULT_MODEL NULL
# define WITH_MODEL_P 0
#else
@@ -86,13 +85,13 @@ typedef struct {
/* A machine variant. */
-typedef struct {
+typedef struct sim_mach {
const char *name;
#define MACH_NAME(m) ((m)->name)
/* This is the argument to bfd_scan_arch. */
const char *bfd_name;
#define MACH_BFD_NAME(m) ((m)->bfd_name)
- enum mach_attr num;
+ int num;
#define MACH_NUM(m) ((m)->num)
int word_bitsize;
@@ -147,8 +146,8 @@ extern MODULE_INSTALL_FN sim_model_install;
/* Support routines. */
extern void sim_model_set (SIM_DESC sd_, sim_cpu *cpu_, const SIM_MODEL *model_);
-extern const SIM_MODEL *sim_model_lookup (const char *name_);
-extern const SIM_MACH *sim_mach_lookup (const char *name_);
-extern const SIM_MACH *sim_mach_lookup_bfd_name (const char *bfd_name_);
+extern const SIM_MODEL *sim_model_lookup (SIM_DESC, const char *name_);
+extern const SIM_MACH *sim_mach_lookup (SIM_DESC, const char *name_);
+extern const SIM_MACH *sim_mach_lookup_bfd_name (SIM_DESC, const char *bfd_name_);
#endif /* SIM_MODEL_H */
new file mode 100644
@@ -0,0 +1,95 @@
+/* Create a fully initialized simulator instance.
+
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
+ Contributed by Analog Devices, Inc.
+
+ This file is part of simulators.
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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, see <http://www.gnu.org/licenses/>. */
+
+#include "sim-main.h"
+#include "gdb/remote-sim.h"
+
+#if WITH_SIMARCH
+
+#ifndef CGEN_ARCH
+# define cgen_cpu_max_extra_bytes() 0
+# define cgen_init(sd)
+#endif
+
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *cb, struct bfd *abfd, char **argv)
+{
+ SIM_DESC sd = sim_state_alloc (kind, cb);
+ const simarch *simarch;
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ /* The cpu data is kept in a separately allocated chunk of memory. */
+ if (sim_cpu_alloc_all (sd, MAX_NR_PROCESSORS, cgen_cpu_max_extra_bytes ())
+ != SIM_RC_OK)
+ goto error_cpu_alloc;
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+ goto error_argv_init;
+
+ /* The parser will print an error message for us, so we silently return. */
+ if (sim_parse_args (sd, argv) != SIM_RC_OK)
+ goto error;
+
+ /* Check for/establish the reference program image. */
+ if (sim_analyze_program (sd, (STATE_PROG_ARGV (sd) != NULL
+ ? *STATE_PROG_ARGV (sd) : NULL),
+ abfd) != SIM_RC_OK)
+ goto error;
+
+ /* With an appropriate prog bfd loaded, try to detect the right sim. */
+ if (sim_simarch_lookup (sd) != SIM_RC_OK)
+ goto error;
+ simarch = STATE_SIMARCH (sd);
+
+ /* Establish any remaining configuration options. */
+ if (sim_config (sd) != SIM_RC_OK)
+ goto error;
+
+ if (sim_post_argv_init (sd) != SIM_RC_OK)
+ goto error;
+
+ /* Port specific state finalization. */
+ if (simarch->state_init)
+ simarch->state_init (sd);
+
+ /* Initialize various cgen things not done by common framework. */
+ cgen_init (sd);
+
+ /* CPU specific initialization. */
+ if (simarch->cpu_init)
+ {
+ size_t i;
+
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ simarch->cpu_init (STATE_CPU (sd, i));
+ }
+
+ return sd;
+
+ error:
+ sim_module_uninstall (sd);
+ error_argv_init:
+ sim_cpu_free_all (sd);
+ error_cpu_alloc:
+ sim_state_free (sd);
+ return NULL;
+}
+
+#endif
@@ -86,7 +86,10 @@ sim_resume (SIM_DESC sd,
}
#endif
- sim_engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver);
+ if (WITH_SIMARCH)
+ STATE_SIMARCH (sd)->engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver);
+ else
+ sim_engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver);
}
engine->jmpbuf = NULL;
new file mode 100644
@@ -0,0 +1,120 @@
+/* Simulator arch ops for support multiple targets in a single build.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Mike Frysinger.
+
+ This file is part of simulators.
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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, see <http://www.gnu.org/licenses/>. */
+
+#include "sim-main.h"
+
+/* Keep a registry of the architectures known by the sim. */
+
+struct simarch_registration
+{
+ const struct bfd_arch_info *bfd_arch_info;
+ const struct simarch *simarch;
+};
+
+static size_t registered_count;
+static struct simarch_registration **simarch_registery;
+
+SIM_RC
+sim_simarch_register (enum bfd_architecture bfd_architecture,
+ const struct simarch *simarch)
+{
+ size_t i;
+ struct simarch_registration *reg;
+ const struct bfd_arch_info *bfd_arch_info;
+
+ bfd_arch_info = bfd_lookup_arch (bfd_architecture, 0);
+ if (bfd_arch_info == NULL)
+ return SIM_RC_FAIL;
+
+ i = registered_count++;
+ simarch_registery = XRESIZEVEC (struct simarch_registration *,
+ simarch_registery, registered_count);
+ reg = simarch_registery[i] = xmalloc (sizeof (*reg));
+ reg->bfd_arch_info = bfd_arch_info;
+ reg->simarch = simarch;
+
+
+ return SIM_RC_OK;
+}
+
+static const struct simarch *
+simarch_lookup (const struct bfd_arch_info *architecture)
+{
+ struct simarch_registration *reg;
+ size_t i;
+
+ for (i = 0; i < registered_count; ++i)
+ {
+ reg = simarch_registery[i];
+ if (architecture == reg->bfd_arch_info)
+ return reg->simarch;
+ }
+
+ return NULL;
+}
+
+SIM_RC
+sim_simarch_lookup (SIM_DESC sd)
+{
+ const struct simarch *simarch = NULL;
+ const struct bfd_arch_info *architecture;
+ struct bfd *abfd;
+ const char **list, **lp;
+
+extern SIM_SIMARCH_REGISTER_FN sim_simarch_register_bfin;
+sim_simarch_register_bfin ();
+
+ /* The prog bfd has been set, use it. */
+ abfd = STATE_PROG_BFD (sd);
+ if (abfd != NULL)
+ {
+ simarch = simarch_lookup (bfd_get_arch_info (abfd));
+ goto done;
+ }
+
+ /* If the state arch has been set, use it. */
+ architecture = STATE_ARCHITECTURE (sd);
+ if (architecture != NULL)
+ {
+ simarch = simarch_lookup (STATE_ARCHITECTURE (sd));
+ goto done;
+ }
+
+ /* Scan all available bfds and blindly use the first one that matches. */
+ list = bfd_arch_list ();
+ if (list != NULL)
+ {
+ for (lp = list; *lp != NULL; lp++)
+ {
+ architecture = bfd_scan_arch (*lp);
+ if (architecture == NULL)
+ continue;
+
+ simarch = simarch_lookup (architecture);
+ if (simarch)
+ break;
+ }
+ free (list);
+ }
+
+ done:
+ STATE_SIMARCH (sd) = simarch;
+ return simarch ? SIM_RC_OK : SIM_RC_FAIL;
+}
new file mode 100644
@@ -0,0 +1,58 @@
+/* Simulator arch ops for support multiple targets in a single build.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Mike Frysinger.
+
+ This file is part of simulators.
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SIM_SIMARCH_H
+#define SIM_SIMARCH_H
+
+/* Not all targets have been converted yet. */
+#ifndef WITH_SIMARCH
+#define WITH_SIMARCH 0
+#endif
+
+typedef SIM_RC (SIM_SIMARCH_REGISTER_FN) (void);
+
+struct sim_mach;
+
+typedef struct simarch
+{
+ /* Runtime callbacks. */
+ void (*engine_run) (SIM_DESC, int, int, int);
+
+ /* Init callbacks. */
+ void (*state_init) (SIM_DESC);
+ void (*cpu_init) (SIM_CPU *);
+ void (*inferior_init) (SIM_DESC, struct bfd *,
+ const char * const *argv, const char * const *envp);
+
+ /* Arch settings. */
+ enum sim_environment default_environment;
+ enum bfd_endian default_endian;
+ enum sim_alignments default_alignment;
+
+ const char *default_model;
+ const struct sim_mach **machs;
+} simarch;
+
+SIM_RC sim_simarch_register (enum bfd_architecture bfd_architecture,
+ const simarch *simarch);
+
+SIM_RC sim_simarch_lookup (SIM_DESC);
+
+#endif /* SIM_SIMARCH_H */