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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [or1k-tdep.c] - Diff between revs 362 and 363

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

Rev 362 Rev 363
Line 144... Line 144...
    {"DME", "DTLB Miss Exception"},
    {"DME", "DTLB Miss Exception"},
    {"IME", "ITLB Miss Exception"},
    {"IME", "ITLB Miss Exception"},
    {"RE", "Range Exception"},
    {"RE", "Range Exception"},
    {"SCE", "SCE Exception"},
    {"SCE", "SCE Exception"},
    {"BRKPTE", "Breakpoint Exception"},
    {"BRKPTE", "Breakpoint Exception"},
    {"TRAPE", "Trap Exception"},
 
    {NULL, NULL}
    {NULL, NULL}
  };
  };
 
 
const char *compare_to_names[NUM_CT_NAMES] =
const char *compare_to_names[NUM_CT_NAMES] =
  {
  {
Line 193... Line 192...
 
 
/* Previous values for buffer display.  */
/* Previous values for buffer display.  */
static int prev_length = 10;
static int prev_length = 10;
static int prev_from = 0;
static int prev_from = 0;
 
 
/* Define NEW_PC_HANDLING if you want to use the new style routines
 
   where control is given to the debug interface AFTER the exception
 
   has already been taken. */
 
 
 
#ifdef NEW_PC_HANDLING
 
 
 
/* Specialized read_pc routine. Looks at returned value. If value
 
   is detected inside the breakpoint exception vector, the actual
 
   value stored in EPC is returned instead. The breakpoint exception
 
   vector should consist of nothing more than an RTE and a NOP. Note
 
   that this mechanism prohibits the use of GDB in an environment
 
   where this restriction is not met, however this is not expected
 
   to cause a significant problem. Anyone wishing to use GDB can
 
   easily store the appropriate instructions at the vector, and if
 
   they're not using GDB, why the hell are they inserting breakpoint
 
   exceptions?...
 
*/
 
 
 
CORE_ADDR or1k_target_read_pc(int pid)
 
{
 
#if defined(PC_REGNUM) && defined(EPC_REGNUM)
 
  if(PC_REGNUM >= 0)
 
    {
 
      unsigned long pc_val = or1k_read_spr_reg(PC_SPRNUM);
 
 
 
      /* If we're currently at the breakpoint exception, get the logical PC
 
         from the exception register instead. */
 
      if(pc_val == 0xD00)
 
        {
 
          unsigned long sr_val = or1k_read_spr_reg(ESR_SPRNUM(CURRENT_CID));
 
 
 
          pc_val = or1k_read_spr_reg(EPC_SPRNUM(CURRENT_CID));
 
#if 0
 
          if(!(sr_val & 0x2000)) /* If ESR[DSX] is not set */
 
            pc_val += 4;
 
#endif
 
        }
 
      return pc_val;
 
    }
 
#endif
 
  internal_error ("or1k_target_read_pc");
 
  return 0;
 
}
 
 
 
void or1k_target_write_pc(CORE_ADDR pc,int pid)
 
{
 
#if defined(PC_REGNUM) && defined(EPC_REGNUM)
 
  if(PC_REGNUM >= 0)
 
    {
 
      unsigned long pc_val = or1k_read_spr_reg(PC_SPRNUM);
 
      if(pc_val == 0xD00)
 
        {
 
          unsigned long sr_val = or1k_read_spr_reg(ESR_SPRNUM(CURRENT_CID));
 
 
 
          if(or1k_read_spr_reg(EPC_SPRNUM(CURRENT_CID)) != pc)
 
            or1k_write_spr_reg(EPC_SPRNUM(CURRENT_CID), pc);
 
        }
 
      else
 
        {
 
          unsigned char break_bytes[4] = BRK_INSTR_STRUCT;
 
          unsigned long b_insn = ntohl(*((unsigned long*)break_bytes));
 
          unsigned long saved_insn = or1k_read_spr_reg((pc_val >> 2) + MEM_SPACE);
 
          unsigned long saved_sr = or1k_read_spr_reg(SR_SPRNUM);
 
          unsigned long saved_dmr1 = or1k_read_spr_reg(DMR1_SPRNUM);
 
          unsigned long working_sr = saved_sr;
 
          unsigned long working_dmr1 = saved_dmr1;
 
          unsigned long new_pc_val = pc_val;
 
 
 
          or1k_save_stall_state();
 
          /* Install a breakpoint */
 
          or1k_write_spr_reg((pc_val >> 2) + MEM_SPACE,b_insn);
 
 
 
          /* Make sure exceptions are enabled and interrupts
 
             are disabled */
 
          working_sr |= 0x02;  /* Exceptions enabled */
 
          working_sr &= ~0x04; /* Interrupts disabled */
 
          or1k_write_spr_reg(SR_SPRNUM,working_sr);
 
 
 
          /* Make sure we are in hardware single step... */
 
          dmr1 |= DMR1_ST;
 
          or1k_write_spr_reg(DMR1_SPRNUM, dmr1);
 
 
 
          or1k_do_1_processor_step();
 
          while((new_pc_val = or1k_read_spr_reg(PC_SPRNUM)) != 0xD00)
 
            {
 
              /* We still haven't managed to get into the exception.
 
                 Perhaps there was an exception pending already and
 
                 it jumped somewhere else? Let's try it again. */
 
 
 
              /* Restore the old instruction */
 
              or1k_write_spr_reg((pc_val >> 2) + MEM_SPACE, saved_insn);
 
              pc_val = new_pc_val;
 
 
 
              /* Install a new breakpoint */
 
              saved_insn = or1k_read_spr_reg(( pc_val >> 2) + MEM_SPACE);
 
              or1k_write_spr_reg((pc_val >> 2) + MEM_SPACE,b_insn);
 
 
 
              /* Again, make sure exceptions are enabled */
 
              working_sr = or1k_read_spr_reg(SR_SPRNUM);
 
              working_sr |= 0x02;  /* Exceptions enabled */
 
              working_sr &= ~0x04; /* Interrupts disabled */
 
              or1k_write_spr_reg(SR_SPRNUM,working_sr);
 
 
 
              or1k_do_1_processor_step();
 
            }
 
 
 
          /* Restore the state of everything */
 
#if 0
 
          if(saved_sr & 0x2000)
 
            or1k_write_spr_reg(EPC_SPRNUM(CURRENT_CID), pc);
 
          else
 
            or1k_write_spr_reg(EPC_SPRNUM(CURRENT_CID), pc-4);
 
#endif
 
          or1k_write_spr_reg(EPC_SPRNUM(CURRENT_CID), pc);
 
          or1k_write_spr_reg(ESR_SPRNUM(CURRENT_CID), saved_sr);
 
          or1k_write_spr_reg((pc_val >> 2) + MEM_SPACE, saved_insn);
 
 
 
          /* Step the processor twice to finish through the
 
             breakpoint instruction */
 
          or1k_do_1_processor_step();
 
          or1k_do_1_processor_step();
 
 
 
          or1k_restore_stall_state();
 
 
 
          /* Reset the single step mode */
 
          or1k_write_spr_reg(DMR1_SPRNUM,saved_dmr1);
 
        }
 
      return;
 
    }
 
#endif
 
  internal_error ("or1k_target_write_pc");
 
  return;
 
}
 
 
 
#endif /* NEW_PC_HANDLING */
 
 
 
/* Converts regno to sprno.  or1k debug unit has GPRs mapped to SPRs,
/* Converts regno to sprno.  or1k debug unit has GPRs mapped to SPRs,
   which are not compact, so we are mapping them for GDB.  */
   which are not compact, so we are mapping them for GDB.  */
/* Rewritten by CZ 12/09/01 */
/* Rewritten by CZ 12/09/01 */
int
int
or1k_regnum_to_sprnum (int regno)
or1k_regnum_to_sprnum (int regno)
Line 783... Line 646...
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (VFRV_REGNUM)], TYPE_LENGTH (valtype));
  else
  else
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
    memcpy (valbuf, &regbuf[REGISTER_BYTE (RV_REGNUM)], TYPE_LENGTH (valtype));
}
}
 
 
/* CZ -- 25/09/01 -- The prologue handling code has been rewritten
/* The or1k cc defines the following
   to bring it inline with the new C compiler and various changes
   prologue:
   that have been made. The code below expects to see various
00000000 <_proc1>:
   instructions that are identified by states. States are ordered
   0:   d7 e1 17 e4     l.sw 0xffffffe4(r1),r2
   and should flow from one to the next. If a state is encountered
   4:   9c 41 00 00     l.addi r2,r1,0x0
   out of order, it is assumed to be function code and not
   8:   9c 21 ff e8     l.addi r1,r1,0xffffffe8
   prologue, so the prologue parsing is terminated. I've tried
   c:   d7 e2 1f f8     l.sw 0xfffffff8(r2),r3
   several real world tests from the C compiler, and this seems
  10:   d7 e2 27 f4     l.sw 0xfffffff4(r2),r4
   to recognize the transition from prologue to code even under
  14:   84 82 ff f8     l.lwz r4,0xfffffff8(r2)
   a worst case (21 instructions) scenario. */
  18:   9d 24 00 00     l.addi r9,r4,0x0
 
  1c:   00 00 00 02     l.j 0x2
