Jordi Vaquero has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/23943 )

Change subject: arch-arm: Implementation of Hardware Breakpoint exception
......................................................................

arch-arm: Implementation of Hardware Breakpoint exception

This code implementes hardware breakpoint exception as part of
software debug explained in ARMv8 reference manual ChapterD2.

+ ArmISA.py: Modify register to allow up to 15 Breakpoint registers
+ Sconscript: Add new file self_debug
+ faults.cc/hh: Defintion and implementation of HardwareBreakpoint
                exception inheriting ArmFault.
+ isa.cc/hh: ArmISA contains now an attribute pointing to the SelfDebug
             object that will be used to be access SelfDebug infrastructure
             Added special cases for setMiscReg to cache debug enable bits.
+ miscregs.hh/cc: Definition and initialization of DBGDCn and DBGDVn
                  registers.
+ tlb.cc/hh: We include the access to check for breakpoint instruction as
part of the tlb translation process, checking if it comes from a
             fetch in the itlb
+ types.hh: Definition of new bitwise register types.
+ utility.cc/hh: Definition and implementation of auxiliar functions for
                the selfDebug.
+ self_debug.hh/cc: Main files that include the implemenattion of
            breakpoint checks, selfdebug enable and auxiliar functions.

Change-Id: I0e2a4be7f778de560c512253a9148da61e3e7e7a
---
M src/arch/arm/ArmISA.py
M src/arch/arm/SConscript
M src/arch/arm/faults.cc
M src/arch/arm/faults.hh
M src/arch/arm/insts/static_inst.cc
M src/arch/arm/insts/static_inst.hh
M src/arch/arm/isa.cc
M src/arch/arm/isa.hh
M src/arch/arm/miscregs.cc
M src/arch/arm/miscregs.hh
M src/arch/arm/miscregs_types.hh
A src/arch/arm/self_debug.cc
A src/arch/arm/self_debug.hh
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
M src/arch/arm/tracers/tarmac_parser.cc
M src/arch/arm/types.hh
M src/arch/arm/utility.cc
M src/arch/arm/utility.hh
19 files changed, 1,805 insertions(+), 171 deletions(-)



diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py
index 7b71895..b884c5b 100644
--- a/src/arch/arm/ArmISA.py
+++ b/src/arch/arm/ArmISA.py
@@ -92,8 +92,8 @@
     id_aa64afr1_el1 = Param.UInt64(0x0000000000000000,
         "AArch64 Auxiliary Feature Register 1")

-    # 1 CTX CMPs | 2 WRPs | 2 BRPs | !PMU | !Trace | Debug v8-A
-    id_aa64dfr0_el1 = Param.UInt64(0x0000000000101006,
+    # 1 CTX CMPs | 2 WRPs | 16 BRPs | !PMU | !Trace | Debug v8-A
+    id_aa64dfr0_el1 = Param.UInt64(0x000000000010F006,
         "AArch64 Debug Feature Register 0")
     # Reserved for future expansion
     id_aa64dfr1_el1 = Param.UInt64(0x0000000000000000,
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index caea1c4..c09cbe6 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -83,6 +83,7 @@
     Source('stacktrace.cc')
     Source('system.cc')
     Source('table_walker.cc')
+    Source('self_debug.cc')
     Source('stage2_mmu.cc')
     Source('stage2_lookup.cc')
     Source('tlb.cc')
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 5a7b8e8..67abb62 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -286,6 +286,10 @@
     "Software Breakpoint",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
     0, 0, 0, 0, true, false, false,  EC_SOFTWARE_BREAKPOINT
 );
+template<> ArmFault::FaultVals ArmFaultVals<HardwareBreakpoint>::vals(
+    "Hardware Breakpoint",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+    0, 0, 0, 0, true, false, false,  EC_HW_BREAKPOINT
+);
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals(
     // Some dummy values
     "ArmSev Flush",          0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
@@ -1080,6 +1084,16 @@
         } else if (stage2) {
             tc->setMiscReg(MISCREG_HPFAR, (faultAddr >> 8) & ~0xf);
             tc->setMiscReg(T::HFarIndex,  OVAddr);
+        } else if (debug > ArmFault::NODEBUG) {
+            DBGDS32 Rext =  tc->readMiscReg(MISCREG_DBGDSCRext);
+            tc->setMiscReg(T::FarIndex, faultAddr);
+            if (debug == ArmFault::BRKPOINT){
+                Rext.moe = 0x1;
+            }
+
+            tc->setMiscReg(T::FsrIndex, fsr);
+            tc->setMiscReg(MISCREG_DBGDSCRext, Rext);
+
         } else {
             tc->setMiscReg(T::FsrIndex, fsr);
             tc->setMiscReg(T::FarIndex, faultAddr);
@@ -1282,9 +1296,10 @@
     toHyp = scr.ns && (currEL(tc) == EL2);
     // otherwise, check whether to take to Hyp mode through Hyp Trap vector
     toHyp |= (stage2 ||
- ((source == DebugEvent) && hdcr.tde && (currEL(tc) != EL2)) | |
-               ((source == SynchronousExternalAbort) && hcr.tge &&
-                (currEL(tc) == EL0))) && !inSecureState(tc);
+       ((source == DebugEvent) && (hdcr.tde || hcr.tge) &&
+        (currEL(tc) != EL2)) ||
+       ((source == SynchronousExternalAbort) && hcr.tge  &&
+        (currEL(tc) == EL0))) && !inSecureState(tc);
     return toHyp;
 }

@@ -1597,6 +1612,58 @@
     return from64 ? EC_SOFTWARE_BREAKPOINT_64 : vals.ec;
 }

+HardwareBreakpoint::HardwareBreakpoint(Addr _vaddr,  uint32_t _iss)
+    : ArmFaultVals<HardwareBreakpoint>(0x0, _iss), vAddr(_vaddr)
+{}
+
+bool
+HardwareBreakpoint::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
+HardwareBreakpoint::ec(ThreadContext *tc) const
+{
+        // AArch64
+        if (toEL == fromEL)
+            return EC_HW_BREAKPOINT_CURR_EL;
+        else
+            return EC_HW_BREAKPOINT_LOWER_EL;
+}
+
+void
+HardwareBreakpoint::invoke(ThreadContext *tc, const StaticInstPtr &inst)
+{
+
+    ArmFaultVals<HardwareBreakpoint>::invoke(tc, inst);
+    MiscRegIndex elr_idx;
+    switch (toEL) {
+      case EL1:
+        elr_idx = MISCREG_ELR_EL1;
+        break;
+      case EL2:
+        assert(ArmSystem::haveVirtualization(tc));
+        elr_idx = MISCREG_ELR_EL2;
+        break;
+      case EL3:
+        assert(ArmSystem::haveSecurity(tc));
+        elr_idx = MISCREG_ELR_EL3;
+        break;
+      default:
+        panic("Invalid target exception level");
+        break;
+    }
+
+    tc->setMiscReg(elr_idx, vAddr);
+
+}
 void
 ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
     DPRINTF(Faults, "Invoking ArmSev Fault\n");
@@ -1630,6 +1697,7 @@
 template class ArmFaultVals<SPAlignmentFault>;
 template class ArmFaultVals<SystemError>;
 template class ArmFaultVals<SoftwareBreakpoint>;
+template class ArmFaultVals<HardwareBreakpoint>;
 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 3f61bc7..500996e 100644
--- a/src/arch/arm/faults.hh
+++ b/src/arch/arm/faults.hh
@@ -154,6 +154,12 @@
         UnknownTran
     };

+    enum DebugType
+    {
+        NODEBUG = 0,
+        BRKPOINT,
+    };
+
     struct FaultVals
     {
         const FaultName name;
@@ -433,14 +439,16 @@
     bool stage2;
     bool s1ptw;
     ArmFault::TranMethod tranMethod;
+    ArmFault::DebugType debug;

   public:
     AbortFault(Addr _faultAddr, bool _write, TlbEntry::DomainType _domain,
                uint8_t _source, bool _stage2,
-               ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+               ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran,
+               ArmFault::DebugType _debug = ArmFault::NODEBUG) :
         faultAddr(_faultAddr), OVAddr(0), write(_write),
         domain(_domain), source(_source), srcEncoded(0),
-        stage2(_stage2), s1ptw(false), tranMethod(_tranMethod)
+ stage2(_stage2), s1ptw(false), tranMethod(_tranMethod), debug(_debug)
     {}

     bool getFaultVAddr(Addr &va) const override;
@@ -466,9 +474,10 @@
     static const MiscRegIndex HFarIndex = MISCREG_HIFAR;

     PrefetchAbort(Addr _addr, uint8_t _source, bool _stage2 = false,
- ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+                  ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran,
+                  ArmFault::DebugType _debug = ArmFault::NODEBUG) :
AbortFault<PrefetchAbort>(_addr, false, TlbEntry::DomainType::NoAccess,
-                _source, _stage2, _tranMethod)
+                _source, _stage2, _tranMethod, _debug)
     {}

     ExceptionClass ec(ThreadContext *tc) const override;
@@ -594,6 +603,18 @@
     ExceptionClass ec(ThreadContext *tc) const override;
 };

