Jordi Vaquero has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/30617 )
Change subject: arch-arm: Implementation of SelfHosted Debug Software step
......................................................................
arch-arm: Implementation of SelfHosted Debug Software step
This commit implements SelfHosted Debug Software step as is defined in
Armv8 Reference manual chapter D2.
+ decoder.hh/cc/isa: Checks the software step bit in order to skip the
instruction
before its decode.
+ faults.hh/cc: implemented SoftwareStep exception and proper modification
of spsr during the invoke of other exceptions
+ isa.cc: Set debug mask if needed during cpsr modification
+ tlb.cc: Checks if software step is in ACTIVE state to avoid trigger
breakpoint or watchpoint exception
+ self_debug.hh/cc: Implementation of State change and ss bit based during
eret.
+ types.hh: Define sofware step flags like step, load or stepped to check
the different flags
that triggering software step should use for the ISS code.
+ pseudo.hh/isa: Triggers the sofware step esception after decode.
+ static_inst.cc: Call debugExceptionReturnsSS durint eret routine.
Change-Id: I3a64507c64842c34c76ad7f6daa5f4306bd55d2c
---
M src/arch/arm/decoder.cc
M src/arch/arm/decoder.hh
M src/arch/arm/faults.cc
M src/arch/arm/faults.hh
M src/arch/arm/insts/pseudo.cc
M src/arch/arm/insts/pseudo.hh
M src/arch/arm/insts/static_inst.cc
M src/arch/arm/isa.cc
M src/arch/arm/isa/bitfields.isa
M src/arch/arm/isa/decoder/decoder.isa
M src/arch/arm/isa/formats/pseudo.isa
M src/arch/arm/self_debug.cc
M src/arch/arm/self_debug.hh
M src/arch/arm/tlb.cc
M src/arch/arm/types.hh
15 files changed, 384 insertions(+), 31 deletions(-)
diff --git a/src/arch/arm/decoder.cc b/src/arch/arm/decoder.cc
index 8f37e63..5b2dd1e 100644
--- a/src/arch/arm/decoder.cc
+++ b/src/arch/arm/decoder.cc
@@ -53,7 +53,9 @@
GenericISA::BasicDecodeCache Decoder::defaultCache;
Decoder::Decoder(ISA* isa)
- : data(0), fpscrLen(0), fpscrStride(0),
decoderFlavor(isa->decoderFlavor())
+ : data(0), fpscrLen(0), fpscrStride(0),
+ softStep(isa->getSelfDebug()->get_Sstep()),
+ decoderFlavor(isa->decoderFlavor())
{
reset();
@@ -181,13 +183,34 @@
pc.nextItstate(itBits);
this_emi.itstate = pc.itstate();
this_emi.illegalExecution = pc.illegalExec() ? 1 : 0;
-
+ this_emi.debugStep = pc.debugStep() ? 1 : 0;
pc.size(inst_size);
emi = 0;
instDone = false;
foundIt = false;
+ bool ldx = false;
+ if (pc.aarch64()){
+ unsigned b1 = bits(this_emi, 29, 16);
+ ldx = (b1 == 0x087F) || (b1 == 0x085F);
+ } else {
+ if (pc.thumb()){
+ unsigned b1 = bits(this_emi, 31, 20); //bits high 15, 4
+ unsigned b2 = bits(this_emi, 6);
+ ldx = (b1 == 0xE85 || (b1 == 0xE8B && b2 == 0x1));
+
+ } else {
+ unsigned b1 = bits(this_emi, 31, 28);
+ unsigned b2 = bits(this_emi, 27, 23);
+ unsigned L = bits(this_emi, 20);
+ unsigned ex = bits(this_emi, 11, 9);
+ ldx = (b1 != 0xF && b2 == 0x3 && L == 0x1 && ex == 0x7);
+ }
+
+ }
+
+ pc.ldx(ldx);
return decode(this_emi, pc.instAddr());
}
diff --git a/src/arch/arm/decoder.hh b/src/arch/arm/decoder.hh
index 774aedd..b714fe4 100644
--- a/src/arch/arm/decoder.hh
+++ b/src/arch/arm/decoder.hh
@@ -44,6 +44,7 @@
#include <cassert>
#include "arch/arm/miscregs.hh"
+#include "arch/arm/self_debug.hh"
#include "arch/arm/types.hh"
#include "arch/generic/decode_cache.hh"
#include "base/types.hh"
@@ -70,6 +71,8 @@
int fpscrLen;
int fpscrStride;
+ SoftwareStep * softStep;
+
/**
* SVE vector length, encoded in the same format as the ZCR_EL<x>.LEN
* bitfields.
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index ce9675a..fde28d6 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -289,6 +289,10 @@
"Watchpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
0, 0, 0, 0, true, false, false, EC_WATCHPOINT
);
+template<> ArmFault::FaultVals ArmFaultVals<SoftwareStepExcpt>::vals(
+ "SoftwareStep", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+ 0, 0, 0, 0, true, false, false, EC_SOFTWARE_STEP
+);
template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals(
// Some dummy values
"ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
@@ -649,6 +653,7 @@
spsr.nz = tc->readCCReg(CCREG_NZ);
spsr.c = tc->readCCReg(CCREG_C);
spsr.v = tc->readCCReg(CCREG_V);
+ spsr.ss = isResetSPSR() ? 0: cpsr.ss;
if (from64) {
// Force some bitfields to 0
spsr.q = 0;
@@ -662,8 +667,6 @@
ITSTATE it = tc->pcState().itstate();
spsr.it2 = it.top6;
spsr.it1 = it.bottom2;
- // Force some bitfields to 0
- spsr.ss = 0;
}
tc->setMiscReg(spsr_idx, spsr);
@@ -705,6 +708,7 @@
pc.aarch64(!cpsr.width);
pc.nextAArch64(!cpsr.width);
pc.illegalExec(false);
+ pc.stepped(false);
tc->pcState(pc);
// Save exception syndrome
@@ -911,7 +915,9 @@
HypervisorCall::HypervisorCall(ExtMachInst _machInst, uint32_t _imm) :
ArmFaultVals<HypervisorCall>(_machInst, _imm)
-{}
+{
+ bStep = true;
+}
ExceptionClass
HypervisorCall::ec(ThreadContext *tc) const
@@ -1739,6 +1745,52 @@
return EC_WATCHPOINT_LOWER_EL;
}
+SoftwareStepExcpt::SoftwareStepExcpt(ExtMachInst _mach_inst, bool _isldx,
+ bool _stepped)
+ : ArmFaultVals<SoftwareStepExcpt>(_mach_inst), isldx(_isldx),
+ stepped(_stepped)
+{
+ bStep = true;
+}
+
+bool
+SoftwareStepExcpt::routeToHyp(ThreadContext *tc) const
+{
+ const bool have_el2 = ArmSystem::haveVirtualization(tc);
+
+ const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
+ const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+
+ return have_el2 && !inSecureState(tc) && fromEL <= EL1 &&
+ (hcr.tge || mdcr.tde);
+}
+
+ExceptionClass
+SoftwareStepExcpt::ec(ThreadContext *tc) const
+{
+ // AArch64
+ if (toEL == fromEL)
+ return EC_SOFTWARE_STEP_CURR_EL;
+ else
+ return EC_SOFTWARE_STEP_LOWER_EL;
+}
+
+uint32_t
+SoftwareStepExcpt::iss() const
+{
+ uint32_t iss= 0x0022;
+ if (stepped) {
+ iss |= 0x1000000;
+ }
+
+ if (isldx) {
+ iss |= 0x40;
+ }
+
+ return iss;
+
+}
+
void
ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
DPRINTF(Faults, "Invoking ArmSev Fault\n");
@@ -1774,6 +1826,7 @@
template class ArmFaultVals<SoftwareBreakpoint>;
template class ArmFaultVals<HardwareBreakpoint>;
template class ArmFaultVals<Watchpoint>;
+template class ArmFaultVals<SoftwareStepExcpt>;
template class ArmFaultVals<ArmSev>;
template class AbortFault<PrefetchAbort>;
template class AbortFault<DataAbort>;
diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh
index 2e1f338..703d6bb 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -64,6 +64,7 @@
uint32_t issRaw;
// Helper variables for ARMv8 exception handling
+ bool bStep; // True if the Arm Faul exception is a software Step
exception
bool from64; // True if the exception is generated from the AArch64
state
bool to64; // True if the exception is taken in AArch64 state
ExceptionLevel fromEL; // Source exception level
@@ -207,8 +208,8 @@
};
ArmFault(ExtMachInst _machInst = 0, uint32_t _iss = 0) :
- machInst(_machInst), issRaw(_iss), from64(false), to64(false),
- fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED),
+ machInst(_machInst), issRaw(_iss), bStep(false), from64(false),
+ to64(false), fromEL(EL0), toEL(EL0), fromMode(MODE_UNDEFINED),
faultUpdated(false), hypRouted(false), span(false) {}
// Returns the actual syndrome register to use based on the target
@@ -223,6 +224,7 @@
void invoke64(ThreadContext *tc, const StaticInstPtr &inst =
StaticInst::nullStaticInstPtr);
void update(ThreadContext *tc);
+ bool isResetSPSR(){ return bStep; }
ArmStaticInst *instrAnnotate(const StaticInstPtr &inst);
virtual void annotate(AnnotationIDs id, uint64_t val) {}
@@ -332,7 +334,9 @@
ExceptionClass _overrideEc = EC_INVALID) :
ArmFaultVals<SupervisorCall>(_machInst, _iss),
overrideEc(_overrideEc)
- {}
+ {
+ bStep = true;
+ }
void invoke(ThreadContext *tc, const StaticInstPtr &inst =
StaticInst::nullStaticInstPtr) override;
@@ -346,7 +350,9 @@
public:
SecureMonitorCall(ExtMachInst _machInst) :
ArmFaultVals<SecureMonitorCall>(_machInst)
- {}
+ {
+ bStep = true;
+ }
void invoke(ThreadContext *tc, const StaticInstPtr &inst =
StaticInst::nullStaticInstPtr) override;
@@ -632,6 +638,19 @@
void annotate(AnnotationIDs id, uint64_t val);
};
+class SoftwareStepExcpt : public ArmFaultVals<SoftwareStepExcpt>
+{
+ private:
+ bool isldx;
+ bool stepped;
+
+ public:
+ SoftwareStepExcpt(ExtMachInst _mach_inst, bool isldx, bool stepped);
+ bool routeToHyp(ThreadContext *tc) const override;
+ uint32_t iss() const override;
+ ExceptionClass ec(ThreadContext *tc) const override;
+};
+
// A fault that flushes the pipe, excluding the faulting instructions
class ArmSev : public ArmFaultVals<ArmSev>
{
@@ -674,6 +693,7 @@
template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals;
template<> ArmFault::FaultVals ArmFaultVals<HardwareBreakpoint>::vals;
template<> ArmFault::FaultVals ArmFaultVals<Watchpoint>::vals;
+template<> ArmFault::FaultVals ArmFaultVals<SoftwareStepExcpt>::vals;
template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals;
/**
diff --git a/src/arch/arm/insts/pseudo.cc b/src/arch/arm/insts/pseudo.cc
index 5c2702b5..99dc045 100644
--- a/src/arch/arm/insts/pseudo.cc
+++ b/src/arch/arm/insts/pseudo.cc
@@ -190,3 +190,20 @@
{
return std::make_shared<IllegalInstSetStateFault>();
}
+
+DebugStep::DebugStep(ExtMachInst _machInst)
+ : ArmStaticInst("DebugStep", _machInst, No_OpClass)
+{ }
+
+Fault
+DebugStep::execute(ExecContext *xc, Trace::InstRecord *traceData) const
+{
+ PCState pc_state(xc->pcState());
+
+ pc_state.debugStep(false);
+ xc->pcState(pc_state);
+
+ return std::make_shared<SoftwareStepExcpt>(machInst, pc_state.ldx(),
+ pc_state.stepped());
+
+}
diff --git a/src/arch/arm/insts/pseudo.hh b/src/arch/arm/insts/pseudo.hh
index 76dca20..7b385f1 100644
--- a/src/arch/arm/insts/pseudo.hh
+++ b/src/arch/arm/insts/pseudo.hh
@@ -131,4 +131,12 @@
Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const;
};
+class DebugStep : public ArmStaticInst
+{
+ public:
+ DebugStep(ExtMachInst _machInst);
+
+ Fault execute(ExecContext *xc, Trace::InstRecord *traceData) const;
+};
+
#endif
diff --git a/src/arch/arm/insts/static_inst.cc
b/src/arch/arm/insts/static_inst.cc
index c4d3bf4..5ef386c 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -43,6 +43,8 @@
#include "arch/arm/faults.hh"
#include "arch/arm/isa.hh"
+#include "arch/arm/self_debug.hh"
+#include "arch/arm/utility.hh"
#include "base/condcodes.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
@@ -1100,10 +1102,7 @@
ArmStaticInst::getPSTATEFromPSR(ThreadContext *tc, CPSR cpsr, CPSR spsr)
const
{
CPSR new_cpsr = 0;
-
- // gem5 doesn't implement single-stepping, so force the SS bit to
- // 0.
- new_cpsr.ss = 0;
+ ExceptionLevel dest;
if (illegalExceptionReturn(tc, cpsr, spsr)) {
// If the SPSR specifies an illegal exception return,
@@ -1117,6 +1116,7 @@
new_cpsr.el = cpsr.el;
new_cpsr.sp = cpsr.sp;
}
+ dest = currEL(tc);
} else {
new_cpsr.il = spsr.il;
if (spsr.width &&
unknownMode32((OperatingMode)(uint8_t)spsr.mode)) {
@@ -1127,6 +1127,7 @@
new_cpsr.el = spsr.el;
new_cpsr.sp = spsr.sp;
}
+ dest = (ExceptionLevel)(uint8_t) spsr.el;
}
new_cpsr.nz = spsr.nz;
@@ -1148,6 +1149,10 @@
new_cpsr.daif = spsr.daif;
}
+ auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
+ SoftwareStep * ss = (isa->getSelfDebug())->get_Sstep();
+ new_cpsr.ss = ss->debugExceptionReturnSS(tc, spsr, dest,
new_cpsr.width);
+
return new_cpsr;
}
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 628cdd5..d36417c 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -830,6 +830,7 @@
pc.nextThumb(cpsr.t);
pc.nextJazelle(cpsr.j);
pc.illegalExec(cpsr.il == 1);
+ selfDebug->setDebugMask(cpsr.d == 1);
tc->getDecoderPtr()->setSveLen((getCurSveVecLenInBits(tc) >> 7) -
1);
diff --git a/src/arch/arm/isa/bitfields.isa b/src/arch/arm/isa/bitfields.isa
index 903bb67..e1fc8bf 100644
--- a/src/arch/arm/isa/bitfields.isa
+++ b/src/arch/arm/isa/bitfields.isa
@@ -46,6 +46,7 @@
// Opcode fields
def bitfield DECODERFAULT decoderFault;
def bitfield ILLEGALEXEC illegalExecution;
+def bitfield DEBUGSTEP debugStep;
def bitfield ENCODING encoding;
def bitfield OPCODE opcode;
diff --git a/src/arch/arm/isa/decoder/decoder.isa
b/src/arch/arm/isa/decoder/decoder.isa
index 1841505..2a979ea 100644
--- a/src/arch/arm/isa/decoder/decoder.isa
+++ b/src/arch/arm/isa/decoder/decoder.isa
@@ -38,17 +38,19 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-decode ILLEGALEXEC default IllegalExec::illegalExec() {
- 0: decode DECODERFAULT default DecoderFault::decoderFault() {
- 0: decode THUMB default Unknown::unknown() {
- 0: decode AARCH64 {
- 0:
- ##include "arm.isa"
+decode DEBUGSTEP default DebugStep::debugStep() {
+ 0: decode ILLEGALEXEC default IllegalExec::illegalExec() {
+ 0: decode DECODERFAULT default DecoderFault::decoderFault() {
+ 0: decode THUMB default Unknown::unknown() {
+ 0: decode AARCH64 {
+ 0:
+ ##include "arm.isa"
+ 1:
+ ##include "aarch64.isa"
+ }
1:
- ##include "aarch64.isa"
+ ##include "thumb.isa"
}
- 1:
- ##include "thumb.isa"
}
}
}
diff --git a/src/arch/arm/isa/formats/pseudo.isa
b/src/arch/arm/isa/formats/pseudo.isa
index a1ee8ec..d827aa4 100644
--- a/src/arch/arm/isa/formats/pseudo.isa
+++ b/src/arch/arm/isa/formats/pseudo.isa
@@ -61,6 +61,15 @@
////////////////////////////////////////////////////////////////////
//
+// Debug Step handling
+//
+
+def format DebugStep() {{
+ decode_block = 'return new DebugStep(machInst);\n'
+}};
+
+////////////////////////////////////////////////////////////////////
+//
// Unknown instruction handling
//
diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc
index 52254f2..53cbb8e 100644
--- a/src/arch/arm/self_debug.cc
+++ b/src/arch/arm/self_debug.cc
@@ -549,3 +549,74 @@
}
}
+bool
+SoftwareStep::debugExceptionReturnSS(ThreadContext *tc, CPSR spsr,
+ ExceptionLevel dest, bool aarch32)
+{
+ bool SS_bit = false;
+ bool enabled_src = false;
+ if (bSS){
+ enabled_src = conf->isDebugEnabled(tc);
+
+ bool enabled_dst = false;
+ bool secure = isSecureBelowEL3(tc) || dest == EL3;
+ CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+ if (cpsr.width)
+ {
+ enabled_dst = conf->isDebugEnabledForEL32(tc, dest, secure,
+ spsr.d==1);
+ } else {
+ enabled_dst = conf->isDebugEnabledForEL64(tc, dest, secure,
+ spsr.d==1);
+ }
+ ExceptionLevel ELd = debugTargetFrom(tc, secure);
+
+ if (!ELIs32(tc, ELd) && !enabled_src && enabled_dst){
+ SS_bit = spsr.ss;
+ if (SS_bit == 0x0){
+ stateSS = ACTIVE_PENDING_STATE;
+ }else{
+ stateSS = ACTIVE_NOT_PENDING_STATE;
+ }
+ }
+ }
+ return SS_bit;
+}
+
+bool
+SoftwareStep::advanceSS(ThreadContext * tc, bool ldx )
+{
+
+ PCState pc = tc->pcState();
+ bool res = false;
+ switch (stateSS){
+ case INACTIVE_STATE:
+ pc.debugStep(false);
+ break;
+
+ case ACTIVE_NOT_PENDING_STATE:
+ pc.debugStep(false);
+ if (cpsr_d == 1 || !bSS){
+ stateSS = INACTIVE_STATE;
+ } else {
+ pc.stepped(true);
+ stateSS = ACTIVE_PENDING_STATE;
+ tc->pcState(pc);
+ }
+ break;
+
+ case ACTIVE_PENDING_STATE:
+ if (!cpsr_d && bSS){
+ pc.debugStep(true);
+ res = true;
+ tc->pcState(pc);
+ }
+ stateSS = INACTIVE_STATE;
+ break;
+
+ default:
+ break;
+ }
+ return res;
+}
+
diff --git a/src/arch/arm/self_debug.hh b/src/arch/arm/self_debug.hh
index 7154085..1404d27 100644
--- a/src/arch/arm/self_debug.hh
+++ b/src/arch/arm/self_debug.hh
@@ -51,11 +51,16 @@
class ThreadContext;
+#define INACTIVE_STATE 0
+#define ACTIVE_PENDING_STATE 1
+#define ACTIVE_NOT_PENDING_STATE 2
+
namespace ArmISA
{
class SelfDebug;
+class SoftwareStep;
class BrkPoint
{
@@ -203,12 +208,67 @@
bool atomic, unsigned size);
};
+class SoftwareStep
+{
+
+ private:
+ bool bSS;
+ int stateSS;
+ SelfDebug * conf;
+ bool cpsr_d;
+
+ bool ctrStepped;
+ bool ctrActivate;
+
+
+ public:
+ SoftwareStep(SelfDebug* s): bSS(false), stateSS(INACTIVE_STATE),
+ conf(s) { }
+
+ ~SoftwareStep() { }
+
+ bool debugExceptionReturnSS(ThreadContext *tc, CPSR spsr,
+ ExceptionLevel dest, bool aarch32);
+ bool advanceSS(ThreadContext * tc, bool ldx );
+
+ inline void setCPSR_D(bool val)
+ {
+ cpsr_d = val;
+ }
+
+ inline void setEnableSS(bool val)
+ {
+ bSS = val;
+ }
+
+ inline void setActivate(bool val)
+ {
+ ctrActivate = false;
+ }
+
+ bool getActivate()
+ {
+ return ctrActivate;
+ }
+
+ bool getStepped()
+ {
+ return ctrStepped;
+ }
+
+ void updatePCState(PCState& pc)
+ {
+ pc.debugStep(false);
+
+ }
+};
class SelfDebug
{
private:
std::vector<BrkPoint> arBrkPoints;
std::vector<WatchPoint> arWatchPoints;
+ SoftwareStep * softStep;
bool initialized;
bool enableTdeTge; // MDCR_EL2.TDE || HCR_EL2.TGE
@@ -226,9 +286,13 @@
public:
SelfDebug(): initialized(false), enableTdeTge(false),
enableFlag(false), bSDD(false), bKDE(false), oslk(false)
- {}
+ {
+ softStep = new SoftwareStep(this);
+ }
- ~SelfDebug(){}
+ ~SelfDebug(){
+ delete softStep;
+ }
Fault testBreakPoints(ThreadContext *tc, Addr vaddr);
Fault testWatchPoints(ThreadContext *tc, Addr vaddr, bool write,
@@ -296,6 +360,7 @@
{
enableFlag = bits(val, 15);
bKDE = bits(val, 13);
+ softStep->setEnableSS((bool)bits(val, 0));
}
inline void setMDBGen(RegVal val)
@@ -323,6 +388,10 @@
arWatchPoints[index].updateControl(val);
}
+ inline void setDebugMask(bool mask)
+ {
+ softStep->setCPSR_D(mask);
+ }
inline bool isAArch32()
{
return aarch32;
@@ -341,6 +410,10 @@
aarch32 = ELIs32(tc, fromEL);
return;
}
+ SoftwareStep * get_Sstep(){
+ return softStep;
+ }
+
bool targetAArch32(ThreadContext * tc)
{
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index fc7a754..4fa9590 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1193,11 +1193,16 @@
}
//Check for Debug Exceptions
- if (fault == NoFault) {
+ if (fault == NoFault)
+ {
auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
SelfDebug * sd = isa->getSelfDebug();
- if (mode == Execute) {
- fault = sd->testBreakPoints(tc, req->getVaddr());
+ if (mode == Execute)
+ {
+ const bool d_step = sd->get_Sstep()->advanceSS(tc, true);
+ if (!d_step){
+ fault = sd->testBreakPoints(tc, req->getVaddr());
+ }
}
else if (!req->isCacheMaintenance() ||
(req->isCacheInvalidate() && !req->isCacheClean()))
@@ -1291,7 +1296,9 @@
// stage 2 translation we prevent marking the translation as delayed
twice,
// one when the translation starts and again when the stage 1
translation
// completes.
- if (translation && (callFromS2 || !stage2Req || req->hasPaddr() ||
fault != NoFault)) {
+
+ if (translation && (callFromS2 || !stage2Req || req->hasPaddr()
+ || fault != NoFault)) {
if (!delay)
translation->finish(fault, req, tc, mode);
else
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
index 3a5e741..6e502bb 100644
--- a/src/arch/arm/types.hh
+++ b/src/arch/arm/types.hh
@@ -69,6 +69,7 @@
// Decoder state
Bitfield<63, 62> decoderFault; // See DecoderFault
Bitfield<61> illegalExecution;
+ Bitfield<60> debugStep;
// SVE vector length, encoded in the same format as the
ZCR_EL<x>.LEN
// bitfields
@@ -228,9 +229,17 @@
uint8_t _nextItstate;
uint8_t _size;
bool _illegalExec;
+
+ // Software Step flags
+ bool _debugStep;
+ bool _ldx;
+ bool _prevLdx;
+ bool _stepped;
+
public:
PCState() : flags(0), nextFlags(0), _itstate(0), _nextItstate(0),
- _size(0), _illegalExec(false)
+ _size(0), _illegalExec(false), _debugStep(false),
+ _ldx(false), _prevLdx(false), _stepped(false)
{}
void
@@ -241,7 +250,9 @@
}
PCState(Addr val) : flags(0), nextFlags(0), _itstate(0),
- _nextItstate(0), _size(0), _illegalExec(false)
+ _nextItstate(0), _size(0), _illegalExec(false),
+ _debugStep(false), _ldx(false),
_prevLdx(false),
+ _stepped(false)
{ set(val); }
bool
@@ -257,6 +268,43 @@
}
bool
+ debugStep() const
+ {
+ return _debugStep;
+ }
+
+ void
+ debugStep(bool val)
+ {
+ _debugStep = val;
+ }
+
+ bool
+ ldx() const
+ {
+ return _prevLdx;
+ }
+
+ void
+ ldx(bool val)
+ {
+ _prevLdx = _ldx;
+ _ldx = val;
+ }
+
+ bool
+ stepped() const
+ {
+ return _stepped;
+ }
+
+ void
+ stepped(bool val)
+ {
+ _stepped = val;
+ }
+
+ bool
thumb() const
{
return flags & ThumbBit;
@@ -491,7 +539,10 @@
flags == opc.flags && nextFlags == opc.nextFlags &&
_itstate == opc._itstate &&
_nextItstate == opc._nextItstate &&
- _illegalExec == opc._illegalExec;
+ _illegalExec == opc._illegalExec &&
+ _debugStep == opc._debugStep &&
+ _ldx == opc._ldx &&
+ _stepped == opc._stepped;
}
bool
@@ -510,6 +561,9 @@
SERIALIZE_SCALAR(_itstate);
SERIALIZE_SCALAR(_nextItstate);
SERIALIZE_SCALAR(_illegalExec);
+ SERIALIZE_SCALAR(_debugStep);
+ SERIALIZE_SCALAR(_ldx);
+ SERIALIZE_SCALAR(_stepped);
}
void
@@ -522,6 +576,9 @@
UNSERIALIZE_SCALAR(_itstate);
UNSERIALIZE_SCALAR(_nextItstate);
UNSERIALIZE_SCALAR(_illegalExec);
+ UNSERIALIZE_SCALAR(_debugStep);
+ UNSERIALIZE_SCALAR(_ldx);
+ UNSERIALIZE_SCALAR(_stepped);
}
};
@@ -648,6 +705,9 @@
EC_HW_BREAKPOINT = 0x30,
EC_HW_BREAKPOINT_LOWER_EL = 0x30,
EC_HW_BREAKPOINT_CURR_EL = 0x31,
+ EC_SOFTWARE_STEP = 0x32,
+ EC_SOFTWARE_STEP_LOWER_EL = 0x32,
+ EC_SOFTWARE_STEP_CURR_EL = 0x33,
EC_WATCHPOINT = 0x34,
EC_WATCHPOINT_LOWER_EL = 0x34,
EC_WATCHPOINT_CURR_EL = 0x35,
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/30617
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I3a64507c64842c34c76ad7f6daa5f4306bd55d2c
Gerrit-Change-Number: 30617
Gerrit-PatchSet: 1
Gerrit-Owner: Jordi Vaquero <jordi.vaqu...@metempsy.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s