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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-or1k.c] - Diff between revs 115 and 118

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

Rev 115 Rev 118
Line 1... Line 1...
/* Remote debugging interface for various or1k debugging protocols.
/* Remote debugging interface for various or1k debugging protocols.
 
   Currently supported or1k targets are: simulator, jtag, dummy.
 
 
   Copyright 1993-1995, 2000 Free Software Foundation, Inc.
   Copyright 1993-1995, 2000 Free Software Foundation, Inc.
   Contributed by Cygnus Support.  Written by Marko Mlinar
   Contributed by Cygnus Support.  Written by Marko Mlinar
   <markom@opencores.org>
   <markom@opencores.org>
 
 
   This file is part of GDB.
   This file is part of GDB.
Line 36... Line 38...
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <fcntl.h>
 
 
 
/* JTAG or1k target ops.  */
extern void jtag_init PARAMS ((char * args));
extern void jtag_init PARAMS ((char * args));
extern unsigned long long int jtag_read_reg PARAMS ((unsigned int regno));
extern unsigned long long int jtag_read_reg PARAMS ((unsigned int regno));
extern void jtag_write_reg PARAMS ((unsigned int regno, unsigned long long int data));
extern void jtag_write_reg PARAMS ((unsigned int regno, unsigned long long int data));
extern void jtag_done PARAMS ((void));
extern void jtag_done PARAMS ((void));
extern void jtag_set_chain PARAMS ((int chain));
extern void jtag_set_chain PARAMS ((int chain));
Line 55... Line 58...
    NULL,
    NULL,
    &or1k_jtag_ops,
    &or1k_jtag_ops,
    OPS_MAGIC
    OPS_MAGIC
  };
  };
 
 
 
/* simulator or1k target ops.  */
struct target_ops or1k_sim_ops;
struct target_ops or1k_sim_ops;
static struct or1k_target_ops or1k_target_sim =
static struct or1k_target_ops or1k_target_sim =
  {
  {
    "simulator",
    "simulator",
    NULL,
    NULL,
Line 69... Line 73...
    NULL,
    NULL,
    &or1k_sim_ops,
    &or1k_sim_ops,
    OPS_MAGIC
    OPS_MAGIC
  };
  };
 
 
 
/* dummy or1k target ops.  */
struct target_ops or1k_dummy_ops;
struct target_ops or1k_dummy_ops;
static struct or1k_target_ops or1k_target_dummy =
static struct or1k_target_ops or1k_target_dummy =
  {
  {
    "dummy",
    "dummy",
    NULL,
    NULL,
Line 128... Line 133...
 
 
/* Set to 1 if the target is open.  */
/* Set to 1 if the target is open.  */
static int or1k_is_open = 0;
static int or1k_is_open = 0;
 
 
/* Error last occured, zero = ok.  */
/* Error last occured, zero = ok.  */
static int err = 0;
int err = 0;
 
 
 
/* Nonzero, if we changed something.  */
 
int debug_regs_changed;
 
 
/* Number of interrupts while waiting for process.  */
/* Number of interrupts while waiting for process.  */
static int interrupt_count = 0;
static int interrupt_count = 0;
 
 
/* Reason of last stop.  */
/* Reason of last stop.  */
static int hit_watchpoint = 0;
static int hit_watchpoint = 0;
 
 
/* Current register values.  */
/* Current register values.  */
static unsigned int dmr1 = 0;
unsigned int dmr1 = 0;
static unsigned int dmr2 = 0;
unsigned int dmr2 = 0;
static unsigned int dsr = 0;
unsigned int dsr = 0;
static unsigned int drr = 0;
unsigned int drr = 0;
 
 
/* Current watchpoints.  */
/* Current matchpoints.  */
static int dvr[8];
unsigned int dvr[MAX_MATCHPOINTS];
static struct dcr_struct dcr[8];
struct dcr_struct dcr[MAX_MATCHPOINTS];
 
 
 
int matchpoint_user_count[MAX_MATCHPOINTS] = {0};
 
 
/* Handle low-level error that we can't recover from.  Note that just
/* Handle low-level error that we can't recover from.  Note that just
   error()ing out from target_wait or some such low-level place will cause
   error()ing out from target_wait or some such low-level place will cause
   all hell to break loose--the rest of GDB will tend to get left in an
   all hell to break loose--the rest of GDB will tend to get left in an
   inconsistent state.  */
   inconsistent state.  */
Line 284... Line 294...
{
{
  int val;
  int val;
  or1k_set_chain (SC_REGISTER);
  or1k_set_chain (SC_REGISTER);
  val = or1k_read_reg (JTAG_RISCOP);
  val = or1k_read_reg (JTAG_RISCOP);
  or1k_write_reg (JTAG_RISCOP, val | 1);
  or1k_write_reg (JTAG_RISCOP, val | 1);
 
 
 
  /* Be cautious - disable trace.  */
 
  val = or1k_read_reg (JTAG_MODER);
 
  or1k_write_reg (JTAG_MODER, val & ~2);
  or1k_flush_pipeline ();
  or1k_flush_pipeline ();
}
}
 
 
/* Unstalls the CPU.  */
/* Unstalls the CPU.  */
 
 
Line 299... Line 313...
  val = or1k_read_reg (JTAG_RISCOP);
  val = or1k_read_reg (JTAG_RISCOP);
  or1k_write_reg (JTAG_RISCOP, val & ~1);
  or1k_write_reg (JTAG_RISCOP, val & ~1);
}
}
 
 
/* Resets the CPU and stalls it.  */
/* Resets the CPU and stalls it.  */
 
 
static void
static void
or1k_reset ()
or1k_reset ()
{
{
  unsigned int val;
  unsigned int val;
  or1k_set_chain (SC_REGISTER);
  or1k_set_chain (SC_REGISTER);
 
 
 
  /* Be cautious - disable trace.  */
 
  val = or1k_read_reg (JTAG_MODER);
 
  or1k_write_reg (JTAG_MODER, val & ~2);
 
 
  val = or1k_read_reg (JTAG_RISCOP);
  val = or1k_read_reg (JTAG_RISCOP);
  val &= ~3;
  val &= ~3;
  or1k_write_reg (JTAG_RISCOP, val | 3); /* Assert reset signal.  */
  /* Assert reset signal.  */
  usleep (1000);  /* give it some time */
  or1k_write_reg (JTAG_RISCOP, val | 3);
 
 
 
  /* give it some time */
 
  usleep (1000);
  or1k_flush_pipeline ();
  or1k_flush_pipeline ();
  or1k_write_reg (JTAG_RISCOP, val | 1); /* Release reset signal, but keep in stall state.  */
  /* Release reset signal, but keep in stall state.  */
 
  or1k_write_reg (JTAG_RISCOP, val | 1);
  or1k_flush_pipeline ();
  or1k_flush_pipeline ();
}
}
 
 
 