+/// System error (AArch64 only)
+class HardwareBreakpoint : public ArmFaultVals<HardwareBreakpoint>
+{
+  private:
+    Addr vAddr;
+  public:
+    void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+                StaticInst::nullStaticInstPtr) override;
+    HardwareBreakpoint(Addr _vaddr, uint32_t _iss);
+    bool routeToHyp(ThreadContext *tc) const override;
+    ExceptionClass ec(ThreadContext *tc) const override;
+};
 // A fault that flushes the pipe, excluding the faulting instructions
 class ArmSev : public ArmFaultVals<ArmSev>
 {
@@ -634,6 +655,7 @@
 template<> ArmFault::FaultVals ArmFaultVals<SPAlignmentFault>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<SystemError>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals;
+template<> ArmFault::FaultVals ArmFaultVals<HardwareBreakpoint>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals;

 /**
diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc
index 1f849b9..303e91c 100644
--- a/src/arch/arm/insts/static_inst.cc
+++ b/src/arch/arm/insts/static_inst.cc
@@ -640,7 +640,10 @@
     } else {
         // Execute AArch32 Software Breakpoint
         return std::make_shared<PrefetchAbort>(readPC(xc),
-                                               ArmFault::DebugEvent);
+                                               ArmFault::DebugEvent,
+                                               false,
+                                               ArmFault::UnknownTran,
+                                               ArmFault::BRKPOINT);
     }
 }

diff --git a/src/arch/arm/insts/static_inst.hh b/src/arch/arm/insts/static_inst.hh
index c58aca4..7faff3e 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -46,6 +46,8 @@

 #include "arch/arm/faults.hh"
 #include "arch/arm/utility.hh"
+#include "arch/arm/isa.hh"
+#include "arch/arm/self_debug.hh"
 #include "arch/arm/system.hh"
 #include "base/trace.hh"
 #include "cpu/exec_context.hh"
@@ -199,6 +201,14 @@
     std::string generateDisassembly(
             Addr pc, const SymbolTable *symtab) const override;

+    static void
+    activateBreakpoint(ThreadContext *tc)
+    {
+            SelfDebug * sd = (tc->getIsaPtr())->getSelfDebug();
+            sd->activateDebug();
+    }
+
+
     static inline uint32_t
     cpsrWriteByInstr(CPSR cpsr, uint32_t val, SCR scr, NSACR nsacr,
uint8_t byteMask, bool affectState, bool nmfi, ThreadContext *tc)
@@ -210,6 +220,9 @@

         uint32_t bitMask = 0;

+        if (affectState && byteMask==0xF){
+            activateBreakpoint(tc);
+        }
         if (bits(byteMask, 3)) {
             unsigned lowIdx = affectState ? 24 : 27;
             bitMask = bitMask | mask(31, lowIdx);
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 767fd9f..1203c55 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -43,6 +43,7 @@
 #include "arch/arm/faults.hh"
 #include "arch/arm/interrupts.hh"
 #include "arch/arm/pmu.hh"
+#include "arch/arm/self_debug.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
 #include "arch/arm/tlbi_op.hh"
@@ -113,6 +114,7 @@
     const_cast<Enums::VecRegRenameMode&>(_vecRegRenameMode) =
         highestELIs64 ? Enums::Full : Enums::Elem;

+    selfDebug = new SelfDebug();
     initializeMiscRegMetadata();
     preUnflattenMiscReg();

@@ -682,7 +684,7 @@
          */
         return 0x5 << 16;
       case MISCREG_DBGDSCRint:
-        return 0;
+        return readMiscRegNoEffect(MISCREG_DBGDSCRint);
       case MISCREG_ISR:
         {
             auto ic = dynamic_cast<ArmISA::Interrupts *>(
@@ -1036,11 +1038,172 @@
                          (readMiscRegNoEffect(MISCREG_FPEXC) & ~fpexcMask);
             }
             break;
-          case MISCREG_HCR:
           case MISCREG_HCR2:
                 if (!haveVirtualization)
                     return;
                 break;
+          case MISCREG_HCR:
+            {
+ const HDCR mdcr = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+                selfDebug->setenableTDETGE((HCR)val, mdcr);
+                if (!haveVirtualization)
+                    return;
+            }
+            break;
+
+          case MISCREG_HDCR:
+            {
+                const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
+                selfDebug->setenableTDETGE(hcr, (HDCR)val);
+            }
+            break;
+          case MISCREG_DBGOSLAR:
+            {
+                OSL r = tc->readMiscReg(MISCREG_DBGOSLSR);
+                const uint32_t temp = (val == 0xC5ACCE55)? 0x1 : 0x0;
+                selfDebug->updateOSLock((RegVal) temp);
+                r.oslk = bits(temp,0);
+                tc->setMiscReg(MISCREG_DBGOSLSR, r);
+            }
+            break;
+          case MISCREG_DBGBCR0:
+            selfDebug->updateDBGBCR(0, val);
+            break;
+          case MISCREG_DBGBCR1:
+            selfDebug->updateDBGBCR(1, val);
+            break;
+          case MISCREG_DBGBCR2:
+            selfDebug->updateDBGBCR(2, val);
+            break;
+          case MISCREG_DBGBCR3:
+            selfDebug->updateDBGBCR(3, val);
+            break;
+          case MISCREG_DBGBCR4:
+            selfDebug->updateDBGBCR(4, val);
+            break;
+          case MISCREG_DBGBCR5:
+            selfDebug->updateDBGBCR(5, val);
+            break;
+          case MISCREG_DBGBCR6:
+            selfDebug->updateDBGBCR(6, val);
+            break;
+          case MISCREG_DBGBCR7:
+            selfDebug->updateDBGBCR(7, val);
+            break;
+          case MISCREG_DBGBCR8:
+            selfDebug->updateDBGBCR(8, val);
+            break;
+          case MISCREG_DBGBCR9:
+            selfDebug->updateDBGBCR(9, val);
+            break;
+          case MISCREG_DBGBCR10:
+            selfDebug->updateDBGBCR(10, val);
+            break;
+          case MISCREG_DBGBCR11:
+            selfDebug->updateDBGBCR(11, val);
+            break;
+          case MISCREG_DBGBCR12:
+            selfDebug->updateDBGBCR(12, val);
+            break;
+          case MISCREG_DBGBCR13:
+            selfDebug->updateDBGBCR(13, val);
+            break;
+          case MISCREG_DBGBCR14:
+            selfDebug->updateDBGBCR(14, val);
+            break;
+          case MISCREG_DBGBCR15:
+            selfDebug->updateDBGBCR(15, val);
+            break;
+
+          case MISCREG_MDCR_EL2:
+            {
+                const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
+                selfDebug->setenableTDETGE(hcr, (HDCR)val);
+            }
+            break;
+          case MISCREG_SDCR:
+          case MISCREG_MDCR_EL3:
+            {
+                selfDebug->setbSDD(val);
+            }
+            break;
+          case MISCREG_DBGDSCRext:
+            {
+                selfDebug->setMDBGen(val);
+                DBGDS32 r = tc->readMiscReg(MISCREG_DBGDSCRint);
+                DBGDS32 v = val;
+                r.moe = v.moe;
+                r.udccdis = v.udccdis;
+                r.mdbgen = v.mdbgen;
+                tc->setMiscReg(MISCREG_DBGDSCRint, r);
+                r = tc->readMiscReg(MISCREG_DBGDSCRint);
+            }
+
+            break;
+          case MISCREG_MDSCR_EL1:
+            {
+                selfDebug->setMDSCRvals(val);
+            }
+            break;
+
+          case MISCREG_OSLAR_EL1:
+            {
+                selfDebug->updateOSLock(val);
+                OSL r = tc->readMiscReg(MISCREG_OSLSR_EL1);
+                r.oslk = bits(val, 0);
+                r.oslm_3 = 1;
+                tc->setMiscReg(MISCREG_OSLSR_EL1, r);
+            }
+            break;
+
+          case MISCREG_DBGBCR0_EL1:
+            selfDebug->updateDBGBCR(0, val);
+            break;
+          case MISCREG_DBGBCR1_EL1:
+            selfDebug->updateDBGBCR(1, val);
+            break;
+          case MISCREG_DBGBCR2_EL1:
+            selfDebug->updateDBGBCR(2, val);
+            break;
+          case MISCREG_DBGBCR3_EL1:
+            selfDebug->updateDBGBCR(3, val);
+            break;
+          case MISCREG_DBGBCR4_EL1:
+            selfDebug->updateDBGBCR(4, val);
+            break;
+          case MISCREG_DBGBCR5_EL1:
+            selfDebug->updateDBGBCR(5, val);
+            break;
+          case MISCREG_DBGBCR6_EL1:
+            selfDebug->updateDBGBCR(6, val);
+            break;
+          case MISCREG_DBGBCR7_EL1:
+            selfDebug->updateDBGBCR(7, val);
+            break;
+          case MISCREG_DBGBCR8_EL1:
+            selfDebug->updateDBGBCR(8, val);
+            break;
+          case MISCREG_DBGBCR9_EL1:
+            selfDebug->updateDBGBCR(9, val);
+            break;
+          case MISCREG_DBGBCR10_EL1:
+            selfDebug->updateDBGBCR(10, val);
+            break;
+          case MISCREG_DBGBCR11_EL1:
+            selfDebug->updateDBGBCR(11, val);
+            break;
+          case MISCREG_DBGBCR12_EL1:
+            selfDebug->updateDBGBCR(12, val);
+            break;
+          case MISCREG_DBGBCR13_EL1:
+            selfDebug->updateDBGBCR(13, val);
+            break;
+          case MISCREG_DBGBCR14_EL1:
+            selfDebug->updateDBGBCR(14, val);
+            break;
+          case MISCREG_DBGBCR15_EL1:
+            selfDebug->updateDBGBCR(15, val);
+            break;
           case MISCREG_IFSR:
             {
                 // ARM ARM (ARM DDI 0406C.b) B4.1.96
@@ -2073,7 +2236,7 @@
           case MISCREG_SPSR_EL1:
             {
                 RegVal spsr_mask = havePAN ?
-                    ~(0x5 << 21) : ~(0x7 << 21);
+                    ~(0x2 << 22) : ~(0x3 << 22);

                 newVal = val & spsr_mask;
                 break;
diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh
index fea372e..946940d 100644
--- a/src/arch/arm/isa.hh
+++ b/src/arch/arm/isa.hh
@@ -46,6 +46,7 @@
 #include "arch/arm/isa_device.hh"
 #include "arch/arm/miscregs.hh"
 #include "arch/arm/registers.hh"
+#include "arch/arm/self_debug.hh"
 #include "arch/arm/system.hh"
 #include "arch/arm/tlb.hh"
 #include "arch/arm/types.hh"
@@ -109,6 +110,8 @@

         bool afterStartup;

+        SelfDebug * selfDebug;
+
         /** MiscReg metadata **/
         struct MiscRegLUTEntry {
             uint32_t lower;  // Lower half mapped to this register
@@ -440,6 +443,10 @@
         void initID64(const ArmISAParams *p);

       public:
+        SelfDebug * getSelfDebug()
+        {
+            return selfDebug;
+        }
         RegVal readMiscRegNoEffect(int misc_reg) const;
         RegVal readMiscReg(int misc_reg, ThreadContext *tc);
         void setMiscRegNoEffect(int misc_reg, RegVal val);
diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc
index 787ba2f..eba6e7a 100644
--- a/src/arch/arm/miscregs.cc
+++ b/src/arch/arm/miscregs.cc
@@ -67,6 +67,90 @@
                     return MISCREG_DBGDSCRint;
                 }
                 break;
+              case 2:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGDTRRXext;
+                  case 2:
+                    return MISCREG_DBGDSCRext;
+                  case 3:
+                    return MISCREG_DBGDTRTXext;
+                  case 6:
+                    return MISCREG_DBGOSECCR;
+                }
+                break;
+              case 4:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGBVR0;
+                  case 1:
+                    return MISCREG_DBGBVR1;
+                  case 2:
+                    return MISCREG_DBGBVR2;
+                  case 3:
+                    return MISCREG_DBGBVR3;
+                  case 4:
+                    return MISCREG_DBGBVR4;
+                  case 5:
+                    return MISCREG_DBGBVR5;
+                  case 6:
+                    return MISCREG_DBGBVR6;
+                  case 7:
+                    return MISCREG_DBGBVR7;
+                  case 8:
+                    return MISCREG_DBGBVR8;
+                  case 9:
+                    return MISCREG_DBGBVR9;
+                  case 10:
+                    return MISCREG_DBGBVR10;
+                  case 11:
+                    return MISCREG_DBGBVR11;
+                  case 12:
+                    return MISCREG_DBGBVR12;
+                  case 13:
+                    return MISCREG_DBGBVR13;
+                  case 14:
+                    return MISCREG_DBGBVR14;
+                  case 15:
+                    return MISCREG_DBGBVR15;
+                }
+                break;
+              case 5:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGBCR0;
+                  case 1:
+                    return MISCREG_DBGBCR1;
+                  case 2:
+                    return MISCREG_DBGBCR2;
+                  case 3:
+                    return MISCREG_DBGBCR3;
+                  case 4:
+                    return MISCREG_DBGBCR4;
+                  case 5:
+                    return MISCREG_DBGBCR5;
+                  case 6:
+                    return MISCREG_DBGBCR6;
+                  case 7:
+                    return MISCREG_DBGBCR7;
+                  case 8:
+                    return MISCREG_DBGBCR8;
+                  case 9:
+                    return MISCREG_DBGBCR9;
+                  case 10:
+                    return MISCREG_DBGBCR10;
+                  case 11:
+                    return MISCREG_DBGBCR11;
+                  case 12:
+                    return MISCREG_DBGBCR12;
+                  case 13:
+                    return MISCREG_DBGBCR13;
+                  case 14:
+                    return MISCREG_DBGBCR14;
+                  case 15:
+                    return MISCREG_DBGBCR15;
+                }
+                break;
             }
             break;
           case 7:
