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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [debug/] [debug_unit.c] - Rev 378

Go to most recent revision | Compare with Previous | Blame | View Log

/* debug_unit.c -- Simulation of Or1k debug unit
   Copyright (C) 2001 Chris Ziomkowski, chris@asics.ws
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/*
  This is an architectural level simulation of the Or1k debug
  unit as described in OpenRISC 1000 System Architecture Manual,
  v. 0.1 on 22 April, 2001. This unit is described in Section 13.
 
  Every attempt has been made to be as accurate as possible with
  respect to the registers and the behavior. There are no known
  limitations at this time.
*/
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
 
#include "debug_unit.h"
#include "sim-config.h"
#include "except.h"
#include "arch.h"
#include "abstract.h"
#include "parse.h"
#include "trace.h"
#include "sprs.h"
#include "../gdb.h"
#include "../cpu/or1k/except.h"
#include "opcode/or32.h"
 
DebugUnit debug_unit;
DevelopmentInterface development;
 
typedef enum {
  false = 0,
  true = 1,
} Boolean;
static void ExecuteInducedInstruction(unsigned long);
 
/* External STALL signal to debug interface */
int cpu_stalled = false;
int in_reset = false;
 
/* An induced instruction has been written to the DIR register */
static Boolean induced = false;
static unsigned long induced_insn;
 
/* A flag to indicate that we must perform an ic mmu cycle */
static Boolean lookup_physical_address = false;
 
/* Variables for implementing ExecuteInducedInstruction */
extern unsigned long pc;
extern unsigned long pcnext;
extern unsigned long  pcdelay;
extern unsigned long pc_phy;
extern int delay_insn;
static void GetIQueueEntry(struct iqueue_entry*);
 
static int CalculateWatchpoints(void);
 
static  int watchpoint[10];
 
/* This function returns true if an induced instruction has
   been inserted into the instruction stream. It will remove
   that instruction and return the result. This function is
   called from the fetch() routine. */
int OverrideFetch(unsigned long* insn)
{
  int valid = induced;
  induced = false;
 
  if(valid)
    *insn = induced_insn;
  return valid;
}
 
void InduceImmediateInstruction(unsigned long insn)
{
  induced = true;
  induced_insn = insn;
 
  if(in_reset)
    return;
 
  if(cpu_stalled)
    {
      ExecuteInducedInstruction(insn);
      induced_insn = 0;
      induced = false;
    }
}
 
void SetCPUStallState(int state)
{
  if(debug_unit.DMR1.DXFW) /* If debugger disabled */
    state = false;
 
  if(state == cpu_stalled)
    return;
 
  if(state && induced)
    {
      ExecuteInducedInstruction(induced_insn);
      induced_insn = 0;
      induced = false;
    }
 
  cpu_stalled = state;
}
 
void ResetDebugUnit()
{
  memset(&debug_unit,'\0',sizeof(DebugUnit));
  cpu_stalled = 0;
}
 
