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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-6.8/] [gdb/] [remote-or1k.c] - Diff between revs 1739 and 1754

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

Rev 1739 Rev 1754
Line 187... Line 187...
static void     or1k_create_inferior (char  *execfile,
static void     or1k_create_inferior (char  *execfile,
                                      char  *args,
                                      char  *args,
                                      char **env,
                                      char **env,
                                      int    from_tty);
                                      int    from_tty);
static void     or1k_mourn_inferior ();
static void     or1k_mourn_inferior ();
 
static void     or1k_rcmd (char           *command,
 
                           struct ui_file *outbuf);
/* Global target operations specific to the OR1K */
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Read a special purpose register from the target
 
 
 
   Use the target operation for this.
 
 
 
   @param[in] regnum  The register to read
 
 
 
   @return  The value read */
 
/*---------------------------------------------------------------------------*/
 
 
 
ULONGEST
 
or1k_read_spr (unsigned int  regnum)
 
{
 
  return or1k_jtag_read_spr (regnum);
 
 
 
}       /* or1k_read_spr() */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Write a special purpose register on the target
 
 
 
   Use the target operation for this.
 
 
 
   @param[in] regnum  The register to write
 
   @param[in] data  The value to write */
 
/*---------------------------------------------------------------------------*/
 
 
 
void
 
or1k_write_spr (unsigned int  regnum,
 
                ULONGEST      data)
 
{
 
  or1k_jtag_write_spr (regnum, data);
 
 
 
}       /* or1k_write_spr() */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Ask the user about an interrupt
/*!Ask the user about an interrupt
 
 
Line 665... Line 629...
    }
    }
 
 
  /* The "special" registers */
  /* The "special" registers */
  switch (regnum)
  switch (regnum)
    {
    {
 
    case OR1K_PPC_REGNUM: return  OR1K_NPC_SPRNUM;
 
    case OR1K_NPC_REGNUM: return  OR1K_NPC_SPRNUM;
    case OR1K_SR_REGNUM:    return  OR1K_SR_SPRNUM;
    case OR1K_SR_REGNUM:    return  OR1K_SR_SPRNUM;
    case OR1K_PC_REGNUM:    return  OR1K_NPC_SPRNUM;
 
 
 
    default:
    default:
      error ("or1k_regnum_to_sprnum: invalid register number!");
      error ("or1k_regnum_to_sprnum: invalid register number!");
      break;
      break;
    }
    }
