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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-or1k.c] - Diff between revs 207 and 362

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

Rev 207 Rev 362
Line 38... 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>
 
 
 
#define debug if (remote_debug) printf_unfiltered
 
 
/* The following prototype is necessary or the compiler will not
/* The following prototype is necessary or the compiler will not
   correctly promote the data argument to ULONGEST */
   correctly promote the data argument to ULONGEST */
static void or1k_write_reg (unsigned int, ULONGEST);
static void or1k_write_reg (unsigned int, ULONGEST);
 
 
/* JTAG or1k target ops.  */
/* JTAG or1k target ops.  */
Line 147... Line 149...
static int or1k_is_open = 0;
static int or1k_is_open = 0;
 
 
/* Error last occured, zero = ok.  */
/* Error last occured, zero = ok.  */
int err = 0;
int err = 0;
 
 
/* Nonzero, if we changed something.  */
/* Nonzero, if we changed something (except DMR1 which is updated on every run anyway).  */
int debug_regs_changed;
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;
 
 
Line 175... Line 177...
 
 
/* Current matchpoints.  */
/* Current matchpoints.  */
unsigned int dvr[MAX_MATCHPOINTS];
unsigned int dvr[MAX_MATCHPOINTS];
struct dcr_struct dcr[MAX_MATCHPOINTS];
struct dcr_struct dcr[MAX_MATCHPOINTS];
 
 
 
/* Number of matchpoint users */
int matchpoint_user_count[MAX_MATCHPOINTS] = {0};
int matchpoint_user_count[MAX_MATCHPOINTS] = {0};
 
 
 
/* Old SIGINT handler.  */
 
static void (*ofunc) PARAMS ((int));
 
 
 
 
/* 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 293... Line 300...
or1k_write_spr_reg (regno, data)
or1k_write_spr_reg (regno, data)
     unsigned int regno;
     unsigned int regno;
     unsigned int data;
     unsigned int data;
{
{
  or1k_set_chain (SC_RISC_DEBUG);
  or1k_set_chain (SC_RISC_DEBUG);
  or1k_write_reg (regno + REG_SPACE, (ULONGEST)data);
  or1k_write_reg (regno, (ULONGEST)data);
}
}
 
 
/* Reads register SPR from regno.  */
/* Reads register SPR from regno.  */
 
 
unsigned int
unsigned int
or1k_read_spr_reg (regno)
or1k_read_spr_reg (regno)
     unsigned int regno;
     unsigned int regno;
{
{
  or1k_set_chain (SC_RISC_DEBUG);
  or1k_set_chain (SC_RISC_DEBUG);
  return or1k_read_reg (regno + REG_SPACE);
  return or1k_read_reg (regno);
 
}
 
 
 
/* Sets mem to data.  */
 
 
 
void
 
or1k_write_mem (addr, data)
 
     unsigned int addr;
 
     unsigned int data;
 
{
 
  or1k_set_chain (SC_WISHBONE);
 
  or1k_write_reg (addr, (ULONGEST)data);
 
}
 
 
 
/* Reads register SPR from regno.  */
 
 
 
unsigned int
 
or1k_read_mem (addr)
 
     unsigned int addr;
 
{
 
  or1k_set_chain (SC_WISHBONE);
 
  return or1k_read_reg (addr);
}
}
 
 
/* CZ 15/09/01 -- This is hacked in right now. This should
/* CZ 15/09/01 -- This is hacked in right now. This should
   probably NOT be called directly, but at the moment I don't
   probably NOT be called directly, but at the moment I don't
   have the time to figure out how to do it right. The problem
   have the time to figure out how to do it right. The problem
Line 369... Line 397...
{
{
  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);
 
  or1k_read_reg (JTAG_RISCOP);
 
 
  /* Be cautious - disable trace.  */
  /* Be cautious - disable trace.  */
  val = or1k_read_reg (JTAG_MODER);
  val = or1k_read_reg (JTAG_MODER);
  or1k_write_reg (JTAG_MODER, val & ~2);
  or1k_write_reg (JTAG_MODER, val & ~2);
  or1k_flush_pipeline ();
 
}
}
 
 
/* Unstalls the CPU.  */
/* Unstalls the CPU.  */
 
 
static void
static void
Line 387... Line 415...
 
 
 
 
  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);
 
  or1k_read_reg (JTAG_RISCOP);
}
}
 
 
/* 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;
 
  int i;
 
  debug ("%08x\n", or1k_read_reg (JTAG_RISCOP));
  or1k_set_chain (SC_REGISTER);
  or1k_set_chain (SC_REGISTER);
 
 
  /* Be cautious - disable trace.  */
  /* Be cautious - disable trace.  */
  val = or1k_read_reg (JTAG_MODER);
  val = or1k_read_reg (JTAG_MODER);
  or1k_write_reg (JTAG_MODER, val & ~2);
  or1k_write_reg (JTAG_MODER, val & ~2);