#ifdef DEBUGMOD_OFF
#define CheckDebugUnit(x,y) 0
#else
inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata)
{
  int i;
  DCR_CT_Settings condition = DCR_CT_Disabled;
  long data = (long)udata;
  int match;
 
  if(DEBUG_ENABLED || in_reset)
    return 0;
 
  /* If we're single stepping, always stop */
  if(debug_unit.DMR1.ST && action == DebugInstructionFetch)
    return 1;
 
  switch(action)
    {
    case DebugInstructionFetch:   condition = DCR_CT_InsnAddress;   break;
    case DebugLoadAddress:        condition = DCR_CT_LoadAddress;   break;
    case DebugStoreAddress:       condition = DCR_CT_StoreAddress;  break;
    case DebugLoadData:           condition = DCR_CT_LoadData;      break;
    case DebugStoreData:          condition = DCR_CT_StoreData;     break;
    }
 
  for(i=0;i<8;i++)
    {
      if(debug_unit.DCR[i].DP == DCR_DP_Absent)
	continue;
 
      if(debug_unit.DCR[i].CT == condition)
	{
	  if(debug_unit.DCR[i].SC == DCR_SC_Signed)
	    {
	      switch(debug_unit.DCR[i].CC)
		{
		case DCR_CC_Equal:        match = data == (int)debug_unit.DVR[i];   break;
		case DCR_CC_LessThan:     match = data < (int)debug_unit.DVR[i];    break;
		case DCR_CC_LessEqual:    match = data <= (int)debug_unit.DVR[i];   break;
		case DCR_CC_GreaterThan:  match = data > (int)debug_unit.DVR[i];    break;
		case DCR_CC_GreaterEqual: match = data >= (int)debug_unit.DVR[i];   break;
		case DCR_CC_NotEqual:     match = data != (int)debug_unit.DVR[i];   break;
		default:                  match = 0;                                break;
		}
	    }
	  else
	    {
	      switch(debug_unit.DCR[i].CC)
		{
		case DCR_CC_Equal:        match = udata == debug_unit.DVR[i];   break;
		case DCR_CC_LessThan:     match = udata < debug_unit.DVR[i];    break;
		case DCR_CC_LessEqual:    match = udata <= debug_unit.DVR[i];   break;
		case DCR_CC_GreaterThan:  match = udata > debug_unit.DVR[i];    break;
		case DCR_CC_GreaterEqual: match = udata >= debug_unit.DVR[i];   break;
		case DCR_CC_NotEqual:     match = udata != debug_unit.DVR[i];   break;
		default:                  match = 0;                            break;
		}
	    }
	}
      match <<= i;
      debug_unit.DCR_hit &= ~match;      /* Clear DCR compare if it has changed */
      debug_unit.DCR_hit |= match;  /* Save the state of each DCR compare */
    }
 
  return CalculateWatchpoints();
}
#endif
 
static int CalculateWatchpoints()
{
  int spec[11];
  int breakpoint = 0;
  int i,bit;
 
  spec[0] = debug_unit.DMR1.CW0;
  spec[1] = debug_unit.DMR1.CW1;
  spec[2] = debug_unit.DMR1.CW2;
  spec[3] = debug_unit.DMR1.CW3;
  spec[4] = debug_unit.DMR1.CW4;
  spec[5] = debug_unit.DMR1.CW5;
  spec[6] = debug_unit.DMR1.CW6;
  spec[7] = debug_unit.DMR1.CW7;
  spec[8] = debug_unit.DMR1.CW8;
  spec[9] = debug_unit.DMR1.CW9;
  spec[10] = debug_unit.DMR1.CW10;
 
  for(i=0,bit=1;i<11;i++,bit<<=1)
    {
      int chain1,chain2;
      int match = 0;
 
      switch(i)
	{
	case 0:
	  chain1 = chain2 = debug_unit.DCR_hit & 0x01;
	  break;
	case 8:
	  chain1 = debug_unit.DWCR[0].COUNT == debug_unit.DWCR[0].MATCH;
	  chain2 = debug_unit.watchpoint & (1 << 7);
	  break;
	case 9:
	  chain1 = debug_unit.DWCR[1].COUNT == debug_unit.DWCR[1].MATCH;
	  chain2 = debug_unit.watchpoint & (1 << 8);
	  break;
	case 10:
	  chain1 = debug_unit.DCR_hit & 0x100; /* External hit */
	  chain2 = debug_unit.watchpoint & (1 << 9);
	  break;
	default:
	  chain1 = debug_unit.DCR_hit & bit;
	  chain2 = debug_unit.watchpoint & (bit >> 1);
	  break;
	}
 
      switch(spec[i])
	{
	case 0:	match = chain1;           break;
	case 1: match = chain1 && chain2; break;
	case 2: match = chain1 || chain2; break;
	default:
	  break;
	}
 
      if(match & !(debug_unit.watchpoint & bit))
	{
	  int counter = (debug_unit.DMR2.AWPC & bit) ? 1 : 0;
	  int enabled = counter ? debug_unit.DMR2.WCE1 : debug_unit.DMR2.WCE0;
 
	  if(enabled)
	    debug_unit.DWCR[counter].COUNT++;
 
	  if(debug_unit.DMR2.WGB & bit)
	    breakpoint = 1;
	}
 
      debug_unit.watchpoint &= ~bit;
      debug_unit.watchpoint |= bit;
    }
 
  return breakpoint;
}
 
