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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-or1k.c] - Diff between revs 379 and 405

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

Rev 379 Rev 405
Line 43... Line 43...
#define debug if (remote_debug) printf_unfiltered
#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);
static int insn_has_delay_slot (unsigned int);
static int insn_modifies_gprs (unsigned int insn);
 
 
/* JTAG or1k target ops.  */
/* JTAG or1k target ops.  */
extern void jtag_init PARAMS ((char * args));
extern void jtag_init PARAMS ((char * args));
extern ULONGEST jtag_read_reg PARAMS ((unsigned int regno));
extern ULONGEST jtag_read_reg PARAMS ((unsigned int regno));
extern void jtag_write_reg PARAMS ((unsigned int regno, ULONGEST data));
extern void jtag_write_reg PARAMS ((unsigned int regno, ULONGEST data));
Line 159... Line 159...
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;
static int hit_breakpoint = 0;
static int hit_breakpoint = 0;
 
static int step_link_insn = 0;
static int new_pc_set = 0;
static int new_pc_set = 0;
 
 
/* Current register values.  */
/* Current register values.  */
unsigned int dmr1 = 0;
unsigned int dmr1 = 0;
unsigned int dmr2 = 0;
unsigned int dmr2 = 0;
unsigned int dsr = 0;
unsigned int dsr = 0;
unsigned int drr = 0;
unsigned int drr = 0;
 
unsigned int lr = 0;
 
 
/* 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];
 
 
Line 297... Line 299...
{
{
  or1k_set_chain (SC_RISC_DEBUG);
  or1k_set_chain (SC_RISC_DEBUG);
  or1k_write_reg (regno, (ULONGEST)data);
  or1k_write_reg (regno, (ULONGEST)data);
  if (regno == PC_SPRNUM) {
  if (regno == PC_SPRNUM) {
    hit_breakpoint = 0;
    hit_breakpoint = 0;
 
    step_link_insn = 0;
    new_pc_set = 1;
    new_pc_set = 1;
  }
  }
}
}
 
 
/* Reads register SPR from regno.  */
/* Reads register SPR from regno.  */
Line 516... Line 519...
  memset (&or1k_htrace, 0, sizeof (or1k_htrace));
  memset (&or1k_htrace, 0, sizeof (or1k_htrace));
 
 
  /* RECSELDEPEND = 0 does not match our trace scheme. */
  /* RECSELDEPEND = 0 does not match our trace scheme. */
  or1k_htrace.moder.rec_sel_dep = 1;
  or1k_htrace.moder.rec_sel_dep = 1;
 
 
  debug_regs_changed = 1;
  debug_regs_changed = 0;//1;
  or1k_commit_debug_registers ();
  or1k_commit_debug_registers ();
 
 
  if (err != 0)
  if (err != 0)
    error ("Cannot connect.");
    error ("Cannot connect.");
 
 
Line 741... Line 744...
  unsigned int pc;
  unsigned int pc;
  unsigned int ppc;
  unsigned int ppc;
  unsigned int npc;
  unsigned int npc;
  unsigned int val;
  unsigned int val;
  unsigned int ppc_insn;
  unsigned int ppc_insn;
 
  unsigned int pc_insn;
 
 
  pc = read_pc();
  pc = read_pc();
  npc = or1k_read_spr_reg (PC_SPRNUM);
  npc = or1k_read_spr_reg (PC_SPRNUM);
  ppc = or1k_read_spr_reg (PPC_SPRNUM);
  ppc = or1k_read_spr_reg (PPC_SPRNUM);
  debug ("pc = %08x BP = %x npc = %08x ppc = %08x\n", pc, breakpoint_here_p (pc), npc, ppc);
  debug ("pc = %08x BP = %x npc = %08x ppc = %08x\n", pc, breakpoint_here_p (pc), npc, ppc);