/* Synchronizes debug registers in memory with those on target,
 
   if there is any change.  */
 
 
 
static void
 
or1k_commit_debug_registers ()
 
{
 
  int i;
 
  unsigned int u;
 
  if (!debug_regs_changed)
 
    return;
 
 
 
  /* Matchpoints (breakpoints, watchpoints).  */
 
  for (i = 0; i < NUM_MATCHPOINTS; i++)
 
    {
 
      unsigned int u;
 
      or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
 
      memcpy (&u, &dcr[i], sizeof(dcr[i]));
 
      or1k_write_spr_reg (DCR0_SPRNUM + i, u);
 
    }
 
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2);
 
 
 
  /* Trace dependent.  */
 
  or1k_set_chain (SC_REGISTER);
 
  memcpy (&u, &or1k_htrace.trig, sizeof(or1k_htrace.trig));
 
  or1k_write_reg (JTAG_TSEL, u);
 
  memcpy (&u, &or1k_htrace.qual, sizeof(or1k_htrace.qual));
 
  or1k_write_reg (JTAG_QSEL, u);
 
  memcpy (&u, &or1k_htrace.stop, sizeof(or1k_htrace.stop));
 
  or1k_write_reg (JTAG_SSEL, u);
 
  debug_regs_changed = 0;
 
  for (i = 0; i < NUM_RECORDS; i++)
 
    {
 
      memcpy (&u, &or1k_htrace.recwp[i], sizeof(or1k_htrace.recwp[i]));
 
      or1k_write_reg (JTAG_RECWP0 + i, u);
 
    }
 
  memcpy (&u, &or1k_htrace.recbp, sizeof(or1k_htrace.recbp));
 
  or1k_write_reg (JTAG_RECBP0, u);
 
  memcpy (&u, &or1k_htrace.moder, sizeof(or1k_htrace.moder));
 
  or1k_write_reg (JTAG_MODER, u);
 
}
 
 
static void
static void
or1k_set_undefined_cleanups (arg)
or1k_set_undefined_cleanups (arg)
     PTR arg;
     PTR arg;
{
{
  or1k_status = TARGET_UNDEFINED;
  or1k_status = TARGET_UNDEFINED;
Line 330... Line 396...
     char *args;
     char *args;
{
{
  struct cleanup *old_cleanups = make_cleanup (or1k_set_undefined_cleanups, NULL);
  struct cleanup *old_cleanups = make_cleanup (or1k_set_undefined_cleanups, NULL);
  int i;
  int i;
  unsigned int tmp;
  unsigned int tmp;
 
  FILE *f;
 
 
  /* What is this code doing here?  I don't see any way it can happen, and
  /* What is this code doing here?  I don't see any way it can happen, and
     it might mean or1k_initializing didn't get cleared properly.
     it might mean or1k_initializing didn't get cleared properly.
     So I'll make it a warning.  */
     So I'll make it a warning.  */
 
 
Line 349... Line 416...
    current_or1k_target->to_init (args);
    current_or1k_target->to_init (args);
 
 
  /* Determine implementation configuration.  */
  /* Determine implementation configuration.  */
  or1k_implementation.VR = or1k_read_spr_reg (VR_SPRNUM);
  or1k_implementation.VR = or1k_read_spr_reg (VR_SPRNUM);
  or1k_implementation.UPR = or1k_read_spr_reg (UPR_SPRNUM);
  or1k_implementation.UPR = or1k_read_spr_reg (UPR_SPRNUM);
 
 
  /* Determine number of gpr_regs.  */
  /* Determine number of gpr_regs.  */
  tmp = or1k_read_spr_reg (CPUCFGR_SPRNUM);
  tmp = or1k_read_spr_reg (CPUCFGR_SPRNUM);
  or1k_implementation.num_gpr_regs = ((tmp >> 4) & 1)?(16):(32);
  or1k_implementation.num_gpr_regs = ((tmp >> 4) & 1)?(16):(32);
 
 
  /* Is any vector or floating point support present? */
  /* Is any vector or floating point support present? */
  or1k_implementation.vf_present = ((tmp >> 7) & 7) != 0;
  or1k_implementation.vf_present = ((tmp >> 7) & 7) != 0;
  or1k_implementation.num_vfpr_regs = (or1k_implementation.vf_present)?(32):(0);
  or1k_implementation.num_vfpr_regs = (or1k_implementation.vf_present)?(32):(0);
 
 
  /* Determine max number of supported matchpoints.  */
  /* Determine max number of supported matchpoints.  */
Line 374... Line 443...
  if (or1k_implementation.has_counters)
  if (or1k_implementation.has_counters)
    warning ("Counters not supported.");
    warning ("Counters not supported.");
 
 
  /* Delete break, watch, catch points.  */
  /* Delete break, watch, catch points.  */
  for(i = 0; i < NUM_MATCHPOINTS; i++)
  for(i = 0; i < NUM_MATCHPOINTS; i++)
    or1k_write_spr_reg (DCR0_SPRNUM + i, 0);
    {
 
      memset (&dcr[i], 0, sizeof (dcr[i]));
 
      matchpoint_user_count[i] = 0;
 
    }
 
 
  dmr1 = 0;
  dmr1 = 0;
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
  dmr2 = 0;
  dmr2 = 0;
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2);
  memset (&or1k_htrace, 0, sizeof (or1k_htrace));
 
 
 
  /* RECSELDEPEND = 0 does not match our trace scheme. */
 
  or1k_htrace.moder.rec_sel_dep = 1;
 
 
 
  debug_regs_changed = 1;
 
  or1k_commit_debug_registers ();
 
 
  if (err != 0)
  if (err != 0)
    error ("Cannot connect.");
    error ("Cannot connect.");
 
 
  /* Stop when breakpoint occurs.  */
  /* Stop when breakpoint occurs.  */
  or1k_write_spr_reg (DSR_SPRNUM, 0x1000);
  or1k_write_spr_reg (DSR_SPRNUM, 0x1000);
Line 393... Line 471...
  /* This should cause an error if not connected.  */
  /* This should cause an error if not connected.  */
  or1k_fetch_registers (-1);
  or1k_fetch_registers (-1);
 
 
  set_current_frame (create_new_frame (read_fp (), read_pc ()));
  set_current_frame (create_new_frame (read_fp (), read_pc ()));
  select_frame (get_current_frame (), 0);
  select_frame (get_current_frame (), 0);
 
 
 
  /* Just empty it.  */
 
  if ((f = fopen (TRACE_FILENAME, "wb+")) == NULL)
 
    error ("Cannot open trace file.");
 
  fclose (f);
 
  trace_size = 0;
}
}
 
 
/* Kill the process running on the board.  */
/* Kill the process running on the board.  */
 
 
void
void
Line 472... Line 556...
 
 
  if (from_tty)
  if (from_tty)
    printf_unfiltered ("Ending remote or1k debugging.\n");
    printf_unfiltered ("Ending remote or1k debugging.\n");
}
}
 
 
 