static void GetIQueueEntry(struct iqueue_entry* iq_entry)
{
  iq_entry->insn = induced_insn;
  iq_entry->insn_index = insn_decode(induced_insn);
  iq_entry->insn_addr = pc_phy;
  iq_entry->op[0] = 0;
  iq_entry->op[MAX_OPERANDS] = OPTYPE_LAST;
}
 
static void ExecuteInducedInstruction(unsigned long insn)
{
  struct iqueue_entry iq_entry;
  unsigned long pc_saved = pc;
  unsigned long pcnext_saved = pcnext;
  unsigned long pcdelay_saved = pcdelay;
  unsigned long pc_phy_saved = pc_phy;
 
  GetIQueueEntry(&iq_entry);
  decode_execute(&iq_entry);
 
  pc = pc_saved;
  pcnext = pcnext_saved;
  pcdelay = pcdelay_saved;
  pc_phy = pc_phy_saved;
}
 
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
 
int DebugGetRegister(unsigned int address,int32_t* data)
{
  int err;
#ifdef DEBUG_JTAG
  printf("Debug get register %x\n",address);
  fflush(stdout);
#endif
  switch(current_scan_chain)
    {
    case JTAG_CHAIN_DEBUG_UNIT:
      err = GetDebugUnitRegister(address,data);
      break;
    case JTAG_CHAIN_TRACE:
      *data = 0;  /* Scan chain not yet implemented */
      err = 0;
      break;
    case JTAG_CHAIN_DEVELOPMENT:
      err = GetDevelopmentInterfaceRegister(address,data);
      break;
    case JTAG_CHAIN_WISHBONE:
      err = GetWishboneMemory(address,data);
      break;
    }
#ifdef DEBUG_JTAG
  printf("!get reg %x\n", *data);
  fflush(stdout);
#endif
  return err;
}
 
int DebugSetRegister(unsigned int address,int32_t data)
{
  int err;
#ifdef DEBUG_JTAG
  printf("Debug set register %x <- %x\n",address, data);
  fflush(stdout);
#endif
  switch(current_scan_chain)
    {
    case JTAG_CHAIN_DEBUG_UNIT:
      err = SetDebugUnitRegister(address,data);
      break;
    case JTAG_CHAIN_TRACE:
      err = JTAG_PROXY_ACCESS_EXCEPTION;
      break;
    case JTAG_CHAIN_DEVELOPMENT:
      err = SetDevelopmentInterfaceRegister(address,data);
      break;
    case JTAG_CHAIN_WISHBONE:
      err = SetWishboneMemory(address,data);
      break;
    }
#ifdef DEBUG_JTAG
  printf("!set reg\n");
  fflush(stdout);
#endif
  return err;
}
 
int DebugSetChain(int chain)
{
#ifdef DEBUG_JTAG
  printf("Debug set chain %x\n",chain);
  fflush(stdout);
#endif
  switch(chain)
    {
    case JTAG_CHAIN_DEBUG_UNIT:
    case JTAG_CHAIN_TRACE:
    case JTAG_CHAIN_DEVELOPMENT:
    case JTAG_CHAIN_WISHBONE:
      current_scan_chain = chain;
      break;     
    default: /* All other chains not implemented */
      return JTAG_PROXY_INVALID_CHAIN;
    }
 
#ifdef DEBUG_JTAG
  printf("!set chain\n");
  fflush(stdout);
#endif
  return 0;
}
 
/* Nearly all compilers today store these bit fields as a packed structure
   in network byte order (Big Endian). If you happen to be unlucky enough
   to be working in a non standard environment, you may need to rewrite
   this routine or the SET_REG32 macro. */
