arch-arm: Implementation of Hardware Breakpoint exception
authorJordi Vaquero <jordi.vaquero@metempsy.com>
Tue, 11 Feb 2020 16:22:25 +0000 (17:22 +0100)
committerJordi Vaquero <jordi.vaquero@metempsy.com>
Mon, 22 Jun 2020 19:27:31 +0000 (19:27 +0000)
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
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27967
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
18 files changed:
src/arch/arm/ArmISA.py
src/arch/arm/SConscript
src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/insts/static_inst.cc
src/arch/arm/insts/static_inst.hh
src/arch/arm/isa.cc
src/arch/arm/isa.hh
src/arch/arm/miscregs.cc
src/arch/arm/miscregs.hh
src/arch/arm/miscregs_types.hh
src/arch/arm/self_debug.cc [new file with mode: 0644]
src/arch/arm/self_debug.hh [new file with mode: 0644]
src/arch/arm/tlb.cc
src/arch/arm/tracers/tarmac_parser.cc
src/arch/arm/types.hh
src/arch/arm/utility.cc
src/arch/arm/utility.hh

index 2641ec3fb3391c5229d0a4a2096de7c59c5512ec..b030e6c947a753acf1409618a9c1ecbef330ad17 100644 (file)
@@ -90,8 +90,8 @@ class ArmISA(BaseISA):
     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,
index 73ebcacf200d1e9267b8ed1f9e3f0cb5eebf6542..3f34216471aa95115eefba66eb4de1a7998be25b 100644 (file)
@@ -85,6 +85,7 @@ if env['TARGET_ISA'] == 'arm':
     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')
index 22894f3ef1c3638b8431e441ddda129e2bcadadd..ba8369ac53396c815565080bce3fa8e060a36ddd 100644 (file)
@@ -281,6 +281,10 @@ template<> ArmFault::FaultVals ArmFaultVals<SoftwareBreakpoint>::vals(
     "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,
@@ -1075,6 +1079,16 @@ AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst)
         } 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);
@@ -1277,9 +1291,10 @@ PrefetchAbort::routeToHyp(ThreadContext *tc) const
     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;
 }
 
@@ -1600,6 +1615,59 @@ SoftwareBreakpoint::ec(ThreadContext *tc) const
     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");
index 1d8f782d71f22ac3a37b6f3c8ea7388bf438a4ff..2db0e8d40116a0f3208723f80b953759847f5727 100644 (file)
@@ -149,6 +149,12 @@ class ArmFault : public FaultBase
         UnknownTran
     };
 
+    enum DebugType
+    {
+        NODEBUG = 0,
+        BRKPOINT,
+    };
+
     struct FaultVals
     {
         const FaultName name;
@@ -428,14 +434,16 @@ class AbortFault : public ArmFaultVals<T>
     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;
@@ -461,9 +469,10 @@ class PrefetchAbort : public AbortFault<PrefetchAbort>
     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;
@@ -590,6 +599,18 @@ class SoftwareBreakpoint : public ArmFaultVals<SoftwareBreakpoint>
     ExceptionClass ec(ThreadContext *tc) const override;
 };
 