@@ -83,6 +167,59 @@
         break;
       case 1:
         switch (opc1) {
+          case 0:
+            switch(opc2) {
+              case 1:
+                switch(crm) {
+                  case 0:
+                      return MISCREG_DBGBXVR0;
+                  case 1:
+                      return MISCREG_DBGBXVR1;
+                  case 2:
+                      return MISCREG_DBGBXVR2;
+                  case 3:
+                      return MISCREG_DBGBXVR3;
+                  case 4:
+                      return MISCREG_DBGBXVR4;
+                  case 5:
+                      return MISCREG_DBGBXVR5;
+                  case 6:
+                      return MISCREG_DBGBXVR6;
+                  case 7:
+                      return MISCREG_DBGBXVR7;
+                  case 8:
+                      return MISCREG_DBGBXVR8;
+                  case 9:
+                      return MISCREG_DBGBXVR9;
+                  case 10:
+                      return MISCREG_DBGBXVR10;
+                  case 11:
+                      return MISCREG_DBGBXVR11;
+                  case 12:
+                      return MISCREG_DBGBXVR12;
+                  case 13:
+                      return MISCREG_DBGBXVR13;
+                  case 14:
+                      return MISCREG_DBGBXVR14;
+                  case 15:
+                      return MISCREG_DBGBXVR15;
+                }
+                break;
+            }
+            switch (opc2) {
+              case 4:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGOSLAR;
+                  case 1:
+                    return MISCREG_DBGOSLSR;
+                  case 3:
+                    return MISCREG_DBGOSDLR;
+                  case 4:
+                    return MISCREG_DBGPRCR;
+                }
+                break;
+            }
           case 6:
             switch (crm) {
               case 0:
@@ -242,7 +379,11 @@
                   case 2:
                     return MISCREG_NSACR;
                 }
+            } else if (crm == 3) {
+                if ( opc2 == 1)
+                    return MISCREG_SDCR;
             }
+
         } else if (opc1 == 4) {
             if (crm == 0) {
                 if (opc2 == 0)
@@ -1525,6 +1666,82 @@
                     switch (op2) {
                       case 2:
                         return MISCREG_OSECCR_EL1;
+                      case 4:
+                        return MISCREG_DBGBVR6_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR6_EL1;
+                    }
+                    break;
+                  case 7:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR7_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR7_EL1;
+                    }
+                    break;
+                  case 8:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR8_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR8_EL1;
+                    }
+                    break;
+                  case 9:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR9_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR9_EL1;
+                    }
+                    break;
+                  case 10:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR10_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR10_EL1;
+                    }
+                    break;
+                  case 11:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR11_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR11_EL1;
+                    }
+                    break;
+                  case 12:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR12_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR12_EL1;
+                    }
+                    break;
+                  case 13:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR13_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR13_EL1;
+                    }
+                    break;
+                  case 14:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR14_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR14_EL1;
+                    }
+                    break;
+                  case 15:
+                    switch (op2) {
+                      case 4:
+                        return MISCREG_DBGBVR15_EL1;
+                      case 5:
+                        return MISCREG_DBGBCR15_EL1;
                     }
                     break;
                 }
@@ -2987,8 +3204,6 @@
       .unimplemented()
       .allPrivileges();
     InitReg(MISCREG_DBGDSCRext)
-      .unimplemented()
-      .warnNotFail()
       .allPrivileges();
     InitReg(MISCREG_DBGDTRTXext)
       .unimplemented()
@@ -2997,41 +3212,69 @@
       .unimplemented()
       .allPrivileges();
     InitReg(MISCREG_DBGBVR0)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBVR1)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBVR2)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBVR3)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBVR4)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBVR5)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR6)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR7)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR8)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR9)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR10)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR11)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR12)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR13)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR14)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBVR15)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR0)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR1)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR2)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR3)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR4)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBCR5)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR6)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR7)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR8)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR9)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR10)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR11)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR12)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR13)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR14)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBCR15)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWVR0)
       .unimplemented()
       .allPrivileges();
@@ -3059,17 +3302,43 @@
     InitReg(MISCREG_DBGDRAR)
       .unimplemented()
       .allPrivileges().monSecureWrite(0).monNonSecureWrite(0);
+    InitReg(MISCREG_DBGBXVR0)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR1)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR2)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR3)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBXVR4)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGBXVR5)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR0)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR6)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR7)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR8)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR9)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR10)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR11)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR12)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR13)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR14)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGBXVR15)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGOSLAR)
-      .unimplemented()
       .allPrivileges().monSecureRead(0).monNonSecureRead(0);
     InitReg(MISCREG_DBGOSLSR)
-      .unimplemented()
       .allPrivileges().monSecureWrite(0).monNonSecureWrite(0);
     InitReg(MISCREG_DBGOSDLR)
       .unimplemented()
@@ -3198,6 +3467,8 @@
       .secure().exceptUserMode();
     InitReg(MISCREG_CPACR)
       .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_SDCR)
+      .mon();
     InitReg(MISCREG_SCR)
       .mon().secure().exceptUserMode()
       .res0(0xff40)  // [31:16], [6]
@@ -3784,41 +4055,101 @@
       .allPrivileges()
       .mapsTo(MISCREG_DBGOSECCR);
     InitReg(MISCREG_DBGBVR0_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR0 /*, MISCREG_DBGBXVR0 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR0, MISCREG_DBGBXVR0);
     InitReg(MISCREG_DBGBVR1_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR1 /*, MISCREG_DBGBXVR1 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR1, MISCREG_DBGBXVR1);
     InitReg(MISCREG_DBGBVR2_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR2 /*, MISCREG_DBGBXVR2 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR2, MISCREG_DBGBXVR2);
     InitReg(MISCREG_DBGBVR3_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR3 /*, MISCREG_DBGBXVR3 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR3, MISCREG_DBGBXVR3);
     InitReg(MISCREG_DBGBVR4_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR4 /*, MISCREG_DBGBXVR4 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR4, MISCREG_DBGBXVR4);
     InitReg(MISCREG_DBGBVR5_EL1)
-      .allPrivileges()
-      .mapsTo(MISCREG_DBGBVR5 /*, MISCREG_DBGBXVR5 */);
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR5, MISCREG_DBGBXVR5);
+    InitReg(MISCREG_DBGBVR6_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR6, MISCREG_DBGBXVR6);
+    InitReg(MISCREG_DBGBVR7_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR7, MISCREG_DBGBXVR7);
+    InitReg(MISCREG_DBGBVR8_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR8, MISCREG_DBGBXVR8);
+    InitReg(MISCREG_DBGBVR9_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR9, MISCREG_DBGBXVR9);
+    InitReg(MISCREG_DBGBVR10_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR10, MISCREG_DBGBXVR10);
+    InitReg(MISCREG_DBGBVR11_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR11, MISCREG_DBGBXVR11);
+    InitReg(MISCREG_DBGBVR12_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR12, MISCREG_DBGBXVR12);
+    InitReg(MISCREG_DBGBVR13_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR13, MISCREG_DBGBXVR13);
+    InitReg(MISCREG_DBGBVR14_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR14, MISCREG_DBGBXVR14);
+    InitReg(MISCREG_DBGBVR15_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBVR15, MISCREG_DBGBXVR15);
     InitReg(MISCREG_DBGBCR0_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR0);
     InitReg(MISCREG_DBGBCR1_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR1);
     InitReg(MISCREG_DBGBCR2_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR2);
     InitReg(MISCREG_DBGBCR3_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR3);
     InitReg(MISCREG_DBGBCR4_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR4);
     InitReg(MISCREG_DBGBCR5_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR5);
+    InitReg(MISCREG_DBGBCR6_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR6);
+    InitReg(MISCREG_DBGBCR7_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR7);
+    InitReg(MISCREG_DBGBCR8_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR8);
+    InitReg(MISCREG_DBGBCR9_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR9);
+    InitReg(MISCREG_DBGBCR10_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR10);
+    InitReg(MISCREG_DBGBCR11_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR11);
+    InitReg(MISCREG_DBGBCR12_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR12);
+    InitReg(MISCREG_DBGBCR13_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR13);
+    InitReg(MISCREG_DBGBCR14_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR14);
+    InitReg(MISCREG_DBGBCR15_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGBCR15);
     InitReg(MISCREG_DBGWVR0_EL1)
       .allPrivileges()
       .mapsTo(MISCREG_DBGWVR0);
@@ -4041,7 +4372,8 @@
     InitReg(MISCREG_CPTR_EL3)
       .mon();
     InitReg(MISCREG_MDCR_EL3)
-      .mon();
+      .mon()
+      .mapsTo(MISCREG_SDCR);
     InitReg(MISCREG_TTBR0_EL1)
       .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_TTBR0_NS);
diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh
index 4f522f2..0277afa 100644
--- a/src/arch/arm/miscregs.hh
+++ b/src/arch/arm/miscregs.hh
@@ -106,12 +106,32 @@
         MISCREG_DBGBVR3,
         MISCREG_DBGBVR4,
         MISCREG_DBGBVR5,
