URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1350 to Rev 1351
- ↔ Reverse comparison
Rev 1350 → Rev 1351
/trunk/or1ksim/debug/debug_unit.c
102,109 → 102,114
/* Checks whether we should stall the RISC or cause an exception */ |
static int calculate_watchpoints(DebugUnitAction action, unsigned long udata) |
{ |
int breakpoint = 0; |
int i, bit; |
int breakpoint = 0; |
int i, bit; |
|
/* Hopefully this loop would be unrolled run at max. speed */ |
for(i = 0, bit = 1; i < 11; i++, bit <<= 1) { |
int chain1, chain2; |
int match = 0; |
int DCR_hit = 0; |
/* Hopefully this loop would be unrolled run at max. speed */ |
for(i = 0, bit = 1; i < 11; i++, bit <<= 1) { |
int chain1, chain2; |
int match = 0; |
int DCR_hit = 0; |
|
/* Calculate first 8 matchpoints, result is put into DCR_hit */ |
if (i < 8) { |
unsigned long dcr = mfspr (SPR_DCR(i)); |
unsigned long dcr_ct=dcr&SPR_DCR_CT; // the CT field alone |
/* Is this matchpoint a propos for the current action? */ |
if ( ((dcr & SPR_DCR_DP) && dcr_ct) &&// DVR/DCP pair present |
(((action==DebugInstructionFetch) && (dcr_ct == SPR_DCR_CT_IFEA)) |
|| ((action==DebugLoadAddress) && ((dcr_ct == SPR_DCR_CT_LEA) || (dcr_ct == SPR_DCR_CT_LSEA))) |
|| ((action==DebugStoreAddress) && ((dcr_ct == SPR_DCR_CT_SEA) || (dcr_ct == SPR_DCR_CT_LSEA))) |
|| ((action==DebugLoadData) && ((dcr_ct == SPR_DCR_CT_LD) || (dcr_ct == SPR_DCR_CT_LSD))) |
|| ((action==DebugStoreData) && ((dcr_ct == SPR_DCR_CT_SD) || (dcr_ct == SPR_DCR_CT_LSD)))) ) |
{ |
unsigned long op1=udata; |
unsigned long op2 = mfspr (SPR_DVR(i)); |
/* 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; |
} |
} |
} |
} |
/* Calculate first 8 matchpoints, result is put into DCR_hit */ |
if (i < 8) { |
unsigned long dcr = mfspr(SPR_DCR(i)); |
unsigned long dcr_ct = dcr & SPR_DCR_CT; /* the CT field alone */ |
/* Is this matchpoint a propos for the current action? */ |
if ( ((dcr & SPR_DCR_DP) && dcr_ct) && /* DVR/DCP pair present */ |
(((action==DebugInstructionFetch) && (dcr_ct == SPR_DCR_CT_IFEA)) || |
((action==DebugLoadAddress) && ((dcr_ct == SPR_DCR_CT_LEA) || |
(dcr_ct == SPR_DCR_CT_LSEA))) || |
((action==DebugStoreAddress) && ((dcr_ct == SPR_DCR_CT_SEA) || |
(dcr_ct == SPR_DCR_CT_LSEA))) || |
((action==DebugLoadData) && ((dcr_ct == SPR_DCR_CT_LD) || |
(dcr_ct == SPR_DCR_CT_LSD))) || |
((action==DebugStoreData) && ((dcr_ct == SPR_DCR_CT_SD) || |
(dcr_ct == SPR_DCR_CT_LSD)))) ) { |
unsigned long op1 = udata; |
unsigned long op2 = mfspr (SPR_DVR(i)); |
/* 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: |
chain1 = chain2 = DCR_hit; |
break; |
case 8: |
chain1 = getsprbits (SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR0, SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 7); |
break; |
case 9: |
chain1 = getsprbits (SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1, SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 8); |
break; |
case 10: |
/* TODO: External watchpoint - not yet handled! */ |
/* Chain matchpoints */ |
switch(i) { |
case 0: |
chain1 = chain2 = DCR_hit; |
break; |
case 8: |
chain1 = getsprbits(SPR_DWCR0, SPR_DWCR_COUNT) == getsprbits(SPR_DWCR0, |
SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 7); |
break; |
case 9: |
chain1 = getsprbits(SPR_DWCR1, SPR_DWCR_COUNT) == getsprbits (SPR_DWCR1, |
SPR_DWCR_MATCH); |
chain2 = watchpoints & (1 << 8); |
break; |
case 10: |
/* TODO: External watchpoint - not yet handled! */ |
#if 0 |
chain1 = external_watchpoint; |
chain2 = watchpoints & (1 << 9); |
chain1 = external_watchpoint; |
chain2 = watchpoints & (1 << 9); |
#else |
chain1 = chain2 = 0; |
chain1 = chain2 = 0; |
#endif |
break; |
default: |
chain1 = DCR_hit; |
chain2 = watchpoints & (bit >> 1); |
break; |
} |
break; |
default: |
chain1 = DCR_hit; |
chain2 = watchpoints & (bit >> 1); |
break; |
} |
|
switch(getsprbits (SPR_DMR1, SPR_DMR1_CW0 << i)) { |
case 0: match = chain1; break; |
case 1: match = chain1 && chain2; break; |
case 2: match = chain1 || chain2; break; |
default: |
break; |
} |
switch(getsprbits(SPR_DMR1, SPR_DMR1_CW0 << i)) { |
case 0: match = chain1; break; |
case 1: match = chain1 && chain2; break; |
case 2: match = chain1 || chain2; break; |
} |
|
// Increment counters & generate counter break |
if(match) |
{ |
if(!(watchpoints & bit)) // watchpoint did not appear before in this clock cycle |
{ |
int counter = (getsprbits (SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0; |
int enabled = counter ? getsprbits (SPR_DMR2, SPR_DMR2_WCE1) : getsprbits (SPR_DMR2, SPR_DMR2_WCE0); |
if(enabled) |
setsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT, getsprbits (SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1); |
watchpoints |= bit; |
} |
/* Increment counters & generate counter break */ |
if(match) { |
/* watchpoint did not appear before in this clock cycle */ |
if(!(watchpoints & bit)) { |
int counter = (getsprbits(SPR_DMR2, SPR_DMR2_AWTC) & bit) ? 1 : 0; |
int enabled = counter ? getsprbits(SPR_DMR2, SPR_DMR2_WCE1) : |
getsprbits(SPR_DMR2, SPR_DMR2_WCE0); |
if(enabled) |
setsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT, |
getsprbits(SPR_DWCR0 + counter, SPR_DWCR_COUNT) + 1); |
watchpoints |= bit; |
} |
|
// should this watchpoint generate a breakpoint? |
if(getsprbits (SPR_DMR2, SPR_DMR2_WGB) & bit) breakpoint = 1; |
} |
} |
return breakpoint; |
/* should this watchpoint generate a breakpoint? */ |
if(getsprbits(SPR_DMR2, SPR_DMR2_WGB) & bit) |
breakpoint = 1; |
} |
} |
|
return breakpoint; |
} |
|
static DebugScanChainIDs current_scan_chain = JTAG_CHAIN_GLOBAL; |