typedef enum {
  20:   15 00 00 00     l.nop
  PrologueStateMachineStart,
 
  PrologueStateMachineFrameInitialized,
00000024 <_L2>:
  PrologueStateMachineFrameSaved,
  24:   84 41 ff fc     l.lwz r2,0xfffffffc(r1)
  PrologueStateMachineFrameAdjusted,
  28:   48 00 58 00     l.jalr r11
  PrologueStateMachineRegisterSaved,
  2c:   9c 21 00 18     l.addi r1,r1,0x18 */
  PrologueStateMachineParameterSaved,
 
  PrologueStateMachineInvalid,
 
} FunctionPrologueStates;
 
 
 
/* Parse the insn and save the arguments */
 
static FunctionPrologueStates getPrologueInsnType(unsigned long insn,
 
                                                  int* arg1,int* arg2)
 
{
 
  int code = insn >> 26;
 
  int state = PrologueStateMachineInvalid;
 
  int op1,op2;
 
  short offset;
 
 
 
  switch(code)
 
    {
 
    case 0x27:  /* l.addi */
 
      op1 = (insn & 0x03E00000) >> 21;
 
      op2 = (insn & 0x001F0000) >> 16;
 
      if(op1 == 1 && op2 == 1)
 
        {
 
          offset = insn & 0xFFFF;
 
          state = PrologueStateMachineFrameInitialized;
 
        }
 
      else if(op1 == 2 && op2 == 1)
 
        {
 
          offset = insn & 0xFFFF;
 
          state = PrologueStateMachineFrameAdjusted;
 
        }
 
      *arg1 = op1;
 
      *arg2 = offset;
 
      break;
 
    case 0x35:  /* l.sw */
 
      op1 = (insn & 0x001F0000) >> 16;
 
      op2 = (insn & 0x0000F800) >> 11;
 
      offset = (insn & 0x000007FF) |
 
        ((insn & 0x03E00000) >> 10);
 
 
 
      if(op1 == 1)
 
        state = (op2 == 2) ? PrologueStateMachineFrameSaved :
 
          PrologueStateMachineRegisterSaved;
 
      else if(op1 == 2)
 
        state = PrologueStateMachineParameterSaved;
 
      *arg1 = op2;
 
      *arg2 = offset;
 
      break;
 
    default:    /* unknown */
 
      break;
 
    }
 
 
 
  return state;
 
}
 
 
 