/* Appends trace data to the trace file.  */
 
 
 
static void
 
or1k_read_trace ()
 
{
 
  struct htrace_data_struct data;
 
  long long int tmp;
 
  int first = 1;
 
  FILE *fd;
 
  if ((fd = fopen (TRACE_FILENAME, "ab")) == NULL)
 
    {
 
      warning ("Cannot append to trace file.");
 
      return;
 
    }
 
 
 
  or1k_set_chain (SC_TRACE);
 
  while (1)
 
    {
 
      tmp = or1k_read_reg (0);
 
      memcpy (&data, &tmp, sizeof (data));
 
 
 
      /* Last record reached. */
 
      if (!data.valid)
 
        break;
 
      data.valid = first;
 
      first = 0;
 
      if (!fwrite (&data, sizeof (data), 1, fd))
 
        {
 
          warning ("Cannot write trace data");
 
          break;
 
        }
 
    }
 
  fclose (fd);
 
}
 
 
/* Resume execution of the target process.  STEP says whether to single-step
/* Resume execution of the target process.  STEP says whether to single-step
   or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
   or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
   to the target, or zero for no signal.  */
   to the target, or zero for no signal.  */
 
 
static void
static void
Line 498... Line 617...
      dmr1 |= DMR1_ST;
      dmr1 |= DMR1_ST;
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
      dmr1 &= ~DMR1_ST;
      dmr1 &= ~DMR1_ST;
    }
    }
 
 
 
  or1k_commit_debug_registers ();
  /* Run the target. */
  /* Run the target. */
  or1k_unstall ();
  or1k_unstall ();
  or1k_status = TARGET_RUNNING;
  or1k_status = TARGET_RUNNING;
}
}
 
 
Line 536... Line 656...
      usleep (10);
      usleep (10);
    }
    }
  while (drr == 0);
  while (drr == 0);
 
 
  status->kind = TARGET_WAITKIND_STOPPED;
  status->kind = TARGET_WAITKIND_STOPPED;
 
 
  or1k_flush_pipeline ();
  or1k_flush_pipeline ();
 
 
  if (drr & DRR_RSTE)
  if (drr & DRR_RSTE)
    status->value.sig = TARGET_SIGNAL_REALTIME_33;
    status->value.sig = TARGET_SIGNAL_REALTIME_33;
  else if (drr & DRR_BUSEE)
  else if (drr & DRR_BUSEE)
