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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [or1ksim/] [libtoplevel.c] - Diff between revs 98 and 143

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 98 Rev 143
Line 39... Line 39...
#include "sched.h"
#include "sched.h"
#include "execute.h"
#include "execute.h"
#include "pic.h"
#include "pic.h"
#include "jtag.h"
#include "jtag.h"
 
 
 
/* Indices of GDB registers that are not GPRs. Must match GDB settings! */
 
#define MAX_GPRS    32                  /*!< Maximum GPRs */
 
#define PPC_REGNUM  (MAX_GPRS + 0)      /*!< Previous PC */
 
#define NPC_REGNUM  (MAX_GPRS + 1)      /*!< Next PC */
 
#define SR_REGNUM   (MAX_GPRS + 2)      /*!< Supervision Register */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize the simulator.
/*!Initialize the simulator.
 
 
   Allows specification of an (optional) config file and an image file. Builds
   Allows specification of an (optional) config file and an image file. Builds
Line 92... Line 98...
  if (parse_args (dummy_argc, dummy_argv))
  if (parse_args (dummy_argc, dummy_argv))
    {
    {
      return OR1KSIM_RC_BADINIT;
      return OR1KSIM_RC_BADINIT;
    }
    }
 
 
 
  config.sim.is_library = 1;    /* Library operation */
  config.sim.profile   = 0;      /* No profiling */
  config.sim.profile   = 0;      /* No profiling */
  config.sim.mprofile  = 0;
  config.sim.mprofile  = 0;
 
 
  config.ext.class_ptr = class_ptr;     /* SystemC linkage */
  config.ext.class_ptr = class_ptr;     /* SystemC linkage */
  config.ext.read_up   = upr;
  config.ext.read_up   = upr;
Line 156... Line 163...
or1ksim_run (double duration)
or1ksim_run (double duration)
{
{
  const int  num_ints = sizeof (runtime.sim.ext_int_set) * 8;
  const int  num_ints = sizeof (runtime.sim.ext_int_set) * 8;
 
 
  /* If we are stalled we can't do anything. We treat this as hitting a
  /* If we are stalled we can't do anything. We treat this as hitting a
     breakpoint. */
     breakpoint or halting. */
  if(runtime.cpu.stalled)
  if(runtime.cpu.stalled)
    {
    {
      return  OR1KSIM_RC_BRKPT;
      return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
    }
    }
 
 
  /* Reset the duration */
  /* Reset the duration */
  or1ksim_reset_duration (duration);
  or1ksim_reset_duration (duration);
 
 
Line 179... Line 186...
       * performed in between. */
       * performed in between. */
      runtime.sim.mem_cycles = 0;
      runtime.sim.mem_cycles = 0;
 
 
      if (cpu_clock ())
      if (cpu_clock ())
        {
        {
          return OR1KSIM_RC_BRKPT;      /* Hit a breakpoint */
          /* This is probably wrong. This is an Or1ksim breakpoint, not a GNU
 
             one. */
 
          return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
 
        }
 
 
 
      /* If we are stalled we can't do anything. We treat this as hitting a
 
         breakpoint or halting. */
 
      if(runtime.cpu.stalled)
 
        {
 
          return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
        }
        }
 
 
      runtime.sim.cycles += runtime.sim.mem_cycles;
      runtime.sim.cycles += runtime.sim.mem_cycles;
 
 
      /* Take any external interrupts. Outer test is for the common case for
      /* Take any external interrupts. Outer test is for the common case for
Line 229... Line 245...
 
 
}       /* or1ksim_run() */
}       /* or1ksim_run() */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 
/*!Step the simulator
 
 
 
   This is just a wrapper for the run function, specifying a time
 
   corresponding to a single cycle. This will in fact mean that a single
 
   instruction is executed, even if takes more than one cycle to execute.
 
 
 
   @todo What happens if an event is triggered - that may mean multiple
 
         instructions.
 
 
 
   @return  OR1KSIM_RC_OK if we step to completion, OR1KSIM_RC_BRKPT if we hit
 
            a breakpoint (not clear how this can be set without CLI access)  */
 
/*---------------------------------------------------------------------------*/
 
int
 
or1ksim_step ()
 
{
 
  return  or1ksim_run ((double) config.sim.clkcycle_ps / 1e12);
 
 
 
}       /* or1ksim_step () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*!Reset the run-time simulation end point
/*!Reset the run-time simulation end point
 
 
  Reset the time for which the simulation should run to the specified duration
  Reset the time for which the simulation should run to the specified duration
  from NOW (i.e. NOT from when the run started).
  from NOW (i.e. NOT from when the run started).
 
 
Line 504... Line 541...
 
 
  return  (double) num_bits * (double) config.debug.jtagcycle_ps / 1.0e12;
  return  (double) num_bits * (double) config.debug.jtagcycle_ps / 1.0e12;
 
 
}       /* or1ksim_jtag_shift_dr () */
}       /* or1ksim_jtag_shift_dr () */
 
 
 No newline at end of file
 No newline at end of file
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Read a block of memory.
 
 
 
   @param[out] buf   Where to put the data.
 
   @param[in]  addr  The address to read from.
 
   @param[in]  len   The number of bytes to read.
 
 
 
   @return  Number of bytes read, or zero if error.                          */
 
