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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_47/] [or1ksim/] [debug/] [debug_unit.c] - Diff between revs 378 and 479

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

Rev 378 Rev 479
Line 25... Line 25...
  Every attempt has been made to be as accurate as possible with
  Every attempt has been made to be as accurate as possible with
  respect to the registers and the behavior. There are no known
  respect to the registers and the behavior. There are no known
  limitations at this time.
  limitations at this time.
*/
*/
 
 
 
#define DEBUG_JTAG 1
 
 
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <inttypes.h>
#include <inttypes.h>
 
 
Line 42... Line 44...
#include "sprs.h"
#include "sprs.h"
#include "../gdb.h"
#include "../gdb.h"
#include "../cpu/or1k/except.h"
#include "../cpu/or1k/except.h"
#include "opcode/or32.h"
#include "opcode/or32.h"
 
 
DebugUnit debug_unit;
 
DevelopmentInterface development;
DevelopmentInterface development;
 
 
typedef enum {
 
  false = 0,
 
  true = 1,
 
} Boolean;
 
static void ExecuteInducedInstruction(unsigned long);
 
 
 
/* External STALL signal to debug interface */
/* External STALL signal to debug interface */
int cpu_stalled = false;
int in_reset = 0;
int in_reset = false;
 
 
 
/* An induced instruction has been written to the DIR register */
/* Risc stall state */
static Boolean induced = false;
int cpu_stalled = 0;
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);
/* Current watchpoint state */
 
unsigned long watchpoints = 0;
 
 
static  int watchpoint[10];
static int calculate_watchpoints ();
 
 
/* 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)
static  int watchpoint[10];
    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)
void set_stall_state(int state)
    {
    {
      ExecuteInducedInstruction(induced_insn);
  development.riscop &= ~RISCOP_STALL;
      induced_insn = 0;
  development.riscop |= state ? RISCOP_STALL : 0;
      induced = false;
  if(testsprbits(SPR_DMR1, SPR_DMR1_DXFW)) /* If debugger disabled */
    }
    state = 0;
 
 
  cpu_stalled = state;
  cpu_stalled = state;
}
}
 
 
void ResetDebugUnit()
void du_reset()
{
{
  memset(&debug_unit,'\0',sizeof(DebugUnit));
  development.riscop = 0;
  cpu_stalled = 0;
  set_stall_state (0);
}
}
 
 
#ifdef DEBUGMOD_OFF
 
#define CheckDebugUnit(x,y) 0
 
#else
 
inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata)
inline int CheckDebugUnit(DebugUnitAction action,unsigned long udata)
{
{
  int i;
  /* Do not stop, if we have debug module disabled or during reset */
  DCR_CT_Settings condition = DCR_CT_Disabled;
  if(!config.debug.enabled || in_reset)
  long data = (long)udata;
 
  int match;
 
 
 
  if(DEBUG_ENABLED || in_reset)
 
    return 0;
    return 0;
 
 
  /* If we're single stepping, always stop */
  /* If we're single stepping, always stop */
  if(debug_unit.DMR1.ST && action == DebugInstructionFetch)
  if(action == DebugInstructionFetch && testsprbits (SPR_DMR1, SPR_DMR1_ST))
    return 1;
    return 1;
 
 
  switch(action)
  return 0;
    {
  /* TODO: Enable matchpoints
    case DebugInstructionFetch:   condition = DCR_CT_InsnAddress;   break;
  switch(action)
    case DebugLoadAddress:        condition = DCR_CT_LoadAddress;   break;
    {
    case DebugStoreAddress:       condition = DCR_CT_StoreAddress;  break;
    case DebugInstructionFetch:   condition = DCR_CT_InsnAddress;   break;
    case DebugLoadData:           condition = DCR_CT_LoadData;      break;
    case DebugLoadAddress:        condition = DCR_CT_LoadAddress;   break;
    case DebugStoreData:          condition = DCR_CT_StoreData;     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();
  return calculate_watchpoints(); */
}
}
#endif
 
 
 
static int CalculateWatchpoints()
/* Checks whether we should stall the RISC or cause an exception */
 
static int calculate_watchpoints()
{
{
  int spec[11];
 
  int breakpoint = 0;
  int breakpoint = 0;
  int i,bit;
  int i,bit;
 
 
  spec[0] = debug_unit.DMR1.CW0;
  /* Hopefully this loop would be unrolled run at max. speed */
  spec[1] = debug_unit.DMR1.CW1;
  for(i = 0, bit = 1; i < 11; i++, bit <<= 1) {
  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 chain1,chain2;
      int match = 0;
      int match = 0;
 
    int DCR_hit = 0;
 
 
      switch(i)
    /* Calculate first 8 matchpoints, result is put into DCR_hit */
        {
    if (i < 8) {
 
      unsigned long dcr = mfspr (SPR_DCR(i));
 
      /* Whether this matchpoint is enabled, calculate conditions */
 
      if ((dcr & SPR_DCR_DP) && (dcr & SPR_DCR_CT != SPR_DCR_CT_DISABLED)) {
 
        /* Get one operand */
 
        unsigned long op1;
 
        unsigned long op2 = mfspr (SPR_DVR(i));
 
        switch (dcr & SPR_DCR_CT) {
 
          case SPR_DCR_CT_IFEA: op1 = runtime.cpu.ifea; break;
 
          case SPR_DCR_CT_LEA:  op1 = runtime.cpu.lea; break;
 
          case SPR_DCR_CT_SEA:  op1 = runtime.cpu.sea; break;
 
          case SPR_DCR_CT_LD:   op1 = runtime.cpu.ld; break;
 
          case SPR_DCR_CT_SD:   op1 = runtime.cpu.sd; break;
 
          case SPR_DCR_CT_LSEA: op1 = runtime.cpu.lsea; break;
 
        }
 
        /* Perform signed comparison?  */
 
        if (dcr & SPR_DCR_SC) {
 
          long sop1 = op1, sop2 = op2; /* Convert to signed */
 
          switch(dcr & SPR_DCR_CC) {
 
            case SPR_DCR_CC_MASKED: DCR_hit = sop1 & sop2; break;
 
            case SPR_DCR_CC_EQUAL: DCR_hit = sop1 == sop2; break;
 
            case SPR_DCR_CC_NEQUAL: DCR_hit = sop1 != sop2; break;
 
            case SPR_DCR_CC_LESS: DCR_hit = sop1 < sop2; break;
 
            case SPR_DCR_CC_LESSE: DCR_hit = sop1 <= sop2; break;
 
            case SPR_DCR_CC_GREAT: DCR_hit = sop1 > sop2; break;
 
            case SPR_DCR_CC_GREATE: DCR_hit = sop1 >= sop2; break;
 
          }
 
        } else {
 
          switch(dcr & SPR_DCR_CC) {
 
            case SPR_DCR_CC_MASKED: DCR_hit = op1 & op2; break;
 
            case SPR_DCR_CC_EQUAL: DCR_hit = op1 == op2; break;
 
            case SPR_DCR_CC_NEQUAL: DCR_hit = op1 != op2; break;
 
            case SPR_DCR_CC_LESS: DCR_hit = op1 < op2; break;
 
            case SPR_DCR_CC_LESSE: DCR_hit = op1 <= op2; break;
 
            case SPR_DCR_CC_GREAT: DCR_hit = op1 > op2; break;
 
            case SPR_DCR_CC_GREATE: DCR_hit = op1 >= op2; break;
 
          }
 
        }
 
      }
 
    }
 
 
 
    /* Chain matchpoints */
 
    switch(i) {
        case 0:
        case 0:
          chain1 = chain2 = debug_unit.DCR_hit & 0x01;
      chain1 = chain2 = DCR_hit;
          break;
          break;
        case 8:
        case 8:
          chain1 = debug_unit.DWCR[0].COUNT == debug_unit.DWCR[0].MATCH;
      chain1 = getsprbits (SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR0, SPR_DWCR_MATCH);
          chain2 = debug_unit.watchpoint & (1 << 7);
      chain2 = watchpoints & (1 << 7);
          break;
          break;
        case 9:
        case 9:
          chain1 = debug_unit.DWCR[1].COUNT == debug_unit.DWCR[1].MATCH;
      chain1 = getsprbits (SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1, SPR_DWCR_MATCH);
          chain2 = debug_unit.watchpoint & (1 << 8);
      chain2 = watchpoints & (1 << 8);
          break;
          break;
        case 10:
        case 10:
          chain1 = debug_unit.DCR_hit & 0x100; /* External hit */
      /* TODO: External watchpoint - not yet handled!  */
          chain2 = debug_unit.watchpoint & (1 << 9);
#if 0
 
      chain1 = external_watchpoint;
 
      chain2 = watchpoints & (1 << 9);
 
#else
 
      chain1 = chain2 = 0;
 
#endif
          break;
          break;
        default:
        default:
          chain1 = debug_unit.DCR_hit & bit;
      chain1 = DCR_hit;
          chain2 = debug_unit.watchpoint & (bit >> 1);
      chain2 = watchpoints & (bit >> 1);
          break;
          break;
        }
        }
 
 
      switch(spec[i])
    switch(getsprbits (SPR_DMR1, SPR_DMR1_CW0 << i)) {
        {
 
        case 0:  match = chain1;           break;
        case 0:  match = chain1;           break;
        case 1: match = chain1 && chain2; break;
        case 1: match = chain1 && chain2; break;
        case 2: match = chain1 || chain2; break;
        case 2: match = chain1 || chain2; break;
        default:
        default:
          break;
          break;
        }
        }
 
 
      if(match & !(debug_unit.watchpoint & bit))
    if(match & !(watchpoints & bit)) {
        {
      int counter = (getsprbits (SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0;
          int counter = (debug_unit.DMR2.AWPC & bit) ? 1 : 0;
      int enabled = counter ? getsprbits (SPR_DMR2, SPR_DMR2_WCE1) : getsprbits (SPR_DMR2, SPR_DMR2_WCE0);
          int enabled = counter ? debug_unit.DMR2.WCE1 : debug_unit.DMR2.WCE0;
 
 
 
          if(enabled)
          if(enabled)
            debug_unit.DWCR[counter].COUNT++;
        setsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT, getsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1);
 
 
          if(debug_unit.DMR2.WGB & bit)
      if(getsprbits (SPR_DMR2, SPR_DMR2_WGB) & bit)
            breakpoint = 1;
            breakpoint = 1;
        }
        }
 
 
      debug_unit.watchpoint &= ~bit;
    watchpoints &= ~bit;
      debug_unit.watchpoint |= bit;
    watchpoints |= bit;
    }
    }
 
 
  return breakpoint;
  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;
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL;
 
 
int DebugGetRegister(unsigned int address,int32_t* data)
int DebugGetRegister(unsigned int address, unsigned long* data)
{
{
  int err;
  int err;
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf("Debug get register %x\n",address);
  printf("Debug get register %x\n",address);
  fflush(stdout);
  fflush(stdout);
#endif
#endif
  switch(current_scan_chain)
  switch(current_scan_chain)
    {
    {
    case JTAG_CHAIN_DEBUG_UNIT:
    case JTAG_CHAIN_DEBUG_UNIT:
      err = GetDebugUnitRegister(address,data);
      *data = mfspr (address);
 
      debug (2, "READ  (%08x) = %08x\n", address, *data);
      break;
      break;
    case JTAG_CHAIN_TRACE:
    case JTAG_CHAIN_TRACE:
      *data = 0;  /* Scan chain not yet implemented */
      *data = 0;  /* Scan chain not yet implemented */
      err = 0;
      err = 0;
      break;
      break;
    case JTAG_CHAIN_DEVELOPMENT:
    case JTAG_CHAIN_DEVELOPMENT:
      err = GetDevelopmentInterfaceRegister(address,data);
      err = get_devint_reg(address,data);
      break;
      break;
    case JTAG_CHAIN_WISHBONE:
    case JTAG_CHAIN_WISHBONE:
      err = GetWishboneMemory(address,data);
      err = GetWishboneMemory(address,data);
      break;
      break;
    }
    }
Line 329... Line 239...
  fflush(stdout);
  fflush(stdout);
#endif
#endif
  return err;
  return err;
}
}
 
 
int DebugSetRegister(unsigned int address,int32_t data)
int DebugSetRegister(unsigned int address,unsigned long data)
{
{
  int err;
  int err;
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf("Debug set register %x <- %x\n",address, data);
  printf("Debug set register %x <- %x\n",address, data);
  fflush(stdout);
  fflush(stdout);
#endif
#endif
  switch(current_scan_chain)
  switch(current_scan_chain)
    {
    {
    case JTAG_CHAIN_DEBUG_UNIT:
    case JTAG_CHAIN_DEBUG_UNIT:
      err = SetDebugUnitRegister(address,data);
      debug (2, "WRITE (%08x) = %08x\n", address, data);
 
      mtspr(address, data);
      break;
      break;
    case JTAG_CHAIN_TRACE:
    case JTAG_CHAIN_TRACE:
      err = JTAG_PROXY_ACCESS_EXCEPTION;
      err = JTAG_PROXY_ACCESS_EXCEPTION;
      break;
      break;
    case JTAG_CHAIN_DEVELOPMENT:
    case JTAG_CHAIN_DEVELOPMENT:
      err = SetDevelopmentInterfaceRegister(address,data);
      err = set_devint_reg (address, data);
      break;
      break;
    case JTAG_CHAIN_WISHBONE:
    case JTAG_CHAIN_WISHBONE:
      err = SetWishboneMemory(address,data);
      err = debug_set_mem (address, data);
      break;
      break;
    }
    }
#ifdef DEBUG_JTAG
#ifdef DEBUG_JTAG
  printf("!set reg\n");
  printf("!set reg\n");
  fflush(stdout);
  fflush(stdout);
Line 383... Line 294...
  fflush(stdout);
  fflush(stdout);
#endif
#endif
  return 0;
  return 0;
}
}
 
 
/* Nearly all compilers today store these bit fields as a packed structure
void sim_reset ();
   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
/* Sets development interface register */
   this routine or the SET_REG32 macro. */
int set_devint_reg(unsigned int address, unsigned long data)
int SetDevelopmentInterfaceRegister(unsigned int address,uint32_t data)
 
{
{
  int err = 0;
  int err = 0;
  uint32_t value = data;
  unsigned long value = data;
  int old_value;
  int old_value;
  char *t_ptr = (char*)&development.RISCOP;
 
 
 
  switch(address)
  switch(address) {
    {
    case DEVELOPINT_MODER: development.moder = value; break;
    case DEVELOPINT_MODER:
    case DEVELOPINT_TSEL:  development.tsel = value;  break;
      SET_REG32(development.MODER,value);
    case DEVELOPINT_QSEL:  development.qsel = value;  break;
      break;
    case DEVELOPINT_SSEL:  development.ssel = 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:
    case DEVELOPINT_RISCOP:
      old_value = development.RISCOP.RESET;
      old_value = (development.riscop & RISCOP_RESET) != 0;
      SET_REG32(development.RISCOP,value);
      development.riscop = value;
 
      in_reset = (development.riscop & RISCOP_RESET) != 0;
      in_reset = development.RISCOP.RESET;
 
 
 
      /* Reset the cpu on the negative edge of RESET */
      /* Reset the cpu on the negative edge of RESET */
      if(old_value && !development.RISCOP.RESET)
      if(old_value && !in_reset)
        {
        sim_reset(); /* Reset all units */
          uart_reset();
      set_stall_state((development.riscop & RISCOP_STALL) != 0);
          tick_reset();
 
          pm_reset();
 
          pic_reset();
 
          reset(); /* Old or new mode */
 
        }
 
 
 
      SetCPUStallState(development.RISCOP.RISCSTALL);
 
      break;
      break;
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP3:
    case DEVELOPINT_RECWP3:
Line 436... Line 327...
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP10:
    case DEVELOPINT_RECWP10: development.recwp[address - DEVELOPINT_RECWP0] = value; break;
      SET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value);
    case DEVELOPINT_RECBP0:  development.recbp = value; break;
      break;
 
    case DEVELOPINT_RECBP0:
 
      SET_REG32(development.RECBP[0],value);
 
      break;
 
    default:
    default:
      err = JTAG_PROXY_INVALID_ADDRESS;
      err = JTAG_PROXY_INVALID_ADDRESS;
      break;
      break;
    }
    }
 
#ifdef DEBUG_JTAG
 
  printf("set_devint_reg %08x = %08x\n", address, data);
 
  fflush(stdout);
 
#endif
  return err;
  return err;
}
}
 
 
int GetDevelopmentInterfaceRegister(unsigned int address,uint32_t *data)
int get_devint_reg(unsigned int address,unsigned long *data)
{
{
  int err = 0;
  int err = 0;
  uint32_t value = 0;
  unsigned long value = 0;
 
 
  switch(address)
  switch(address) {
    {
    case DEVELOPINT_MODER:    value = development.moder; break;
    case DEVELOPINT_MODER:    GET_REG32(development.MODER,value);      break;
    case DEVELOPINT_TSEL:     value = development.tsel; break;
    case DEVELOPINT_TSEL:     GET_REG32(development.TSEL,value);       break;
    case DEVELOPINT_QSEL:     value = development.qsel; break;
    case DEVELOPINT_QSEL:     GET_REG32(development.QSEL,value);       break;
    case DEVELOPINT_SSEL:     value = development.ssel; break;
    case DEVELOPINT_SSEL:     GET_REG32(development.SSEL,value);       break;
    case DEVELOPINT_RISCOP:   value = development.riscop; break;
    case DEVELOPINT_RISCOP:   GET_REG32(development.RISCOP,value);     break;
 
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP0:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP1:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP2:
    case DEVELOPINT_RECWP3:
    case DEVELOPINT_RECWP3:
    case DEVELOPINT_RECWP4:
    case DEVELOPINT_RECWP4:
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP5:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP6:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP7:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP8:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP9:
    case DEVELOPINT_RECWP10:  GET_REG32(development.RECWP[address-DEVELOPINT_RECWP0],value); break;
    case DEVELOPINT_RECWP10:  value = development.recwp[address - DEVELOPINT_RECWP0]; break;
    case DEVELOPINT_RECBP0:   GET_REG32(development.RECBP[0],value);   break;
    case DEVELOPINT_RECBP0:   value = development.recbp; break;
    default:                  err = JTAG_PROXY_INVALID_ADDRESS;        break;
    default:                  err = JTAG_PROXY_INVALID_ADDRESS;        break;
    }
    }
 
 
 
#ifdef DEBUG_JTAG
 
  printf("get_devint_reg %08x = %08x\n", address, value);
 
  fflush(stdout);
 
#endif
  *data = value;
  *data = value;
  return err;
  return err;
}
}
 
 
/* Nearly all compilers today store these bit fields as a packed structure
/* Writes to bus address */
   in network byte order (Big Endian). If you happen to be unlucky enough
int debug_set_mem (unsigned int address,unsigned long data)
   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;
  int err = 0;
  uint32_t value = data;
  debug (2, "MEMWRITE (%08x) = %08x\n", address, data);
  int old_value;
 
  int group = address >> 11;
 
 
 
  address <<= 2;
 
 
 
  if(!verify_memoryarea(address))
  if(!verify_memoryarea(address))
          err = JTAG_PROXY_INVALID_ADDRESS;
          err = JTAG_PROXY_INVALID_ADDRESS;
  else
  else {
        {
 
          unsigned char t_data[4];
          unsigned char t_data[4];
          int *tmp = (int*)t_data;
          int *tmp = (int*)t_data;
          extern char null_str[1];  /* From cpu/common/parse.c */
          extern char null_str[1];  /* From cpu/common/parse.c */
          int i;
          int i;
 
 
Line 678... Line 399...
          setsim_mem8(address++, t_data[3]);
          setsim_mem8(address++, t_data[3]);
        }
        }
  return err;
  return err;
}
}
 
 
int GetWishboneMemory(unsigned int address,uint32_t *data)
int GetWishboneMemory(unsigned int address,unsigned long *data)
{
{
  int err = 0;
  int err = 0;
  uint32_t value = 0;
 
  int group = address >> 11;
 
 
 
  address <<= 2;
 
 
 
  if(!verify_memoryarea(address))
  if(!verify_memoryarea(address))
          err = JTAG_PROXY_INVALID_ADDRESS;
          err = JTAG_PROXY_INVALID_ADDRESS;
  else
  else
        {
        {
          unsigned char t_data[4];
          unsigned char t_data[4];
Line 701... Line 417...
          t_data[2] = evalsim_mem8(address++);
          t_data[2] = evalsim_mem8(address++);
          t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
          t_data[3] = evalsim_mem8(address++); /* Already in network byte order */
 
 
          *data = ntohl(*tmp);  /* But we assume it is in host order later */
          *data = ntohl(*tmp);  /* But we assume it is in host order later */
        }
        }
 
  debug (2, "MEMREAD  (%08x) = %08x\n", address, *data);
  return err;
  return err;
}
}
 
 
/* DebugCheckException returns 1 if the exception should be ignored.
/* debug_ignore_exception returns 1 if the exception should be ignored. */
   Currently, this is true only if the exception is a breakpoint