+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>
 {
@@ -630,6 +651,7 @@ template<> ArmFault::FaultVals ArmFaultVals<PCAlignmentFault>::vals;
 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;
 
 /**
index 9966b9ee522544775fb3bceb684b7c5010db0761..f23cc797819a95af564b79c810ce71e40065ef1f 100644 (file)
@@ -640,7 +640,10 @@ ArmStaticInst::softwareBreakpoint32(ExecContext *xc, uint16_t imm) const
     } else {
         // Execute AArch32 Software Breakpoint
         return std::make_shared<PrefetchAbort>(readPC(xc),
-                                               ArmFault::DebugEvent);
+                                               ArmFault::DebugEvent,
+                                               false,
+                                               ArmFault::UnknownTran,
+                                               ArmFault::BRKPOINT);
     }
 }
 
index bee39036b4a648e1a130abeee9d07745e8393d5a..82bf61d0fb5645a7af004772fba5a588e41a6ba0 100644 (file)
@@ -45,6 +45,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"
@@ -198,6 +200,14 @@ class ArmStaticInst : public StaticInst
     std::string generateDisassembly(
             Addr pc, const Loader::SymbolTable *symtab) const override;
 
+    static void
+    activateBreakpoint(ThreadContext *tc)
+    {
+        auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
+        SelfDebug * sd = isa->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)
@@ -209,6 +219,9 @@ class ArmStaticInst : public StaticInst
 
         uint32_t bitMask = 0;
 
+        if (affectState && byteMask==0xF){
+            activateBreakpoint(tc);
+        }
         if (bits(byteMask, 3)) {
             unsigned lowIdx = affectState ? 24 : 27;
             bitMask = bitMask | mask(31, lowIdx);
index 29c5538782f482f8be713862287268aaefa1e225..f88d2ef07960e35456442b3394949b89f42a816f 100644 (file)
@@ -40,6 +40,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"
@@ -105,6 +106,7 @@ ISA::ISA(Params *p) : BaseISA(p), system(NULL),
     const_cast<Enums::VecRegRenameMode&>(_vecRegRenameMode) =
         highestELIs64 ? Enums::Full : Enums::Elem;
 
+    selfDebug = new SelfDebug();
     initializeMiscRegMetadata();
     preUnflattenMiscReg();
 
@@ -426,6 +428,7 @@ ISA::startup()
         setupThreadContext();
 
     afterStartup = true;
+    selfDebug->init(tc);
 }
 
 void
@@ -698,7 +701,7 @@ ISA::readMiscReg(int misc_reg)
          */
         return 0x5 << 16;
       case MISCREG_DBGDSCRint:
-        return 0;
+        return readMiscRegNoEffect(MISCREG_DBGDSCRint);
       case MISCREG_ISR:
         {
             auto ic = dynamic_cast<ArmISA::Interrupts *>(
@@ -1047,11 +1050,172 @@ ISA::setMiscReg(int misc_reg, RegVal val)
                          (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
@@ -1868,7 +2032,6 @@ ISA::setMiscReg(int misc_reg, RegVal val)
           case MISCREG_DACR:
           case MISCREG_VTTBR:
           case MISCREG_SCR_EL3:
-          case MISCREG_HCR_EL2:
           case MISCREG_TCR_EL1:
           case MISCREG_TCR_EL2:
           case MISCREG_TCR_EL3:
@@ -1883,6 +2046,14 @@ ISA::setMiscReg(int misc_reg, RegVal val)
             getITBPtr(tc)->invalidateMiscReg();
             getDTBPtr(tc)->invalidateMiscReg();
             break;
+          case MISCREG_HCR_EL2:
+            {
+                const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+                selfDebug->setenableTDETGE((HCR)val, mdcr);
+                getITBPtr(tc)->invalidateMiscReg();
+                getDTBPtr(tc)->invalidateMiscReg();
+            }
+            break;
           case MISCREG_NZCV:
             {
                 CPSR cpsr = val;
@@ -2070,7 +2241,7 @@ ISA::setMiscReg(int misc_reg, RegVal val)
           case MISCREG_SPSR_EL1:
             {
                 RegVal spsr_mask = havePAN ?
-                    ~(0x5 << 21) : ~(0x7 << 21);
+                    ~(0x2 << 22) : ~(0x3 << 22);
 
                 newVal = val & spsr_mask;
                 break;
index e7c81802d8914de45d9c00287294a7c3935cdb29..be57f4115d5534a4afb0c34955322c0ef438a8a2 100644 (file)
@@ -44,6 +44,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"
@@ -106,6 +107,8 @@ namespace ArmISA
 
         bool afterStartup;
 
+        SelfDebug * selfDebug;
+
         /** MiscReg metadata **/
         struct MiscRegLUTEntry {
             uint32_t lower;  // Lower half mapped to this register
@@ -462,6 +465,10 @@ namespace ArmISA
         void initID64(const ArmISAParams *p);
 
       public:
+        SelfDebug * getSelfDebug()
+        {
+            return selfDebug;
+        }
         RegVal readMiscRegNoEffect(int misc_reg) const;
         RegVal readMiscReg(int misc_reg);
         void setMiscRegNoEffect(int misc_reg, RegVal val);
index 3c80de4bf60f4f5c3c8fa7751877eefff83f2bb2..86b3aaa947960de5272b03f071ff32f29e838854 100644 (file)
@@ -63,6 +63,90 @@ decodeCP14Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
                     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:
@@ -79,6 +163,59 @@ decodeCP14Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
         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:
@@ -238,6 +375,9 @@ decodeCP15Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
                   case 2:
                     return MISCREG_NSACR;
                 }
+            } else if (crm == 3) {
+                if ( opc2 == 1)
+                    return MISCREG_SDCR;
             }
         } else if (opc1 == 4) {
             if (crm == 0) {
@@ -1562,6 +1702,82 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                     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;
                 }
@@ -3087,8 +3303,6 @@ ISA::initializeMiscRegMetadata()
       .unimplemented()
       .allPrivileges();
     InitReg(MISCREG_DBGDSCRext)
-      .unimplemented()
-      .warnNotFail()
       .allPrivileges();
     InitReg(MISCREG_DBGDTRTXext)
       .unimplemented()
@@ -3097,41 +3311,69 @@ ISA::initializeMiscRegMetadata()
       .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();
@@ -3159,20 +3401,47 @@ ISA::initializeMiscRegMetadata()
     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);
+       .allPrivileges().monSecureRead(0).monNonSecureRead(0);
     InitReg(MISCREG_DBGOSLSR)
-      .unimplemented()
       .allPrivileges().monSecureWrite(0).monNonSecureWrite(0);
     InitReg(MISCREG_DBGOSDLR)
       .unimplemented()
+      .warnNotFail()
       .allPrivileges();
     InitReg(MISCREG_DBGPRCR)
       .unimplemented()
@@ -3298,6 +3567,8 @@ ISA::initializeMiscRegMetadata()
       .secure().exceptUserMode();
     InitReg(MISCREG_CPACR)
       .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_SDCR)
+      .mon();
     InitReg(MISCREG_SCR)
       .mon().secure().exceptUserMode()
       .res0(0xff40)  // [31:16], [6]
@@ -3900,41 +4171,101 @@ ISA::initializeMiscRegMetadata()
       .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);
@@ -4179,7 +4510,8 @@ ISA::initializeMiscRegMetadata()
     InitReg(MISCREG_CPTR_EL3)
       .mon();
     InitReg(MISCREG_MDCR_EL3)
-      .mon();
+      .mon()
+      .mapsTo(MISCREG_SDCR);
     InitReg(MISCREG_TTBR0_EL1)
       .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_TTBR0_NS);
index 550b51cd900f4762192af02e8d864f6d996fe32f..1f053e35d0d5d2cd74aca436568a923bee7258ea 100644 (file)
@@ -105,12 +105,32 @@ namespace ArmISA
         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,
@@ -120,8 +140,22 @@ namespace ArmISA
         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,
@@ -175,6 +209,7 @@ namespace ArmISA
         MISCREG_ACTLR_NS,
         MISCREG_ACTLR_S,
         MISCREG_CPACR,
+        MISCREG_SDCR,
         MISCREG_SCR,
         MISCREG_SDER,
         MISCREG_NSACR,
@@ -396,12 +431,32 @@ namespace ArmISA
         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,
@@ -1082,12 +1137,32 @@ namespace ArmISA
         "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",
@@ -1097,8 +1172,22 @@ namespace ArmISA
         "dbgwcr2",
         "dbgwcr3",
         "dbgdrar",
+        "dbgbxvr0",
+        "dbgbxvr1",
+        "dbgbxvr2",
+        "dbgbxvr3",
         "dbgbxvr4",
         "dbgbxvr5",
+        "dbgbxvr6",
+        "dbgbxvr7",
+        "dbgbxvr8",
+        "dbgbxvr9",
+        "dbgbxvr10",
+        "dbgbxvr11",
+        "dbgbxvr12",
+        "dbgbxvr13",
+        "dbgbxvr14",
+        "dbgbxvr15",
         "dbgoslar",
         "dbgoslsr",
         "dbgosdlr",
@@ -1152,6 +1241,7 @@ namespace ArmISA
         "actlr_ns",
         "actlr_s",
         "cpacr",
+        "sdrc",
         "scr",
         "sder",
         "nsacr",
@@ -1371,12 +1461,32 @@ namespace ArmISA
         "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",
index cbc7adb16b5edaae5e0596a47705a1308a5715c5..642fa6eedf5afba97882edc79da56ceb97d4b2c0 100644 (file)
@@ -676,6 +676,51 @@ namespace ArmISA
         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 (file)
index 0000000..5234be4
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * 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.
+ */
+
+#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)
+{
+    if (!enableFlag)
+        return NoFault;
+
+    setAArch32(tc);
+
+    to32 = targetAArch32(tc);
+
+    init(tc);
+
+    if (!isDebugEnabled(tc))
+        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
+SelfDebug::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
+SelfDebug::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;
+}
+
+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 (file)
index 0000000..4453e7c
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * 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.
+ */
+
+#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;
+
+  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 isDebugEnabledForEL32(ThreadContext *tc, ExceptionLevel el,
+                             bool secure, bool mask);
+
+    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)
+    {
+        if (initialized)
+            return;
+        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
index 84160bba845b9363d5044e68eb592c734785facb..a00cba85725489c8b4915fe37bbf71c2189c1954 100644 (file)
@@ -45,7 +45,9 @@
 #include <vector>
 
 #include "arch/arm/faults.hh"
+#include "arch/arm/isa.hh"
 #include "arch/arm/pagetable.hh"
+#include "arch/arm/self_debug.hh"
 #include "arch/arm/stage2_lookup.hh"
 #include "arch/arm/stage2_mmu.hh"
 #include "arch/arm/system.hh"
@@ -1177,17 +1179,29 @@ TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
         }
     }
 
