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

Reply via email to