Line 706... Line 671...
      dcr |= or1k_dbgcache.dcr[i].dp ? OR1K_DCR_DP : 0;
      dcr |= or1k_dbgcache.dcr[i].dp ? OR1K_DCR_DP : 0;
      dcr |= (or1k_dbgcache.dcr[i].cc << OR1K_DCR_CC_OFF) & OR1K_DCR_CC;
      dcr |= (or1k_dbgcache.dcr[i].cc << OR1K_DCR_CC_OFF) & OR1K_DCR_CC;
      dcr |= or1k_dbgcache.dcr[i].sc ? OR1K_DCR_SC : 0;
      dcr |= or1k_dbgcache.dcr[i].sc ? OR1K_DCR_SC : 0;
      dcr |= (or1k_dbgcache.dcr[i].ct << OR1K_DCR_CT_OFF) & OR1K_DCR_CT;
      dcr |= (or1k_dbgcache.dcr[i].ct << OR1K_DCR_CT_OFF) & OR1K_DCR_CT;
 
 
      or1k_write_spr (OR1K_DVR0_SPRNUM + i, or1k_dbgcache.dvr[i]);
      or1k_jtag_write_spr (OR1K_DVR0_SPRNUM + i, or1k_dbgcache.dvr[i]);
      or1k_write_spr (OR1K_DCR0_SPRNUM + i, dcr);
      or1k_jtag_write_spr (OR1K_DCR0_SPRNUM + i, dcr);
    }
    }
 
 
  or1k_write_spr (OR1K_DMR1_SPRNUM, or1k_dbgcache.dmr1);
  or1k_jtag_write_spr (OR1K_DMR1_SPRNUM, or1k_dbgcache.dmr1);
  or1k_write_spr (OR1K_DMR2_SPRNUM, or1k_dbgcache.dmr2);
  or1k_jtag_write_spr (OR1K_DMR2_SPRNUM, or1k_dbgcache.dmr2);
  or1k_write_spr (OR1K_DSR_SPRNUM,  or1k_dbgcache.dsr);
  or1k_jtag_write_spr (OR1K_DSR_SPRNUM,  or1k_dbgcache.dsr);
  or1k_write_spr (OR1K_DRR_SPRNUM,  or1k_dbgcache.drr);
  or1k_jtag_write_spr (OR1K_DRR_SPRNUM,  or1k_dbgcache.drr);
 
 
}       /* or1k_commit_debug_registers() */
}       /* or1k_commit_debug_registers() */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 807... Line 772...
 
 
  /* Initialize the connection to the remote target. */
  /* Initialize the connection to the remote target. */
  or1k_jtag_init (name);
  or1k_jtag_init (name);
 
 
  /* Make sure we have system and debug groups implemented. */
  /* Make sure we have system and debug groups implemented. */
  tmp = or1k_read_spr (OR1K_UPR_SPRNUM);
  tmp = or1k_jtag_read_spr (OR1K_UPR_SPRNUM);
  if (0 == (tmp & OR1K_SPR_UPR_UP))
  if (0 == (tmp & OR1K_SPR_UPR_UP))
    {
    {
      error ("or1k_open: system group missing");
      error ("or1k_open: system group missing");
    }
    }
  if (0 == (tmp & OR1K_SPR_UPR_DUP))
  if (0 == (tmp & OR1K_SPR_UPR_DUP))
Line 820... Line 785...
    }
    }
 
 
  /* Determine number of gpr_regs (this is a bit simplified - the bit just
  /* Determine number of gpr_regs (this is a bit simplified - the bit just
     means "less than 32", but we assume that means 16) and the number of
     means "less than 32", but we assume that means 16) and the number of
     supported watchpoints. */
     supported watchpoints. */
  tmp                = or1k_read_spr (OR1K_CPUCFGR_SPRNUM);
  tmp                = or1k_jtag_read_spr (OR1K_CPUCFGR_SPRNUM);
  tdep->num_gpr_regs = (0 == (tmp & OR1K_SPR_CPUCFGR_CGF)) ? 32 : 16;
  tdep->num_gpr_regs = (0 == (tmp & OR1K_SPR_CPUCFGR_CGF)) ? 32 : 16;
 
 
  tmp                   = or1k_read_spr (OR1K_DCFGR_SPRNUM);
  tmp                   = or1k_jtag_read_spr (OR1K_DCFGR_SPRNUM);
  tdep->num_matchpoints = (tmp & OR1K_SPR_DCFGR_NDP) + 1;
  tdep->num_matchpoints = (tmp & OR1K_SPR_DCFGR_NDP) + 1;
 
 
  /* Stall the processor. A pause after stalling is appropriate for real
  /* Stall the processor. A pause after stalling is appropriate for real
     hardware. */
     hardware. */
  or1k_jtag_stall ();
  or1k_jtag_stall ();