int SetDevelopmentInterfaceRegister(unsigned int address,uint32_t data)
{
  int err = 0;
  uint32_t value = data;
  int old_value;
  char *t_ptr = (char*)&development.RISCOP;
 
  switch(address)
    {
    case DEVELOPINT_MODER:
      SET_REG32(development.MODER,value);
      break;
    case DEVELOPINT_TSEL:
      SET_REG32(development.TSEL,value);
      break;
    case DEVELOPINT_QSEL:
      SET_REG32(development.QSEL,value);
      break;
    case DEVELOPINT_SSEL:
      SET_REG32(development.SSEL,value);
      break;
    case DEVELOPINT_RISCOP:
      old_value = development.RISCOP.RESET;
      SET_REG32(development.RISCOP,value);
 
      in_reset = development.RISCOP.RESET;
 
      /* Reset the cpu on the negative edge of RESET */
      if(old_value && !development.RISCOP.RESET)
	{
	  uart_reset();
	  tick_reset();
	  pm_reset();
	  pic_reset();
	  reset(); /* Old or new mode */
	}
 
      SetCPUStallState(development.RISCOP.RISCSTALL);
      break;
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP3:
    case DEVELOPINT_RECWP4:
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP10:
      SET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value);
      break;
    case DEVELOPINT_RECBP0:
      SET_REG32(development.RECBP[0],value);
      break;
    default:
      err = JTAG_PROXY_INVALID_ADDRESS;
      break;
    }
  return err;
}
 
int GetDevelopmentInterfaceRegister(unsigned int address,uint32_t *data)
{
  int err = 0;
  uint32_t value = 0;
 
  switch(address)
    {
    case DEVELOPINT_MODER:    GET_REG32(development.MODER,value);      break;
    case DEVELOPINT_TSEL:     GET_REG32(development.TSEL,value);       break;
    case DEVELOPINT_QSEL:     GET_REG32(development.QSEL,value);       break;
    case DEVELOPINT_SSEL:     GET_REG32(development.SSEL,value);       break;
    case DEVELOPINT_RISCOP:   GET_REG32(development.RISCOP,value);     break;
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP3:
    case DEVELOPINT_RECWP4:
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP10:  GET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); break;
    case DEVELOPINT_RECBP0:   GET_REG32(development.RECBP[0],value);   break;
    default:                  err = JTAG_PROXY_INVALID_ADDRESS;        break;
    }
 
  *data = value;
  return err;
}
 
/* Nearly all compilers today store these bit fields as a packed structure
   in network byte order (Big Endian). If you happen to be unlucky enough
   to be working in a non standard environment, you may need to rewrite
   this routine or the SET_REG32 macro. */
int SetDebugUnitRegister(unsigned int address,uint32_t data)
{
  int err = 0;
  uint32_t value = data;
  int old_value;
  int group = address >> 11;
 
  address &= 0x07FF;
 
  /*****************************************************/
  /*  TEMPORARY!!!!                                    */
  /*****************************************************/
  if(group == 6)
    address -= 32;
 
  if(group == 6)
    {
      switch(address)
	{
	case DEBUGINT_DVR0:
	case DEBUGINT_DVR1:
	case DEBUGINT_DVR2:
	case DEBUGINT_DVR3:
	case DEBUGINT_DVR4:
	case DEBUGINT_DVR5:
	case DEBUGINT_DVR6:
	case DEBUGINT_DVR7:
	  printf("DVR %d set to 0x%08x\n",address-DEBUGINT_DVR0,value);
	  SET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value);
	  break;
	case DEBUGINT_DCR0:
	case DEBUGINT_DCR1:
	case DEBUGINT_DCR2:
	case DEBUGINT_DCR3:
	case DEBUGINT_DCR4:
	case DEBUGINT_DCR5:
	case DEBUGINT_DCR6:
	case DEBUGINT_DCR7:
	  printf("DCR %d set to 0x%08x\n",address-DEBUGINT_DCR0,value);
	  SET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value);
	  break;
	case DEBUGINT_DMR1:
	  SET_REG32(debug_unit.DMR1,value);
	  break;
	case DEBUGINT_DMR2:
	  SET_REG32(debug_unit.DMR2,value);
	  break;
	case DEBUGINT_DWCR0:
	  SET_REG32(debug_unit.DWCR[0],value);
	  break;
	case DEBUGINT_DWCR1:
	  SET_REG32(debug_unit.DWCR[1],value);
	  break;
	case DEBUGINT_DSR:
	  SET_REG32(debug_unit.DSR,value);
	  break;
	case DEBUGINT_DRR:
	  SET_REG32(debug_unit.DRR,value);
	  break;
	case DEBUGINT_DIR:
	  InduceImmediateInstruction(value);
	  break;
	default:
	  err = JTAG_PROXY_INVALID_ADDRESS;
	  break;
	}
    }
  else if(group == 0)
    {
      extern unsigned long reg[32];
 
      if(!address)
	err = JTAG_PROXY_ACCESS_EXCEPTION;
      else if(address < 32)
	{
	  /* Assume that a write to the PC implies
	     that the debugging software has recognized
	     the exception and wants to do something
	     else instead. */
 
	  if(address == SPR_NPC)
	    {
	      ClearPendingException();
	      ClearPreparedPCState();
	    }
	  mtspr(address,data);
	}
      else if(address >= 0x0400 && address < 0x0420)
	reg[address - 0x0400] = data;
      else if(address < 0x0600 || address >= 0x0620)
	err = JTAG_PROXY_INVALID_ADDRESS;
    }
  else
    err = JTAG_PROXY_INVALID_ADDRESS;
 
  return err;
}
 
