OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [v850/] [interp.c] - Diff between revs 24 and 157

Only display areas with differences | Details | Blame | View Log

Rev 24 Rev 157
#include "sim-main.h"
#include "sim-main.h"
#include "sim-options.h"
#include "sim-options.h"
#include "v850_sim.h"
#include "v850_sim.h"
#include "sim-assert.h"
#include "sim-assert.h"
#include "itable.h"
#include "itable.h"
 
 
#ifdef HAVE_STDLIB_H
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#include <stdlib.h>
#endif
#endif
 
 
#ifdef HAVE_STRING_H
#ifdef HAVE_STRING_H
#include <string.h>
#include <string.h>
#else
#else
#ifdef HAVE_STRINGS_H
#ifdef HAVE_STRINGS_H
#include <strings.h>
#include <strings.h>
#endif
#endif
#endif
#endif
 
 
#include "bfd.h"
#include "bfd.h"
 
 
#ifndef INLINE
#ifndef INLINE
#ifdef __GNUC__
#ifdef __GNUC__
#define INLINE inline
#define INLINE inline
#else
#else
#define INLINE
#define INLINE
#endif
#endif
#endif
#endif
 
 
static const char * get_insn_name (sim_cpu *, int);
static const char * get_insn_name (sim_cpu *, int);
 
 
/* For compatibility */
/* For compatibility */
SIM_DESC simulator;
SIM_DESC simulator;
 
 
 
 
 
 
/* v850 interrupt model */
/* v850 interrupt model */
 
 
enum interrupt_type
enum interrupt_type
{
{
  int_reset,
  int_reset,
  int_nmi,
  int_nmi,
  int_intov1,
  int_intov1,
  int_intp10,
  int_intp10,
  int_intp11,
  int_intp11,
  int_intp12,
  int_intp12,
  int_intp13,
  int_intp13,
  int_intcm4,
  int_intcm4,
  num_int_types
  num_int_types
};
};
 
 
char *interrupt_names[] = {
char *interrupt_names[] = {
  "reset",
  "reset",
  "nmi",
  "nmi",
  "intov1",
  "intov1",
  "intp10",
  "intp10",
  "intp11",
  "intp11",
  "intp12",
  "intp12",
  "intp13",
  "intp13",
  "intcm4",
  "intcm4",
  NULL
  NULL
};
};
 
 
static void
static void
do_interrupt (sd, data)
do_interrupt (sd, data)
     SIM_DESC sd;
     SIM_DESC sd;
     void *data;
     void *data;
{
{
  char **interrupt_name = (char**)data;
  char **interrupt_name = (char**)data;
  enum interrupt_type inttype;
  enum interrupt_type inttype;
  inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
  inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names);
 
 
  /* For a hardware reset, drop everything and jump to the start
  /* For a hardware reset, drop everything and jump to the start
     address */
     address */
  if (inttype == int_reset)
  if (inttype == int_reset)
    {
    {
      PC = 0;
      PC = 0;
      PSW = 0x20;
      PSW = 0x20;
      ECR = 0;
      ECR = 0;
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
    }
    }
 
 
  /* Deliver an NMI when allowed */
  /* Deliver an NMI when allowed */
  if (inttype == int_nmi)
  if (inttype == int_nmi)
    {
    {
      if (PSW & PSW_NP)
      if (PSW & PSW_NP)
        {
        {
          /* We're already working on an NMI, so this one must wait
          /* We're already working on an NMI, so this one must wait
             around until the previous one is done.  The processor
             around until the previous one is done.  The processor
             ignores subsequent NMIs, so we don't need to count them.
             ignores subsequent NMIs, so we don't need to count them.
             Just keep re-scheduling a single NMI until it manages to
             Just keep re-scheduling a single NMI until it manages to
             be delivered */
             be delivered */
          if (STATE_CPU (sd, 0)->pending_nmi != NULL)
          if (STATE_CPU (sd, 0)->pending_nmi != NULL)
            sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
            sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi);
          STATE_CPU (sd, 0)->pending_nmi =
          STATE_CPU (sd, 0)->pending_nmi =
            sim_events_schedule (sd, 1, do_interrupt, data);
            sim_events_schedule (sd, 1, do_interrupt, data);
          return;
          return;
        }
        }
      else
      else
        {
        {
          /* NMI can be delivered.  Do not deschedule pending_nmi as
          /* NMI can be delivered.  Do not deschedule pending_nmi as
             that, if still in the event queue, is a second NMI that
             that, if still in the event queue, is a second NMI that
             needs to be delivered later. */
             needs to be delivered later. */
          FEPC = PC;
          FEPC = PC;
          FEPSW = PSW;
          FEPSW = PSW;
          /* Set the FECC part of the ECR. */
          /* Set the FECC part of the ECR. */
          ECR &= 0x0000ffff;
          ECR &= 0x0000ffff;
          ECR |= 0x10;
          ECR |= 0x10;
          PSW |= PSW_NP;
          PSW |= PSW_NP;
          PSW &= ~PSW_EP;
          PSW &= ~PSW_EP;
          PSW |= PSW_ID;
          PSW |= PSW_ID;
          PC = 0x10;
          PC = 0x10;
          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
          sim_engine_restart (sd, NULL, NULL, NULL_CIA);
        }
        }
    }
    }
 
 
  /* deliver maskable interrupt when allowed */
  /* deliver maskable interrupt when allowed */
  if (inttype > int_nmi && inttype < num_int_types)
  if (inttype > int_nmi && inttype < num_int_types)
    {
    {
      if ((PSW & PSW_NP) || (PSW & PSW_ID))
      if ((PSW & PSW_NP) || (PSW & PSW_ID))
        {
        {
          /* Can't deliver this interrupt, reschedule it for later */
          /* Can't deliver this interrupt, reschedule it for later */
          sim_events_schedule (sd, 1, do_interrupt, data);
          sim_events_schedule (sd, 1, do_interrupt, data);
          return;
          return;
        }
        }
      else
      else
        {
        {
          /* save context */
          /* save context */
          EIPC = PC;
          EIPC = PC;
          EIPSW = PSW;
          EIPSW = PSW;
          /* Disable further interrupts.  */
          /* Disable further interrupts.  */
          PSW |= PSW_ID;
          PSW |= PSW_ID;
          /* Indicate that we're doing interrupt not exception processing.  */
          /* Indicate that we're doing interrupt not exception processing.  */
          PSW &= ~PSW_EP;
          PSW &= ~PSW_EP;
          /* Clear the EICC part of the ECR, will set below. */
          /* Clear the EICC part of the ECR, will set below. */
          ECR &= 0xffff0000;
          ECR &= 0xffff0000;
          switch (inttype)
          switch (inttype)
            {
            {
            case int_intov1:
            case int_intov1:
              PC = 0x80;
              PC = 0x80;
              ECR |= 0x80;
              ECR |= 0x80;
              break;
              break;
            case int_intp10:
            case int_intp10:
              PC = 0x90;
              PC = 0x90;
              ECR |= 0x90;
              ECR |= 0x90;
              break;
              break;
            case int_intp11:
            case int_intp11:
              PC = 0xa0;
              PC = 0xa0;
              ECR |= 0xa0;
              ECR |= 0xa0;
              break;
              break;
            case int_intp12:
            case int_intp12:
              PC = 0xb0;
              PC = 0xb0;
              ECR |= 0xb0;
              ECR |= 0xb0;
              break;
              break;
            case int_intp13:
            case int_intp13:
              PC = 0xc0;
              PC = 0xc0;
              ECR |= 0xc0;
              ECR |= 0xc0;
              break;
              break;
            case int_intcm4:
            case int_intcm4:
              PC = 0xd0;
              PC = 0xd0;
              ECR |= 0xd0;
              ECR |= 0xd0;
              break;
              break;
            default:
            default:
              /* Should never be possible.  */
              /* Should never be possible.  */
              sim_engine_abort (sd, NULL, NULL_CIA,
              sim_engine_abort (sd, NULL, NULL_CIA,
                                "do_interrupt - internal error - bad switch");
                                "do_interrupt - internal error - bad switch");
              break;
              break;
            }
            }
        }
        }
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
      sim_engine_restart (sd, NULL, NULL, NULL_CIA);
    }
    }
 
 
  /* some other interrupt? */
  /* some other interrupt? */
  sim_engine_abort (sd, NULL, NULL_CIA,
  sim_engine_abort (sd, NULL, NULL_CIA,
                    "do_interrupt - internal error - interrupt %d unknown",
                    "do_interrupt - internal error - interrupt %d unknown",
                    inttype);
                    inttype);
}
}
 
 
/* Return name of an insn, used by insn profiling.  */
/* Return name of an insn, used by insn profiling.  */
 
 
static const char *
static const char *
get_insn_name (sim_cpu *cpu, int i)
get_insn_name (sim_cpu *cpu, int i)
{
{
  return itable[i].name;
  return itable[i].name;
}
}
 
 
/* These default values correspond to expected usage for the chip.  */
/* These default values correspond to expected usage for the chip.  */
 
 
uint32 OP[4];
uint32 OP[4];
 
 
 
 
SIM_DESC
SIM_DESC
sim_open (kind, cb, abfd, argv)
sim_open (kind, cb, abfd, argv)
     SIM_OPEN_KIND kind;
     SIM_OPEN_KIND kind;
     host_callback *cb;
     host_callback *cb;
     struct bfd *abfd;
     struct bfd *abfd;
     char **argv;
     char **argv;
{
{
  SIM_DESC sd = sim_state_alloc (kind, cb);
  SIM_DESC sd = sim_state_alloc (kind, cb);
  int mach;
  int mach;
 
 
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
 
 
  /* for compatibility */
  /* for compatibility */
  simulator = sd;
  simulator = sd;
 
 
  /* FIXME: should be better way of setting up interrupts */
  /* FIXME: should be better way of setting up interrupts */
  STATE_WATCHPOINTS (sd)->pc = &(PC);
  STATE_WATCHPOINTS (sd)->pc = &(PC);
  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
  STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
  STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt;
  STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
  STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names;
 
 
  /* Initialize the mechanism for doing insn profiling.  */
  /* Initialize the mechanism for doing insn profiling.  */
  CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name;
  CPU_INSN_NAME (STATE_CPU (sd, 0)) = get_insn_name;
  CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries;
  CPU_MAX_INSNS (STATE_CPU (sd, 0)) = nr_itable_entries;
 
 
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    return 0;
    return 0;
 
 
  /* Allocate core managed memory */
  /* Allocate core managed memory */
 
 
  /* "Mirror" the ROM addresses below 1MB. */
  /* "Mirror" the ROM addresses below 1MB. */
  sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
  sim_do_commandf (sd, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
  /* Chunk of ram adjacent to rom */
  /* Chunk of ram adjacent to rom */
  sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
  sim_do_commandf (sd, "memory region 0x100000,0x%lx", V850_LOW_END-0x100000);
  /* peripheral I/O region - mirror 1K across 4k (0x1000) */
  /* peripheral I/O region - mirror 1K across 4k (0x1000) */
  sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
  sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
  /* similarly if in the internal RAM region */
  /* similarly if in the internal RAM region */
  sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
  sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
 
 
  /* getopt will print the error message so we just have to exit if this fails.
  /* 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
     FIXME: Hmmm...  in the case of gdb we need getopt to call
     print_filtered.  */
     print_filtered.  */
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
    {
    {
      /* Uninstall the modules to avoid memory leaks,
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
         file descriptor leaks, etc.  */
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
  /* check for/establish the a reference program image */
  /* check for/establish the a reference program image */
  if (sim_analyze_program (sd,
  if (sim_analyze_program (sd,
                           (STATE_PROG_ARGV (sd) != NULL
                           (STATE_PROG_ARGV (sd) != NULL
                            ? *STATE_PROG_ARGV (sd)
                            ? *STATE_PROG_ARGV (sd)
                            : NULL),
                            : NULL),
                           abfd) != SIM_RC_OK)
                           abfd) != SIM_RC_OK)
    {
    {
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
  /* establish any remaining configuration options */
  /* establish any remaining configuration options */
  if (sim_config (sd) != SIM_RC_OK)
  if (sim_config (sd) != SIM_RC_OK)
    {
    {
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
  if (sim_post_argv_init (sd) != SIM_RC_OK)
  if (sim_post_argv_init (sd) != SIM_RC_OK)
    {
    {
      /* Uninstall the modules to avoid memory leaks,
      /* Uninstall the modules to avoid memory leaks,
         file descriptor leaks, etc.  */
         file descriptor leaks, etc.  */
      sim_module_uninstall (sd);
      sim_module_uninstall (sd);
      return 0;
      return 0;
    }
    }
 
 
 
 
  /* determine the machine type */
  /* determine the machine type */
  if (STATE_ARCHITECTURE (sd) != NULL
  if (STATE_ARCHITECTURE (sd) != NULL
      && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850)
      && STATE_ARCHITECTURE (sd)->arch == bfd_arch_v850)
    mach = STATE_ARCHITECTURE (sd)->mach;
    mach = STATE_ARCHITECTURE (sd)->mach;
  else
  else
    mach = bfd_mach_v850; /* default */
    mach = bfd_mach_v850; /* default */
 
 
  /* set machine specific configuration */
  /* set machine specific configuration */
  switch (mach)
  switch (mach)
    {
    {
    case bfd_mach_v850:
    case bfd_mach_v850:
    case bfd_mach_v850e:
    case bfd_mach_v850e:
    case bfd_mach_v850e1:
    case bfd_mach_v850e1:
      STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
      STATE_CPU (sd, 0)->psw_mask = (PSW_NP | PSW_EP | PSW_ID | PSW_SAT
                                     | PSW_CY | PSW_OV | PSW_S | PSW_Z);
                                     | PSW_CY | PSW_OV | PSW_S | PSW_Z);
      break;
      break;
    }
    }
 
 
  return sd;
  return sd;
}
}
 
 
 
 
void
void
sim_close (sd, quitting)
sim_close (sd, quitting)
     SIM_DESC sd;
     SIM_DESC sd;
     int quitting;
     int quitting;
{
{
  sim_module_uninstall (sd);
  sim_module_uninstall (sd);
}
}
 
 
SIM_RC
SIM_RC
sim_create_inferior (sd, prog_bfd, argv, env)
sim_create_inferior (sd, prog_bfd, argv, env)
     SIM_DESC sd;
     SIM_DESC sd;
     struct bfd *prog_bfd;
     struct bfd *prog_bfd;
     char **argv;
     char **argv;
     char **env;
     char **env;
{
{
  memset (&State, 0, sizeof (State));
  memset (&State, 0, sizeof (State));
  if (prog_bfd != NULL)
  if (prog_bfd != NULL)
    PC = bfd_get_start_address (prog_bfd);
    PC = bfd_get_start_address (prog_bfd);
  return SIM_RC_OK;
  return SIM_RC_OK;
}
}
 
 
int
int
sim_fetch_register (sd, rn, memory, length)
sim_fetch_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char *memory;
     unsigned char *memory;
     int length;
     int length;
{
{
  *(unsigned32*)memory = H2T_4 (State.regs[rn]);
  *(unsigned32*)memory = H2T_4 (State.regs[rn]);
  return -1;
  return -1;
}
}
 
 
int
int
sim_store_register (sd, rn, memory, length)
sim_store_register (sd, rn, memory, length)
     SIM_DESC sd;
     SIM_DESC sd;
     int rn;
     int rn;
     unsigned char *memory;
     unsigned char *memory;
     int length;
     int length;
{
{
  State.regs[rn] = T2H_4 (*(unsigned32*)memory);
  State.regs[rn] = T2H_4 (*(unsigned32*)memory);
  return -1;
  return -1;
}
}
 
 
void
void
sim_do_command (sd, cmd)
sim_do_command (sd, cmd)
     SIM_DESC sd;
     SIM_DESC sd;
     char *cmd;
     char *cmd;
{
{
  char *mm_cmd = "memory-map";
  char *mm_cmd = "memory-map";
  char *int_cmd = "interrupt";
  char *int_cmd = "interrupt";
 
 
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
    {
    {
      if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
      if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
        sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
        sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
      else if (strncmp (cmd, int_cmd, strlen (int_cmd)) == 0)
        sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
        sim_io_eprintf (sd, "`interrupt' command replaced by `sim watch'\n");
      else
      else
        sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
        sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
    }
    }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.