/*---------------------------------------------------------------------------*/
 
int
 
or1ksim_read_mem (unsigned char *buf,
 
                  unsigned int   addr,
 
                  int            len)
 
{
 
  int             off;                  /* Offset into the memory */
 
 
 
  /* Fill the buffer with data */
 
  for (off = 0; off < len; off++)
 
    {
 
      /* Check memory area is valid */
 
      if (NULL == verify_memoryarea (addr + off))
 
        {
 
          /* Fail silently - others can raise any error message. */
 
          return  0;
 
        }
 
      else
 
        {
 
          /* Get the memory direct - no translation. */
 
          buf[off] = eval_direct8 (addr + off, 0, 0);
 
        }
 
    }
 
 
 
  return  len;
 
 
 
}       /* or1ksim_read_mem () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Write a block of memory.
 
 
 
   @param[in] buf   Where to get the data from.
 
   @param[in] addr  The address to write to.
 
   @param[in] len   The number of bytes to write.
 
 
 
   @return  Number of bytes written, or zero if error.                       */
 
/*---------------------------------------------------------------------------*/
 
int
 
or1ksim_write_mem (unsigned char *buf,
 
                   unsigned int   addr,
 
                   int            len)
 
{
 
  int             off;                  /* Offset into the memory */
 
 
 
  /* Write the bytes to memory */
 
  for (off = 0; off < len; off++)
 
    {
 
      if (NULL == verify_memoryarea (addr + off))
 
        {
 
          /* Fail silently - others can raise any error message. */
 
          return  0;
 
        }
 
      else
 
        {
 
          /* circumvent the read-only check usually done for mem accesses data
 
             is in host order, because that's what set_direct32 needs */
 
          set_program8 (addr + off, buf[off]);
 
        }
 
    }
 
 
 
  return  len;
 
 
 
}       /* or1ksim_write_mem () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Read a single register
 
 
 
   The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
 
   (i.e. SPR NPC) and SR (i.e. SPR SR).
 
 
 
   @param[out] buf     Where to put the data.
 
   @param[in]  regnum  The register to read.
 
   @param[in]  len     Size of the register in bytes
 
 
 
   @return  Size of the register, or zero if error.                          */
 
/*---------------------------------------------------------------------------*/
 
int
 
or1ksim_read_reg (unsigned char *buf,
 
                  int            regnum,
 
                  int            len)
 
{
 
  unsigned long int *regbuf = (unsigned long *) buf;
 
 
 
  if (4 != len)
 
    {
 
      return  0;                 /* Not 32-bit reg */
 
    }
 
 
 
  /* Get the relevant register */
 
  if (regnum < MAX_GPRS)
 
    {
 
      *regbuf = cpu_state.reg[regnum];
 
    }
 
  else if (PPC_REGNUM == regnum)
 
    {
 
      *regbuf = cpu_state.sprs[SPR_PPC];
 
    }
 
  else if (NPC_REGNUM == regnum)
 
    {
 
      *regbuf = cpu_state.pc;
 
    }
 
  else if (SR_REGNUM == regnum)
 
    {
 
      *regbuf = cpu_state.sprs[SPR_SR];
 
    }
 
  else
 
    {
 
      /* Silent error response if we don't know the register */
 
      return  0;
 
    }
 
 
 
  return  len;
 
 
 
}       /* or1ksim_read_reg () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Write a single register
 
 
 
   The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
 
   (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
 
   sequence of bytes in target endian order.
 
 
 
   Each byte is packed as a pair of hex digits.
 
 
 
   @param[in] buf     Where to get the data from.
 
   @param[in] regnum  The register to write.
 
   @param[in]  len     Size of the register in bytes
 
 
 
   @return  Size of the register, or zero if error.                          */
 
/*---------------------------------------------------------------------------*/
 
int
 
or1ksim_write_reg (unsigned char *buf,
 
                   int            regnum,
 
                   int            len)
 
{
 
  unsigned long int *regbuf = (unsigned long *) buf;
 
  unsigned long int  regval = *regbuf;
 
 
 
  if (4 != len)
 
    {
 
      return  0;                 /* Not 32-bit reg */
 
    }
 
 
 
  /* Set the relevant register */
 
  if (regnum < MAX_GPRS)
 
    {
 
      cpu_state.reg[regnum] =regval;
 
    }
 
  else if (PPC_REGNUM == regnum)
 
    {
 
      cpu_state.sprs[SPR_PPC] = regval;
 
    }
 
  else if (NPC_REGNUM == regnum)
 
    {
 
      if (cpu_state.pc != regval)
 
        {
 
          cpu_state.pc         = regval;
 
          cpu_state.delay_insn = 0;
 
          pcnext               = regval + 4;
 
        }
 
    }
 
  else if (SR_REGNUM == regnum)
 
    {
 
      cpu_state.sprs[SPR_SR] = regval;
 
    }
 
  else
 
    {
 
      /* Silent error response if we don't know the register */
 
      return  0;
 
    }
 
 
 
  return  len;
 
 
 
}       /* or1ksim_write_reg () */
 
 
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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