Line 582... Line 701...
      /* Search all active breakpoints for a match.  */
      /* Search all active breakpoints for a match.  */
      CORE_ADDR pc = read_pc ();
      CORE_ADDR pc = read_pc ();
      int breakpoint = 0;
      int breakpoint = 0;
      int i;
      int i;
      for (i = 0; i < or1k_implementation.num_used_matchpoints; i++)
      for (i = 0; i < or1k_implementation.num_used_matchpoints; i++)
        if (dvr[i] == pc && dcr[i].dp && dcr[i].cc == CC_EQUAL && !dcr[i].sc && dcr[i].ct == CT_FETCH)
        if (dvr[i] == pc && dcr[i].dp && dcr[i].cc == CC_EQUAL
 
            && !dcr[i].sc && dcr[i].ct == CT_FETCH)
          {
          {
            breakpoint = 1;
            breakpoint = 1;
            break;
            break;
          }
          }
      hit_watchpoint = !breakpoint;
      hit_watchpoint = !breakpoint;
Line 605... Line 725...
    find_pc_partial_function (pc, &func_name, &func_start, NULL);
    find_pc_partial_function (pc, &func_name, &func_start, NULL);
    if (func_name != NULL && strcmp (func_name, "_exit") == 0
    if (func_name != NULL && strcmp (func_name, "_exit") == 0
        && func_start == pc)
        && func_start == pc)
      status->kind = TARGET_WAITKIND_EXITED;
      status->kind = TARGET_WAITKIND_EXITED;
  }
  }
 
 
 
  or1k_read_trace ();
  return 0;
  return 0;
}
}
 
 
/* Fetch a word from the target board.  All memory accesses to the
/* Fetch a word from the target board.  All memory accesses to the
   remote board are word aligned.  */
   remote board are word aligned.  */
 
 
static unsigned int
unsigned int
or1k_fetch_word (addr)
or1k_fetch_word (addr)
     CORE_ADDR addr;
     CORE_ADDR addr;
{
{
  if (addr & 3)
  if (addr & 3)
    {
    {
Line 637... Line 759...
    }
    }
}
}
 
 
/* Store a word to the target board.  Returns errno code or zero for
/* Store a word to the target board.  Returns errno code or zero for
   success.  All memory accesses to the remote board are word aligned.  */
   success.  All memory accesses to the remote board are word aligned.  */
 
 