+    Fault fault = NoFault;
     // If guest MMU is off or hcr.vm=0 go straight to stage2
     if ((isStage2 && !hcr.vm) || (!isStage2 && !sctlr.m)) {
-        return translateMmuOff(tc, req, mode, tranType, vaddr,
-                               long_desc_format);
+        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
-        return translateMmuOn(tc, req, mode, translation, delay, timing,
-                              functional, vaddr, tranMethod);
+        fault = translateMmuOn(tc, req, mode, translation, delay, timing,
+                               functional, vaddr, tranMethod);
     }
+
+    //Check for Debug Exceptions
+    if (fault == NoFault) {
+        auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
+        SelfDebug * sd = isa->getSelfDebug();
+        if (mode == Execute) {
+            fault = sd->testBreakPoints(tc, req->getVaddr());
+        }
+    }
+
+    return fault;
 }
 
 Fault
index 96678b07b416579e1442e1489f5acb903e5fb763..fa7f1be84db705986031edf6cda343a9e06c4201 100644 (file)
@@ -93,12 +93,32 @@ TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
     { "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 },
@@ -108,8 +128,22 @@ TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
     { "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 },
@@ -354,12 +388,32 @@ TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
     { "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 },
index 83248b35149b57796d330aaed38f7d1e4fb862dc..0dd3dac9f3c9023bb280ac34960f66b87ee70ea7 100644 (file)
@@ -645,6 +645,9 @@ namespace ArmISA
         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,
     };
index 9947bdd28dc94204462d953a1f3d790468e92702..e72c2301a181ded5f2d249c0024a163856a383e9 100644 (file)
@@ -179,13 +179,42 @@ inSecureState(ThreadContext *tc)
         scr, tc->readMiscReg(MISCREG_CPSR));
 }
 