+        MISCREG_DBGBVR6,
+        MISCREG_DBGBVR7,
+        MISCREG_DBGBVR8,
+        MISCREG_DBGBVR9,
+        MISCREG_DBGBVR10,
+        MISCREG_DBGBVR11,
+        MISCREG_DBGBVR12,
+        MISCREG_DBGBVR13,
+        MISCREG_DBGBVR14,
+        MISCREG_DBGBVR15,
         MISCREG_DBGBCR0,
         MISCREG_DBGBCR1,
         MISCREG_DBGBCR2,
         MISCREG_DBGBCR3,
         MISCREG_DBGBCR4,
         MISCREG_DBGBCR5,
+        MISCREG_DBGBCR6,
+        MISCREG_DBGBCR7,
+        MISCREG_DBGBCR8,
+        MISCREG_DBGBCR9,
+        MISCREG_DBGBCR10,
+        MISCREG_DBGBCR11,
+        MISCREG_DBGBCR12,
+        MISCREG_DBGBCR13,
+        MISCREG_DBGBCR14,
+        MISCREG_DBGBCR15,
         MISCREG_DBGWVR0,
         MISCREG_DBGWVR1,
         MISCREG_DBGWVR2,
@@ -121,8 +141,22 @@
         MISCREG_DBGWCR2,
         MISCREG_DBGWCR3,
         MISCREG_DBGDRAR,
+        MISCREG_DBGBXVR0,
+        MISCREG_DBGBXVR1,
+        MISCREG_DBGBXVR2,
+        MISCREG_DBGBXVR3,
         MISCREG_DBGBXVR4,
         MISCREG_DBGBXVR5,
+        MISCREG_DBGBXVR6,
+        MISCREG_DBGBXVR7,
+        MISCREG_DBGBXVR8,
+        MISCREG_DBGBXVR9,
+        MISCREG_DBGBXVR10,
+        MISCREG_DBGBXVR11,
+        MISCREG_DBGBXVR12,
+        MISCREG_DBGBXVR13,
+        MISCREG_DBGBXVR14,
+        MISCREG_DBGBXVR15,
         MISCREG_DBGOSLAR,
         MISCREG_DBGOSLSR,
         MISCREG_DBGOSDLR,
@@ -176,6 +210,7 @@
         MISCREG_ACTLR_NS,
         MISCREG_ACTLR_S,
         MISCREG_CPACR,
+        MISCREG_SDCR,
         MISCREG_SCR,
         MISCREG_SDER,
         MISCREG_NSACR,
@@ -395,12 +430,32 @@
         MISCREG_DBGBVR3_EL1,
         MISCREG_DBGBVR4_EL1,
         MISCREG_DBGBVR5_EL1,
+        MISCREG_DBGBVR6_EL1,
+        MISCREG_DBGBVR7_EL1,
+        MISCREG_DBGBVR8_EL1,
+        MISCREG_DBGBVR9_EL1,
+        MISCREG_DBGBVR10_EL1,
+        MISCREG_DBGBVR11_EL1,
+        MISCREG_DBGBVR12_EL1,
+        MISCREG_DBGBVR13_EL1,
+        MISCREG_DBGBVR14_EL1,
+        MISCREG_DBGBVR15_EL1,
         MISCREG_DBGBCR0_EL1,
         MISCREG_DBGBCR1_EL1,
         MISCREG_DBGBCR2_EL1,
         MISCREG_DBGBCR3_EL1,
         MISCREG_DBGBCR4_EL1,
         MISCREG_DBGBCR5_EL1,
+        MISCREG_DBGBCR6_EL1,
+        MISCREG_DBGBCR7_EL1,
+        MISCREG_DBGBCR8_EL1,
+        MISCREG_DBGBCR9_EL1,
+        MISCREG_DBGBCR10_EL1,
+        MISCREG_DBGBCR11_EL1,
+        MISCREG_DBGBCR12_EL1,
+        MISCREG_DBGBCR13_EL1,
+        MISCREG_DBGBCR14_EL1,
+        MISCREG_DBGBCR15_EL1,
         MISCREG_DBGWVR0_EL1,
         MISCREG_DBGWVR1_EL1,
         MISCREG_DBGWVR2_EL1,
@@ -1052,12 +1107,32 @@
         "dbgbvr3",
         "dbgbvr4",
         "dbgbvr5",
+        "dbgbvr6",
+        "dbgbvr7",
+        "dbgbvr8",
+        "dbgbvr9",
+        "dbgbvr10",
+        "dbgbvr11",
+        "dbgbvr12",
+        "dbgbvr13",
+        "dbgbvr14",
+        "dbgbvr15",
         "dbgbcr0",
         "dbgbcr1",
         "dbgbcr2",
         "dbgbcr3",
         "dbgbcr4",
         "dbgbcr5",
+        "dbgbcr6",
+        "dbgbcr7",
+        "dbgbcr8",
+        "dbgbcr9",
+        "dbgbcr10",
+        "dbgbcr11",
+        "dbgbcr12",
+        "dbgbcr13",
+        "dbgbcr14",
+        "dbgbcr15",
         "dbgwvr0",
         "dbgwvr1",
         "dbgwvr2",
@@ -1067,8 +1142,22 @@
         "dbgwcr2",
         "dbgwcr3",
         "dbgdrar",
+        "dbgbxvr0",
+        "dbgbxvr1",
+        "dbgbxvr2",
+        "dbgbxvr3",
         "dbgbxvr4",
         "dbgbxvr5",
+        "dbgbxvr6",
+        "dbgbxvr7",
+        "dbgbxvr8",
+        "dbgbxvr9",
+        "dbgbxvr10",
+        "dbgbxvr11",
+        "dbgbxvr12",
+        "dbgbxvr13",
+        "dbgbxvr14",
+        "dbgbxvr15",
         "dbgoslar",
         "dbgoslsr",
         "dbgosdlr",
@@ -1122,6 +1211,7 @@
         "actlr_ns",
         "actlr_s",
         "cpacr",
+        "sdrc",
         "scr",
         "sder",
         "nsacr",
@@ -1341,12 +1431,32 @@
         "dbgbvr3_el1",
         "dbgbvr4_el1",
         "dbgbvr5_el1",
+        "dbgbvr6_el1",
+        "dbgbvr7_el1",
+        "dbgbvr8_el1",
+        "dbgbvr9_el1",
+        "dbgbvr10_el1",
+        "dbgbvr11_el1",
+        "dbgbvr12_el1",
+        "dbgbvr13_el1",
+        "dbgbvr14_el1",
+        "dbgbvr15_el1",
         "dbgbcr0_el1",
         "dbgbcr1_el1",
         "dbgbcr2_el1",
         "dbgbcr3_el1",
         "dbgbcr4_el1",
         "dbgbcr5_el1",
+        "dbgbcr6_el1",
+        "dbgbcr7_el1",
+        "dbgbcr8_el1",
+        "dbgbcr9_el1",
+        "dbgbcr10_el1",
+        "dbgbcr11_el1",
+        "dbgbcr12_el1",
+        "dbgbcr13_el1",
+        "dbgbcr14_el1",
+        "dbgbcr15_el1",
         "dbgwvr0_el1",
         "dbgwvr1_el1",
         "dbgwvr2_el1",
diff --git a/src/arch/arm/miscregs_types.hh b/src/arch/arm/miscregs_types.hh
index 07e2262..ad915b6 100644
--- a/src/arch/arm/miscregs_types.hh
+++ b/src/arch/arm/miscregs_types.hh
@@ -653,6 +653,51 @@
         Bitfield<3, 0> len;
     EndBitUnion(ZCR)

+   BitUnion32(OSL)
+        Bitfield<64, 4> res0;
+        Bitfield<3> oslm_3;
+        Bitfield<2> nTT;
+        Bitfield<1> oslk;
+        Bitfield<0> oslm_0;
+   EndBitUnion(OSL)
+
+   BitUnion64(DBGBCR)
+        Bitfield<63, 24> res0_2;
+        Bitfield<23, 20> bt;
+        Bitfield<19, 16> lbn;
+        Bitfield<15, 14> ssc;
+        Bitfield<13> hmc;
+        Bitfield<12, 9> res0_1;
+        Bitfield<8, 5> bas;
+        Bitfield<4, 3> res0_0;
+        Bitfield<2, 1> pmc;
+        Bitfield<0> e;
+   EndBitUnion(DBGBCR)
+
+   BitUnion32(DBGDS32)
+        Bitfield<31> tfo;
+        Bitfield<30> rxfull;
+        Bitfield<29> txfull;
+        Bitfield<28> res0_5;
+        Bitfield<27> rxo;
+        Bitfield<26> txu;
+        Bitfield<25, 24> res0_4;
+        Bitfield<23, 22> intdis;
+        Bitfield<21> tda;
+        Bitfield<20> res0_3;
+        Bitfield<19> sc2;
+        Bitfield<18> ns;
+        Bitfield<17> spniddis;
+        Bitfield<16> spiddis;
+        Bitfield<15> mdbgen;
+        Bitfield<14> hde;
+        Bitfield<13> res0_;
+        Bitfield<12> udccdis;
+        Bitfield<11, 7> res0_2;
+        Bitfield<6> err;
+        Bitfield<5, 2> moe;
+        Bitfield<1, 0> res0_1;
+   EndBitUnion(DBGDS32)
 }

 #endif // __ARCH_ARM_MISCREGS_TYPES_HH__
diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc
new file mode 100644
index 0000000..e706977
--- /dev/null
+++ b/src/arch/arm/self_debug.cc
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2019 Metempsy Technology LSC
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Jordi Vaquero
+ */
+
+#include "arch/arm/self_debug.hh"
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/miscregs_types.hh"
+#include "base/bitfield.hh"
+
+using namespace ArmISA;
+using namespace std;
+
+Fault
+SelfDebug::testBreakPoints(ThreadContext *tc, Addr vaddr)
+{
+    setAArch32(tc);
+    to32 = targetAArch32(tc);
+    if (!initialized)
+        init(tc);
+    if (!isDebugEnabled(tc) || !enableFlag)
+        return NoFault;
+
+    ExceptionLevel el = (ExceptionLevel) currEL(tc);
+    for (auto &p: arBrkPoints){
+        PCState pcst = tc->pcState();
+        Addr pc = vaddr;
+        if (pcst.itstate() != 0x0)
+            pc = pcst.pc();
+        if (p.getEnable() && p.isActive(pc) &&(!to32 || !p.isSet())){
+            const DBGBCR ctr = p.getControlReg(tc);
+            if (p.isEnabled(tc, el, ctr.hmc, ctr.ssc, ctr.pmc)) {
+                bool debug = p.test(tc, pc, el, ctr, false);
+                if (debug){
+                    if (to32)
+                        p.setOnUse();
+                    return triggerException(tc, pc);
+                }
+            }
+        }
+    }
+    return NoFault;
+}
+
+
+Fault
+SelfDebug::triggerException(ThreadContext * tc, Addr vaddr)
+{
+    if (isTo32()) {
+        return std::make_shared<PrefetchAbort>(vaddr,
+                                   ArmFault::DebugEvent, false,
+                                   ArmFault::UnknownTran,
+                                   ArmFault::BRKPOINT);
+    } else {
+        return std::make_shared<HardwareBreakpoint>(vaddr, 0x22);
+    }
+}
+
+bool
+BrkPoint::testLinkedBk(ThreadContext *tc, Addr vaddr, ExceptionLevel el)
+{
+    bool debug = false;
+    const DBGBCR ctr = getControlReg(tc);
+    if ((ctr.bt & 0x1) && getEnable()){
+        debug = test(tc, vaddr, el, ctr, true);
+    }
+    return debug;
+}
+
+bool
+BrkPoint::test(ThreadContext *tc, Addr pc, ExceptionLevel el, DBGBCR ctr,
+               bool from_link)
+{
+    bool v = false;
+    switch (ctr.bt)
+    {
+        case 0x0:
+            v = testAddrMatch(tc, pc, ctr.bas);
+            break;
+        case 0x1:
+            v = testAddrMatch(tc, pc, ctr.bas); // linked
+            if (v){
+                v = (conf->getBrkPoint(ctr.lbn))->testLinkedBk(tc, pc, el);
+            }
+            break;
+        case 0x2:
+            v = testContextMatch(tc, true);
+            break;
+        case 0x3:
+            if (from_link){
+                v = testContextMatch(tc, true); //linked
+            }
+            break;
+        case 0x4:
+            v = testAddrMissMatch(tc, pc, ctr.bas);
+            break;
+        case 0x5:
+            v = testAddrMissMatch(tc, pc, ctr.bas); // linked
+            if (v && !from_link)
+                v = v && (conf->getBrkPoint(ctr.lbn))->testLinkedBk(tc,
+                                                                 pc, el);
+            break;
+        case 0x6:
+            // VHE not implemented
+            // v = testContextMatch(tc, true);
+            break;
+        case 0x7:
+            // VHE not implemented
+            // if (from_link)
+            //     v = testContextMatch(tc, true);
+            break;
+        case 0x8:
+            v = testVMIDMatch(tc);
+            break;
+        case 0x9:
+            if (from_link && ArmSystem::haveEL(tc, EL2)){
+                v = testVMIDMatch(tc); // linked
+            }
+            break;
+        case 0xa:
+            if (ArmSystem::haveEL(tc, EL2)){
+                v = testContextMatch(tc, true);
+                if (v && !from_link)
+                v = v && testVMIDMatch(tc);
+            }
+            break;
+        case 0xb:
+            if (from_link && ArmSystem::haveEL(tc, EL2)){
+                v = testContextMatch(tc, true);
+                v = v && testVMIDMatch(tc);
+            }
+            break;
+        case 0xc:
+            // VHE not implemented
+            // v = testContextMatch(tc, false); // CONTEXTIDR_EL2
+            break;
+        case 0xd:
+            // VHE not implemented
+            // if (from_link)
+            //     v = testContextMatch(tc, false);
+            // CONTEXTIDR_EL2 AND LINKED
+
+            break;
+       case 0xe:
+            // VHE not implemented
+            // v = testContextMatch(tc, true); // CONTEXTIDR_EL1
+            // v = v && testContextMatch(tc, false); // CONTEXTIDR_EL2
+            break;
+        case 0xf:
+            // VHE not implemented
+            // if (from_link){
+            //     v = testContextMatch(tc, true); // CONTEXTIDR_EL1
+            //     v = v && testContextMatch(tc, false); // CONTEXTIDR_EL2
+            // }
+            break;
+    }
+    return v;
+}
+
+bool
+BrkPoint::testAddrMatch(ThreadContext *tc, Addr in_pc, uint8_t bas)
+{
+    Addr pc_tocmp = getAddrfromReg(tc);
+    Addr pc = bits(in_pc, maxAddrSize, 2);
+
+    bool prs = true;
+    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+    bool thumb = cpsr.t;
+
+    if (thumb){
+        if (bas == 0xc)
+            prs = bits(in_pc, 1, 0) == 0x2;
+        else if (bas == 0x3)
+            prs = bits(in_pc, 1, 0) == 0x0;
+    }
+    return (pc == pc_tocmp) && prs;
+}
+
+bool
+BrkPoint::testAddrMissMatch(ThreadContext *tc, Addr in_pc, uint8_t bas)
+{
+    if (bas == 0x0)
+        return true;
+    Addr pc_tocmp = getAddrfromReg(tc);
+    Addr pc = bits(in_pc, maxAddrSize, 2);
+    bool prs = false;
+    CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+    bool thumb = cpsr.t;
+
+    if (thumb){
+        if (bas == 0xc)
+            prs = bits(in_pc, 1, 0) == 0x2;
+        else if (bas == 0x3)
+            prs = bits(in_pc, 1, 0) == 0x0;
+    }
+    return (pc != pc_tocmp) && !prs;
+}
+
+bool
+BrkPoint::testContextMatch(ThreadContext *tc, bool ctx1)
+{
+    if (!isCntxtAware)
+        return false;
+    MiscRegIndex miscridx;
+    ExceptionLevel el = currEL(tc);
+    bool a32 = conf->isAArch32();
+
+    if (ctx1){
+        miscridx = a32? MISCREG_CONTEXTIDR: MISCREG_CONTEXTIDR_EL1;
+        if ((el == EL3 && !a32) || el ==EL2)
+            return false;
+    }else{
+        miscridx = MISCREG_CONTEXTIDR_EL2;
+        if (el == EL2 && a32)
+            return false;
+    }
+
+    RegVal ctxid = tc->readMiscReg(miscridx);
+    RegVal v = getContextfromReg(tc, ctx1);
+    return (v== ctxid);
+}
+
+bool
+BrkPoint::testVMIDMatch(ThreadContext *tc)
+{
+    uint32_t vmid_index = 55;
+    if (VMID16enabled)
+        vmid_index = 63;
+    ExceptionLevel el = currEL(tc);
+    if (el == EL2)
+        return false;
+
+ uint32_t vmid = bits(tc->readMiscReg(MISCREG_VTTBR_EL2), vmid_index, 48);
+    uint32_t v = getVMIDfromReg(tc);
+    return (v == vmid);
+}
+
+
+bool
+BrkPoint::isEnabled(ThreadContext* tc, ExceptionLevel el,
+                    uint8_t hmc, uint8_t ssc, uint8_t pmc){
+    bool v;
+    bool aarch32 = conf->isAArch32();
+    bool noEL2 = !ArmSystem::haveEL(tc, EL2);
+    bool noEL3 = !ArmSystem::haveEL(tc, EL3);
+
+    if (noEL3 && !noEL2 && (ssc==0x1 || ssc==0x2)
+            && !(hmc && ssc == 0x1 && pmc==0x0)){
+        return false;
+    }
+    else if (noEL3 && noEL2 &&( hmc != 0x0 || ssc !=0x0)
+            && !(!aarch32 && ((hmc && ssc == 0x1  && pmc == 0x0)
+                    || ssc == 0x3))){
+        return false;
+    }
+    else if (noEL2 && hmc && ssc == 0x3 && pmc == 0x0){
+        return false;
+    }
+    else if (ssc == 0x11 && pmc==0x1 &&
+        !(!aarch32 && hmc && ssc == 0x3 &&pmc == 0x0)){
+        // AND secureEL2 not implemented
+        return false;
+    }
+ else if (hmc && ssc == 0x1 && pmc == 0x0){//AND secureEL2 not implemented
+        return false;
+    }
+    switch (el) {
+        case EL0:
+            v = (pmc == 0x3) || (pmc == 0x2 && hmc == 0x0) ;
+            if (aarch32)
+                v = v || (pmc == 0x0 && ssc != 0x3 && hmc == 0x0);
+            if (v && ssc == 0x3)
+                panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
+            break;
+        case EL1:
+            v = (pmc == 0x3) || (pmc == 0x1);
+            if (aarch32)
+                v = v || (pmc == 0x0 && hmc == 0x0 && ssc !=0x3);
+            break;
+        case EL2:
+            v = (ssc == 0x3) ||
+                ((hmc == 0x1) && !((ssc==0x2) && (pmc = 0x0)));
+            if (v && pmc == 0x2)
+                panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
+            break;
+        case EL3:
+            if (ssc == 0x1)
+                panic("Unexpected EL in SelfDebug::isDebugEnabled.\n");
+            v = (hmc == 0x1) & (ssc != 0x3);
+            break;
+        default:
+            panic("Unexpected EL %d in BrkPoint::isEnabled.\n", el);
+    }
+    return v && SelfDebug::securityStateMatch(tc, ssc, hmc || !aarch32);
+}
+
+uint32_t
+BrkPoint::getVMIDfromReg(ThreadContext *tc)
+{
+    uint32_t vmid_index = 39;
+    if (VMID16enabled)
+        vmid_index = 47;
+    return bits(tc->readMiscReg(valRegIndex), vmid_index, 32);
+}
+
diff --git a/src/arch/arm/self_debug.hh b/src/arch/arm/self_debug.hh
new file mode 100644
index 0000000..ca03668
--- /dev/null
+++ b/src/arch/arm/self_debug.hh
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2019 Metempsy Technology LSC
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Jordi Vaquero
+ */
+
+#ifndef __ARCH_ARM_SELF_DEBUG_HH__
+#define __ARCH_ARM_SELF_DEBUG_HH__
+
+
+#include "arch/arm/faults.hh"
+#include "arch/arm/miscregs.hh"
+#include "arch/arm/system.hh"
+#include "arch/arm/types.hh"
+#include "arch/arm/utility.hh"
+#include "cpu/thread_context.hh"
+
+class ThreadContext;
+
+
+namespace ArmISA
+{
+
+
+class SelfDebug;
+
+class BrkPoint
+{
+  private:
+    MiscRegIndex ctrlRegIndex;
+    MiscRegIndex valRegIndex;
+    MiscRegIndex xRegIndex;
+    SelfDebug * conf;
+    bool isCntxtAware;
+    bool VMID16enabled;
+    Addr active_pc;
+    bool enable;
+    int maxAddrSize;
+    bool onUse;
+
+    inline int getMaxAddrSize()
+    {
+        return maxAddrSize;
+    }
+
+  public:
+    BrkPoint(MiscRegIndex _ctrlIndex, MiscRegIndex _valIndex,
+             MiscRegIndex _xIndex, SelfDebug* _conf, bool _ctxAw, bool lva,
+             bool vmid16, bool aarch32):
+                ctrlRegIndex(_ctrlIndex), valRegIndex(_valIndex),
+                xRegIndex(_xIndex), conf(_conf), isCntxtAware(_ctxAw),
+                VMID16enabled(vmid16), active_pc(0x0), enable(false)
+    {
+        maxAddrSize = lva ? 52: 48 ;
+        maxAddrSize = aarch32 ? 31 : maxAddrSize;
+        onUse=false;
+    }
+    void setOnUse()
+    {
+        onUse = true;
+    }
+    void unsetOnUse()
+    {
+        onUse = false;
+    }
+    bool isSet()
+    {
+        return onUse;
+    }
+    bool testLinkedBk(ThreadContext *tc, Addr vaddr, ExceptionLevel el);
+    bool test(ThreadContext *tc, Addr pc, ExceptionLevel el, DBGBCR ctr,
+              bool from_link);
+
+  protected:
+    inline Addr getAddrfromReg(ThreadContext *tc)
+    {
+        return bits(tc->readMiscReg(valRegIndex), maxAddrSize, 2);
+    }
+
+    inline RegVal getContextfromReg(ThreadContext *tc, bool ctxid1)
+    {
+        if (ctxid1)
+            return bits(tc->readMiscReg(valRegIndex), 31, 0);
+        else
+            return bits(tc->readMiscReg(valRegIndex), 63, 32);
+    }
+
+
+    inline uint32_t getVMIDfromReg(ThreadContext *tc);
+
+  public:
+    bool testAddrMatch(ThreadContext *tc, Addr pc, uint8_t bas);
+    bool testAddrMissMatch(ThreadContext *tc, Addr pc, uint8_t bas);
+    bool testContextMatch(ThreadContext *tc, bool ctx1);
+    bool testVMIDMatch(ThreadContext *tc);
+    const DBGBCR getControlReg(ThreadContext *tc)
+    {
+        const DBGBCR ctr = tc->readMiscReg(ctrlRegIndex);
+        return ctr;
+    }
+    bool isEnabled(ThreadContext* tc, ExceptionLevel el,
+                   uint8_t hmc, uint8_t ssc, uint8_t pmc);
+    bool isActive(Addr vaddr)
+    {
+        if (vaddr==active_pc){
+            active_pc = 0x0;
+            return false;
+        }else{
+            active_pc = vaddr;
+            return true;
+        }
+    }
+    inline void updateControl(DBGBCR val)
+    {
+        enable = val.e == 0x1;
+    }
+    bool getEnable()
+    {
+        return enable;
+    }
+
+};
+
+
+class SelfDebug
+{
+  private:
+    std::vector<BrkPoint> arBrkPoints;
+
+    bool initialized;
+    bool enableTdeTge; // MDCR_EL2.TDE || HCR_EL2.TGE
+
+    // THIS is MDSCR_EL1.MDE in aarch64 and DBGDSCRext.MDBGen in aarch32
+    bool enableFlag;
+
+    bool bSDD; // MDCR_EL3.SDD
+    bool bKDE; // MDSCR_EL1.KDE
+    bool oslk; // OS lock flag
+
+    bool aarch32; // updates with stage1 aarch64/32
+    bool to32;
+
+  public:
+    SelfDebug(): initialized(false), enableTdeTge(false),
+                 enableFlag(false), bSDD(false), bKDE(false), oslk(false)
+    {}
+
+    ~SelfDebug(){}
+
+    Fault testBreakPoints(ThreadContext *tc, Addr vaddr);
+    Fault triggerException(ThreadContext * tc, Addr vaddr);
+
+    inline BrkPoint* getBrkPoint(uint8_t index)
+    {
+        return &arBrkPoints[index];
+    }
+
+    static inline bool
+    securityStateMatch(ThreadContext *tc, uint8_t ssc, bool hmc)
+    {
+        switch(ssc)
+        {
+            case 0x0: return true;
+            case 0x1: return !inSecureState(tc);
+            case 0x2: return inSecureState(tc);
+            case 0x3:
+                {
+                    bool b = hmc? true: inSecureState(tc);
+                    return b;
+                }
+            default: panic("Unreachable value");
+        }
+        return false;
+    }
+
+    bool isDebugEnabledForEL64(ThreadContext *tc, ExceptionLevel el,
+                             bool secure, bool mask)
+    {
+        bool route_to_el2 =  ArmSystem::haveEL(tc, EL2)
+                             && !secure && enableTdeTge;
+        ExceptionLevel target_el = route_to_el2? EL2 : EL1;
+        if (oslk || (bSDD && secure && ArmSystem::haveEL(tc, EL3))){
+            return false;
+        }
+        if (el == target_el){
+            return bKDE  && !mask;
+        }else{
+            return target_el > el;
+        }
+    }
+
+    bool isDebugEnabledForEL32(ThreadContext *tc, ExceptionLevel el,
+                             bool secure, bool mask)
+    {
+        if (el==EL0 && !ELStateUsingAArch32(tc, EL1, secure)){
+            return isDebugEnabledForEL64(tc, el, secure, mask);
+        }
+        if (oslk){
+            return false;
+        }
+
+        bool enabled;
+        if (secure && ArmSystem::haveEL(tc, EL3)){
+ // We ignore the check for invasive External debug checking SPIDEN
+            // and DBGEN signals. They are not implemented
+            bool spd32 = bits(tc->readMiscReg(MISCREG_MDCR_EL3), 14);
+            enabled = spd32;
+
+            bool suiden = bits(tc->readMiscReg(MISCREG_SDER), 0);
+            enabled  = el == EL0 ? (enabled || suiden) : enabled;
+        }
+        else
+        {
+            enabled = el != EL2;
+        }
+        return enabled;
+    }
+
+    void activateDebug()
+    {
+        for (auto &p: arBrkPoints){
+            p.unsetOnUse();
+        }
+    }
+
+    inline bool isDebugEnabled(ThreadContext *tc)
+    {
+        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+        ExceptionLevel el = (ExceptionLevel) currEL(tc);
+        if (aarch32){
+            return isDebugEnabledForEL32(tc, el, inSecureState(tc),
+                                         (bool)cpsr.d == 1);
+        }else{
+            return isDebugEnabledForEL64(tc, el, inSecureState(tc),
+                                         (bool)cpsr.d == 1 );
+        }
+    }
+
+    inline void setbSDD(RegVal val)
+    {
+        bSDD = bits(val, 16);
+    }
+
+    inline void setMDSCRvals(RegVal val)
+    {
+        enableFlag = bits(val, 15);
+        bKDE = bits(val, 13);
+    }
+
+    inline void setMDBGen(RegVal val)
+    {
+        enableFlag = bits(val, 15);
+    }
+
+    inline void setenableTDETGE(HCR hcr, HDCR mdcr)
+    {
+        enableTdeTge = (mdcr.tde == 0x1 || hcr.tge == 0x1);
+    }
+
+    inline void updateOSLock(RegVal val)
+    {
+        oslk = bool(bits(val, 0));
+    }
+
+    inline void updateDBGBCR(int index, DBGBCR val)
+    {
+        arBrkPoints[index].updateControl(val);
+    }
+
+    inline bool isAArch32()
+    {
+        return aarch32;
+    }
+
+    inline bool isTo32()
+    {
+        return to32;
+    }
+    inline void setAArch32(ThreadContext * tc)
+    {
+        ExceptionLevel fromEL = (ExceptionLevel) currEL(tc);
+        if (fromEL == EL0)
+            aarch32 = ELIs32(tc, EL0) && ELIs32(tc, EL1);
+        else
+            aarch32 = ELIs32(tc, fromEL);
+        return;
+    }
+
+    bool targetAArch32(ThreadContext * tc)
+    {
+        ExceptionLevel ELd = debugTargetFrom(tc, inSecureState(tc));
+        return ELIs32(tc, ELd) && aarch32;
+    }
+
+    void init(ThreadContext *tc)
+    {
+        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
+        aarch32 = cpsr.width == 1;
+
+        const AA64DFR0 dfr = tc->readMiscReg(MISCREG_ID_AA64DFR0_EL1);
+        const AA64MMFR2 mm_fr2 = tc->readMiscReg(MISCREG_ID_AA64MMFR2_EL1);
+        const AA64MMFR1 mm_fr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
+        const uint8_t nCtxtAwareBp = dfr.ctx_cmps;
+        const bool VMIDBits = mm_fr1.vmidbits;
+        for (int i=0; i<=dfr.brps; i++){
+            const bool isctxaw = i>=(dfr.brps-nCtxtAwareBp);
+
+            BrkPoint  bkp = BrkPoint((MiscRegIndex)(MISCREG_DBGBCR0_EL1+i),
+                                     (MiscRegIndex)(MISCREG_DBGBVR0_EL1+i),
+                                     (MiscRegIndex)(MISCREG_DBGBXVR0+i),
+                                     this, isctxaw, (bool)mm_fr2.varange,
+                                     VMIDBits, aarch32);
+            const DBGBCR ctr = tc->readMiscReg(MISCREG_DBGBCR0_EL1+i);
+
+            bkp.updateControl(ctr);
+            arBrkPoints.push_back(bkp);
+        }
+
+
+        initialized = true ;
+
+        RegVal oslar_el1 = tc->readMiscReg(MISCREG_OSLAR_EL1);
+        updateOSLock(oslar_el1);
+        // Initialize preloaded control booleans
+        uint64_t mdscr_el1 = tc->readMiscReg(MISCREG_MDSCR_EL1);
+        setMDSCRvals(mdscr_el1);
+
+        const uint64_t mdcr_el3 = tc->readMiscReg(MISCREG_MDCR_EL3);
+        setbSDD(mdcr_el3);
+
+        const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
+        const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+        setenableTDETGE(hcr, mdcr);
+
+    }
+};
+
+}
+#endif
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 1e4904c..b2c64e9 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1033,6 +1033,129 @@
 }

 Fault
