/* interp.c -- Simulator for Motorola 68HC11/68HC12
- Copyright (C) 1999-2015 Free Software Foundation, Inc.
+ Copyright (C) 1999-2021 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@nerim.fr)
This file is part of GDB, the GNU debugger.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+/* This must come before any other includes. */
+#include "defs.h"
+
#include "sim-main.h"
#include "sim-assert.h"
#include "sim-hw.h"
static void sim_get_info (SIM_DESC sd, char *cmd);
-
-char *interrupt_names[] = {
- "reset",
- "nmi",
- "int",
- NULL
-};
-
-#ifndef INLINE
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
-#define INLINE __inline__
-#else
-#define INLINE
-#endif
-#endif
-
struct sim_info_list
{
const char *name;
sim_io_eprintf (sd, "Valid devices: cpu timer sio eeprom\n");
return;
}
- hw_dev = sim_hw_parse (sd, dev_list[i].device);
+ hw_dev = sim_hw_parse (sd, "%s", dev_list[i].device);
if (hw_dev == 0)
{
sim_io_eprintf (sd, "Device '%s' not found\n", dev_list[i].device);
cpu_type = "/m68hc12";
}
- hw_cpu = sim_hw_parse (sd, cpu_type);
+ hw_cpu = sim_hw_parse (sd, "%s", cpu_type);
if (hw_cpu == 0)
{
sim_io_eprintf (sd, "%s cpu not found in device tree.", cpu_type);
/* Allocate core managed memory */
/* the monitor */
- sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
+ sim_do_commandf (sd, "memory region 0x%x@%d,0x%x",
/* MONITOR_BASE, MONITOR_SIZE */
0x8000, M6811_RAM_LEVEL, 0x8000);
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
sim_hw_parse (sd, "/m68hc11/reg 0x1000 0x03F");
if (cpu->bank_start < cpu->bank_end)
{
- sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
+ sim_do_commandf (sd, "memory region 0x%x@%d,0x100000",
cpu->bank_virtual, M6811_RAM_LEVEL);
sim_hw_parse (sd, "/m68hc11/use_bank 1");
}
if (hw_tree_find_property (device_tree, "/m68hc12/reg") == 0)
{
/* Allocate core external memory. */
- sim_do_commandf (sd, "memory region 0x%lx@%d,0x%lx",
+ sim_do_commandf (sd, "memory region 0x%x@%d,0x%x",
0x8000, M6811_RAM_LEVEL, 0x8000);
sim_do_commandf (sd, "memory region 0x000@%d,0x8000",
M6811_RAM_LEVEL);
if (cpu->bank_start < cpu->bank_end)
{
- sim_do_commandf (sd, "memory region 0x%lx@%d,0x100000",
+ sim_do_commandf (sd, "memory region 0x%x@%d,0x100000",
cpu->bank_virtual, M6811_RAM_LEVEL);
sim_hw_parse (sd, "/m68hc12/use_bank 1");
}
/* Get the memory bank parameters by looking at the global symbols
defined by the linker. */
static int
-sim_get_bank_parameters (SIM_DESC sd, bfd* abfd)
+sim_get_bank_parameters (SIM_DESC sd)
{
sim_cpu *cpu;
- long symsize;
- long symbol_count, i;
unsigned size;
- asymbol** asymbols;
- asymbol** current;
+ bfd_vma addr;
cpu = STATE_CPU (sd, 0);
- symsize = bfd_get_symtab_upper_bound (abfd);
- if (symsize < 0)
- {
- sim_io_eprintf (sd, "Cannot read symbols of program");
- return 0;
- }
- asymbols = (asymbol **) xmalloc (symsize);
- symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
- if (symbol_count < 0)
- {
- sim_io_eprintf (sd, "Cannot read symbols of program");
- return 0;
- }
+ addr = trace_sym_value (sd, BFD_M68HC11_BANK_START_NAME);
+ if (addr != -1)
+ cpu->bank_start = addr;
- size = 0;
- for (i = 0, current = asymbols; i < symbol_count; i++, current++)
- {
- const char* name = bfd_asymbol_name (*current);
+ size = trace_sym_value (sd, BFD_M68HC11_BANK_SIZE_NAME);
+ if (size == -1)
+ size = 0;
- if (strcmp (name, BFD_M68HC11_BANK_START_NAME) == 0)
- {
- cpu->bank_start = bfd_asymbol_value (*current);
- }
- else if (strcmp (name, BFD_M68HC11_BANK_SIZE_NAME) == 0)
- {
- size = bfd_asymbol_value (*current);
- }
- else if (strcmp (name, BFD_M68HC11_BANK_VIRTUAL_NAME) == 0)
- {
- cpu->bank_virtual = bfd_asymbol_value (*current);
- }
- }
- free (asymbols);
+ addr = trace_sym_value (sd, BFD_M68HC11_BANK_VIRTUAL_NAME);
+ if (addr != -1)
+ cpu->bank_virtual = addr;
cpu->bank_end = cpu->bank_start + size;
cpu->bank_shift = 0;
{
bfd_size_type size;
- size = bfd_get_section_size (s);
+ size = bfd_section_size (s);
if (size > 0)
{
bfd_vma lma;
if (STATE_LOAD_AT_LMA_P (sd))
- lma = bfd_section_lma (abfd, s);
+ lma = bfd_section_lma (s);
else
- lma = bfd_section_vma (abfd, s);
+ lma = bfd_section_vma (s);
if (lma <= 0xFFFE && lma+size >= 0x10000)
cpu->cpu_use_elf_start = 0;
if (elf_flags & E_M68HC12_BANKS)
{
- if (sim_get_bank_parameters (sd, abfd) != 0)
+ if (sim_get_bank_parameters (sd) != 0)
sim_io_eprintf (sd, "Memory bank parameters are not initialized\n");
}
}
cpu_set_pc (cpu, pc);
}
+static int m68hc11_reg_fetch (SIM_CPU *, int, unsigned char *, int);
+static int m68hc11_reg_store (SIM_CPU *, int, unsigned char *, int);
+
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
- bfd *abfd, char **argv)
+ bfd *abfd, char * const *argv)
{
int i;
SIM_DESC sd;
SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+ /* Set default options before parsing user options. */
+ current_target_byte_order = BFD_ENDIAN_BIG;
+
/* 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)
+ if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
{
free_state (sd);
return 0;
cpu = STATE_CPU (sd, 0);
- /* for compatibility */
- current_alignment = NONSTRICT_ALIGNMENT;
- current_target_byte_order = BIG_ENDIAN;
-
cpu_initialize (sd, cpu);
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
return 0;
}
- /* getopt will print the error message so we just have to exit if this fails.
- FIXME: Hmmm... in the case of gdb we need getopt to call
- print_filtered. */
+ /* The parser will print an error message for us, so we silently return. */
if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
/* Uninstall the modules to avoid memory leaks,
{
SIM_CPU *cpu = STATE_CPU (sd, i);
+ CPU_REG_FETCH (cpu) = m68hc11_reg_fetch;
+ CPU_REG_STORE (cpu) = m68hc11_reg_store;
CPU_PC_FETCH (cpu) = m68hc11_pc_get;
CPU_PC_STORE (cpu) = m68hc11_pc_set;
}
return sd;
}
-
-void
-sim_close (SIM_DESC sd, int quitting)
-{
- /* shut down modules */
- sim_module_uninstall (sd);
-
- /* Ensure that any resources allocated through the callback
- mechanism are released: */
- sim_io_shutdown (sd);
-
- /* FIXME - free SD */
- sim_state_free (sd);
- return;
-}
-
/* Generic implementation of sim_engine_run that works within the
sim_engine setjmp/longjmp framework. */
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
- char **argv, char **env)
+ char * const *argv, char * const *env)
{
return sim_prepare_for_program (sd, abfd);
}
-int
-sim_fetch_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+m68hc11_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
- sim_cpu *cpu;
uint16 val;
int size = 2;
- cpu = STATE_CPU (sd, 0);
switch (rn)
{
case A_REGNUM:
return size;
}
-int
-sim_store_register (SIM_DESC sd, int rn, unsigned char *memory, int length)
+static int
+m68hc11_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
uint16 val;
- sim_cpu *cpu;
-
- cpu = STATE_CPU (sd, 0);
val = *memory++;
if (length == 2)
return 2;
}
-
-/* Halt the simulator after just one instruction */
-
-static void
-has_stepped (SIM_DESC sd,
- void *data)
-{
- ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
- sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
-}
-
-
-/* Generic resume - assumes the existance of sim_engine_run */
-
-void
-sim_resume (SIM_DESC sd,
- int step,
- int siggnal)
-{
- sim_engine *engine = STATE_ENGINE (sd);
- jmp_buf buf;
- int jmpval;
-
- ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
-
- /* we only want to be single stepping the simulator once */
- if (engine->stepper != NULL)
- {
- sim_events_deschedule (sd, engine->stepper);
- engine->stepper = NULL;
- }
- sim_module_resume (sd);
-
- /* run/resume the simulator */
- engine->jmpbuf = &buf;
- jmpval = setjmp (buf);
- if (jmpval == sim_engine_start_jmpval
- || jmpval == sim_engine_restart_jmpval)
- {
- int last_cpu_nr = sim_engine_last_cpu_nr (sd);
- int next_cpu_nr = sim_engine_next_cpu_nr (sd);
- int nr_cpus = sim_engine_nr_cpus (sd);
-
- sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
- if (next_cpu_nr >= nr_cpus)
- next_cpu_nr = 0;
-
- /* Only deliver the siggnal ]sic] the first time through - don't
- re-deliver any siggnal during a restart. */
- if (jmpval == sim_engine_restart_jmpval)
- siggnal = 0;
-
- /* Install the stepping event after having processed some
- pending events. This is necessary for HC11/HC12 simulator
- because the tick counter is incremented by the number of cycles
- the instruction took. Some pending ticks to process can still
- be recorded internally by the simulator and sim_events_preprocess
- will handle them. If the stepping event is inserted before,
- these pending ticks will raise the event and the simulator will
- stop without having executed any instruction. */
- if (step)
- engine->stepper = sim_events_schedule (sd, 0, has_stepped, sd);
-
-#ifdef SIM_CPU_EXCEPTION_RESUME
- {
- sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr);
- SIM_CPU_EXCEPTION_RESUME(sd, cpu, siggnal);
- }
-#endif
-
- sim_engine_run (sd, next_cpu_nr, nr_cpus, siggnal);
- }
- engine->jmpbuf = NULL;
-
- sim_module_suspend (sd);
-}