+#include "config.h"
+#include <inttypes.h>
#include <signal.h>
-#include "sysdep.h"
#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"
-#include "d10v_sim.h"
+#include "sim-main.h"
+#include "sim-options.h"
+
#include "gdb/sim-d10v.h"
#include "gdb/signals.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRING_H */
+#endif /* HAVE_STRINGS_H */
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
enum _leftright { LEFT_FIRST, RIGHT_FIRST };
-static char *myname;
-static SIM_OPEN_KIND sim_kind;
int d10v_debug;
/* Set this to true to get the previous segment layout. */
int old_segment_mapping;
-host_callback *d10v_callback;
unsigned long ins_type_counters[ (int)INS_MAX ];
uint16 OP[4];
-static int init_text_p = 0;
-/* non-zero if we opened prog_bfd */
-static int prog_bfd_was_opened_p;
-bfd *prog_bfd;
-asection *text;
-bfd_vma text_start;
-bfd_vma text_end;
-
-static long hash PARAMS ((long insn, int format));
-static struct hash_entry *lookup_hash PARAMS ((uint32 ins, int size));
-static void get_operands PARAMS ((struct simops *s, uint32 ins));
-static void do_long PARAMS ((uint32 ins));
-static void do_2_short PARAMS ((uint16 ins1, uint16 ins2, enum _leftright leftright));
-static void do_parallel PARAMS ((uint16 ins1, uint16 ins2));
-static char *add_commas PARAMS ((char *buf, int sizeof_buf, unsigned long value));
-extern void sim_set_profile PARAMS ((int n));
-extern void sim_set_profile_size PARAMS ((int n));
-static INLINE uint8 *map_memory (unsigned phys_addr);
-
-#ifdef NEED_UI_LOOP_HOOK
-/* How often to run the ui_loop update, when in use */
-#define UI_LOOP_POLL_INTERVAL 0x14000
-
-/* Counter for the ui_loop_hook update */
-static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
-
-/* Actual hook to call to run through gdb's gui event loop */
-extern int (*deprecated_ui_loop_hook) PARAMS ((int signo));
-#endif /* NEED_UI_LOOP_HOOK */
-
-#ifndef INLINE
-#if defined(__GNUC__) && defined(__OPTIMIZE__)
-#define INLINE __inline__
-#else
-#define INLINE
-#endif
-#endif
+static long hash (long insn, int format);
+static struct hash_entry *lookup_hash (SIM_DESC, SIM_CPU *, uint32 ins, int size);
+static void get_operands (struct simops *s, uint32 ins);
+static void do_long (SIM_DESC, SIM_CPU *, uint32 ins);
+static void do_2_short (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2, enum _leftright leftright);
+static void do_parallel (SIM_DESC, SIM_CPU *, uint16 ins1, uint16 ins2);
+static char *add_commas (char *buf, int sizeof_buf, unsigned long value);
+static INLINE uint8 *map_memory (SIM_DESC, SIM_CPU *, unsigned phys_addr);
#define MAX_HASH 63
struct hash_entry
struct hash_entry hash_table[MAX_HASH+1];
INLINE static long
-hash(insn, format)
- long insn;
- int format;
+hash (long insn, int format)
{
if (format & LONG_OPCODE)
return ((insn & 0x3F000000) >> 24);
}
INLINE static struct hash_entry *
-lookup_hash (ins, size)
- uint32 ins;
- int size;
+lookup_hash (SIM_DESC sd, SIM_CPU *cpu, uint32 ins, int size)
{
struct hash_entry *h;
while ((ins & h->mask) != h->opcode || h->size != size)
{
if (h->next == NULL)
- {
- State.exception = SIGILL;
- State.pc_changed = 1; /* Don't increment the PC. */
- return NULL;
- }
+ sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGILL);
h = h->next;
}
return (h);
State.trace.psw = PSW;
}
-bfd_vma
-decode_pc ()
-{
- asection *s;
- if (!init_text_p && prog_bfd != NULL)
- {
- init_text_p = 1;
- for (s = prog_bfd->sections; s; s = s->next)
- if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
- {
- text = s;
- text_start = bfd_get_section_vma (prog_bfd, s);
- text_end = text_start + bfd_section_size (prog_bfd, s);
- break;
- }
- }
-
- return (PC << 2) + text_start;
-}
-
static void
-do_long (ins)
- uint32 ins;
+do_long (SIM_DESC sd, SIM_CPU *cpu, uint32 ins)
{
struct hash_entry *h;
#ifdef DEBUG
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
- (*d10v_callback->printf_filtered) (d10v_callback, "do_long 0x%x\n", ins);
+ sim_io_printf (sd, "do_long 0x%x\n", ins);
#endif
- h = lookup_hash (ins, 1);
+ h = lookup_hash (sd, cpu, ins, 1);
if (h == NULL)
return;
get_operands (h->ops, ins);
State.ins_type = INS_LONG;
ins_type_counters[ (int)State.ins_type ]++;
- (h->ops->func)();
+ (h->ops->func) (sd, cpu);
}
static void
-do_2_short (ins1, ins2, leftright)
- uint16 ins1, ins2;
- enum _leftright leftright;
+do_2_short (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2, enum _leftright leftright)
{
struct hash_entry *h;
enum _ins_type first, second;
#ifdef DEBUG
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
- (*d10v_callback->printf_filtered) (d10v_callback, "do_2_short 0x%x (%s) -> 0x%x\n",
- ins1, (leftright) ? "left" : "right", ins2);
+ sim_io_printf (sd, "do_2_short 0x%x (%s) -> 0x%x\n", ins1,
+ leftright ? "left" : "right", ins2);
#endif
if (leftright == LEFT_FIRST)
}
/* Issue the first instruction */
- h = lookup_hash (ins1, 0);
+ h = lookup_hash (sd, cpu, ins1, 0);
if (h == NULL)
return;
get_operands (h->ops, ins1);
State.ins_type = first;
ins_type_counters[ (int)State.ins_type ]++;
- (h->ops->func)();
+ (h->ops->func) (sd, cpu);
/* Issue the second instruction (if the PC hasn't changed) */
- if (!State.pc_changed && !State.exception)
+ if (!State.pc_changed)
{
/* finish any existing instructions */
SLOT_FLUSH ();
- h = lookup_hash (ins2, 0);
+ h = lookup_hash (sd, cpu, ins2, 0);
if (h == NULL)
return;
get_operands (h->ops, ins2);
State.ins_type = second;
ins_type_counters[ (int)State.ins_type ]++;
ins_type_counters[ (int)INS_CYCLES ]++;
- (h->ops->func)();
+ (h->ops->func) (sd, cpu);
}
- else if (!State.exception)
+ else
ins_type_counters[ (int)INS_COND_JUMP ]++;
}
static void
-do_parallel (ins1, ins2)
- uint16 ins1, ins2;
+do_parallel (SIM_DESC sd, SIM_CPU *cpu, uint16 ins1, uint16 ins2)
{
struct hash_entry *h1, *h2;
#ifdef DEBUG
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
- (*d10v_callback->printf_filtered) (d10v_callback, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
+ sim_io_printf (sd, "do_parallel 0x%x || 0x%x\n", ins1, ins2);
#endif
ins_type_counters[ (int)INS_PARALLEL ]++;
- h1 = lookup_hash (ins1, 0);
+ h1 = lookup_hash (sd, cpu, ins1, 0);
if (h1 == NULL)
return;
- h2 = lookup_hash (ins2, 0);
+ h2 = lookup_hash (sd, cpu, ins2, 0);
if (h2 == NULL)
return;
get_operands (h1->ops, ins1);
State.ins_type = INS_LEFT_COND_TEST;
ins_type_counters[ (int)State.ins_type ]++;
- (h1->ops->func)();
+ (h1->ops->func) (sd, cpu);
if (State.exe)
{
ins_type_counters[ (int)INS_COND_TRUE ]++;
get_operands (h2->ops, ins2);
State.ins_type = INS_RIGHT_COND_EXE;
ins_type_counters[ (int)State.ins_type ]++;
- (h2->ops->func)();
+ (h2->ops->func) (sd, cpu);
}
else
ins_type_counters[ (int)INS_COND_FALSE ]++;
get_operands (h2->ops, ins2);
State.ins_type = INS_RIGHT_COND_TEST;
ins_type_counters[ (int)State.ins_type ]++;
- (h2->ops->func)();
+ (h2->ops->func) (sd, cpu);
if (State.exe)
{
ins_type_counters[ (int)INS_COND_TRUE ]++;
get_operands (h1->ops, ins1);
State.ins_type = INS_LEFT_COND_EXE;
ins_type_counters[ (int)State.ins_type ]++;
- (h1->ops->func)();
+ (h1->ops->func) (sd, cpu);
}
else
ins_type_counters[ (int)INS_COND_FALSE ]++;
get_operands (h1->ops, ins1);
State.ins_type = INS_LEFT_PARALLEL;
ins_type_counters[ (int)State.ins_type ]++;
- (h1->ops->func)();
- if (!State.exception)
- {
- get_operands (h2->ops, ins2);
- State.ins_type = INS_RIGHT_PARALLEL;
- ins_type_counters[ (int)State.ins_type ]++;
- (h2->ops->func)();
- }
+ (h1->ops->func) (sd, cpu);
+ get_operands (h2->ops, ins2);
+ State.ins_type = INS_RIGHT_PARALLEL;
+ ins_type_counters[ (int)State.ins_type ]++;
+ (h2->ops->func) (sd, cpu);
}
}
static char *
-add_commas(buf, sizeof_buf, value)
- char *buf;
- int sizeof_buf;
- unsigned long value;
+add_commas (char *buf, int sizeof_buf, unsigned long value)
{
int comma = 3;
char *endbuf = buf + sizeof_buf - 1;
return endbuf;
}
-void
-sim_size (power)
- int power;
-
+static void
+sim_size (int power)
{
int i;
for (i = 0; i < IMEM_SEGMENTS; i++)
};
static void
-set_dmap_register (int reg_nr, unsigned long value)
+set_dmap_register (SIM_DESC sd, int reg_nr, unsigned long value)
{
- uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
+ uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
+ DMAP0_OFFSET + 2 * reg_nr);
WRITE_16 (raw, value);
#ifdef DEBUG
if ((d10v_debug & DEBUG_MEMORY))
{
- (*d10v_callback->printf_filtered)
- (d10v_callback, "mem: dmap%d=0x%04lx\n", reg_nr, value);
+ sim_io_printf (sd, "mem: dmap%d=0x%04lx\n", reg_nr, value);
}
#endif
}
static unsigned long
-dmap_register (void *regcache, int reg_nr)
+dmap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
{
- uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
+ uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
+ DMAP0_OFFSET + 2 * reg_nr);
return READ_16 (raw);
}
static void
-set_imap_register (int reg_nr, unsigned long value)
+set_imap_register (SIM_DESC sd, int reg_nr, unsigned long value)
{
- uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
+ uint8 *raw = map_memory (sd, NULL, SIM_D10V_MEMORY_DATA
+ IMAP0_OFFSET + 2 * reg_nr);
WRITE_16 (raw, value);
#ifdef DEBUG
if ((d10v_debug & DEBUG_MEMORY))
{
- (*d10v_callback->printf_filtered)
- (d10v_callback, "mem: imap%d=0x%04lx\n", reg_nr, value);
+ sim_io_printf (sd, "mem: imap%d=0x%04lx\n", reg_nr, value);
}
#endif
}
static unsigned long
-imap_register (void *regcache, int reg_nr)
+imap_register (SIM_DESC sd, SIM_CPU *cpu, void *regcache, int reg_nr)
{
- uint8 *raw = map_memory (SIM_D10V_MEMORY_DATA
+ uint8 *raw = map_memory (sd, cpu, SIM_D10V_MEMORY_DATA
+ IMAP0_OFFSET + 2 * reg_nr);
return READ_16 (raw);
}
/* Given a virtual address in the DMAP address space, translate it
into a physical address. */
-unsigned long
-sim_d10v_translate_dmap_addr (unsigned long offset,
+static unsigned long
+sim_d10v_translate_dmap_addr (SIM_DESC sd,
+ SIM_CPU *cpu,
+ unsigned long offset,
int nr_bytes,
unsigned long *phys,
void *regcache,
- unsigned long (*dmap_register) (void *regcache,
+ unsigned long (*dmap_register) (SIM_DESC,
+ SIM_CPU *,
+ void *regcache,
int reg_nr))
{
short map;
/* Don't cross a BLOCK boundary */
nr_bytes = DMAP_BLOCK_SIZE - (offset % DMAP_BLOCK_SIZE);
}
- map = dmap_register (regcache, regno);
+ map = dmap_register (sd, cpu, regcache, regno);
if (regno == 3)
{
/* Always maps to data memory */
/* Given a virtual address in the IMAP address space, translate it
into a physical address. */
-unsigned long
-sim_d10v_translate_imap_addr (unsigned long offset,
+static unsigned long
+sim_d10v_translate_imap_addr (SIM_DESC sd,
+ SIM_CPU *cpu,
+ unsigned long offset,
int nr_bytes,
unsigned long *phys,
void *regcache,
- unsigned long (*imap_register) (void *regcache,
+ unsigned long (*imap_register) (SIM_DESC,
+ SIM_CPU *,
+ void *regcache,
int reg_nr))
{
short map;
/* Don't cross a BLOCK boundary */
nr_bytes = IMAP_BLOCK_SIZE - offset;
}
- map = imap_register (regcache, regno);
+ map = imap_register (sd, cpu, regcache, regno);
sp = (map & 0x3000) >> 12;
segno = (map & 0x007f);
switch (sp)
return nr_bytes;
}
-unsigned long
-sim_d10v_translate_addr (unsigned long memaddr,
+static unsigned long
+sim_d10v_translate_addr (SIM_DESC sd,
+ SIM_CPU *cpu,
+ unsigned long memaddr,
int nr_bytes,
unsigned long *targ_addr,
void *regcache,
- unsigned long (*dmap_register) (void *regcache,
+ unsigned long (*dmap_register) (SIM_DESC,
+ SIM_CPU *,
+ void *regcache,
int reg_nr),
- unsigned long (*imap_register) (void *regcache,
+ unsigned long (*imap_register) (SIM_DESC,
+ SIM_CPU *,
+ void *regcache,
int reg_nr))
{
unsigned long phys;
break;
case 0x10: /* in logical data address segment */
- nr_bytes = sim_d10v_translate_dmap_addr (off, nr_bytes, &phys, regcache,
- dmap_register);
+ nr_bytes = sim_d10v_translate_dmap_addr (sd, cpu, off, nr_bytes, &phys,
+ regcache, dmap_register);
break;
case 0x11: /* in logical instruction address segment */
- nr_bytes = sim_d10v_translate_imap_addr (off, nr_bytes, &phys, regcache,
- imap_register);
+ nr_bytes = sim_d10v_translate_imap_addr (sd, cpu, off, nr_bytes, &phys,
+ regcache, imap_register);
break;
default:
isn't going to cross a segment boundary. */
uint8 *
-map_memory (unsigned phys_addr)
+map_memory (SIM_DESC sd, SIM_CPU *cpu, unsigned phys_addr)
{
uint8 **memory;
uint8 *raw;
default:
/* OOPS! */
last_segname = "scrap";
- return State.mem.fault;
+ sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
}
if (*memory == NULL)
- {
- *memory = calloc (1, SEGMENT_SIZE);
- if (*memory == NULL)
- {
- (*d10v_callback->printf_filtered) (d10v_callback, "Malloc failed.\n");
- return State.mem.fault;
- }
- }
+ *memory = xcalloc (1, SEGMENT_SIZE);
offset = (phys_addr % SEGMENT_SIZE);
raw = *memory + offset;
than aborting the entire run. */
static int
-xfer_mem (SIM_ADDR virt,
+xfer_mem (SIM_DESC sd,
+ SIM_ADDR virt,
unsigned char *buffer,
int size,
int write_p)
uint8 *memory;
unsigned long phys;
int phys_size;
- phys_size = sim_d10v_translate_addr (virt, size, &phys, NULL,
+ phys_size = sim_d10v_translate_addr (sd, NULL, virt, size, &phys, NULL,
dmap_register, imap_register);
if (phys_size == 0)
return 0;
- memory = map_memory (phys);
+ memory = map_memory (sd, NULL, phys);
#ifdef DEBUG
if ((d10v_debug & DEBUG_INSTRUCTION) != 0)
{
- (*d10v_callback->printf_filtered)
- (d10v_callback,
+ sim_io_printf
+ (sd,
"sim_%s %d bytes: 0x%08lx (%s) -> 0x%08lx (%s) -> 0x%08lx (%s)\n",
- (write_p ? "write" : "read"),
+ write_p ? "write" : "read",
phys_size, virt, last_from,
phys, last_to,
(long) memory, last_segname);
int
-sim_write (sd, addr, buffer, size)
- SIM_DESC sd;
- SIM_ADDR addr;
- const unsigned char *buffer;
- int size;
+sim_write (SIM_DESC sd, SIM_ADDR addr, const unsigned char *buffer, int size)
{
/* FIXME: this should be performing a virtual transfer */
- return xfer_mem( addr, buffer, size, 1);
+ return xfer_mem (sd, addr, buffer, size, 1);
}
int
-sim_read (sd, addr, buffer, size)
- SIM_DESC sd;
- SIM_ADDR addr;
- unsigned char *buffer;
- int size;
+sim_read (SIM_DESC sd, SIM_ADDR addr, unsigned char *buffer, int size)
{
/* FIXME: this should be performing a virtual transfer */
- return xfer_mem( addr, buffer, size, 0);
+ return xfer_mem (sd, addr, buffer, size, 0);
+}
+
+static sim_cia
+d10v_pc_get (sim_cpu *cpu)
+{
+ return PC;
+}
+
+static void
+d10v_pc_set (sim_cpu *cpu, sim_cia pc)
+{
+ SIM_DESC sd = CPU_STATE (cpu);
+ SET_PC (pc);
+}
+
+static void
+free_state (SIM_DESC sd)
+{
+ if (STATE_MODULES (sd) != NULL)
+ sim_module_uninstall (sd);
+ sim_cpu_free_all (sd);
+ sim_state_free (sd);
}
+static int d10v_reg_fetch (SIM_CPU *, int, unsigned char *, int);
+static int d10v_reg_store (SIM_CPU *, int, unsigned char *, int);
SIM_DESC
-sim_open (kind, callback, abfd, argv)
- SIM_OPEN_KIND kind;
- host_callback *callback;
- struct bfd *abfd;
- char **argv;
+sim_open (SIM_OPEN_KIND kind, host_callback *cb,
+ struct bfd *abfd, char * const *argv)
{
struct simops *s;
struct hash_entry *h;
static int init_p = 0;
char **p;
+ int i;
+ SIM_DESC sd = sim_state_alloc (kind, cb);
+ 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, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
+
+ /* 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;
+ }
+
+ /* 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;
+ }
+
+ /* Configure/verify the target byte order and other runtime
+ configuration options. */
+ if (sim_config (sd) != SIM_RC_OK)
+ {
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ if (sim_post_argv_init (sd) != SIM_RC_OK)
+ {
+ /* Uninstall the modules to avoid memory leaks,
+ file descriptor leaks, etc. */
+ sim_module_uninstall (sd);
+ return 0;
+ }
+
+ /* CPU specific initialization. */
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, i);
+
+ CPU_REG_FETCH (cpu) = d10v_reg_fetch;
+ CPU_REG_STORE (cpu) = d10v_reg_store;
+ CPU_PC_FETCH (cpu) = d10v_pc_get;
+ CPU_PC_STORE (cpu) = d10v_pc_set;
+ }
- sim_kind = kind;
- d10v_callback = callback;
- myname = argv[0];
old_segment_mapping = 0;
/* NOTE: This argument parsing is only effective when this function
else if (strncmp (*p, "-t", 2) == 0)
d10v_debug = atoi (*p + 2);
#endif
- else
- (*d10v_callback->printf_filtered) (d10v_callback, "ERROR: unsupported option(s): %s\n",*p);
}
/* put all the opcodes in the hash table */
/* reset the processor state */
if (!State.mem.data[0])
sim_size (1);
- sim_create_inferior ((SIM_DESC) 1, NULL, NULL, NULL);
-
- /* Fudge our descriptor. */
- return (SIM_DESC) 1;
-}
-
-
-void
-sim_close (sd, quitting)
- SIM_DESC sd;
- int quitting;
-{
- if (prog_bfd != NULL && prog_bfd_was_opened_p)
- {
- bfd_close (prog_bfd);
- prog_bfd = NULL;
- prog_bfd_was_opened_p = 0;
- }
-}
-
-void
-sim_set_profile (n)
- int n;
-{
- (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile %d\n",n);
-}
-void
-sim_set_profile_size (n)
- int n;
-{
- (*d10v_callback->printf_filtered) (d10v_callback, "sim_set_profile_size %d\n",n);
+ return sd;
}
uint8 *
-dmem_addr (uint16 offset)
+dmem_addr (SIM_DESC sd, SIM_CPU *cpu, uint16 offset)
{
unsigned long phys;
uint8 *mem;
things like ``0xfffe + 0x0e60 == 0x10e5d''. Since offset's type
is uint16 this is modulo'ed onto 0x0e5d. */
- phys_size = sim_d10v_translate_dmap_addr (offset, 1, &phys, NULL,
+ phys_size = sim_d10v_translate_dmap_addr (sd, cpu, offset, 1, &phys, NULL,
dmap_register);
if (phys_size == 0)
- {
- mem = State.mem.fault;
- }
- else
- mem = map_memory (phys);
+ sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
+ mem = map_memory (sd, cpu, phys);
#ifdef DEBUG
if ((d10v_debug & DEBUG_MEMORY))
{
- (*d10v_callback->printf_filtered)
- (d10v_callback,
+ sim_io_printf
+ (sd,
"mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
offset, last_from,
phys, phys_size, last_to,
}
uint8 *
-imem_addr (uint32 offset)
+imem_addr (SIM_DESC sd, SIM_CPU *cpu, uint32 offset)
{
unsigned long phys;
uint8 *mem;
- int phys_size = sim_d10v_translate_imap_addr (offset, 1, &phys, NULL,
+ int phys_size = sim_d10v_translate_imap_addr (sd, cpu, offset, 1, &phys, NULL,
imap_register);
if (phys_size == 0)
- {
- return State.mem.fault;
- }
- mem = map_memory (phys);
+ sim_engine_halt (sd, cpu, NULL, PC, sim_stopped, SIM_SIGBUS);
+ mem = map_memory (sd, cpu, phys);
#ifdef DEBUG
if ((d10v_debug & DEBUG_MEMORY))
{
- (*d10v_callback->printf_filtered)
- (d10v_callback,
+ sim_io_printf
+ (sd,
"mem: 0x%08x (%s) -> 0x%08lx %d (%s) -> 0x%08lx (%s)\n",
offset, last_from,
phys, phys_size, last_to,
return mem;
}
-static int stop_simulator = 0;
-
-int
-sim_stop (sd)
- SIM_DESC sd;
-{
- stop_simulator = 1;
- return 1;
-}
-
-
-/* Run (or resume) the program. */
-void
-sim_resume (sd, step, siggnal)
- SIM_DESC sd;
- int step, siggnal;
+static void
+step_once (SIM_DESC sd, SIM_CPU *cpu)
{
uint32 inst;
uint8 *iaddr;
-/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_resume (%d,%d) PC=0x%x\n",step,siggnal,PC); */
- State.exception = 0;
- if (step)
- sim_stop (sd);
-
- switch (siggnal)
+ /* TODO: Unindent this block. */
{
- case 0:
- break;
-#ifdef SIGBUS
- case SIGBUS:
-#endif
- case SIGSEGV:
- SET_BPC (PC);
- SET_BPSW (PSW);
- SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
- JMP (AE_VECTOR_START);
- SLOT_FLUSH ();
- break;
- case SIGILL:
- SET_BPC (PC);
- SET_BPSW (PSW);
- SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
- JMP (RIE_VECTOR_START);
- SLOT_FLUSH ();
- break;
- default:
- /* just ignore it */
- break;
- }
-
- do
- {
- iaddr = imem_addr ((uint32)PC << 2);
- if (iaddr == State.mem.fault)
- {
- State.exception = SIGBUS;
- break;
- }
+ iaddr = imem_addr (sd, cpu, (uint32)PC << 2);
inst = get_longword( iaddr );
{
case 0xC0000000:
/* long instruction */
- do_long (inst & 0x3FFFFFFF);
+ do_long (sd, cpu, inst & 0x3FFFFFFF);
break;
case 0x80000000:
/* R -> L */
- do_2_short ( inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
+ do_2_short (sd, cpu, inst & 0x7FFF, (inst & 0x3FFF8000) >> 15, RIGHT_FIRST);
break;
case 0x40000000:
/* L -> R */
- do_2_short ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
+ do_2_short (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF, LEFT_FIRST);
break;
case 0:
- do_parallel ((inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
+ do_parallel (sd, cpu, (inst & 0x3FFF8000) >> 15, inst & 0x7FFF);
break;
}
/* Writeback all the DATA / PC changes */
SLOT_FLUSH ();
-
-#ifdef NEED_UI_LOOP_HOOK
- if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
- {
- ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
- deprecated_ui_loop_hook (0);
- }
-#endif /* NEED_UI_LOOP_HOOK */
}
- while ( !State.exception && !stop_simulator);
-
- if (step && !State.exception)
- State.exception = SIGTRAP;
}
void
-sim_set_trace (void)
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal)
{
-#ifdef DEBUG
- d10v_debug = DEBUG;
-#endif
+ sim_cpu *cpu;
+
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ cpu = STATE_CPU (sd, 0);
+
+ switch (siggnal)
+ {
+ case 0:
+ break;
+ case GDB_SIGNAL_BUS:
+ SET_BPC (PC);
+ SET_BPSW (PSW);
+ SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
+ JMP (AE_VECTOR_START);
+ SLOT_FLUSH ();
+ break;
+ case GDB_SIGNAL_ILL:
+ SET_BPC (PC);
+ SET_BPSW (PSW);
+ SET_HW_PSW ((PSW & (PSW_F0_BIT | PSW_F1_BIT | PSW_C_BIT)));
+ JMP (RIE_VECTOR_START);
+ SLOT_FLUSH ();
+ break;
+ default:
+ /* just ignore it */
+ break;
+ }
+
+ while (1)
+ {
+ step_once (sd, cpu);
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
+ }
}
void
-sim_info (sd, verbose)
- SIM_DESC sd;
- int verbose;
+sim_info (SIM_DESC sd, int verbose)
{
char buf1[40];
char buf2[40];
int nop_size = strlen (add_commas (buf1, sizeof (buf1), (left_nops > right_nops) ? left_nops : right_nops));
int normal_size = strlen (add_commas (buf1, sizeof (buf1), (left > right) ? left : right));
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
- size, add_commas (buf1, sizeof (buf1), left_total),
- normal_size, add_commas (buf2, sizeof (buf2), left),
- parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
- cond_size, add_commas (buf4, sizeof (buf4), left_cond),
- nop_size, add_commas (buf5, sizeof (buf5), left_nops));
-
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
- size, add_commas (buf1, sizeof (buf1), right_total),
- normal_size, add_commas (buf2, sizeof (buf2), right),
- parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
- cond_size, add_commas (buf4, sizeof (buf4), right_cond),
- nop_size, add_commas (buf5, sizeof (buf5), right_nops));
+ sim_io_printf (sd,
+ "executed %*s left instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
+ size, add_commas (buf1, sizeof (buf1), left_total),
+ normal_size, add_commas (buf2, sizeof (buf2), left),
+ parallel_size, add_commas (buf3, sizeof (buf3), left_parallel),
+ cond_size, add_commas (buf4, sizeof (buf4), left_cond),
+ nop_size, add_commas (buf5, sizeof (buf5), left_nops));
+
+ sim_io_printf (sd,
+ "executed %*s right instruction(s), %*s normal, %*s parallel, %*s EXExxx, %*s nops\n",
+ size, add_commas (buf1, sizeof (buf1), right_total),
+ normal_size, add_commas (buf2, sizeof (buf2), right),
+ parallel_size, add_commas (buf3, sizeof (buf3), right_parallel),
+ cond_size, add_commas (buf4, sizeof (buf4), right_cond),
+ nop_size, add_commas (buf5, sizeof (buf5), right_nops));
if (ins_long)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s long instruction(s)\n",
- size, add_commas (buf1, sizeof (buf1), ins_long));
+ sim_io_printf (sd,
+ "executed %*s long instruction(s)\n",
+ size, add_commas (buf1, sizeof (buf1), ins_long));
if (parallel)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s parallel instruction(s)\n",
- size, add_commas (buf1, sizeof (buf1), parallel));
+ sim_io_printf (sd,
+ "executed %*s parallel instruction(s)\n",
+ size, add_commas (buf1, sizeof (buf1), parallel));
if (leftright)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s instruction(s) encoded L->R\n",
- size, add_commas (buf1, sizeof (buf1), leftright));
+ sim_io_printf (sd,
+ "executed %*s instruction(s) encoded L->R\n",
+ size, add_commas (buf1, sizeof (buf1), leftright));
if (rightleft)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s instruction(s) encoded R->L\n",
- size, add_commas (buf1, sizeof (buf1), rightleft));
+ sim_io_printf (sd,
+ "executed %*s instruction(s) encoded R->L\n",
+ size, add_commas (buf1, sizeof (buf1), rightleft));
if (unknown)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s unknown instruction(s)\n",
- size, add_commas (buf1, sizeof (buf1), unknown));
+ sim_io_printf (sd,
+ "executed %*s unknown instruction(s)\n",
+ size, add_commas (buf1, sizeof (buf1), unknown));
if (cond_true)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s instruction(s) due to EXExxx condition being true\n",
- size, add_commas (buf1, sizeof (buf1), cond_true));
+ sim_io_printf (sd,
+ "executed %*s instruction(s) due to EXExxx condition being true\n",
+ size, add_commas (buf1, sizeof (buf1), cond_true));
if (cond_false)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "skipped %*s instruction(s) due to EXExxx condition being false\n",
- size, add_commas (buf1, sizeof (buf1), cond_false));
+ sim_io_printf (sd,
+ "skipped %*s instruction(s) due to EXExxx condition being false\n",
+ size, add_commas (buf1, sizeof (buf1), cond_false));
if (cond_jump)
- (*d10v_callback->printf_filtered) (d10v_callback,
- "skipped %*s instruction(s) due to conditional branch succeeding\n",
- size, add_commas (buf1, sizeof (buf1), cond_jump));
+ sim_io_printf (sd,
+ "skipped %*s instruction(s) due to conditional branch succeeding\n",
+ size, add_commas (buf1, sizeof (buf1), cond_jump));
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s cycle(s)\n",
- size, add_commas (buf1, sizeof (buf1), cycles));
+ sim_io_printf (sd,
+ "executed %*s cycle(s)\n",
+ size, add_commas (buf1, sizeof (buf1), cycles));
- (*d10v_callback->printf_filtered) (d10v_callback,
- "executed %*s total instructions\n",
- size, add_commas (buf1, sizeof (buf1), total));
+ sim_io_printf (sd,
+ "executed %*s total instructions\n",
+ size, add_commas (buf1, sizeof (buf1), total));
}
SIM_RC
-sim_create_inferior (sd, abfd, argv, env)
- SIM_DESC sd;
- struct bfd *abfd;
- char **argv;
- char **env;
+sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
+ char * const *argv, char * const *env)
{
bfd_vma start_address;
/* reset all state information */
- memset (&State.regs, 0, (int)&State.mem - (int)&State.regs);
+ memset (&State.regs, 0, (uintptr_t)&State.mem - (uintptr_t)&State.regs);
/* There was a hack here to copy the values of argc and argv into r0
and r1. The values were also saved into some high memory that
start_address = 0xffc0 << 2;
#ifdef DEBUG
if (d10v_debug)
- (*d10v_callback->printf_filtered) (d10v_callback, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
+ sim_io_printf (sd, "sim_create_inferior: PC=0x%lx\n", (long) start_address);
#endif
- SET_CREG (PC_CR, start_address >> 2);
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, 0);
+ SET_CREG (PC_CR, start_address >> 2);
+ }
/* cpu resets imap0 to 0 and imap1 to 0x7f, but D10V-EVA board
initializes imap0 and imap1 to 0x1000 as part of its ROM
if (old_segment_mapping)
{
/* External memory startup. This is the HARD reset state. */
- set_imap_register (0, 0x0000);
- set_imap_register (1, 0x007f);
- set_dmap_register (0, 0x2000);
- set_dmap_register (1, 0x2000);
- set_dmap_register (2, 0x0000); /* Old DMAP */
- set_dmap_register (3, 0x0000);
+ set_imap_register (sd, 0, 0x0000);
+ set_imap_register (sd, 1, 0x007f);
+ set_dmap_register (sd, 0, 0x2000);
+ set_dmap_register (sd, 1, 0x2000);
+ set_dmap_register (sd, 2, 0x0000); /* Old DMAP */
+ set_dmap_register (sd, 3, 0x0000);
}
else
{
/* Internal memory startup. This is the ROM intialized state. */
- set_imap_register (0, 0x1000);
- set_imap_register (1, 0x1000);
- set_dmap_register (0, 0x2000);
- set_dmap_register (1, 0x2000);
- set_dmap_register (2, 0x2000); /* DMAP2 initial internal value is
- 0x2000 on the new board. */
- set_dmap_register (3, 0x0000);
+ set_imap_register (sd, 0, 0x1000);
+ set_imap_register (sd, 1, 0x1000);
+ set_dmap_register (sd, 0, 0x2000);
+ set_dmap_register (sd, 1, 0x2000);
+ set_dmap_register (sd, 2, 0x2000); /* DMAP2 initial internal value is
+ 0x2000 on the new board. */
+ set_dmap_register (sd, 3, 0x0000);
}
SLOT_FLUSH ();
return SIM_RC_OK;
}
-
-void
-sim_set_callbacks (p)
- host_callback *p;
-{
- d10v_callback = p;
-}
-
-void
-sim_stop_reason (sd, reason, sigrc)
- SIM_DESC sd;
- enum sim_stop *reason;
- int *sigrc;
-{
-/* (*d10v_callback->printf_filtered) (d10v_callback, "sim_stop_reason: PC=0x%x\n",PC<<2); */
-
- switch (State.exception)
- {
- case SIG_D10V_STOP: /* stop instruction */
- *reason = sim_exited;
- *sigrc = 0;
- break;
-
- case SIG_D10V_EXIT: /* exit trap */
- *reason = sim_exited;
- *sigrc = GPR (0);
- break;
-
- case SIG_D10V_BUS:
- *reason = sim_stopped;
- *sigrc = GDB_SIGNAL_BUS;
- break;
-
- default: /* some signal */
- *reason = sim_stopped;
- if (stop_simulator && !State.exception)
- *sigrc = GDB_SIGNAL_INT;
- else
- *sigrc = State.exception;
- break;
- }
-
- stop_simulator = 0;
-}
-
-int
-sim_fetch_register (sd, rn, memory, length)
- SIM_DESC sd;
- int rn;
- unsigned char *memory;
- int length;
+static int
+d10v_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
+ SIM_DESC sd = CPU_STATE (cpu);
int size;
switch ((enum sim_d10v_regs) rn)
{
break;
case SIM_D10V_IMAP0_REGNUM:
case SIM_D10V_IMAP1_REGNUM:
- WRITE_16 (memory, imap_register (NULL, rn - SIM_D10V_IMAP0_REGNUM));
+ WRITE_16 (memory, imap_register (sd, cpu, NULL, rn - SIM_D10V_IMAP0_REGNUM));
size = 2;
break;
case SIM_D10V_DMAP0_REGNUM:
case SIM_D10V_DMAP1_REGNUM:
case SIM_D10V_DMAP2_REGNUM:
case SIM_D10V_DMAP3_REGNUM:
- WRITE_16 (memory, dmap_register (NULL, rn - SIM_D10V_DMAP0_REGNUM));
+ WRITE_16 (memory, dmap_register (sd, cpu, NULL, rn - SIM_D10V_DMAP0_REGNUM));
size = 2;
break;
case SIM_D10V_TS2_DMAP_REGNUM:
return size;
}
-int
-sim_store_register (sd, rn, memory, length)
- SIM_DESC sd;
- int rn;
- unsigned char *memory;
- int length;
+static int
+d10v_reg_store (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
{
+ SIM_DESC sd = CPU_STATE (cpu);
int size;
switch ((enum sim_d10v_regs) rn)
{
break;
case SIM_D10V_IMAP0_REGNUM:
case SIM_D10V_IMAP1_REGNUM:
- set_imap_register (rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
+ set_imap_register (sd, rn - SIM_D10V_IMAP0_REGNUM, READ_16(memory));
size = 2;
break;
case SIM_D10V_DMAP0_REGNUM:
case SIM_D10V_DMAP1_REGNUM:
case SIM_D10V_DMAP2_REGNUM:
case SIM_D10V_DMAP3_REGNUM:
- set_dmap_register (rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
+ set_dmap_register (sd, rn - SIM_D10V_DMAP0_REGNUM, READ_16(memory));
size = 2;
break;
case SIM_D10V_TS2_DMAP_REGNUM:
SLOT_FLUSH ();
return size;
}
-
-
-void
-sim_do_command (sd, cmd)
- SIM_DESC sd;
- char *cmd;
-{
- (*d10v_callback->printf_filtered) (d10v_callback, "sim_do_command: %s\n",cmd);
-}
-
-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. */
-
- if (prog_bfd != NULL && prog_bfd_was_opened_p)
- {
- bfd_close (prog_bfd);
- prog_bfd_was_opened_p = 0;
- }
- prog_bfd = sim_load_file (sd, myname, d10v_callback, prog, abfd,
- sim_kind == SIM_OPEN_DEBUG,
- 1/*LMA*/, sim_write);
- if (prog_bfd == NULL)
- return SIM_RC_FAIL;
- prog_bfd_was_opened_p = abfd == NULL;
- return SIM_RC_OK;
-}