+TLB::translateMmuOff(ThreadContext *tc, const RequestPtr &req, Mode mode,
+ TLB::ArmTranslationType tranType, Addr vaddr, bool long_desc_format)
+{
+     bool is_fetch  = (mode == Execute);
+     req->setPaddr(vaddr);
+     // When the MMU is off the security attribute corresponds to the
+     // security state of the processor
+     if (isSecure)
+         req->setFlags(Request::SECURE);
+
+     // @todo: double check this (ARM ARM issue C B3.2.1)
+     if (long_desc_format || sctlr.tre == 0 || nmrr.ir0 == 0 ||
+         nmrr.or0 == 0 || prrr.tr0 != 0x2) {
+         if (!req->isCacheMaintenance()) {
+             req->setFlags(Request::UNCACHEABLE);
+         }
+         req->setFlags(Request::STRICT_ORDER);
+     }
+
+     // Set memory attributes
+     TlbEntry temp_te;
+     temp_te.ns = !isSecure;
+     if (isStage2 || hcr.dc == 0 || isSecure ||
+        (isHyp && !(tranType & S1CTran))) {
+
+         temp_te.mtype      = is_fetch ? TlbEntry::MemoryType::Normal
+ : TlbEntry::MemoryType::StronglyOrdered;
+         temp_te.innerAttrs = 0x0;
+         temp_te.outerAttrs = 0x0;
+         temp_te.shareable  = true;
+         temp_te.outerShareable = true;
+     } else {
+         temp_te.mtype      = TlbEntry::MemoryType::Normal;
+         temp_te.innerAttrs = 0x3;
+         temp_te.outerAttrs = 0x3;
+         temp_te.shareable  = false;
+         temp_te.outerShareable = false;
+     }
+     temp_te.setAttributes(long_desc_format);
+     DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable: "
+             "%d, innerAttrs: %d, outerAttrs: %d, isStage2: %d\n",
+             temp_te.shareable, temp_te.innerAttrs, temp_te.outerAttrs,
+             isStage2);
+     setAttr(temp_te.attributes);
+
+     return testTranslation(req, mode, TlbEntry::DomainType::NoAccess);
+}
+
+Fault
+TLB::translateMmuOn(ThreadContext* tc, const RequestPtr &req, Mode mode,
+                    Translation *translation, bool &delay, bool timing,
+                    bool functional, Addr vaddr,
+                    ArmFault::TranMethod tranMethod)
+{
+
+    TlbEntry *te = NULL;
+    bool is_fetch  = (mode == Execute);
+    TlbEntry mergeTe;
+
+    Request::Flags flags = req->getFlags();
+    Addr vaddr_tainted = req->getVaddr();
+
+
+    Fault fault = getResultTe(&te, req, tc, mode, translation, timing,
+                              functional, &mergeTe);
+    // only proceed if we have a valid table entry
+    if ((te == NULL) && (fault == NoFault)) delay = true;
+
+    // If we have the table entry transfer some of the attributes to the
+    // request that triggered the translation
+    if (te != NULL) {
+        // Set memory attributes
+        DPRINTF(TLBVerbose,
+ "Setting memory attributes: shareable: %d, innerAttrs: %d, "
+                "outerAttrs: %d, mtype: %d, isStage2: %d\n",
+                te->shareable, te->innerAttrs, te->outerAttrs,
+                static_cast<uint8_t>(te->mtype), isStage2);
+        setAttr(te->attributes);
+
+        if (te->nonCacheable && !req->isCacheMaintenance())
+            req->setFlags(Request::UNCACHEABLE);
+
+        // Require requests to be ordered if the request goes to
+        // strongly ordered or device memory (i.e., anything other
+        // than normal memory requires strict order).
+        if (te->mtype != TlbEntry::MemoryType::Normal)
+            req->setFlags(Request::STRICT_ORDER);
+
+        Addr pa = te->pAddr(vaddr);
+        req->setPaddr(pa);
+
+        if (isSecure && !te->ns) {
+            req->setFlags(Request::SECURE);
+        }
+        if ((!is_fetch) && (vaddr & mask(flags & AlignmentMask)) &&
+            (te->mtype != TlbEntry::MemoryType::Normal)) {
+ // Unaligned accesses to Device memory should always cause an
+                // abort regardless of sctlr.a
+                alignFaults++;
+                bool is_write  = (mode == Write);
+                return std::make_shared<DataAbort>(
+                    vaddr_tainted,
+                    TlbEntry::DomainType::NoAccess, is_write,
+                    ArmFault::AlignmentFault, isStage2,
+                    tranMethod);
+        }
+
+        // Check for a trickbox generated address fault
+        if (fault == NoFault)
+            fault = testTranslation(req, mode, te->domain);
+    }
+
+    if (fault == NoFault) {
+        // Don't try to finalize a physical address unless the
+        // translation has completed (i.e., there is a table entry).
+        fault = te ? finalizePhysical(req, tc, mode) : NoFault;
+    }
+
+    return fault;
+}
+
+
+Fault
 TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
         Translation *translation, bool &delay, bool timing,
         TLB::ArmTranslationType tranType, bool functional)