Line 950... Line 915...
    {
    {
      error ("or1k_fetch_registers: invalid register number");
      error ("or1k_fetch_registers: invalid register number");
    }
    }
 
 
  /* Convert to SPRNUM and read.  */
  /* Convert to SPRNUM and read.  */
  val = or1k_read_spr (or1k_regnum_to_sprnum (regnum));
  val = or1k_jtag_read_spr (or1k_regnum_to_sprnum (regnum));
 
 
  /* We got the number the register holds, but gdb expects to see a value in
  /* We got the number the register holds, but gdb expects to see a value in
     the target byte ordering.
     the target byte ordering.
 
 
     This is new for GDB 6.8. Not sure if I need get_thread_regcache() using
     This is new for GDB 6.8. Not sure if I need get_thread_regcache() using
Line 996... Line 961...
      error ("or1k_store_registers: invalid register number");
      error ("or1k_store_registers: invalid register number");
    }
    }
 
 
  regcache = get_current_regcache();
  regcache = get_current_regcache();
  regcache_cooked_read_unsigned (regcache, regnum, &res);
  regcache_cooked_read_unsigned (regcache, regnum, &res);
  or1k_write_spr (or1k_regnum_to_sprnum (regnum), res);
  or1k_jtag_write_spr (or1k_regnum_to_sprnum (regnum), res);
 
 
}       /* or1k_store_registers() */
}       /* or1k_store_registers() */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 1489... Line 1454...
 
 
  /* We can now continue normally, independent of step. If this is called for
  /* We can now continue normally, independent of step. If this is called for
     the first time due to a run command, we won't actually be executing, so
     the first time due to a run command, we won't actually be executing, so
     start the target running. */
     start the target running. */
 
 
  or1k_write_spr( OR1K_NPC_SPRNUM, read_pc());
  or1k_jtag_write_spr( OR1K_NPC_SPRNUM, read_pc());
  target_has_execution = 1;
  target_has_execution = 1;
  or1k_jtag_unstall ();
  or1k_jtag_unstall ();
 
 
}       /* or1k_resume() */
}       /* or1k_resume() */
 
 
Line 1534... Line 1499...
 
 
  /* Registers and frame caches are now all unreliable */
  /* Registers and frame caches are now all unreliable */
  registers_changed();
  registers_changed();
 
 
  /* Refresh the debug registers that may have changed */
  /* Refresh the debug registers that may have changed */
  or1k_dbgcache.drr  = or1k_read_spr (OR1K_DRR_SPRNUM);
  or1k_dbgcache.drr  = or1k_jtag_read_spr (OR1K_DRR_SPRNUM);
  or1k_dbgcache.dmr2 = or1k_read_spr (OR1K_DMR2_SPRNUM);
  or1k_dbgcache.dmr2 = or1k_jtag_read_spr (OR1K_DMR2_SPRNUM);
 
 
  /* If we got a trap, then it was a breakpoint/watchpoint of some sort (but
  /* If we got a trap, then it was a breakpoint/watchpoint of some sort (but
     not single step, which does not set the trap exception). We need to back
     not single step, which does not set the trap exception). We need to back
     up the program counter, so the instruction will be re-executed. This
     up the program counter, so the instruction will be re-executed. This
     must be the value of the PPC, in case we have just done a branch. */
     must be the value of the PPC, in case we have just done a branch. */
 
 
  if (OR1K_DRR_TE == (or1k_dbgcache.drr & OR1K_DRR_TE))
  if (OR1K_DRR_TE == (or1k_dbgcache.drr & OR1K_DRR_TE))
    {
    {
      write_pc (or1k_read_spr (OR1K_PPC_SPRNUM));
      write_pc (or1k_jtag_read_spr (OR1K_PPC_SPRNUM));
    }
    }
 
 
  /* Single step does not set trap exception, so we set it manually to
  /* Single step does not set trap exception, so we set it manually to
     simplify our code. */
     simplify our code. */
  if (OR1K_DMR1_ST == (or1k_dbgcache.dmr1 & OR1K_DMR1_ST))
  if (OR1K_DMR1_ST == (or1k_dbgcache.dmr1 & OR1K_DMR1_ST))
Line 1583... Line 1548...
         interrupt. This happens at reset and exit. The latter we distinquish
         interrupt. This happens at reset and exit. The latter we distinquish
         by looking at the instruction just executed, to see if it is
         by looking at the instruction just executed, to see if it is
         "l.nop NOP_EXIT". If this is the case, get the result from GPR 3 and
         "l.nop NOP_EXIT". If this is the case, get the result from GPR 3 and
         set the NPC to the reset vector, so a new start will behave well. */
         set the NPC to the reset vector, so a new start will behave well. */
 
 
      addr = or1k_read_spr (OR1K_PPC_SPRNUM);
      addr = or1k_jtag_read_spr (OR1K_PPC_SPRNUM);
      res  = read_memory_nobpt (addr, buf, OR1K_INSTLEN);
      res  = read_memory_nobpt (addr, buf, OR1K_INSTLEN);
      if (0 != res)
      if (0 != res)
        {
        {
          memory_error (res, addr);
          memory_error (res, addr);
        }
        }