static int
static int
or1k_store_word (addr, val)
or1k_store_word (addr, val)
     CORE_ADDR addr;
     CORE_ADDR addr;
     unsigned int val;
     unsigned int val;
{
{
Line 696... Line 819...
       value in the target byte ordering.  */
       value in the target byte ordering.  */
    store_unsigned_integer (buf, REGISTER_RAW_SIZE (regno), val);
    store_unsigned_integer (buf, REGISTER_RAW_SIZE (regno), val);
    supply_register (regno, buf);
    supply_register (regno, buf);
  }
  }
  if (err)
  if (err)
    or1k_error ("Can't read register %d(%i): %s", regno, REGNUM_TO_SPRNUM(regno) + REG_SPACE, or1k_err_name (err));
    or1k_error ("Can't read register %d(%i): %s", regno,
 
                REGNUM_TO_SPRNUM(regno) + REG_SPACE, or1k_err_name (err));
}
}
 
 
/* Fetch and return instruction from the specified location.  */
/* Fetch and return instruction from the specified location.  */
 
 
unsigned int
unsigned int
Line 788... Line 912...
          store_unsigned_integer (&buffer[(count - 1) * 4], 4,
          store_unsigned_integer (&buffer[(count - 1) * 4], 4,
                                  or1k_fetch_word (addr + (count - 1) * 4));
                                  or1k_fetch_word (addr + (count - 1) * 4));
        }
        }
 
 
      /* Copy data to be written over corresponding part of buffer */
      /* Copy data to be written over corresponding part of buffer */
 
 
      memcpy ((char *) buffer + (memaddr & 3), myaddr, len);
      memcpy ((char *) buffer + (memaddr & 3), myaddr, len);
 
 
      /* Write the entire buffer.  */
      /* Write the entire buffer.  */
 
 
      for (i = 0; i < count; i++, addr += 4)
      for (i = 0; i < count; i++, addr += 4)
        {
        {
          status = or1k_store_word (addr,
          status = or1k_store_word (addr,
                               extract_unsigned_integer (&buffer[i * 4], 4));
                               extract_unsigned_integer (&buffer[i * 4], 4));
          /* Report each kilobyte (we download 32-bit words at a time) */
          /* Report each kilobyte (we download 32-bit words at a time) */
Line 867... Line 989...
  /* Print target info. */
  /* Print target info. */
  printf_filtered ("Status: %s\n", status_name[or1k_status]);
  printf_filtered ("Status: %s\n", status_name[or1k_status]);
}
}
 
 
/* Tell whether we can support a hardware breakpoint.  */
/* Tell whether we can support a hardware breakpoint.  */
 
 
static int
static int
or1k_can_use_hardware_breakpoint ()
or1k_can_use_hardware_breakpoint ()
{
{
  int i;
  int i;
 
 
  /* Search for unused breakpoint.  */
  /* Search for unused breakpoint.  */
  return or1k_implementation.num_used_matchpoints < or1k_implementation.num_matchpoints;
  return or1k_implementation.num_used_matchpoints < or1k_implementation.num_matchpoints;
}
}
 
 
/* Insert a breakpoint.  On targets that don't have built-in breakpoint
/* Insert a breakpoint.  On targets that don't have built-in breakpoint
Line 921... Line 1045...
  /* Are there at least two matchpoints left for watch? - estimate lower bound  */
  /* Are there at least two matchpoints left for watch? - estimate lower bound  */
  return cnt + ((bp_type == bp_hardware_watchpoint)?(1):(0))
  return cnt + ((bp_type == bp_hardware_watchpoint)?(1):(0))
    <= or1k_implementation.num_matchpoints;
    <= or1k_implementation.num_matchpoints;
}
}
 
 
 
/* Moves matchpoint.  This is very tricky - we have to update
 
   all references to matchpoint indexes.  We assume here that
 
   matchpoint with index to is unused! */
 
 
 
static void
 
move_matchpoint (int from, int to)
 