@@ -1086,114 +1209,32 @@
         }
     }

+    Fault fault = NoFault;
     // If guest MMU is off or hcr.vm=0 go straight to stage2
     if ((isStage2 && !hcr.vm) || (!isStage2 && !sctlr.m)) {
-
-        req->setPaddr(vaddr);
-        // When the MMU is off the security attribute corresponds to the
-        // security state of the processor
-        if (isSecure)
-            req->setFlags(Request::SECURE);
-
-        // @todo: double check this (ARM ARM issue C B3.2.1)
-        if (long_desc_format || sctlr.tre == 0 || nmrr.ir0 == 0 ||
-            nmrr.or0 == 0 || prrr.tr0 != 0x2) {
-            if (!req->isCacheMaintenance()) {
-                req->setFlags(Request::UNCACHEABLE);
-            }
-            req->setFlags(Request::STRICT_ORDER);
+        fault = translateMmuOff(tc, req, mode, tranType, vaddr,
+                                long_desc_format);
+    }
+    else
+    {
+        DPRINTF(TLBVerbose, "Translating %s=%#x context=%d\n",
+                isStage2 ? "IPA" : "VA", vaddr_tainted, asid);
+        // Translation enabled
+        fault = translateMmuOn(tc, req, mode, translation, delay, timing,
+                               functional, vaddr, tranMethod);
+    }
+
+    //Check for Debug Exceptions
+    if (fault == NoFault)
+    {
+        SelfDebug * sd = (tc->getIsaPtr())->getSelfDebug();
+        if (mode == Execute)
+        {
+            fault = sd->testBreakPoints(tc, req->getVaddr());
         }
-
-        // Set memory attributes
-        TlbEntry temp_te;
-        temp_te.ns = !isSecure;
-        if (isStage2 || hcr.dc == 0 || isSecure ||
-           (isHyp && !(tranType & S1CTran))) {
-
-            temp_te.mtype      = is_fetch ? TlbEntry::MemoryType::Normal
- : TlbEntry::MemoryType::StronglyOrdered;
-            temp_te.innerAttrs = 0x0;
-            temp_te.outerAttrs = 0x0;
-            temp_te.shareable  = true;
-            temp_te.outerShareable = true;
-        } else {
-            temp_te.mtype      = TlbEntry::MemoryType::Normal;
-            temp_te.innerAttrs = 0x3;
-            temp_te.outerAttrs = 0x3;
-            temp_te.shareable  = false;
-            temp_te.outerShareable = false;
-        }
-        temp_te.setAttributes(long_desc_format);
- DPRINTF(TLBVerbose, "(No MMU) setting memory attributes: shareable: "
-                "%d, innerAttrs: %d, outerAttrs: %d, isStage2: %d\n",
-                temp_te.shareable, temp_te.innerAttrs, temp_te.outerAttrs,
-                isStage2);
-        setAttr(temp_te.attributes);
-
-        return testTranslation(req, mode, TlbEntry::DomainType::NoAccess);
     }

-    DPRINTF(TLBVerbose, "Translating %s=%#x context=%d\n",
-            isStage2 ? "IPA" : "VA", vaddr_tainted, asid);
-    // Translation enabled
-
-    TlbEntry *te = NULL;
-    TlbEntry mergeTe;
-    Fault fault = getResultTe(&te, req, tc, mode, translation, timing,
-                              functional, &mergeTe);
-    // only proceed if we have a valid table entry
-    if ((te == NULL) && (fault == NoFault)) delay = true;
-
-    // If we have the table entry transfer some of the attributes to the
-    // request that triggered the translation
-    if (te != NULL) {
-        // Set memory attributes
-        DPRINTF(TLBVerbose,
- "Setting memory attributes: shareable: %d, innerAttrs: %d, "
-                "outerAttrs: %d, mtype: %d, isStage2: %d\n",
-                te->shareable, te->innerAttrs, te->outerAttrs,
-                static_cast<uint8_t>(te->mtype), isStage2);
-        setAttr(te->attributes);
-
-        if (te->nonCacheable && !req->isCacheMaintenance())
-            req->setFlags(Request::UNCACHEABLE);
-
-        // Require requests to be ordered if the request goes to
-        // strongly ordered or device memory (i.e., anything other
-        // than normal memory requires strict order).
-        if (te->mtype != TlbEntry::MemoryType::Normal)
-            req->setFlags(Request::STRICT_ORDER);
-
-        Addr pa = te->pAddr(vaddr);
-        req->setPaddr(pa);
-
-        if (isSecure && !te->ns) {
-            req->setFlags(Request::SECURE);
-        }
-        if ((!is_fetch) && (vaddr & mask(flags & AlignmentMask)) &&
-            (te->mtype != TlbEntry::MemoryType::Normal)) {
- // Unaligned accesses to Device memory should always cause an
-                // abort regardless of sctlr.a
-                alignFaults++;
-                return std::make_shared<DataAbort>(
-                    vaddr_tainted,
-                    TlbEntry::DomainType::NoAccess, is_write,
-                    ArmFault::AlignmentFault, isStage2,
-                    tranMethod);
-        }
-
-        // Check for a trickbox generated address fault
-        if (fault == NoFault)
-            fault = testTranslation(req, mode, te->domain);
-    }
-
-    if (fault == NoFault) {
-        // Don't try to finalize a physical address unless the
-        // translation has completed (i.e., there is a table entry).
-        return te ? finalizePhysical(req, tc, mode) : NoFault;
-    } else {
-        return fault;
-    }
+    return fault;
 }

 Fault
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index ea78a21..8fa8b6c 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -44,6 +44,7 @@
 #define __ARCH_ARM_TLB_HH__


+#include "arch/arm/isa.hh"
 #include "arch/arm/isa_traits.hh"
 #include "arch/arm/pagetable.hh"
 #include "arch/arm/utility.hh"
@@ -351,6 +352,12 @@
         return _attr;
     }

+ Fault translateMmuOff(ThreadContext *tc, const RequestPtr &req, Mode mode, + TLB::ArmTranslationType tranType, Addr vaddr, bool long_desc_format); + Fault translateMmuOn(ThreadContext *tc, const RequestPtr &req, Mode mode, + Translation *translation, bool &delay, bool timing, bool functional,
+        Addr vaddr, ArmFault::TranMethod tranMethod);
+
     Fault translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
             Translation *translation, bool &delay,
bool timing, ArmTranslationType tranType, bool functional = false); diff --git a/src/arch/arm/tracers/tarmac_parser.cc b/src/arch/arm/tracers/tarmac_parser.cc
index cade9d3..39ac985 100644
--- a/src/arch/arm/tracers/tarmac_parser.cc
+++ b/src/arch/arm/tracers/tarmac_parser.cc
@@ -95,12 +95,32 @@
     { "dbgbvr3", MISCREG_DBGBVR3 },
     { "dbgbvr4", MISCREG_DBGBVR4 },
     { "dbgbvr5", MISCREG_DBGBVR5 },