Line 406... Line 437...
  val = or1k_read_reg (JTAG_RISCOP);
  val = or1k_read_reg (JTAG_RISCOP);
  val &= ~3;
  val &= ~3;
  /* Assert reset signal.  */
  /* Assert reset signal.  */
  or1k_write_reg (JTAG_RISCOP, val | 3);
  or1k_write_reg (JTAG_RISCOP, val | 3);
 
 
 
  /* Just do something */
 
  for (i = 0; i < 100; i++)
 
    or1k_read_reg (JTAG_RISCOP);
 
 
  /* give it some time */
  /* give it some time */
  usleep (1000);
  usleep (1000);
  or1k_flush_pipeline ();
 
 
 
  or1k_set_chain (SC_REGISTER);  /* CZ: Changed 16/06/01...must reset
  or1k_set_chain (SC_REGISTER);
                                    scan chain after flush_pipeline() */
 
  /* Release reset signal, but keep in stall state.  */
  /* Release reset signal, but keep in stall state.  */
  or1k_write_reg (JTAG_RISCOP, val | 1);
  or1k_write_reg (JTAG_RISCOP, val | 1);
  or1k_flush_pipeline ();
  or1k_read_reg (JTAG_RISCOP);
}
}
 
 
/* Synchronizes debug registers in memory with those on target,
/* Synchronizes debug registers in memory with those on target,
   if there is any change.  */
   if there is any change.  */
 
 
Line 492... Line 525...
 
 
  or1k_status = TARGET_CONNECTING;
  or1k_status = TARGET_CONNECTING;
  if (current_or1k_target != NULL && current_or1k_target->to_init != NULL)
  if (current_or1k_target != NULL && current_or1k_target->to_init != NULL)
    current_or1k_target->to_init (args);
    current_or1k_target->to_init (args);
 
 
  or1k_reset ();
  debug("%08x\n", read_pc ());
 
  or1k_stall ();
 
  debug("%08x\n", read_pc ());
 
  usleep (1000);
 
 
  /* 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);
 
 
Line 542... Line 578...
  or1k_commit_debug_registers ();
  or1k_commit_debug_registers ();
 
 
  if (err != 0)
  if (err != 0)
    error ("Cannot connect.");
    error ("Cannot connect.");
 
 
 
  /* Enable exceptions */
 
  or1k_write_spr_reg (SR_SPRNUM, or1k_read_spr_reg(SR_SPRNUM) | 0x2);
 
 
  /* Stop when breakpoint occurs.  */
  /* Stop when breakpoint occurs.  */
  or1k_write_spr_reg (DSR_SPRNUM, 0x1000);
  or1k_write_spr_reg (DSR_SPRNUM, 0x2000);
 
 
  do_cleanups (old_cleanups);
  do_cleanups (old_cleanups);
 
 
  /* This should cause an error if not connected.  */
  /* This should cause an error if not connected.  */
  or1k_fetch_registers (-1);
  or1k_fetch_registers (-1);
Line 603... Line 642...
  set_current_frame (create_new_frame (read_fp (), stop_pc));
  set_current_frame (create_new_frame (read_fp (), stop_pc));
  select_frame (get_current_frame (), 0);
  select_frame (get_current_frame (), 0);
  print_stack_frame (selected_frame, -1, 1);
  print_stack_frame (selected_frame, -1, 1);
}
}
 
 
 
/* This is the generic stop called via the target vector. When a target
 
   interrupt is requested, either by the command line or the GUI, we
 
   will eventually end up here. */
 
static void
 
or1k_stop ()
 