Line 759... Line 763...
  /* 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 ();
  or1k_commit_debug_registers ();
 
 
 
  /* Fetch previous insn */
  ppc_insn = or1k_fetch_instruction(ppc);
  ppc_insn = or1k_fetch_instruction(ppc);
 
 
  /* Else clause added by CZ 26/06/01 */
  /* Fetch next insn */
 
  pc_insn = or1k_fetch_instruction (pc);
 
 
  if (step)
  if (step)
    {
    {
      /* HW STEP.  Set DMR1_ST.  */
      /* HW STEP.  Set DMR1_ST.  */
      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;
 
 
      if (new_pc_set)
      if (new_pc_set)
        {
        {
          debug("resume: 1\n");
          debug("resume: 1\n");
 
          /* If new PC was set, then just set it again to fill the pipeline */
 
 
          or1k_write_spr_reg (PC_SPRNUM, pc);
          or1k_write_spr_reg (PC_SPRNUM, pc);
          new_pc_set = 0;
 
 
          if (is_delayed (pc_insn) && insn_modifies_gprs (pc_insn))
 
            {
 
              debug("resume: 10\n");
 
              /* We are steping across jump an link insn - save link
 
                 register, so we will be able to restore it when we will
 
                 step across delay slot insn */
 
              step_link_insn = 1;
 
              lr = or1k_read_spr_reg (REGNUM_TO_SPRNUM(9));
        }
        }
      else if (insn_has_delay_slot (ppc_insn) && (ppc != pc))
        }
 
      else if (is_delayed (ppc_insn) && (ppc != pc))
        {
        {
          /* Steping across delay slot insn - we have to reexcute branch insn */
 
          debug("resume: 2\n");
          debug("resume: 2\n");
 
          /* Steping across delay slot insn - we have to reexcute branch insn */
 
 
          if(breakpoint_here_p (ppc))
          if(breakpoint_here_p (ppc))
              or1k_write_mem(ppc, ppc_insn);
              or1k_write_mem(ppc, ppc_insn);
 
 
 
          if (insn_modifies_gprs (ppc_insn) && step_link_insn)
 
            {
 
              debug("resume: 11\n");
 
              /* If this is delay slot of jump an link insn that was
 
                 allready executed - restore link register first */
 
              or1k_write_spr_reg (REGNUM_TO_SPRNUM(9), lr);
 
              step_link_insn = 0;
 
            }
 
 
          or1k_write_spr_reg (PC_SPRNUM, ppc);
          or1k_write_spr_reg (PC_SPRNUM, ppc);
 
 
          or1k_unstall ();
          or1k_unstall ();
 
 
          or1k_set_chain (SC_REGISTER);
          or1k_set_chain (SC_REGISTER);
          val = or1k_read_reg (JTAG_RISCOP);
          val = or1k_read_reg (JTAG_RISCOP);
          do {
          do {
            val = or1k_read_reg (JTAG_RISCOP);
            val = or1k_read_reg (JTAG_RISCOP);
          } while ((val & 1) == 0);
          } while ((val & 1) == 0);
 
 
          new_pc_set = 0;
 
        }
        }
      else if (hit_breakpoint && ((ppc + 4) != npc))
      else if (hit_breakpoint && ((ppc + 4) != npc) && (pc != npc))
       {
       {
          debug("resume: 3\n");
          debug("resume: 3\n");
          /* Trapped on delay slot instruction. */
          /* Trapped on delay slot instruction. */
          /* Set PC to branch insn preceding delay slot. */
          /* Set PC to branch insn preceding delay slot. */
          or1k_write_spr_reg (PC_SPRNUM, ppc - 4);
          or1k_write_spr_reg (PC_SPRNUM, ppc - 4);
 
 
 
          if (insn_modifies_gprs (or1k_fetch_instruction (ppc - 4)))
 
            {
 
              debug("resume: 12\n");
 
              /* We are steping across jump an link insn - save link
 
                 register, so we will be able to restore it when we will
 
                 step across delay slot insn */
 
              step_link_insn = 1;
 
              lr = or1k_read_spr_reg (REGNUM_TO_SPRNUM(9));
 
            }
 
 
          or1k_unstall ();
          or1k_unstall ();
 
 
          or1k_set_chain (SC_REGISTER);
          or1k_set_chain (SC_REGISTER);
          val = or1k_read_reg (JTAG_RISCOP);
          val = or1k_read_reg (JTAG_RISCOP);
          do {
          do {
            val = or1k_read_reg (JTAG_RISCOP);
            val = or1k_read_reg (JTAG_RISCOP);
          } while ((val & 1) == 0);
          } while ((val & 1) == 0);
 
 
          new_pc_set = 0;
 
        }
        }
      else
      else
        {
        {
          debug("resume: 4\n");
          debug("resume: 4\n");
 
          /* Steping across 'non delay slot' insn - set PC to fill the pipeline */
 
 
          or1k_write_spr_reg (PC_SPRNUM, pc);
          or1k_write_spr_reg (PC_SPRNUM, pc);
 
 
          new_pc_set = 0;
          if (is_delayed (pc_insn) && insn_modifies_gprs (pc_insn))
 
            {
 
              debug("resume: 13\n");
 
              /* We are steping across jump an link insn - save link
 
                 register, so we will be able to restore it when we will
 
                 step across delay slot insn */
 
              step_link_insn = 1;
 
              lr = or1k_read_spr_reg (REGNUM_TO_SPRNUM(9));
 
            }
        }
        }
    }
    }
  else
  else
    {
    {
      dmr1 &= ~DMR1_ST;
      dmr1 &= ~DMR1_ST;
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
 
      if (new_pc_set)
      if (new_pc_set)
        {
        {
          debug("resume: 5\n");
          debug("resume: 5\n");
          or1k_write_spr_reg (PC_SPRNUM, pc);
          /* If new PC was set, then just set it again to fill the pipeline */
 
 
          new_pc_set = 0;
          step_link_insn = 0;
 
          or1k_write_spr_reg (PC_SPRNUM, pc);
        }
        }
      else if (insn_has_delay_slot (ppc_insn) && !breakpoint_here_p (ppc))
      else if (is_delayed (ppc_insn) && !breakpoint_here_p (ppc))
        {
        {
          debug("resume: 6\n");
          debug("resume: 6\n");
          or1k_write_spr_reg (PC_SPRNUM, ppc);
          /* If next insn is delay slot insn - set PC to previous branch insn
 
             and continue from there to refill the pipeline */
 
 
          new_pc_set = 0;
          if (insn_modifies_gprs (ppc_insn) && step_link_insn)
 
            {
 
              debug("resume: 14\n");
 
              /* If this is delay slot of jump an link insn that was
 
                 allready executed - restore link register first */
 
              or1k_write_spr_reg (REGNUM_TO_SPRNUM(9), lr);
 
              step_link_insn = 0;
 
            }
 
 
 
           or1k_write_spr_reg (PC_SPRNUM, ppc);
        }
        }
      else if (insn_has_delay_slot (ppc_insn) && breakpoint_here_p (ppc))
      else if (is_delayed (ppc_insn) && breakpoint_here_p (ppc))
        {
        {
          debug("resume: 7\n");
          debug("resume: 7\n");
 
          /* If next insn is delay slot insn and previous branch insn
 
             is actually BP - replace BP with original branch insn, set PC
 
             to that insn step over it, put back BP and continue */
 
 
          or1k_write_mem(ppc, ppc_insn);
          or1k_write_mem(ppc, ppc_insn);
 
 
          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_write_spr_reg (PC_SPRNUM, ppc);
          or1k_write_spr_reg (PC_SPRNUM, ppc);
 
 
 
          if (insn_modifies_gprs (ppc_insn) && step_link_insn)
 
            {
 
              debug("resume: 15\n");
 
              /* If this is delay slot of jump an link insn that was
 
                 allready executed - restore link register first */
 
              or1k_write_spr_reg (REGNUM_TO_SPRNUM(9), lr);
 
              step_link_insn = 0;
 
            }
 
 
          or1k_unstall ();
          or1k_unstall ();
 
 
          or1k_set_chain (SC_REGISTER);
          or1k_set_chain (SC_REGISTER);
          val = or1k_read_reg (JTAG_RISCOP);
          val = or1k_read_reg (JTAG_RISCOP);
          do {
          do {
Line 861... Line 928...
          } while ((val & 1) == 0);
          } while ((val & 1) == 0);
 
 
          or1k_write_mem(ppc, 0x21000001);
          or1k_write_mem(ppc, 0x21000001);
 
 
          or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
          or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
 
 
          new_pc_set = 0;
 
        }
        }
      else
      else
        {
        {
          debug("resume: 8\n");
          debug("resume: 8\n");
          or1k_write_spr_reg (PC_SPRNUM, pc);
          /* Continue from 'non delay slot' insn - set PC to fill the pipeline */
 
 
          new_pc_set = 0;
          or1k_write_spr_reg (PC_SPRNUM, pc);
        }
        }
    }
    }
 
 
 
  /* Now we are in normal program flow again */
 
  new_pc_set = 0;
 
 
  /* 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);
  debug ("-resume %i, %i, %i\n",step, siggnal, or1k_status);
}
}
Line 1826... Line 1894...
      if ((dmr2 >> (i + 11)) & 1)
      if ((dmr2 >> (i + 11)) & 1)
        printf_filtered (", increments counter");
        printf_filtered (", increments counter");
      printf_filtered ("\n");
      printf_filtered ("\n");
    }
    }
}
}
 
 
static int
static int
insn_has_delay_slot (insn)
insn_modifies_gprs(unsigned int insn)
     unsigned int insn;
 
{
{
  if (((insn >> 26) <= 4) || ((insn >> 26) == 17) || ((insn >> 26) == 18))
  /* l.jal */
 
  if ((insn >> 26) == 0x01)
    return 1;
    return 1;
  else
 
 
  /* l.jalr */
 
  if ((insn >> 26) == 0x12)
 
    return 1;
 
 
    return 0;
    return 0;
}
}
 
 
void
void
_initialize_remote_or1k ()
_initialize_remote_or1k ()

powered by: WebSVN 2.1.0

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