int GetDebugUnitRegister(unsigned int address,uint32_t *data)
{
  int err = 0;
  uint32_t value = 0;
  int group = address >> 11;
 
  address &= 0x07FF;
 
  /*****************************************************/
  /*  TEMPORARY!!!!                                    */
  /*****************************************************/
  if(group == 6)
    address -= 32;
 
  if(group == 6)
    {
      switch(address)
	{
	case DEBUGINT_DVR0:
	case DEBUGINT_DVR1:
	case DEBUGINT_DVR2:
	case DEBUGINT_DVR3:
	case DEBUGINT_DVR4:
	case DEBUGINT_DVR5:
	case DEBUGINT_DVR6:
	case DEBUGINT_DVR7:    GET_REG32(debug_unit.DVR[address-DEBUGINT_DVR0],value);  break;
	case DEBUGINT_DCR0:
	case DEBUGINT_DCR1:
	case DEBUGINT_DCR2:
	case DEBUGINT_DCR3:
	case DEBUGINT_DCR4:
	case DEBUGINT_DCR5:
	case DEBUGINT_DCR6:
	case DEBUGINT_DCR7:    GET_REG32(debug_unit.DCR[address-DEBUGINT_DCR0],value);  break;
	case DEBUGINT_DMR1:    GET_REG32(debug_unit.DMR1,value);         break;
	case DEBUGINT_DMR2:    GET_REG32(debug_unit.DMR2,value);         break;
	case DEBUGINT_DWCR0:   GET_REG32(debug_unit.DWCR[0],value);        break;
	case DEBUGINT_DWCR1:   GET_REG32(debug_unit.DWCR[1],value);        break;
	case DEBUGINT_DSR:     GET_REG32(debug_unit.DSR,value);          break;
	case DEBUGINT_DRR:     GET_REG32(debug_unit.DRR,value);          break;
	case DEBUGINT_DIR:     err = JTAG_PROXY_ACCESS_EXCEPTION;        break;
	default:               err = JTAG_PROXY_INVALID_ADDRESS;         break;
	}
    }
  else if(group == 0)
    {
      extern unsigned long reg[32];
 
      if(address < 32)
	value = mfspr(address);
      else if(address >= 0x0400 && address < 0x0420)
	value = reg[address - 0x400];
      else if(address >= 0x0600 && address < 0x0620)
	value = 0;
      else
	err = JTAG_PROXY_INVALID_ADDRESS;
    }
  else
    err = JTAG_PROXY_INVALID_ADDRESS;
 
  *data = value;
  return err;
}
 