{
 
  /* Send a break or a ^C, depending on user preference.  */
 
  debug ("remote_stop called\n");
 
 
 
  /* We should not stop the target immediately, since it can be in an
 
     unfinished state.  So we do a single step.  This should not affect
 
     on anything.  */
 
  or1k_stall ();
 
  /* HW STEP.  Set DMR1_ST.  */
 
  dmr1 |= DMR1_ST;
 
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
  dmr1 &= ~DMR1_ST;
 
  or1k_unstall ();
 
}
 
 
/* Close a connection to the remote board.  */
/* Close a connection to the remote board.  */
 
 
static void
static void
or1k_close (quitting)
or1k_close (quitting)
     int quitting;
     int quitting;
Line 672... Line 731...
        }
        }
    }
    }
  fclose (fd);
  fclose (fd);
}
}
 
 
 
/* ^C Interrupt handling */
 
 
 
/* Ask the user what to do when an interrupt is received.  */
 
static void
 
interrupt_query ()
 
{
 
  target_terminal_ours ();
 
 
 
  if (query ("Interrupted while waiting for the program.\n\
 
Give up (and stop debugging it)? "))
 
    {
 
      target_mourn_inferior ();
 
      return_to_top_level (RETURN_QUIT);
 
    }
 
 
 
  target_terminal_inferior ();
 
}
 
 
 
static void or1k_interrupt_twice (int signo);
 
 
 
 
 
/* The command line interface's stop routine. This function is installed
 
   as a signal handler for SIGINT. The first time a user requests a
 
   stop, we call remote_stop to send a break or ^C. If there is no
 
   response from the target (it didn't stop when the user requested it),
 
   we ask the user if he'd like to detach from the target. */
 
static void
 
or1k_interrupt (signo)
 
     int signo;
 
{
 
        debug ("interrupt");
 
  /* If this doesn't work, try more severe steps. */
 
  signal (signo, or1k_interrupt_twice);
 
 
 
  debug ("remote_interrupt called\n");
 
 
 
  interrupt_count++;
 
}
 
 
 
/* The user typed ^C twice.  */
 
 
 
static void
 
or1k_interrupt_twice (signo)
 
     int signo;
 
{
 
        debug ("interrupt2");
 
  signal (signo, ofunc);
 
  interrupt_query ();
 
  signal (signo, or1k_interrupt);
 
}
 
 
/* 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
or1k_resume (pid, step, siggnal)
or1k_resume (pid, step, siggnal)
     int pid, step;
     int pid, step;
     enum target_signal siggnal;
     enum target_signal siggnal;
{
{
 
        debug ("pc = %08x\n", read_pc());
 
  debug ("resume %i, %i, %i\n",step, siggnal, or1k_status);
  if (or1k_status != TARGET_STOPPED)
  if (or1k_status != TARGET_STOPPED)
    if (or1k_status == TARGET_RUNNING)
    if (or1k_status == TARGET_RUNNING)
      error ("Program is already running.");
      error ("Program is already running.");
    else
    else
      error ("The program is not being run.");
      error ("The program is not being run.");
 
 
 
 
  /* Clear reason register for later.  */
  /* Clear reason register for later.  */
  or1k_write_spr_reg (DRR_SPRNUM, 0);
  or1k_write_spr_reg (DRR_SPRNUM, 0);
 
 
 
  or1k_commit_debug_registers ();
 
 
  /* Else clause added by CZ 26/06/01 */
  /* Else clause added by CZ 26/06/01 */
  if (step)
  if (step)
    {
    {
      /* HW STEP.  Set DMR1_ST.  */
      /* HW STEP.  Set DMR1_ST.  */
      dmr1 |= DMR1_ST;
      dmr1 |= DMR1_ST;
Line 705... Line 819...
    {
    {
      dmr1 &= ~DMR1_ST;
      dmr1 &= ~DMR1_ST;
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
    }
    }
 
 
  or1k_commit_debug_registers ();
 
  /* Run the target. */
  /* Run the target. */
#ifdef NEW_PC_HANDLING
#ifdef NEW_PC_HANDLING
 
 
  /* In the new style PC handling mode, we should always
  /* In the new style PC handling mode, we should always
     keep stepping the target until we get out of the
     keep stepping the target until we get out of the
Line 729... Line 842...
#endif
#endif
 
 
  /* We can now continue normally, independent of step */
  /* We can now continue normally, independent of step */
  or1k_unstall ();
  or1k_unstall ();
  or1k_status = TARGET_RUNNING;
  or1k_status = TARGET_RUNNING;
 
  debug ("-resume %i, %i, %i\n",step, siggnal, or1k_status);
}
}
 
 
/* Wait until the remote stops, and return a wait status.  */
/* Wait until the remote stops, and return a wait status.  */
 
 
static int
static int
or1k_wait (pid, status)
or1k_wait (pid, status)
     int pid;
     int pid;
     struct target_waitstatus *status;
     struct target_waitstatus *status;
{
{
 
  unsigned long val;
 
  unsigned long pc;
 
  char buf[MAX_REGISTER_RAW_SIZE];
  interrupt_count = 0;
  interrupt_count = 0;
 
 
 
  debug ("pc = %08x\n", read_pc());
 
  debug ("wait %i %i\n", pid, or1k_status);
  /* If we have not sent a single step or continue command, then the
  /* If we have not sent a single step or continue command, then the
     board is waiting for us to do something.  Return a status
     board is waiting for us to do something.  Return a status
     indicating that it is stopped.  */
     indicating that it is stopped.  */
  if (or1k_status != TARGET_RUNNING)
  if (or1k_status != TARGET_RUNNING)
    {
    {
Line 755... Line 874...
    }
    }
 
 
  if (err)
  if (err)
    or1k_error ("Remote failure: %s", or1k_err_name (err));
    or1k_error ("Remote failure: %s", or1k_err_name (err));
 
 
  /* Wait for or1k DRR register to be nonzero.  */
  /* Set new signal handler */
  interrupt_requested = 0;
  ofunc = signal (SIGINT, or1k_interrupt);
  old_sigint = signal (SIGINT, or1k_request_int);
 
  do
  /* Wait for risc to stop.  */
    {
  do {
      if(interrupt_requested)
    or1k_set_chain (SC_REGISTER);
        {
    val = or1k_read_reg (JTAG_RISCOP);
          or1k_stall();
 
          status->kind = TARGET_WAITKIND_STOPPED;
    /* When we press Ctrl-C, interrupt count is set, but we must wait
          status->value.sig = TARGET_SIGNAL_INT;
         for or1k_read_reg to finish, otherwise we would interrupt transaction.  */
          or1k_status = TARGET_STOPPED;
    if (interrupt_count)
          or1k_read_trace();
        or1k_stop ();
          return 0;
 
        }
 
      drr = or1k_read_spr_reg (DRR_SPRNUM);
 
      usleep (10);
      usleep (10);
    }
    debug ("%i", val);
  while (drr == 0);
  } while ((val & 1) == 0);
 
 
 
  drr = or1k_read_spr_reg (DRR_SPRNUM);
 
 
 
  /* Restore old INT signal handler */
 
  signal (SIGINT, ofunc);
 
 
 
  /* If we encounter breakpoint, drr is not set, so we set it manually.  */
 
  if (!drr)
 
    drr |= DRR_BE;
 
 
  signal (SIGINT, old_sigint);
 
  status->kind = TARGET_WAITKIND_STOPPED;
  status->kind = TARGET_WAITKIND_STOPPED;
  or1k_flush_pipeline ();
 
 
  debug ("epcr0 = %08x\n", or1k_read_spr_reg (EPCR0_SPRNUM));
 
  debug ("drr = %08x\n", drr);
 
 
 
  pc = read_pc ();
 
 
  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)
    status->value.sig = TARGET_SIGNAL_BUS;
    status->value.sig = TARGET_SIGNAL_BUS;
Line 804... Line 933...
    status->value.sig = TARGET_SIGNAL_REALTIME_39;
    status->value.sig = TARGET_SIGNAL_REALTIME_39;
  else if (drr & DRR_SCE)
  else if (drr & DRR_SCE)
    status->value.sig = TARGET_SIGNAL_REALTIME_40;
    status->value.sig = TARGET_SIGNAL_REALTIME_40;
  else if (drr & DRR_BE)
  else if (drr & DRR_BE)
    status->value.sig = TARGET_SIGNAL_TRAP;
    status->value.sig = TARGET_SIGNAL_TRAP;
  else if (drr & DRR_TE)
  else if (drr & DRR_BE2)
    status->value.sig = TARGET_SIGNAL_REALTIME_41;
 
  else if (drr & DRR_SS)  /* CZ 16/09/01 */
 
    status->value.sig = TARGET_SIGNAL_TRAP;
 
  else
 
    {
    {
 
      /* PC has already stepped over the l.trap instruction.  */
 
      pc -= 4;
 
      status->value.sig = TARGET_SIGNAL_TRAP;
 
    } else {
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      warning ("Invalid exception occured.");
      warning ("Invalid exception occured.");
    }
    }
 
 
 
  /* Write into PC flushes the pipeline! */
 
  /* We got the number the register holds, but gdb expects to see a
 
     value in the target byte ordering.  */
 
  store_unsigned_integer (buf, REGISTER_RAW_SIZE (PC_REGNUM), pc);
 
  supply_register (PC_REGNUM, buf);
 
 
  /* Log remote stop.  */
  /* Log remote stop.  */
  or1k_status = TARGET_STOPPED;
  or1k_status = TARGET_STOPPED;
 
 
  /* Determine what caused trap - breakpoint or watchpoint.  */
  /* Determine what caused trap - breakpoint or watchpoint.  */
  if (status->value.sig == TARGET_SIGNAL_TRAP)
  if (status->value.sig == TARGET_SIGNAL_TRAP)
Line 846... Line 981...
         by a write command. All pending exceptions are cleared and
         by a write command. All pending exceptions are cleared and
         the simulator continues at the PC value specified. We need
         the simulator continues at the PC value specified. We need
         to do this if the instruction at the current PC has the
         to do this if the instruction at the current PC has the
         value BRK_INSTR_STRUCT */
         value BRK_INSTR_STRUCT */
 
 
      if(b_insn == or1k_read_reg((pc >> 2) + MEM_SPACE))
      if(b_insn == or1k_read_mem((pc & 3)))
        {
        {
          or1k_write_spr_reg(PC_SPRNUM,value);
          or1k_write_spr_reg(PC_SPRNUM,value);
        }
        }
#endif
#endif
 
 
Line 887... Line 1022...
        && func_start == pc)
        && func_start == pc)
      status->kind = TARGET_WAITKIND_EXITED;
      status->kind = TARGET_WAITKIND_EXITED;
  }
  }
 
 
  or1k_read_trace ();
  or1k_read_trace ();
 
  debug ("-wait %i %i\n", pid, or1k_status);
  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.  */