-inline bool
+bool
 isSecureBelowEL3(ThreadContext *tc)
 {
     SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
     return ArmSystem::haveEL(tc, EL3) && scr.ns == 0;
 }
 
+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;
+}
+
 bool
 inAArch64(ThreadContext *tc)
 {
@@ -358,6 +387,13 @@ ELIsInHost(ThreadContext *tc, ExceptionLevel el)
 
 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);
@@ -382,7 +418,7 @@ ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
         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) {
@@ -401,6 +437,15 @@ ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
     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(const ThreadContext *tc)
 {
index 231b8b957d7388d4e26119493ed6120dedc333db..87e51d97e1015993de39d8d47bb2672c698c5fc4 100644 (file)
@@ -172,6 +172,12 @@ bool EL2Enabled(ThreadContext *tc);
 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);
@@ -182,8 +188,10 @@ bool ELIs64(ThreadContext *tc, ExceptionLevel el);
  */
 bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);
 
+ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure);
 bool isBigEndian64(const ThreadContext *tc);
 
+
 /**
  * badMode is checking if the execution mode provided as an argument is
  * valid and implemented for AArch32
@@ -249,6 +257,8 @@ inSecureState(SCR scr, CPSR cpsr)
 
 bool inSecureState(ThreadContext *tc);
 
+bool isSecureBelowEL3(ThreadContext *tc);
+
 bool longDescFormatInUse(ThreadContext *tc);
 
 /** This helper function is either returing the value of