Line 1721... Line 1686...
    }
    }
}       /* or1k_mourn_inferior () */
}       /* or1k_mourn_inferior () */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 
/*!Send a command to the remote target
 
 
 
   The target can't actually run any remote commands, in the sense of having a
 
   command interpreter. However we use this as a GDB "standard" way of
 
   wrapping up commands to access the SPRs.
 
 
 
   Current commands supported are:
 
   - readspr  <regno>
 
   - writespr <regno> <value>
 
 
 
   The output is either the value read (for successful read) or OK (for
 
   successful write) or E01 to indicate and wrror. All values are represented
 
   as unsigned hex.
 
 
 
   @param[in]  command  The command to execute
 
   @param[out] output   The result of the command                            */
 
/*---------------------------------------------------------------------------*/
 
 
 
static void  or1k_rcmd (char           *command,
 
                        struct ui_file *outbuf)
 
{
 
  /* Sort out which command */
 
  if (0 == strncmp ("readspr", command, strlen ("readspr")))
 
    {
 
      unsigned int  regno;              /* SPR to read */
 
 
 
      if (1 != sscanf (command, "readspr %4x", &regno))
 
        {
 
          error ("or1k_rcmd: unrecognized readspr");
 
          fputs_unfiltered ("E01", outbuf);
 
        }
 
      else
 
        {
 
          char      strbuf[sizeof ("ffffffff")];
 
          ULONGEST  data = or1k_jtag_read_spr (regno);
 
 
 
          sprintf (strbuf, "%8llx", data);
 
          fputs_unfiltered (strbuf, outbuf);
 
        }
 
    }
 
  else if (0 == strncmp ("writespr", command, strlen ("writespr")))
 
    {
 
      unsigned int  regno;              /* SPR to write */
 
      ULONGEST      data;               /* Value to write */
 
 
 
      if (2 != sscanf (command, "writespr %4x %8llx", &regno, &data))
 
        {
 
          error ("or1k_rcmd: unrecognized writespr");
 
          fputs_unfiltered ("E01", outbuf);
 
        }
 
      else
 
        {
 
          or1k_jtag_write_spr (regno, data);
 
          fputs_unfiltered ("OK", outbuf);
 
        }
 
    }
 
  else
 
    {
 
      error ("or1k_rcmd: unrecognized remote command");
 
      fputs_unfiltered ("E01", outbuf);
 
    }
 
}       /* or1k_rcmd () */
 
 
 
 
 
/*---------------------------------------------------------------------------*/
/*!Main entry point for the remote OpenRISC JTAG protocol
/*!Main entry point for the remote OpenRISC JTAG protocol
 
 
   Initializes the target ops for each version of the remote
   Initializes the target ops for each version of the remote
   protocol. Currently only the JTAG protocol is implemented.
   protocol. Currently only the JTAG protocol is implemented.
 
 
Line 1790... Line 1820...
  or1k_target.to_stop                        = or1k_stop;
  or1k_target.to_stop                        = or1k_stop;
  or1k_target.to_kill                        = or1k_kill;
  or1k_target.to_kill                        = or1k_kill;
  or1k_target.to_create_inferior             = or1k_create_inferior;
  or1k_target.to_create_inferior             = or1k_create_inferior;
  or1k_target.to_mourn_inferior              = or1k_mourn_inferior;
  or1k_target.to_mourn_inferior              = or1k_mourn_inferior;
 
 
 
  or1k_target.to_rcmd                        = or1k_rcmd;
 
 
  or1k_target.to_magic                       = OPS_MAGIC;
  or1k_target.to_magic                       = OPS_MAGIC;
 
 
  /* Tell GDB about the new target */
  /* Tell GDB about the new target */
 
 
  add_target (&or1k_target);
  add_target (&or1k_target);

powered by: WebSVN 2.1.0

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