Line 903... Line 1039...
    {
    {
      int subaddr = addr & 3;
      int subaddr = addr & 3;
      unsigned char buf[8];
      unsigned char buf[8];
      unsigned int low, high;
      unsigned int low, high;
      addr >>= 2;
      addr >>= 2;
      low = or1k_read_reg (addr + MEM_SPACE);
      low = or1k_read_mem (addr << 2);
      high = or1k_read_reg (addr + 1 + MEM_SPACE);
      high = or1k_read_reg ((addr + 1) << 2);
      memcpy (&buf[0], &low, 4);
      memcpy (&buf[0], &low, 4);
      memcpy (&buf[4], &high, 4);
      memcpy (&buf[4], &high, 4);
      memcpy (&low, &buf[subaddr], 4);
      memcpy (&low, &buf[subaddr], 4);
      return low;
      return low;
    }
    }
  else
  else
    {
    {
      addr >>= 2;
      return or1k_read_mem (addr);
      return or1k_read_reg (addr + MEM_SPACE);
 
    }
    }
}
}
 
 
/* 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.  */
Line 931... Line 1066...
    {
    {
      int subaddr = addr & 3;
      int subaddr = addr & 3;
      unsigned char buf[8];
      unsigned char buf[8];
      unsigned int low, high;
      unsigned int low, high;
      addr >>= 2;
      addr >>= 2;
      low = or1k_read_reg (addr + MEM_SPACE);
      low = or1k_read_mem (addr << 2);
      high = or1k_read_reg (addr + 1 + MEM_SPACE);
      high = or1k_read_mem ((addr + 1) << 2);
      memcpy (&buf[0], &low, 4);
      memcpy (&buf[0], &low, 4);
      memcpy (&buf[4], &high, 4);
      memcpy (&buf[4], &high, 4);
      memcpy (&buf[subaddr], &val, 4);
      memcpy (&buf[subaddr], &val, 4);
      memcpy (&low, &buf[0], 4);
      memcpy (&low, &buf[0], 4);
      memcpy (&high, &buf[4], 4);
      memcpy (&high, &buf[4], 4);
      or1k_write_reg (addr + MEM_SPACE, low);
      or1k_write_mem (addr << 2, low);
      or1k_write_reg (addr + 1 + MEM_SPACE, high);
      or1k_write_mem ((addr + 1) << 2, high);
    }
    }
  else
  else
    {
    {
      addr >>= 2;
      or1k_write_mem (addr, val);
      or1k_write_reg (addr + MEM_SPACE, val);
 
    }
    }
  return err;
  return err;
}
}
 
 
/* Fetch the remote registers.  */
/* Fetch the remote registers.  */
Line 980... Line 1114...
    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,
    or1k_error ("Can't read register %d(%i): %s", regno,
                REGNUM_TO_SPRNUM(regno) + REG_SPACE, or1k_err_name (err));
                REGNUM_TO_SPRNUM(regno), 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 1021... Line 1155...
    }
    }
 
 
  if (regno >= NUM_REGS)
  if (regno >= NUM_REGS)
    error("Invalid register number!");
    error("Invalid register number!");
 
 
  or1k_write_spr_reg (REGNUM_TO_SPRNUM(regno), or1k_read_spr_reg (REGNUM_TO_SPRNUM(regno)));
  or1k_write_spr_reg (REGNUM_TO_SPRNUM(regno), read_register (regno));
  if (err)
  if (err)
    or1k_error ("Can't write register %d(%i): %s", regno, REGNUM_TO_SPRNUM(regno), or1k_err_name (err));
    or1k_error ("Can't write register %d(%i): %s", regno, REGNUM_TO_SPRNUM(regno), or1k_err_name (err));
}
}
 
 
/* Read or write LEN bytes from inferior memory at MEMADDR,
/* Read or write LEN bytes from inferior memory at MEMADDR,
Line 1054... Line 1188...
 
 
  int block_xfer_size = 256; /* CZ 21/06/01 ... number of 32 bit words */
  int block_xfer_size = 256; /* CZ 21/06/01 ... number of 32 bit words */
  int nBlocks = (count + block_xfer_size -1)/block_xfer_size;
  int nBlocks = (count + block_xfer_size -1)/block_xfer_size;
  int terminate = 0;  /* Terminate the printing of '*'s... */
  int terminate = 0;  /* Terminate the printing of '*'s... */
 
 
 