{
 
  int i, j, tmp, chaining;
 
  if (matchpoint_user_count[to] != 0)
 
    error ("Internal: Destination matchpoint still has users");
 
  matchpoint_user_count[to] = matchpoint_user_count[from];
 
  matchpoint_user_count[from] = 0;
 
  debug_regs_changed = 1;
 
 
 
  dvr[to] = dvr[from];
 
  dcr[to] = dcr[from];
 
  dcr[from].dp = 0;
 
 
 
  /* Copy chaining bits.  */
 
  chaining = dmr1 & (3 << (2 * from));
 
  dmr1 &= ~(3 << (2 * to));
 
  dmr1 |= chaining << (2 * to);
 
  dmr1 &= ~(3 << (2 * from));
 
 
 
  /* Copy watchpoint bits */
 
  tmp = dmr2 & (1 << from);
 
  dmr2 &= 1 << to;
 
  dmr2 |= tmp << to;
 
  dmr2 &= 1 << from;
 
 
 
  /* Update hwatch table.  Here we assume that matchpoint
 
     group is connected (it cannot be implemented in HW
 
     otherwise), so if we move first, we will have to move
 
     others later.  */
 
  for (i = 0; i < num_hw_watches; i++)
 
    if (or1k_hwatch[i].matchpoint_start == from)
 
      or1k_hwatch[i].matchpoint_start = to;
 
 
 
  /* Update htrace struct.  */
 
  tmp = or1k_htrace.trig.wp_trig & (1 << from);
 
  or1k_htrace.trig.wp_trig &= 1 << to;
 
  or1k_htrace.trig.wp_trig |= tmp << to;
 
  or1k_htrace.trig.wp_trig &= 1 << from;
 
 
 
  tmp = or1k_htrace.qual.wp_trig & (1 << from);
 
  or1k_htrace.qual.wp_trig &= 1 << to;
 
  or1k_htrace.qual.wp_trig |= tmp << to;
 
  or1k_htrace.qual.wp_trig &= 1 << from;
 
 
 
  tmp = or1k_htrace.stop.wp_trig & (1 << from);
 
  or1k_htrace.stop.wp_trig &= 1 << to;
 
  or1k_htrace.stop.wp_trig |= tmp << to;
 
  or1k_htrace.stop.wp_trig &= 1 << from;
 
 
 
  for (i = 0; i < MAX_MATCHPOINTS; i++)
 
    {
 
      tmp = or1k_htrace.wp_record_uses[i] & (1 << from);
 
      or1k_htrace.wp_record_uses[i] &= 1 << to;
 
      or1k_htrace.wp_record_uses[i] |= tmp << to;
 
      or1k_htrace.wp_record_uses[i] &= 1 << from;
 
    }
 
 
 
  /* Do we need to move other references also? */
 
}
 
 
/* Sifts unused matchpoints to higher indexses.  */
/* Sifts unused matchpoints to higher indexses.  */
 
 
static void
void
sift_matchpoints ()
sift_matchpoints ()
{
{
  int i, first_free = 0;
  int i, first_free = 0;
  unsigned int u;
 
  for (i = 0; i < or1k_implementation.num_matchpoints; i++)
  for (i = 0; i < or1k_implementation.num_matchpoints; i++)
    if (dcr[i].dp)
    if (dcr[i].dp)
      {
      {
        int chaining;
        /* Move references.  */
        dvr[first_free] = dvr[i];
        move_matchpoint (i, first_free);
        dcr[first_free] = dcr[i];
 
 
 
        /* Copy chaining bits.  */
 
        chaining = dmr1 & (3 << (2 * i));
 
        dmr1 &= ~(3 << (2 * first_free));
 
        dmr1 |= chaining << (2 * first_free);
 
        /* Copy watchpoint bits */
 
        chaining = dmr2 & (1 << i);
 
        dmr2 &= 1 << first_free;
 
        dmr2 |= chaining << first_free;
 
        /* !!! move references also */
 
 
 
        or1k_write_spr_reg (DVR0_SPRNUM + first_free, dvr[first_free]);
 
        memcpy (&u, &dcr[first_free], sizeof(dcr[first_free]));
 
        or1k_write_spr_reg (DCR0_SPRNUM + first_free, u);
 
        first_free++;
        first_free++;
      }
      }
  /* Disable unused.  */
 
  for (i = first_free; i < or1k_implementation.num_matchpoints; i++)
  /* Unused matchpoints should be disabled by move_matchpoint,
    {
     so we are done here.  */
      dmr2 &= ~(1 << i);
 
      dcr[i].dp = 0;
 
    }
 
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2);
 
}
}
 
 
/* Translates gdb watchpoint type into one in DCR register.  */
/* Translates gdb watchpoint type into one in DCR register.  */
 
 
static int
static int
Line 990... Line 1159...
     CORE_ADDR addr;
     CORE_ADDR addr;
     int len;
     int len;
     int type;
     int type;
{
{
  int i;
  int i;
  unsigned int u;
 
  if (len < 1)
  if (len < 1)
    return -1;
    return -1;
 
 
  type = translate_type (type);
  type = translate_type (type);
 
 
  /* Moves unused watchpoints to the top.  */
  /* Moves unused watchpoints to the top.  */
  sift_matchpoints ();
  sift_matchpoints ();
 
 
  /* Place at first free matchpoint.  */
  /* Place at first free matchpoint.  */
  i = or1k_implementation.num_used_matchpoints;
  i = or1k_implementation.num_used_matchpoints;
  dvr[i] = addr;
  dvr[i] = addr;
  dcr[i].dp = 1;
  dcr[i].dp = 1;
  dcr[i].cc = CC_GREATE;
  dcr[i].cc = CC_GREATE;
  dcr[i].sc = 0;
  dcr[i].sc = 0;
  dcr[i].ct = type;
  dcr[i].ct = type;
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
 
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
 
 
 
  /* Set && chaining here.  */
  /* Set && chaining here.  */
  dmr1 &= ~(3 << (2 * i));
  dmr1 &= ~(3 << (2 * i));
  dmr1 |= 2 << (2 * i);
  dmr1 |= CHAINING_AND << (2 * i);
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
 
 
  /* Set upper watchpoint bound.  */
  /* Set upper watchpoint bound.  */
  i++;
  i++;
  dvr[i] = addr + len - 1;
  dvr[i] = addr + len - 1;
  dcr[i].dp = 1;
  dcr[i].dp = 1;
  dcr[i].cc = CC_LESSE;
  dcr[i].cc = CC_LESSE;
  dcr[i].sc = 0;
  dcr[i].sc = 0;
  dcr[i].ct = type;
  dcr[i].ct = type;
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
 
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
 
 
 
  /* Matchpoints will cause breakpoints */
  /* Matchpoints will cause breakpoints */
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 |= (1 << i));
  dmr2 |= (1 << i);
  or1k_implementation.num_used_matchpoints += 2;
  or1k_implementation.num_used_matchpoints += 2;
 
  debug_regs_changed = 1;
  return 0;
  return 0;
}
}
 
 
/* Removes a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
/* Removes a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
   watchpoint. */
   watchpoint. */
 
 