int debug_ignore_exception (unsigned long except)
   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;
  int result = 0;
 
  unsigned long dsr = mfspr (SPR_DSR);
 
  unsigned long drr = mfspr (SPR_DRR);
 
 
  switch(exception)
  &debug_ignore_exception;
    {
  printf ("0x%08x 0x%08x \n", dsr, drr);
    case EXCEPT_RESET:     result = debug_unit.DRR.RSTE   = debug_unit.DSR.RSTE;   break;
  switch(except) {
    case EXCEPT_BUSERR:    result = debug_unit.DRR.BUSEE  = debug_unit.DSR.BUSEE;  break;
    case EXCEPT_RESET:     drr |= result = dsr & SPR_DSR_RSTE; break;
    case EXCEPT_DPF:       result = debug_unit.DRR.DPFE   = debug_unit.DSR.DPFE;   break;
    case EXCEPT_BUSERR:    drr |= result = dsr & SPR_DSR_BUSEE; break;
    case EXCEPT_IPF:       result = debug_unit.DRR.IPFE   = debug_unit.DSR.IPFE;   break;
    case EXCEPT_DPF:       drr |= result = dsr & SPR_DSR_DPFE; break;
    case EXCEPT_LPINT:     result = debug_unit.DRR.LPINTE = debug_unit.DSR.LPINTE; break;
    case EXCEPT_IPF:       drr |= result = dsr & SPR_DSR_IPFE; break;
    case EXCEPT_ALIGN:     result = debug_unit.DRR.AE     = debug_unit.DSR.AE;     break;
    case EXCEPT_LPINT:     drr |= result = dsr & SPR_DSR_LPINTE; break;
    case EXCEPT_ILLEGAL:   result = debug_unit.DRR.IIE    = debug_unit.DSR.IIE;    break;
    case EXCEPT_ALIGN:     drr |= result = dsr & SPR_DSR_AE; break;
    case EXCEPT_HPINT:     result = debug_unit.DRR.HPINTE = debug_unit.DSR.HPINTE; break;
    case EXCEPT_ILLEGAL:   drr |= result = dsr & SPR_DSR_IIE; break;
    case EXCEPT_DTLBMISS:  result = debug_unit.DRR.DME    = debug_unit.DSR.DME;    break;
    case EXCEPT_HPINT:     drr |= result = dsr & SPR_DSR_LPINTE; break;
    case EXCEPT_ITLBMISS:  result = debug_unit.DRR.IME    = debug_unit.DSR.IME;    break;
    case EXCEPT_DTLBMISS:  drr |= result = dsr & SPR_DSR_DME; break;
    case EXCEPT_RANGE:     result = debug_unit.DRR.RE     = debug_unit.DSR.RE;     break;
    case EXCEPT_ITLBMISS:  drr |= result = dsr & SPR_DSR_IME; break;
    case EXCEPT_SYSCALL:   result = debug_unit.DRR.SCE    = debug_unit.DSR.SCE;    break;
    case EXCEPT_RANGE:     drr |= result = dsr & SPR_DSR_RE; break;
    case EXCEPT_BREAK:     result = debug_unit.DRR.BE     = debug_unit.DSR.BE;     break;
    case EXCEPT_SYSCALL:   drr |= result = dsr & SPR_DSR_SCE; break;
    case EXCEPT_TRAP:      result = debug_unit.DRR.TE     = debug_unit.DSR.TE;     break;
    case EXCEPT_TRAP:      drr |= result = dsr & SPR_DSR_TE; break;
    default:
    default:
      break;
      break;
    }
    }
 
  printf ("0x%08x 0x%08x %i\n", dsr, drr, result);
 
 
  if(result)
  mtspr (SPR_DRR, drr);
    SetCPUStallState(true);
  set_stall_state (result != 0);
 
  return (result != 0);
  return (debug_unit.DMR1.ST && exception == EXCEPT_BREAK);
 
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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