#ifdef DEBUG_JTAG
 
  debug ("xfer_memory %s addr=%x, len=%i, \n", write?"write":"read", memaddr, len);
 
  fflush(stdout);
 
#endif
 
 
 
#if 0
  if (memaddr >= MEM_SPACE)
  if (memaddr >= MEM_SPACE)
    error("Invalid address");
    error("Invalid address");
 
#endif
 
 
  /* (CZ 21/06/01 -- because upper layers which know nothing about
  /* (CZ 21/06/01 -- because upper layers which know nothing about
     Or1k or JTAG call this function directly, it is always necessary
     Or1k or JTAG call this function directly, it is always necessary
     to set the chain to point to the Debug Unit. Otherwise, it may
     to set the chain to point to the Debug Unit. Otherwise, it may
     be pointing to the Development Interface chain, in which case
     be pointing to the Development Interface chain, in which case
     we're going to get bupkiss... */
     we're going to get bupkiss... */
 
 
  or1k_set_chain (SC_RISC_DEBUG);
 
 
 
  if (write)
  if (write)
    {
    {
      /* Fill start and end extra bytes of buffer with existing data.  */
      /* Fill start and end extra bytes of buffer with existing data.  */
      if (addr != memaddr || len < 4)
      if (addr != memaddr || len < 4)
        {
        {
Line 1103... Line 1242...
              return 0;
              return 0;
            }
            }
 
 
          for(j=0;j<n;j++)
          for(j=0;j<n;j++)
            __buf[j] = (unsigned long)extract_unsigned_integer(&buffer[(i * block_xfer_size +j)*4], 4);
            __buf[j] = (unsigned long)extract_unsigned_integer(&buffer[(i * block_xfer_size +j)*4], 4);
 
          or1k_set_chain (SC_WISHBONE);
          status = or1k_store_block(addr,__buf,n);
          status = or1k_store_block(addr,__buf,n);
          free(__buf);
          free(__buf);
          if(n == block_xfer_size)
          if(n == block_xfer_size)
            {
            {
              printf_unfiltered ("*");
              debug ("*");
              gdb_flush (gdb_stdout);
              gdb_flush (gdb_stdout);
            }
            }
          if (status)
          if (status)
            {
            {
              errno = status;
              errno = status;
              return 0;
              return 0;
            }
            }
          /* FIXME: Do we want a QUIT here?  */
          /* FIXME: Do we want a QUIT here?  */
        }
        }
      if (terminate)
      if (terminate)
        printf_unfiltered ("\n");
        debug ("\n");
    }
    }
  else
  else
    {
    {
      for(i=0;i<nBlocks;i++,count-=block_xfer_size,addr += block_xfer_size*4)
      for(i=0;i<nBlocks;i++,count-=block_xfer_size,addr += block_xfer_size*4)
        {
        {
          int j;
          int j;
          int n = count < block_xfer_size ? count : block_xfer_size;
          int n = count < block_xfer_size ? count : block_xfer_size;
          unsigned long *__buf;
          unsigned long *__buf;
 
 
 
    or1k_set_chain (SC_WISHBONE);
          __buf = (unsigned long*)malloc(n*sizeof(unsigned long));
          __buf = (unsigned long*)malloc(n*sizeof(unsigned long));
          status = or1k_load_block(addr,__buf,n);
          status = or1k_load_block(addr,__buf,n);
          if (!status)
          if (!status)
            for(j=0;j<n;j++)
            for(j=0;j<n;j++)
              store_unsigned_integer (&buffer[(i * block_xfer_size +j)*4], 4, __buf[j]);
              store_unsigned_integer (&buffer[(i * block_xfer_size +j)*4], 4, __buf[j]);
Line 1149... Line 1290...
}
}
 
 
int or1k_load_block(CORE_ADDR addr,void* buffer,int nRegisters)
int or1k_load_block(CORE_ADDR addr,void* buffer,int nRegisters)
{
{
  int i=0;
  int i=0;
  unsigned int regno = (addr >> 2) + MEM_SPACE;
  unsigned int regno = addr;
 
 
  if (current_or1k_target != NULL && current_or1k_target->to_read_block != NULL)
  if (current_or1k_target != NULL && current_or1k_target->to_read_block != NULL)
    return current_or1k_target->to_read_block (regno,buffer,nRegisters);
    return current_or1k_target->to_read_block (regno,buffer,nRegisters);
  else
  else
    for(i=0;i<nRegisters;i++)
    for(i=0;i<nRegisters;i++)
Line 1161... Line 1302...
  return 0;
  return 0;
}
}
 
 
int or1k_store_block(CORE_ADDR addr,void* buffer,int nRegisters)
int or1k_store_block(CORE_ADDR addr,void* buffer,int nRegisters)
{
{
  unsigned int regno = (addr >> 2) + MEM_SPACE;
  unsigned int regno = addr;
 
 
  if (current_or1k_target != NULL && current_or1k_target->to_write_block != NULL)
  if (current_or1k_target != NULL && current_or1k_target->to_write_block != NULL)
    return current_or1k_target->to_write_block (regno,buffer,nRegisters);
    return current_or1k_target->to_write_block (regno,buffer,nRegisters);
  return 0;
  return 0;
}
}
 
 
/* Flushes pipeline. May not be needed by all implementations, but
 
   it doen't hurt to do it. This function should be called every time
 
   or1k stops.
 
   When or1k stops it still has instructions in pipeline.
 
   We do this by inserting nop instructions.
 
   IF cycle remains unaffacted by writing to DIR, and it still holds
 
   instruction, that caused break or watchpoint. */
 
 
 
void
 
or1k_flush_pipeline ()
 
{
 
  /* CZ 15/09/01 -- Damjan has made it perfectly clear
 
     that the DIR will not be implemented on any chip
 
     as the entire concept is poorly conceived. This
 
     section has therefore been removed. */
 
  /* or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
 
  or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
 
  or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR); */
 
}
 
 
 
/* Print info on this target.  */
/* Print info on this target.  */
 
 
static void
static void
or1k_files_info (ignore)
or1k_files_info (ignore)
     struct target_ops *ignore;
     struct target_ops *ignore;
Line 1658... Line 1779...
  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_stop = or1k_stop;
 
 
  /* 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_all_memory = 0;
 
 
  or1k_dummy_ops.to_has_memory = 1;
  or1k_dummy_ops.to_has_memory = 1;

powered by: WebSVN 2.1.0

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