int
int
or1k_remove_watchpoint (addr, len, type)
or1k_remove_watchpoint (addr, len, type)
     CORE_ADDR addr;
     CORE_ADDR addr;
     int len;
     int len;
     int type;
     int type;
{
{
  int i, found = -1;
  int i, found = -1;
  unsigned int u;
 
  if (len < 1)
  if (len < 1)
    return -1;
    return -1;
 
 
  type = translate_type (type);
  type = translate_type (type);
 
 
Line 1061... Line 1226...
 
 
  if (found < 0)
  if (found < 0)
    return -1;
    return -1;
 
 
  dcr[found].dp = 0;
  dcr[found].dp = 0;
  memcpy (&u, &dcr[found], sizeof(dcr[found]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + found, u);
 
  dcr[found + 1].dp = 0;
  dcr[found + 1].dp = 0;
  memcpy (&u, &dcr[found + 1], sizeof(dcr[found + 1]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + found + 1, u);
 
 
 
  /* Matchpoints will not cause breakpoints anymore. */
  /* Matchpoints will not cause breakpoints anymore. */
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 &= ~(1 << i));
  dmr2 &= ~(1 << i);
  or1k_implementation.num_used_matchpoints -= 2;
  or1k_implementation.num_used_matchpoints -= 2;
 
  debug_regs_changed = 1;
  return 0;
  return 0;
}
}
 
 
int
int
or1k_stopped_by_watchpoint (void)
or1k_stopped_by_watchpoint (void)
Line 1086... Line 1248...
int
int
set_breakpoint (addr)
set_breakpoint (addr)
     CORE_ADDR addr;
     CORE_ADDR addr;
{
{
  int i;
  int i;
  unsigned int u;
 
  /* Search for unused breakpoint.  */
  /* Search for unused breakpoint.  */
  for (i = 0; i < NUM_MATCHPOINTS; i++)
  for (i = 0; i < NUM_MATCHPOINTS; i++)
    if (dcr[i].dp == 0) break;
    if (dcr[i].dp == 0) break;
  if (i >= NUM_MATCHPOINTS) return 1;
  if (i >= NUM_MATCHPOINTS) return 1;
  dvr[i] = addr;
  dvr[i] = addr;
  dcr[i].dp = 1;
  dcr[i].dp = 1;
  dcr[i].cc = CC_EQUAL;
  dcr[i].cc = CC_EQUAL;
  dcr[i].sc = 0;
  dcr[i].sc = 0;
  dcr[i].ct = CT_FETCH;
  dcr[i].ct = CT_FETCH;
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
 
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
 
  or1k_implementation.num_used_matchpoints++;
  or1k_implementation.num_used_matchpoints++;
 
 
  /* No chaining here.  */
  /* No chaining here.  */
  dmr1 &= ~(3 << (2*i));
  dmr1 &= ~(3 << (2*i));
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
  /* Matchpoints will cause breakpoints */
  /* Matchpoints will cause breakpoints */
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 |= (1 << i));
  dmr2 |= (1 << i);
 
  debug_regs_changed = 1;
  return 0;
  return 0;
}
}
 
 
/* Clear a breakpoint.  */
/* Clear a breakpoint.  */
 
 
int
int
clear_breakpoint (addr)
clear_breakpoint (addr)
     CORE_ADDR addr;
     CORE_ADDR addr;
{
{
  int i;
  int i;
  unsigned int u;
 
  /* Search for matching breakpoint.  */
  /* Search for matching breakpoint.  */
  for (i = 0; i < NUM_MATCHPOINTS; i++)
  for (i = 0; i < NUM_MATCHPOINTS; i++)
    if ((dcr[i].dp == 1) && (dvr[i] == addr) && (dcr[i].cc == CC_EQUAL)
    if ((dcr[i].dp == 1) && (dvr[i] == addr) && (dcr[i].cc == CC_EQUAL)
        && (dcr[i].sc == 0) && (dcr[i].ct == CT_FETCH)) break;
        && (dcr[i].sc == 0) && (dcr[i].ct == CT_FETCH)) break;
 
 
  if (i >= NUM_MATCHPOINTS) return 1;
  if (i >= NUM_MATCHPOINTS) return 1;
  dcr[i].dp = 0;
  dcr[i].dp = 0;
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
 
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
 
  /* Matchpoints will cause breakpoints */
  /* Matchpoints will cause breakpoints */
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 &= ~(1 << i));
  dmr2 &= ~(1 << i);
  or1k_implementation.num_used_matchpoints--;
  or1k_implementation.num_used_matchpoints--;
 
  debug_regs_changed = 1;
  return 0;
  return 0;
}
}
 
 
/* Start running on the target board.  */
/* Start running on the target board.  */
 
 
Line 1144... Line 1304...
{
{
  CORE_ADDR entry_pt;
  CORE_ADDR entry_pt;
 
 
  if (args && *args)
  if (args && *args)
    {
    {
      warning ("\
      warning ("Can't pass arguments to remote OR1K board; arguments ignored.");
Can't pass arguments to remote OR1K board; arguments ignored.");
 
      /* And don't try to use them on the next "run" command.  */
      /* And don't try to use them on the next "run" command.  */
      execute_command ("set args", 0);
      execute_command ("set args", 0);
    }
    }
 
 
  if (execfile == 0 || exec_bfd == 0)
  if (execfile == 0 || exec_bfd == 0)
Line 1161... Line 1321...
  entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
  entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
  init_wait_for_inferior ();
  init_wait_for_inferior ();
 
 
  /* FIXME: Should we set inferior_pid here?  */
  /* FIXME: Should we set inferior_pid here?  */
 
 
  insert_breakpoints ();        /* Needed to get correct instruction in cache */
  /* Needed to get correct instruction in cache */
 
  insert_breakpoints ();
  clear_proceed_status ();
  clear_proceed_status ();
  or1k_status = TARGET_STOPPED;
  or1k_status = TARGET_STOPPED;
  proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
  proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
}
}
 
 
Line 1272... Line 1433...
  or1k_dummy_ops.to_kill = or1k_kill;
  or1k_dummy_ops.to_kill = or1k_kill;
  or1k_dummy_ops.to_load = generic_load;
  or1k_dummy_ops.to_load = generic_load;
  or1k_dummy_ops.to_create_inferior = or1k_create_inferior;
  or1k_dummy_ops.to_create_inferior = or1k_create_inferior;
  or1k_dummy_ops.to_mourn_inferior = or1k_mourn_inferior;
  or1k_dummy_ops.to_mourn_inferior = or1k_mourn_inferior;
  or1k_dummy_ops.to_stratum = process_stratum;
  or1k_dummy_ops.to_stratum = process_stratum;
  or1k_dummy_ops.to_has_all_memory = 0; /* We can access memory while program is running.  */
 
 
  /* We can access memory while program is running.  */
 
  or1k_dummy_ops.to_has_all_memory = 0;
 
 
  or1k_dummy_ops.to_has_memory = 1;
  or1k_dummy_ops.to_has_memory = 1;
  or1k_dummy_ops.to_has_stack = 1;
  or1k_dummy_ops.to_has_stack = 1;
  or1k_dummy_ops.to_has_registers = 1;
  or1k_dummy_ops.to_has_registers = 1;
  or1k_dummy_ops.to_has_execution = 1;
  or1k_dummy_ops.to_has_execution = 1;
  or1k_dummy_ops.to_magic = OPS_MAGIC;
  or1k_dummy_ops.to_magic = OPS_MAGIC;

powered by: WebSVN 2.1.0

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