/* Nearly all compilers today store these bit fields as a packed structure
   in network byte order (Big Endian). If you happen to be unlucky enough
   to be working in a non standard environment, you may need to rewrite
   this routine or the SET_REG32 macro. */
int SetWishboneMemory(unsigned int address,uint32_t data)
{
  int err = 0;
  uint32_t value = data;
  int old_value;
  int group = address >> 11;
 
  address <<= 2;
 
  if(!verify_memoryarea(address))
	  err = JTAG_PROXY_INVALID_ADDRESS;
  else
	{
	  unsigned char t_data[4];
	  int *tmp = (int*)t_data;
	  extern char null_str[1];  /* From cpu/common/parse.c */
	  int i;
 
	  *tmp = htonl(data); /* We have already converted to host order */
 
	  setsim_mem8(address++, t_data[0]); /* Back to network byte order */
	  setsim_mem8(address++, t_data[1]);
	  setsim_mem8(address++, t_data[2]);
	  setsim_mem8(address++, t_data[3]);
	}
  return err;
}
 
int GetWishboneMemory(unsigned int address,uint32_t *data)
{
  int err = 0;
  uint32_t value = 0;
  int group = address >> 11;
 
  address <<= 2;
 
  if(!verify_memoryarea(address))
	  err = JTAG_PROXY_INVALID_ADDRESS;
  else
	{
	  unsigned char t_data[4];
	  int *tmp = (int*)t_data;
	  int bp;
 
	  t_data[0] = evalsim_mem8(address++);
	  t_data[1] = evalsim_mem8(address++);
	  t_data[2] = evalsim_mem8(address++);
	  t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
 
	  *data = ntohl(*tmp);  /* But we assume it is in host order later */
	}
  return err;
}
 
/* DebugCheckException returns 1 if the exception should be ignored.
   Currently, this is true only if the exception is a breakpoint
   exception and debug_unit.DMR1.ST is set. Sorry, this is a quick
   hack to disable processing of breakpoint exceptions on single
   stepping. Just one of those historical accidents. Feel free
   to rewrite the behavior. */
int DebugCheckException(int exception)
{
  int result = 0;
 
  switch(exception)
    {
    case EXCEPT_RESET:     result = debug_unit.DRR.RSTE   = debug_unit.DSR.RSTE;   break;
    case EXCEPT_BUSERR:    result = debug_unit.DRR.BUSEE  = debug_unit.DSR.BUSEE;  break;
    case EXCEPT_DPF:       result = debug_unit.DRR.DPFE   = debug_unit.DSR.DPFE;   break;
    case EXCEPT_IPF:       result = debug_unit.DRR.IPFE   = debug_unit.DSR.IPFE;   break;
    case EXCEPT_LPINT:     result = debug_unit.DRR.LPINTE = debug_unit.DSR.LPINTE; break;
    case EXCEPT_ALIGN:     result = debug_unit.DRR.AE     = debug_unit.DSR.AE;     break;
    case EXCEPT_ILLEGAL:   result = debug_unit.DRR.IIE    = debug_unit.DSR.IIE;    break;
    case EXCEPT_HPINT:     result = debug_unit.DRR.HPINTE = debug_unit.DSR.HPINTE; break;
    case EXCEPT_DTLBMISS:  result = debug_unit.DRR.DME    = debug_unit.DSR.DME;    break;
    case EXCEPT_ITLBMISS:  result = debug_unit.DRR.IME    = debug_unit.DSR.IME;    break;
    case EXCEPT_RANGE:     result = debug_unit.DRR.RE     = debug_unit.DSR.RE;     break;
    case EXCEPT_SYSCALL:   result = debug_unit.DRR.SCE    = debug_unit.DSR.SCE;    break;
    case EXCEPT_BREAK:     result = debug_unit.DRR.BE     = debug_unit.DSR.BE;     break;
    case EXCEPT_TRAP:      result = debug_unit.DRR.TE     = debug_unit.DSR.TE;     break;
    default:
      break;
    }
 
  if(result)
    SetCPUStallState(true);
 
  return (debug_unit.DMR1.ST && exception == EXCEPT_BREAK);
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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