CORE_ADDR or1k_skip_prologue (CORE_ADDR pc)
CORE_ADDR
 
or1k_skip_prologue (CORE_ADDR pc)
{
{
  int frame_size = 0,i;
  unsigned long inst;
  FunctionPrologueStates state = PrologueStateMachineStart;
  CORE_ADDR skip_pc;
  CORE_ADDR t_pc;
  CORE_ADDR func_addr, func_end;
 
  struct symtab_and_line sal;
  /*
  int i;
     Maximum prologue: save even reg's 10-30 (11 insns)
  int offset = 0;
     save params passed in regs (6 insns)
 
     adjust stack (1 insn), adjust frame (1 insn),
 
     save old frame pointer (1 insn),
 
     save old link register (1 insn)
 
  */
 
  static const int MAX_PROLOGUE_LENGTH = 21;
 
 
 
  for (i = 0; i < MAX_GPR_REGS; i++)
  for (i = 0; i < MAX_GPR_REGS; i++)
    or1k_saved_reg_addr[i] = -1;
    or1k_saved_reg_addr[i] = -1;
 
 
  /* Is there a prologue?  */
  /* Is there a prologue?  */
Line 890... Line 697...
      /* get saved reg. */
      /* get saved reg. */
      or1k_saved_reg_addr[(inst >> 11) & 0x1f] = offset++;
      or1k_saved_reg_addr[(inst >> 11) & 0x1f] = offset++;
      pc += OR1K_INSTLEN;
      pc += OR1K_INSTLEN;
      inst = or1k_fetch_instruction (pc);
      inst = or1k_fetch_instruction (pc);
    }
    }
 
  return pc;
  return t_pc;
 
}
}
 
 
/* Determines whether this function has frame.  */
/* Determines whether this function has frame.  */
 
 
int
int

powered by: WebSVN 2.1.0

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