+    { "dbgbvr6", MISCREG_DBGBVR6 },
+    { "dbgbvr7", MISCREG_DBGBVR7 },
+    { "dbgbvr8", MISCREG_DBGBVR8 },
+    { "dbgbvr9", MISCREG_DBGBVR9 },
+    { "dbgbvr10", MISCREG_DBGBVR10 },
+    { "dbgbvr11", MISCREG_DBGBVR11 },
+    { "dbgbvr12", MISCREG_DBGBVR12 },
+    { "dbgbvr13", MISCREG_DBGBVR13 },
+    { "dbgbvr14", MISCREG_DBGBVR14 },
+    { "dbgbvr15", MISCREG_DBGBVR15 },
     { "dbgbcr0", MISCREG_DBGBCR0 },
     { "dbgbcr1", MISCREG_DBGBCR1 },
     { "dbgbcr2", MISCREG_DBGBCR2 },
     { "dbgbcr3", MISCREG_DBGBCR3 },
     { "dbgbcr4", MISCREG_DBGBCR4 },
     { "dbgbcr5", MISCREG_DBGBCR5 },
+    { "dbgbcr6", MISCREG_DBGBCR6 },
+    { "dbgbcr7", MISCREG_DBGBCR7 },
+    { "dbgbcr8", MISCREG_DBGBCR8 },
+    { "dbgbcr9", MISCREG_DBGBCR9 },
+    { "dbgbcr10", MISCREG_DBGBCR10 },
+    { "dbgbcr11", MISCREG_DBGBCR11 },
+    { "dbgbcr12", MISCREG_DBGBCR12 },
+    { "dbgbcr13", MISCREG_DBGBCR13 },
+    { "dbgbcr14", MISCREG_DBGBCR14 },
+    { "dbgbcr15", MISCREG_DBGBCR15 },
     { "dbgwvr0", MISCREG_DBGWVR0 },
     { "dbgwvr1", MISCREG_DBGWVR1 },
     { "dbgwvr2", MISCREG_DBGWVR2 },
@@ -110,8 +130,22 @@
     { "dbgwcr2", MISCREG_DBGWCR2 },
     { "dbgwcr3", MISCREG_DBGWCR3 },
     { "dbgdrar", MISCREG_DBGDRAR },
+    { "dbgbxvr0", MISCREG_DBGBXVR0 },
+    { "dbgbxvr1", MISCREG_DBGBXVR1 },
+    { "dbgbxvr2", MISCREG_DBGBXVR2 },
+    { "dbgbxvr3", MISCREG_DBGBXVR3 },
     { "dbgbxvr4", MISCREG_DBGBXVR4 },
     { "dbgbxvr5", MISCREG_DBGBXVR5 },
+    { "dbgbxvr6", MISCREG_DBGBXVR6 },
+    { "dbgbxvr7", MISCREG_DBGBXVR7 },
+    { "dbgbxvr8", MISCREG_DBGBXVR8 },
+    { "dbgbxvr9", MISCREG_DBGBXVR9 },
+    { "dbgbxvr10", MISCREG_DBGBXVR10 },
+    { "dbgbxvr11", MISCREG_DBGBXVR11 },
+    { "dbgbxvr12", MISCREG_DBGBXVR12 },
+    { "dbgbxvr13", MISCREG_DBGBXVR13 },
+    { "dbgbxvr14", MISCREG_DBGBXVR14 },
+    { "dbgbxvr15", MISCREG_DBGBXVR15 },
     { "dbgoslar", MISCREG_DBGOSLAR },
     { "dbgoslsr", MISCREG_DBGOSLSR },
     { "dbgosdlr", MISCREG_DBGOSDLR },
@@ -356,12 +390,32 @@
     { "dbgbvr3_el1", MISCREG_DBGBVR3_EL1 },
     { "dbgbvr4_el1", MISCREG_DBGBVR4_EL1 },
     { "dbgbvr5_el1", MISCREG_DBGBVR5_EL1 },
+    { "dbgbvr6_el1", MISCREG_DBGBVR6_EL1 },
+    { "dbgbvr7_el1", MISCREG_DBGBVR7_EL1 },
+    { "dbgbvr8_el1", MISCREG_DBGBVR8_EL1 },
+    { "dbgbvr9_el1", MISCREG_DBGBVR9_EL1 },
+    { "dbgbvr10_el1", MISCREG_DBGBVR10_EL1 },
+    { "dbgbvr11_el1", MISCREG_DBGBVR11_EL1 },
+    { "dbgbvr12_el1", MISCREG_DBGBVR12_EL1 },
+    { "dbgbvr13_el1", MISCREG_DBGBVR13_EL1 },
+    { "dbgbvr14_el1", MISCREG_DBGBVR14_EL1 },
+    { "dbgbvr15_el1", MISCREG_DBGBVR15_EL1 },
     { "dbgbcr0_el1", MISCREG_DBGBCR0_EL1 },
     { "dbgbcr1_el1", MISCREG_DBGBCR1_EL1 },
     { "dbgbcr2_el1", MISCREG_DBGBCR2_EL1 },
     { "dbgbcr3_el1", MISCREG_DBGBCR3_EL1 },
     { "dbgbcr4_el1", MISCREG_DBGBCR4_EL1 },
     { "dbgbcr5_el1", MISCREG_DBGBCR5_EL1 },
+    { "dbgbcr6_el1", MISCREG_DBGBCR6_EL1 },
+    { "dbgbcr7_el1", MISCREG_DBGBCR7_EL1 },
+    { "dbgbcr8_el1", MISCREG_DBGBCR8_EL1 },
+    { "dbgbcr9_el1", MISCREG_DBGBCR9_EL1 },
+    { "dbgbcr10_el1", MISCREG_DBGBCR10_EL1 },
+    { "dbgbcr11_el1", MISCREG_DBGBCR11_EL1 },
+    { "dbgbcr12_el1", MISCREG_DBGBCR12_EL1 },
+    { "dbgbcr13_el1", MISCREG_DBGBCR13_EL1 },
+    { "dbgbcr14_el1", MISCREG_DBGBCR14_EL1 },
+    { "dbgbcr15_el1", MISCREG_DBGBCR15_EL1 },
     { "dbgwvr0_el1", MISCREG_DBGWVR0_EL1 },
     { "dbgwvr1_el1", MISCREG_DBGWVR1_EL1 },
     { "dbgwvr2_el1", MISCREG_DBGWVR2_EL1 },
diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh
index a608a20..4251292 100644
--- a/src/arch/arm/types.hh
+++ b/src/arch/arm/types.hh
@@ -646,6 +646,9 @@
         EC_FP_EXCEPTION            = 0x28,
         EC_FP_EXCEPTION_64         = 0x2C,
         EC_SERROR                  = 0x2F,
+        EC_HW_BREAKPOINT           = 0x30,
+        EC_HW_BREAKPOINT_LOWER_EL  = 0x30,
+        EC_HW_BREAKPOINT_CURR_EL   = 0x31,
         EC_SOFTWARE_BREAKPOINT     = 0x38,
         EC_SOFTWARE_BREAKPOINT_64  = 0x3C,
     };
diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc
index 5ab5645..bb4079b 100644
--- a/src/arch/arm/utility.cc
+++ b/src/arch/arm/utility.cc
@@ -210,7 +210,7 @@
         scr, tc->readMiscReg(MISCREG_CPSR));
 }

-inline bool
+bool
 isSecureBelowEL3(ThreadContext *tc)
 {
     SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
@@ -343,9 +343,45 @@
             (el == EL2 || (el == EL0 && hcr.tge == 1)));
 }

+ExceptionLevel
+debugTargetFrom(ThreadContext *tc, bool secure)
+{
+    bool route_to_el2;
+    if (ArmSystem::haveEL(tc, EL2) && !secure){
+        if (ELIs32(tc, EL2)){
+            const HCR hcr = tc->readMiscReg(MISCREG_HCR);
+            const HDCR hdcr  = tc->readMiscRegNoEffect(MISCREG_HDCR);
+            route_to_el2 = (hdcr.tde == 1 || hcr.tge == 1);
+        }else{
+            const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
+            const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+            route_to_el2 = (mdcr.tde == 1 || hcr.tge == 1);
+        }
+    }else{
+        route_to_el2 = false;
+    }
+    ExceptionLevel target;
+    if (route_to_el2) {
+        target = EL2;
+    }else if (ArmSystem::haveEL(tc, EL3) && !ArmSystem::highestELIs64(tc)
+              && secure){
+        target = EL3;
+    }else{
+        target = EL1;
+    }
+    return target;
+}
+
 std::pair<bool, bool>
 ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
 {
+    bool secure  = isSecureBelowEL3(tc);
+    return ELStateUsingAArch32K(tc, el, secure);
+}
+
+std::pair<bool, bool>
+ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure)
+{
     // Return true if the specified EL is in aarch32 state.
     const bool have_el3 = ArmSystem::haveSecurity(tc);
     const bool have_el2 = ArmSystem::haveVirtualization(tc);
@@ -369,8 +405,7 @@
         HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
         bool aarch32_at_el1 = (aarch32_below_el3
                                || (have_el2
-                               && !isSecureBelowEL3(tc) && hcr.rw == 0));
-
+                               && !secure && hcr.rw == 0));
         // Only know if EL0 using AArch32 from PSTATE
         if (el == EL0 && !aarch32_at_el1) {
             // EL0 controlled by PSTATE
@@ -388,6 +423,16 @@
     return std::make_pair(known, aarch32);
 }

+bool ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure)
+{
+
+    bool known, aarch32;
+    std::tie(known, aarch32) = ELStateUsingAArch32K(tc, el, secure);
+    panic_if(!known, "EL state is UNKNOWN");
+    return aarch32;
+}
+
+
 bool
 isBigEndian64(ThreadContext *tc)
 {
diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh
index 7ec44f8..008b834 100644
--- a/src/arch/arm/utility.hh
+++ b/src/arch/arm/utility.hh
@@ -188,6 +188,12 @@
 std::pair<bool, bool>
 ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el);

+std::pair<bool, bool>
+ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure);
+
+bool
+ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure);
+
 bool ELIs32(ThreadContext *tc, ExceptionLevel el);

 bool ELIs64(ThreadContext *tc, ExceptionLevel el);
@@ -198,6 +204,8 @@
  */
 bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);

+ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure);
+
 bool isBigEndian64(ThreadContext *tc);

 /**
@@ -265,7 +273,7 @@
  * Differs from inSecureState in that it ignores the current EL
  * or Mode in considering security state.
  */
-inline bool isSecureBelowEL3(ThreadContext *tc);
+bool isSecureBelowEL3(ThreadContext *tc);

 bool longDescFormatInUse(ThreadContext *tc);


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/23943
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I0e2a4be7f778de560c512253a9148da61e3e7e7a
Gerrit-Change-Number: 23943
Gerrit-PatchSet: 1
Gerrit-Owner: Jordi Vaquero <jordi.vaqu...@metempsy.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to