arch-arm: Implementation of ARMv8 SelfDebug Watchpoints
authorJordi Vaquero <jordi.vaquero@metempsy.com>
Tue, 29 Oct 2019 15:01:56 +0000 (16:01 +0100)
committerJordi Vaquero <jordi.vaquero@metempsy.com>
Mon, 29 Jun 2020 06:10:35 +0000 (06:10 +0000)
This change includes ArmV8 SelfDebug Watchpoint implementation
as is described in Armv8 Reference manual D2/G2
The changes specific descriptions are as follow:
+ ArmISA.py: Enable up to 16 DBGWn registers
+ isa.cc: Include in setMiscReg specific cases for DBGWCn registers enable bit
+ miscregs_types.hh: Define DBGWC bitwise types
+ miscregs.hh/cc: Definition of watchpoint registers and its initialization
+ tlb.cc: Call for watchpoint entry point on tlb translation for dtlb.
+ fault.cc/hh: Definition/implementation of Watchpoint exception and
               modification on DataAbort Exception accordingly to handle
               AArch32 Watchpoint exceptions.
+ types.hh: Exception Code for watchpoint.
+ self_debug.cc/hh: Watchpoint check and comparison. Definition and
                    implementation of all the watchpoint auxiliar functions.

Change-Id: If275e4df0d28918dd887ab78166e653da875310a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28589
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
13 files changed:
src/arch/arm/ArmISA.py
src/arch/arm/faults.cc
src/arch/arm/faults.hh
src/arch/arm/isa.cc
src/arch/arm/miscregs.cc
src/arch/arm/miscregs.hh
src/arch/arm/miscregs_types.hh
src/arch/arm/self_debug.cc
src/arch/arm/self_debug.hh
src/arch/arm/tlb.cc
src/arch/arm/tracers/tarmac_parser.cc
src/arch/arm/types.hh
src/arch/arm/utility.hh

index b030e6c947a753acf1409618a9c1ecbef330ad17..f701f7d151005915f14e6cd31c8e192ba0c85c5e 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 | 16 BRPs | !PMU | !Trace | Debug v8-A
-    id_aa64dfr0_el1 = Param.UInt64(0x000000000010F006,
+    # 1 CTX CMPs | 16 WRPs | 16 BRPs | !PMU | !Trace | Debug v8-A
+    id_aa64dfr0_el1 = Param.UInt64(0x0000000000F0F006,
         "AArch64 Debug Feature Register 0")
     # Reserved for future expansion
     id_aa64dfr1_el1 = Param.UInt64(0x0000000000000000,
index ba8369ac53396c815565080bce3fa8e060a36ddd..ce9675aee7aeff918e83af1c220ed8d165768eb3 100644 (file)
@@ -285,6 +285,10 @@ 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<Watchpoint>::vals(
+    "Watchpoint",   0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC,
+    0, 0, 0, 0, true, false, false,  EC_WATCHPOINT
+);
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals(
     // Some dummy values
     "ArmSev Flush",          0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC,
@@ -1084,6 +1088,9 @@ AbortFault<T>::invoke(ThreadContext *tc, const StaticInstPtr &inst)
             tc->setMiscReg(T::FarIndex, faultAddr);
             if (debug == ArmFault::BRKPOINT){
                 Rext.moe = 0x1;
+            } else if (debug > ArmFault::BRKPOINT) {
+                Rext.moe = 0xa;
+                fsr.cm = (debug == ArmFault::WPOINT_CM)? 1 : 0;
             }
 
             tc->setMiscReg(T::FsrIndex, fsr);
@@ -1354,10 +1361,10 @@ DataAbort::routeToHyp(ThreadContext *tc) const
     toHyp |= (stage2 ||
               ((currEL(tc) != EL2) &&
                (((source == AsynchronousExternalAbort) && hcr.amo) ||
-                ((source == DebugEvent) && hdcr.tde))) ||
-               ((currEL(tc) == EL0) && hcr.tge &&
-                ((source == AlignmentFault) ||
-                 (source == SynchronousExternalAbort)))) && !inSecureState(tc);
+                ((source == DebugEvent) && (hdcr.tde || hcr.tge)))) ||
+              ((currEL(tc) == EL0) && hcr.tge &&
+               ((source == AlignmentFault) ||
+                (source == SynchronousExternalAbort)))) && !inSecureState(tc);
     return toHyp;
 }
 
@@ -1668,6 +1675,70 @@ HardwareBreakpoint::invoke(ThreadContext *tc, const StaticInstPtr &inst)
 
 }
 
+Watchpoint::Watchpoint(ExtMachInst _mach_inst, Addr _vaddr,
+                       bool _write, bool _cm)
+    : ArmFaultVals<Watchpoint>(_mach_inst), vAddr(_vaddr),
+      write(_write), cm(_cm)
+{}
+
+uint32_t
+Watchpoint::iss() const
+{
+    uint32_t iss = 0x0022;
+// NV
+//    if (toEL == EL2)
+//        iss |= 0x02000;
+    if (cm)
+        iss |= 0x00100;
+    if (write)
+        iss |= 0x00040;
+    return iss;
+}
+
+void
+Watchpoint::invoke(ThreadContext *tc, const StaticInstPtr &inst)
+{
+    ArmFaultVals<Watchpoint>::invoke(tc, inst);
+    // Set the FAR
+    tc->setMiscReg(getFaultAddrReg64(), vAddr);
+
+}
+
+bool
+Watchpoint::routeToHyp(ThreadContext *tc) const
+{
+    const HCR hcr  = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
+    const HDCR mdcr  = tc->readMiscRegNoEffect(MISCREG_MDCR_EL2);
+
+    return fromEL == EL2 || (EL2Enabled(tc) && fromEL <= EL1 &&
+                             (hcr.tge || mdcr.tde));
+}
+
+void
+Watchpoint::annotate(AnnotationIDs id, uint64_t val)
+{
+    ArmFaultVals<Watchpoint>::annotate(id, val);
+    switch (id)
+    {
+      case OFA:
+        vAddr  = val;
+        break;
+      // Just ignore unknown ID's
+      default:
+        break;
+    }
+}
+
+ExceptionClass
+Watchpoint::ec(ThreadContext *tc) const
+{
+        // AArch64
+        if (toEL == fromEL)
+            return EC_WATCHPOINT_CURR_EL;
+        else
+            return EC_WATCHPOINT_LOWER_EL;
+}
+
 void
 ArmSev::invoke(ThreadContext *tc, const StaticInstPtr &inst) {
     DPRINTF(Faults, "Invoking ArmSev Fault\n");
@@ -1701,6 +1772,8 @@ template class ArmFaultVals<PCAlignmentFault>;
 template class ArmFaultVals<SPAlignmentFault>;
 template class ArmFaultVals<SystemError>;
 template class ArmFaultVals<SoftwareBreakpoint>;
+template class ArmFaultVals<HardwareBreakpoint>;
+template class ArmFaultVals<Watchpoint>;
 template class ArmFaultVals<ArmSev>;
 template class AbortFault<PrefetchAbort>;
 template class AbortFault<DataAbort>;
index 2db0e8d40116a0f3208723f80b953759847f5727..2e1f3387bd04cd4ab72c1051d38794573aec4ff4 100644 (file)
@@ -153,6 +153,8 @@ class ArmFault : public FaultBase
     {
         NODEBUG = 0,
         BRKPOINT,
+        WPOINT_CM,
+        WPOINT_NOCM
     };
 
     struct FaultVals
@@ -498,9 +500,11 @@ class DataAbort : public AbortFault<DataAbort>
     bool ar;
 
     DataAbort(Addr _addr, TlbEntry::DomainType _domain, bool _write, uint8_t _source,
-              bool _stage2 = false, ArmFault::TranMethod _tranMethod = ArmFault::UnknownTran) :
+              bool _stage2=false,
+              ArmFault::TranMethod _tranMethod=ArmFault::UnknownTran,
+              ArmFault::DebugType _debug_type=ArmFault::NODEBUG) :
         AbortFault<DataAbort>(_addr, _write, _domain, _source, _stage2,
-                              _tranMethod),
+                              _tranMethod, _debug_type),
         isv(false), sas (0), sse(0), srt(0), cm(0), sf(false), ar(false)
     {}
 
@@ -611,6 +615,23 @@ class HardwareBreakpoint : public ArmFaultVals<HardwareBreakpoint>
     ExceptionClass ec(ThreadContext *tc) const override;
 };
 
+class Watchpoint : public ArmFaultVals<Watchpoint>
+{
+  private:
+    Addr vAddr;
+    bool write;
+    bool cm;
+
+  public:
+    Watchpoint(ExtMachInst _mach_inst, Addr _vaddr, bool _write, bool _cm);
+    void invoke(ThreadContext *tc, const StaticInstPtr &inst =
+                StaticInst::nullStaticInstPtr) override;
+    bool routeToHyp(ThreadContext *tc) const override;
+    uint32_t iss() const override;
+    ExceptionClass ec(ThreadContext *tc) const override;
+    void annotate(AnnotationIDs id, uint64_t val);
+};
+
 // A fault that flushes the pipe, excluding the faulting instructions
 class ArmSev : public ArmFaultVals<ArmSev>
 {
@@ -652,6 +673,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<Watchpoint>::vals;
 template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals;
 
 /**
index a48b3495ff4ed891ae8858f6f91c3da6ddca24ee..07713be8a9e58951fdb125d06108cb980e2ab17f 100644 (file)
@@ -1127,6 +1127,54 @@ ISA::setMiscReg(int misc_reg, RegVal val)
           case MISCREG_DBGBCR15:
             selfDebug->updateDBGBCR(15, val);
             break;
+          case MISCREG_DBGWCR0:
+            selfDebug->updateDBGWCR(0, val);
+            break;
+          case MISCREG_DBGWCR1:
+            selfDebug->updateDBGWCR(1, val);
+            break;
+          case MISCREG_DBGWCR2:
+            selfDebug->updateDBGWCR(2, val);
+            break;
+          case MISCREG_DBGWCR3:
+            selfDebug->updateDBGWCR(3, val);
+            break;
+          case MISCREG_DBGWCR4:
+            selfDebug->updateDBGWCR(4, val);
+            break;
+          case MISCREG_DBGWCR5:
+            selfDebug->updateDBGWCR(5, val);
+            break;
+          case MISCREG_DBGWCR6:
+            selfDebug->updateDBGWCR(6, val);
+            break;
+          case MISCREG_DBGWCR7:
+            selfDebug->updateDBGWCR(7, val);
+            break;
+          case MISCREG_DBGWCR8:
+            selfDebug->updateDBGWCR(8, val);
+            break;
+          case MISCREG_DBGWCR9:
+            selfDebug->updateDBGWCR(9, val);
+            break;
+          case MISCREG_DBGWCR10:
+            selfDebug->updateDBGWCR(10, val);
+            break;
+          case MISCREG_DBGWCR11:
+            selfDebug->updateDBGWCR(11, val);
+            break;
+          case MISCREG_DBGWCR12:
+            selfDebug->updateDBGWCR(12, val);
+            break;
+          case MISCREG_DBGWCR13:
+            selfDebug->updateDBGWCR(13, val);
+            break;
+          case MISCREG_DBGWCR14:
+            selfDebug->updateDBGWCR(14, val);
+            break;
+          case MISCREG_DBGWCR15:
+            selfDebug->updateDBGWCR(15, val);
+            break;
 
           case MISCREG_MDCR_EL2:
             {
@@ -1217,6 +1265,54 @@ ISA::setMiscReg(int misc_reg, RegVal val)
           case MISCREG_DBGBCR15_EL1:
             selfDebug->updateDBGBCR(15, val);
             break;
+          case MISCREG_DBGWCR0_EL1:
+            selfDebug->updateDBGWCR(0, val);
+            break;
+          case MISCREG_DBGWCR1_EL1:
+            selfDebug->updateDBGWCR(1, val);
+            break;
+          case MISCREG_DBGWCR2_EL1:
+            selfDebug->updateDBGWCR(2, val);
+            break;
+          case MISCREG_DBGWCR3_EL1:
+            selfDebug->updateDBGWCR(3, val);
+            break;
+          case MISCREG_DBGWCR4_EL1:
+            selfDebug->updateDBGWCR(4, val);
+            break;
+          case MISCREG_DBGWCR5_EL1:
+            selfDebug->updateDBGWCR(5, val);
+            break;
+          case MISCREG_DBGWCR6_EL1:
+            selfDebug->updateDBGWCR(6, val);
+            break;
+          case MISCREG_DBGWCR7_EL1:
+            selfDebug->updateDBGWCR(7, val);
+            break;
+          case MISCREG_DBGWCR8_EL1:
+            selfDebug->updateDBGWCR(8, val);
+            break;
+          case MISCREG_DBGWCR9_EL1:
+            selfDebug->updateDBGWCR(9, val);
+            break;
+          case MISCREG_DBGWCR10_EL1:
+            selfDebug->updateDBGWCR(10, val);
+            break;
+          case MISCREG_DBGWCR11_EL1:
+            selfDebug->updateDBGWCR(11, val);
+            break;
+          case MISCREG_DBGWCR12_EL1:
+            selfDebug->updateDBGWCR(12, val);
+            break;
+          case MISCREG_DBGWCR13_EL1:
+            selfDebug->updateDBGWCR(13, val);
+            break;
+          case MISCREG_DBGWCR14_EL1:
+            selfDebug->updateDBGWCR(14, val);
+            break;
+          case MISCREG_DBGWCR15_EL1:
+            selfDebug->updateDBGWCR(15, val);
+            break;
           case MISCREG_IFSR:
             {
                 // ARM ARM (ARM DDI 0406C.b) B4.1.96
index 2bdbaa48d867628dc48106b491ed615f0694068d..2dd1d78e3bf5bf39ee6c335c4841e229b19c826c 100644 (file)
@@ -147,6 +147,79 @@ decodeCP14Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
                     return MISCREG_DBGBCR15;
                 }
                 break;
+              case 6:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGWVR0;
+                  case 1:
+                    return MISCREG_DBGWVR1;
+                  case 2:
+                    return MISCREG_DBGWVR2;
+                  case 3:
+                    return MISCREG_DBGWVR3;
+                  case 4:
+                    return MISCREG_DBGWVR4;
+                  case 5:
+                    return MISCREG_DBGWVR5;
+                  case 6:
+                    return MISCREG_DBGWVR6;
+                  case 7:
+                    return MISCREG_DBGWVR7;
+                  case 8:
+                    return MISCREG_DBGWVR8;
+                  case 9:
+                    return MISCREG_DBGWVR9;
+                  case 10:
+                    return MISCREG_DBGWVR10;
+                  case 11:
+                    return MISCREG_DBGWVR11;
+                  case 12:
+                    return MISCREG_DBGWVR12;
+                  case 13:
+                    return MISCREG_DBGWVR13;
+                  case 14:
+                    return MISCREG_DBGWVR14;
+                  case 15:
+                    return MISCREG_DBGWVR15;
+                    break;
+                }
+                break;
+              case 7:
+                switch (crm) {
+                  case 0:
+                    return MISCREG_DBGWCR0;
+                  case 1:
+                    return MISCREG_DBGWCR1;
+                  case 2:
+                    return MISCREG_DBGWCR2;
+                  case 3:
+                    return MISCREG_DBGWCR3;
+                  case 4:
+                    return MISCREG_DBGWCR4;
+                  case 5:
+                    return MISCREG_DBGWCR5;
+                  case 6:
+                    return MISCREG_DBGWCR6;
+                  case 7:
+                    return MISCREG_DBGWCR7;
+                  case 8:
+                    return MISCREG_DBGWCR8;
+                  case 9:
+                    return MISCREG_DBGWCR9;
+                  case 10:
+                    return MISCREG_DBGWCR10;
+                  case 11:
+                    return MISCREG_DBGWCR11;
+                  case 12:
+                    return MISCREG_DBGWCR12;
+                  case 13:
+                    return MISCREG_DBGWCR13;
+                  case 14:
+                    return MISCREG_DBGWCR14;
+                  case 15:
+                    return MISCREG_DBGWCR15;
+                }
+                break;
             }
             break;
           case 7:
@@ -1687,6 +1760,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR4_EL1;
                       case 5:
                         return MISCREG_DBGBCR4_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR4_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR4_EL1;
                     }
                     break;
                   case 5:
@@ -1695,6 +1772,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR5_EL1;
                       case 5:
                         return MISCREG_DBGBCR5_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR5_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR5_EL1;
                     }
                     break;
                   case 6:
@@ -1705,6 +1786,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR6_EL1;
                       case 5:
                         return MISCREG_DBGBCR6_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR6_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR6_EL1;
                     }
                     break;
                   case 7:
@@ -1713,6 +1798,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR7_EL1;
                       case 5:
                         return MISCREG_DBGBCR7_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR7_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR7_EL1;
                     }
                     break;
                   case 8:
@@ -1721,6 +1810,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR8_EL1;
                       case 5:
                         return MISCREG_DBGBCR8_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR8_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR8_EL1;
                     }
                     break;
                   case 9:
@@ -1729,6 +1822,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR9_EL1;
                       case 5:
                         return MISCREG_DBGBCR9_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR9_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR9_EL1;
                     }
                     break;
                   case 10:
@@ -1737,6 +1834,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR10_EL1;
                       case 5:
                         return MISCREG_DBGBCR10_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR10_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR10_EL1;
                     }
                     break;
                   case 11:
@@ -1745,6 +1846,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR11_EL1;
                       case 5:
                         return MISCREG_DBGBCR11_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR11_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR11_EL1;
                     }
                     break;
                   case 12:
@@ -1753,6 +1858,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR12_EL1;
                       case 5:
                         return MISCREG_DBGBCR12_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR12_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR12_EL1;
                     }
                     break;
                   case 13:
@@ -1761,6 +1870,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR13_EL1;
                       case 5:
                         return MISCREG_DBGBCR13_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR13_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR13_EL1;
                     }
                     break;
                   case 14:
@@ -1769,6 +1882,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR14_EL1;
                       case 5:
                         return MISCREG_DBGBCR14_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR14_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR14_EL1;
                     }
                     break;
                   case 15:
@@ -1777,6 +1894,10 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
                         return MISCREG_DBGBVR15_EL1;
                       case 5:
                         return MISCREG_DBGBCR15_EL1;
+                      case 6:
+                        return MISCREG_DBGWVR15_EL1;
+                      case 7:
+                        return MISCREG_DBGWCR15_EL1;
                     }
                     break;
                 }
@@ -3374,29 +3495,69 @@ ISA::initializeMiscRegMetadata()
     InitReg(MISCREG_DBGBCR15)
       .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWVR0)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWVR1)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWVR2)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWVR3)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR4)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR5)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR6)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR7)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR8)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR9)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR10)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR11)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR12)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR13)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR14)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWVR15)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWCR0)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWCR1)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWCR2)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGWCR3)
-      .unimplemented()
-      .allPrivileges();
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR4)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR5)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR6)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR7)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR8)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR9)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR10)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR11)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR12)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR13)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR14)
+      .allPrivileges().exceptUserMode();
+    InitReg(MISCREG_DBGWCR15)
+      .allPrivileges().exceptUserMode();
     InitReg(MISCREG_DBGDRAR)
       .unimplemented()
       .allPrivileges().monSecureWrite(0).monNonSecureWrite(0);
@@ -4266,29 +4427,101 @@ ISA::initializeMiscRegMetadata()
       .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGBCR15);
     InitReg(MISCREG_DBGWVR0_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWVR0);
     InitReg(MISCREG_DBGWVR1_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWVR1);
     InitReg(MISCREG_DBGWVR2_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWVR2);
     InitReg(MISCREG_DBGWVR3_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWVR3);
+    InitReg(MISCREG_DBGWVR4_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR4);
+    InitReg(MISCREG_DBGWVR5_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR5);
+    InitReg(MISCREG_DBGWVR6_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR6);
+    InitReg(MISCREG_DBGWVR7_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR7);
+    InitReg(MISCREG_DBGWVR8_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR8);
+    InitReg(MISCREG_DBGWVR9_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR9);
+    InitReg(MISCREG_DBGWVR10_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR10);
+    InitReg(MISCREG_DBGWVR11_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR11);
+    InitReg(MISCREG_DBGWVR12_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR12);
+    InitReg(MISCREG_DBGWVR13_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR13);
+    InitReg(MISCREG_DBGWVR14_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR14);
+    InitReg(MISCREG_DBGWVR15_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWVR15);
     InitReg(MISCREG_DBGWCR0_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWCR0);
     InitReg(MISCREG_DBGWCR1_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWCR1);
     InitReg(MISCREG_DBGWCR2_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWCR2);
     InitReg(MISCREG_DBGWCR3_EL1)
-      .allPrivileges()
+      .allPrivileges().exceptUserMode()
       .mapsTo(MISCREG_DBGWCR3);
+    InitReg(MISCREG_DBGWCR4_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR4);
+    InitReg(MISCREG_DBGWCR5_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR5);
+    InitReg(MISCREG_DBGWCR6_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR6);
+    InitReg(MISCREG_DBGWCR7_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR7);
+    InitReg(MISCREG_DBGWCR8_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR8);
+    InitReg(MISCREG_DBGWCR9_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR9);
+    InitReg(MISCREG_DBGWCR10_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR10);
+    InitReg(MISCREG_DBGWCR11_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR11);
+    InitReg(MISCREG_DBGWCR12_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR12);
+    InitReg(MISCREG_DBGWCR13_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR13);
+    InitReg(MISCREG_DBGWCR14_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR14);
+    InitReg(MISCREG_DBGWCR15_EL1)
+      .allPrivileges().exceptUserMode()
+      .mapsTo(MISCREG_DBGWCR15);
     InitReg(MISCREG_MDCCSR_EL0)
       .allPrivileges().monSecureWrite(0).monNonSecureWrite(0)
       .mapsTo(MISCREG_DBGDSCRint);
index 1f053e35d0d5d2cd74aca436568a923bee7258ea..ac5d68fa5f320b9769be868201fc45bb20e58b48 100644 (file)
@@ -135,10 +135,34 @@ namespace ArmISA
         MISCREG_DBGWVR1,
         MISCREG_DBGWVR2,
         MISCREG_DBGWVR3,
+        MISCREG_DBGWVR4,
+        MISCREG_DBGWVR5,
+        MISCREG_DBGWVR6,
+        MISCREG_DBGWVR7,
+        MISCREG_DBGWVR8,
+        MISCREG_DBGWVR9,
+        MISCREG_DBGWVR10,
+        MISCREG_DBGWVR11,
+        MISCREG_DBGWVR12,
+        MISCREG_DBGWVR13,
+        MISCREG_DBGWVR14,
+        MISCREG_DBGWVR15,
         MISCREG_DBGWCR0,
         MISCREG_DBGWCR1,
         MISCREG_DBGWCR2,
         MISCREG_DBGWCR3,
+        MISCREG_DBGWCR4,
+        MISCREG_DBGWCR5,
+        MISCREG_DBGWCR6,
+        MISCREG_DBGWCR7,
+        MISCREG_DBGWCR8,
+        MISCREG_DBGWCR9,
+        MISCREG_DBGWCR10,
+        MISCREG_DBGWCR11,
+        MISCREG_DBGWCR12,
+        MISCREG_DBGWCR13,
+        MISCREG_DBGWCR14,
+        MISCREG_DBGWCR15,
         MISCREG_DBGDRAR,
         MISCREG_DBGBXVR0,
         MISCREG_DBGBXVR1,
@@ -461,10 +485,34 @@ namespace ArmISA
         MISCREG_DBGWVR1_EL1,
         MISCREG_DBGWVR2_EL1,
         MISCREG_DBGWVR3_EL1,
+        MISCREG_DBGWVR4_EL1,
+        MISCREG_DBGWVR5_EL1,
+        MISCREG_DBGWVR6_EL1,
+        MISCREG_DBGWVR7_EL1,
+        MISCREG_DBGWVR8_EL1,
+        MISCREG_DBGWVR9_EL1,
+        MISCREG_DBGWVR10_EL1,
+        MISCREG_DBGWVR11_EL1,
+        MISCREG_DBGWVR12_EL1,
+        MISCREG_DBGWVR13_EL1,
+        MISCREG_DBGWVR14_EL1,
+        MISCREG_DBGWVR15_EL1,
         MISCREG_DBGWCR0_EL1,
         MISCREG_DBGWCR1_EL1,
         MISCREG_DBGWCR2_EL1,
         MISCREG_DBGWCR3_EL1,
+        MISCREG_DBGWCR4_EL1,
+        MISCREG_DBGWCR5_EL1,
+        MISCREG_DBGWCR6_EL1,
+        MISCREG_DBGWCR7_EL1,
+        MISCREG_DBGWCR8_EL1,
+        MISCREG_DBGWCR9_EL1,
+        MISCREG_DBGWCR10_EL1,
+        MISCREG_DBGWCR11_EL1,
+        MISCREG_DBGWCR12_EL1,
+        MISCREG_DBGWCR13_EL1,
+        MISCREG_DBGWCR14_EL1,
+        MISCREG_DBGWCR15_EL1,
         MISCREG_MDCCSR_EL0,
         MISCREG_MDDTR_EL0,
         MISCREG_MDDTRTX_EL0,
@@ -1167,10 +1215,34 @@ namespace ArmISA
         "dbgwvr1",
         "dbgwvr2",
         "dbgwvr3",
+        "dbgwvr4",
+        "dbgwvr5",
+        "dbgwvr6",
+        "dbgwvr7",
+        "dbgwvr8",
+        "dbgwvr9",
+        "dbgwvr10",
+        "dbgwvr11",
+        "dbgwvr12",
+        "dbgwvr13",
+        "dbgwvr14",
+        "dbgwvr15",
         "dbgwcr0",
         "dbgwcr1",
         "dbgwcr2",
         "dbgwcr3",
+        "dbgwcr4",
+        "dbgwcr5",
+        "dbgwcr6",
+        "dbgwcr7",
+        "dbgwcr8",
+        "dbgwcr9",
+        "dbgwcr10",
+        "dbgwcr11",
+        "dbgwcr12",
+        "dbgwcr13",
+        "dbgwcr14",
+        "dbgwcr15",
         "dbgdrar",
         "dbgbxvr0",
         "dbgbxvr1",
@@ -1491,10 +1563,34 @@ namespace ArmISA
         "dbgwvr1_el1",
         "dbgwvr2_el1",
         "dbgwvr3_el1",
+        "dbgwvr4_el1",
+        "dbgwvr5_el1",
+        "dbgwvr6_el1",
+        "dbgwvr7_el1",
+        "dbgwvr8_el1",
+        "dbgwvr9_el1",
+        "dbgwvr10_el1",
+        "dbgwvr11_el1",
+        "dbgwvr12_el1",
+        "dbgwvr13_el1",
+        "dbgwvr14_el1",
+        "dbgwvr15_el1",
         "dbgwcr0_el1",
         "dbgwcr1_el1",
         "dbgwcr2_el1",
         "dbgwcr3_el1",
+        "dbgwcr4_el1",
+        "dbgwcr5_el1",
+        "dbgwcr6_el1",
+        "dbgwcr7_el1",
+        "dbgwcr8_el1",
+        "dbgwcr9_el1",
+        "dbgwcr10_el1",
+        "dbgwcr11_el1",
+        "dbgwcr12_el1",
+        "dbgwcr13_el1",
+        "dbgwcr14_el1",
+        "dbgwcr15_el1",
         "mdccsr_el0",
         "mddtr_el0",
         "mddtrtx_el0",
index 642fa6eedf5afba97882edc79da56ceb97d4b2c0..301d6fb2effe71fb06c348fc60e1dab7f5f568ce 100644 (file)
@@ -697,6 +697,20 @@ namespace ArmISA
         Bitfield<0> e;
    EndBitUnion(DBGBCR)
 
+    BitUnion64(DBGWCR)
+        Bitfield<63, 29> res0_2;
+        Bitfield<28, 24> mask;
+        Bitfield<23, 21> res0_1;
+        Bitfield<20> wt;
+        Bitfield<19, 16> lbn;
+        Bitfield<15, 14> ssc;
+        Bitfield<13> hmc;
+        Bitfield<12, 5> bas;
+        Bitfield<4, 3> lsv;
+        Bitfield<2, 1> pac;
+        Bitfield<0> e;
+   EndBitUnion(DBGWCR)
+
    BitUnion32(DBGDS32)
         Bitfield<31> tfo;
         Bitfield<30> rxfull;
index 5234be44ecef93cfd14759ae895618e48914bb8a..85c6656bbbb8c5c43c6a5e528874a021470fa278 100644 (file)
@@ -94,6 +94,48 @@ SelfDebug::triggerException(ThreadContext * tc, Addr vaddr)
     }
 }
 
+Fault
+SelfDebug::testWatchPoints(ThreadContext *tc, Addr vaddr, bool write,
+                           bool atomic, unsigned size, bool cm)
+{
+    setAArch32(tc);
+    to32 = targetAArch32(tc);
+    if (!initialized)
+        init(tc);
+    if (!isDebugEnabled(tc) || !enableFlag)
+        return NoFault;
+
+    ExceptionLevel el = (ExceptionLevel) currEL(tc);
+    int idxtmp = -1;
+    for (auto &p: arWatchPoints){
+        idxtmp ++;
+        if (p.getEnable())
+        {
+            bool debug = p.test(tc, vaddr, el, write, atomic, size);
+            if (debug){
+                return triggerWatchpointException(tc, vaddr, write, cm);
+            }
+        }
+    }
+    return NoFault;
+}
+
+Fault
+SelfDebug::triggerWatchpointException(ThreadContext *tc, Addr vaddr,
+                                      bool write, bool cm)
+{
+    if (isTo32()) {
+        ArmFault::DebugType d = cm? ArmFault::WPOINT_CM:
+                                    ArmFault::WPOINT_NOCM;
+        return std::make_shared<DataAbort>(vaddr,
+                                           TlbEntry::DomainType::NoAccess,
+                                           write, ArmFault::DebugEvent, cm,
+                                           ArmFault::UnknownTran, d);
+    } else {
+        return std::make_shared<Watchpoint>(0, vaddr, write, cm);
+    }
+}
+
 bool
 SelfDebug::isDebugEnabledForEL64(ThreadContext *tc, ExceptionLevel el,
                          bool secure, bool mask)
@@ -386,3 +428,122 @@ BrkPoint::getVMIDfromReg(ThreadContext *tc)
     return bits(tc->readMiscReg(valRegIndex), vmid_index, 32);
 }
 
+
+bool
+WatchPoint::isEnabled(ThreadContext* tc, ExceptionLevel el,
+                      bool hmc, uint8_t ssc, uint8_t pac)
+{
+
+    bool v;
+    bool aarch32 = conf->isAArch32();
+    bool noEL2 = !ArmSystem::haveEL(tc, EL2);
+    bool noEL3 = !ArmSystem::haveEL(tc, EL3);
+
+    if (aarch32){
+        // WatchPoint PL2 using aarch32 is disabled except for
+        // debug state. Check G2-5395 table G2-15.
+        if (el==EL2)
+            return false;
+        if (noEL3){
+            if (ssc == 0x01 || ssc == 0x02){
+                return false;
+            }
+            else if (noEL2 && ((!hmc && ssc==0x3) || (hmc && ssc==0x0)))
+            {
+                return false;
+            }
+        }
+        if (noEL2 && hmc && ssc == 0x03 && pac == 0)
+            return false;
+    }
+    switch (el) {
+        case EL0:
+            v = (pac == 0x3 || (pac == 0x2 && !hmc && ssc != 0x3));
+            break;
+        case EL1:
+            v = (pac == 0x1 || pac == 0x3);
+            break;
+        case EL2:
+            v = (hmc && (ssc != 0x2 || pac != 0x0));
+            break;
+        case EL3:
+            v = (hmc && (ssc == 0x2 ||
+                        (ssc == 0x1 && (pac == 0x1 || pac == 0x3))));
+            break;
+        default:
+            panic("Unexpected EL in WatchPoint::isEnabled.\n");
+    }
+    return v && SelfDebug::securityStateMatch(tc, ssc, hmc);
+}
+
+bool
+WatchPoint::test(ThreadContext *tc, Addr addr, ExceptionLevel el, bool& wrt,
+                 bool atomic, unsigned size)
+{
+
+    bool v = false;
+    const DBGWCR ctr = tc->readMiscReg(ctrlRegIndex);
+    if (isEnabled(tc, el, ctr.hmc, ctr.ssc, ctr.pac) &&
+            ((wrt && (ctr.lsv & 0x2)) || (!wrt && (ctr.lsv & 0x1)) || atomic))
+    {
+        v = compareAddress(tc, addr, ctr.bas, ctr.mask, size);
+        if (ctr.wt){
+            v = v && (conf->getBrkPoint(ctr.lbn))->testLinkedBk(tc, addr, el);
+        }
+    }
+    if (atomic && (ctr.lsv & 0x1)){
+        wrt = false;
+    }
+    return v;
+}
+
+bool
+WatchPoint::compareAddress(ThreadContext *tc, Addr in_addr, uint8_t bas,
+        uint8_t mask, unsigned size)
+{
+    Addr addr_tocmp = getAddrfromReg(tc);
+    int maxAddrSize = getMaxAddrSize();
+    int maxbits = isDoubleAligned(addr_tocmp) ? 4: 8;
+    int bottom = isDoubleAligned(addr_tocmp) ? 2: 3;
+    Addr addr = bits(in_addr, maxAddrSize, 0);
+
+    if (bas == 0x0)
+        return false;
+
+    if (mask == 0x0){
+
+        for (int i=0; i < maxbits; i++){
+            uint8_t bas_m = 0x1 << i;
+            uint8_t masked_bas = bas & bas_m;
+            if (masked_bas == bas_m){
+                uint8_t off = log2(masked_bas);
+                Addr cmpaddr = addr_tocmp | off;
+                for (int j=0; j<size; j++){
+                    if ((addr+j) == cmpaddr) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+    else
+    {
+        bool v = false;
+        for (int j=0; j<size; j++)
+        {
+            Addr compaddr;
+            if (mask > bottom){
+                addr = bits((in_addr+j), maxAddrSize, mask);
+                compaddr = bits(addr_tocmp, maxAddrSize, mask);
+            }
+            else{
+                addr = bits((in_addr+j), maxAddrSize, bottom);
+                compaddr = bits(addr_tocmp, maxAddrSize, bottom);
+            }
+            v = v || (addr==compaddr) ;
+        }
+        return v;
+    }
+}
+
index 4453e7c9fe80fb857b245e2530a68511132ab887..c8ae711c1bc2e6871902517831e36e3cb5f84c52 100644 (file)
@@ -147,11 +147,66 @@ class BrkPoint
 
 };
 
+class WatchPoint
+{
+  private:
+    MiscRegIndex ctrlRegIndex;
+    MiscRegIndex valRegIndex;
+    SelfDebug * conf;
+    bool enable;
+    int maxAddrSize;
+
+    inline int getMaxAddrSize()
+    {
+        return maxAddrSize;
+    }
+
+
+  public:
+    WatchPoint(MiscRegIndex _ctrlIndex, MiscRegIndex _valIndex,
+               SelfDebug* _conf, bool lva, bool aarch32):
+                ctrlRegIndex(_ctrlIndex),
+                valRegIndex(_valIndex), conf(_conf), enable(false)
+    {
+        maxAddrSize = lva ? 52: 48 ;
+        maxAddrSize = aarch32 ? 31 : maxAddrSize;
+    }
+
+    bool compareAddress(ThreadContext *tc, Addr in_addr,
+                        uint8_t bas, uint8_t mask, unsigned size);
+
+    inline Addr getAddrfromReg(ThreadContext *tc)
+    {
+       return bits(tc->readMiscReg(valRegIndex), maxAddrSize, 0);
+
+    }
+
+    inline bool isDoubleAligned(Addr addr)
+    {
+        return addr & 0x4;
+    }
+
+    inline void updateControl(DBGWCR val)
+    {
+        enable = val.e == 0x1;
+    }
+    bool getEnable()
+    {
+        return enable;
+    }
+
+    bool isEnabled(ThreadContext* tc, ExceptionLevel el, bool hmc,
+                   uint8_t ssc, uint8_t pac);
+    bool test(ThreadContext *tc, Addr addr, ExceptionLevel el, bool& wrt,
+              bool atomic, unsigned size);
+};
+
 
 class SelfDebug
 {
   private:
     std::vector<BrkPoint> arBrkPoints;
+    std::vector<WatchPoint> arWatchPoints;
 
     bool initialized;
     bool enableTdeTge; // MDCR_EL2.TDE || HCR_EL2.TGE
@@ -174,7 +229,13 @@ class SelfDebug
     ~SelfDebug(){}
 
     Fault testBreakPoints(ThreadContext *tc, Addr vaddr);
+    Fault testWatchPoints(ThreadContext *tc, Addr vaddr, bool write,
+                          bool atomic, unsigned size, bool cm);
+    Fault testVectorCatch(ThreadContext *tc, Addr addr, ArmFault* flt);
+
     Fault triggerException(ThreadContext * tc, Addr vaddr);
+    Fault triggerWatchpointException(ThreadContext *tc, Addr vaddr,
+                                     bool write, bool cm);
 
     inline BrkPoint* getBrkPoint(uint8_t index)
     {
@@ -255,6 +316,11 @@ class SelfDebug
         arBrkPoints[index].updateControl(val);
     }
 
+    inline void updateDBGWCR(int index, DBGWCR val)
+    {
+        arWatchPoints[index].updateControl(val);
+    }
+
     inline bool isAArch32()
     {
         return aarch32;
@@ -306,6 +372,15 @@ class SelfDebug
             arBrkPoints.push_back(bkp);
         }
 
+        for (int i=0; i<=dfr.wrps; i++){
+            WatchPoint  wtp = WatchPoint((MiscRegIndex)(MISCREG_DBGWCR0+i),
+                                         (MiscRegIndex)(MISCREG_DBGWVR0+i),
+                                         this, (bool)mm_fr2.varange, aarch32);
+            const DBGWCR ctr = tc->readMiscReg(MISCREG_DBGWCR0+i);
+
+            wtp.updateControl(ctr);
+            arWatchPoints.push_back(wtp);
+        }
 
         initialized = true;
 
index a00cba85725489c8b4915fe37bbf71c2189c1954..fc7a7545b53e038617e6e0dfad4002676e4ba78d 100644 (file)
@@ -1199,6 +1199,15 @@ TLB::translateFs(const RequestPtr &req, ThreadContext *tc, Mode mode,
         if (mode == Execute) {
             fault = sd->testBreakPoints(tc, req->getVaddr());
         }
+        else if (!req->isCacheMaintenance() ||
+                 (req->isCacheInvalidate() && !req->isCacheClean()))
+        {
+            bool md = mode == Write ? true: false;
+            fault = sd->testWatchPoints(tc, req->getVaddr(), md,
+                                        req->isAtomic(),
+                                        req->getSize(),
+                                        req->isCacheMaintenance());
+        }
     }
 
     return fault;
index fa7f1be84db705986031edf6cda343a9e06c4201..9ed5bf40eb3b780ec4720e3f5d67301f876dff19 100644 (file)
@@ -123,10 +123,34 @@ TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
     { "dbgwvr1", MISCREG_DBGWVR1 },
     { "dbgwvr2", MISCREG_DBGWVR2 },
     { "dbgwvr3", MISCREG_DBGWVR3 },
+    { "dbgwvr4", MISCREG_DBGWVR4 },
+    { "dbgwvr5", MISCREG_DBGWVR5 },
+    { "dbgwvr6", MISCREG_DBGWVR6 },
+    { "dbgwvr7", MISCREG_DBGWVR7 },
+    { "dbgwvr8", MISCREG_DBGWVR8 },
+    { "dbgwvr9", MISCREG_DBGWVR9 },
+    { "dbgwvr10", MISCREG_DBGWVR10 },
+    { "dbgwvr11", MISCREG_DBGWVR11 },
+    { "dbgwvr12", MISCREG_DBGWVR12 },
+    { "dbgwvr13", MISCREG_DBGWVR13 },
+    { "dbgwvr14", MISCREG_DBGWVR14 },
+    { "dbgwvr15", MISCREG_DBGWVR15 },
     { "dbgwcr0", MISCREG_DBGWCR0 },
     { "dbgwcr1", MISCREG_DBGWCR1 },
     { "dbgwcr2", MISCREG_DBGWCR2 },
     { "dbgwcr3", MISCREG_DBGWCR3 },
+    { "dbgwcr4", MISCREG_DBGWCR4 },
+    { "dbgwcr5", MISCREG_DBGWCR5 },
+    { "dbgwcr6", MISCREG_DBGWCR6 },
+    { "dbgwcr7", MISCREG_DBGWCR7 },
+    { "dbgwcr8", MISCREG_DBGWCR8 },
+    { "dbgwcr9", MISCREG_DBGWCR9 },
+    { "dbgwcr10", MISCREG_DBGWCR10 },
+    { "dbgwcr11", MISCREG_DBGWCR11 },
+    { "dbgwcr12", MISCREG_DBGWCR12 },
+    { "dbgwcr13", MISCREG_DBGWCR13 },
+    { "dbgwcr14", MISCREG_DBGWCR14 },
+    { "dbgwcr15", MISCREG_DBGWCR15 },
     { "dbgdrar", MISCREG_DBGDRAR },
     { "dbgbxvr0", MISCREG_DBGBXVR0 },
     { "dbgbxvr1", MISCREG_DBGBXVR1 },
@@ -418,10 +442,34 @@ TarmacParserRecord::MiscRegMap TarmacParserRecord::miscRegMap = {
     { "dbgwvr1_el1", MISCREG_DBGWVR1_EL1 },
     { "dbgwvr2_el1", MISCREG_DBGWVR2_EL1 },
     { "dbgwvr3_el1", MISCREG_DBGWVR3_EL1 },
+    { "dbgwvr4_el1", MISCREG_DBGWVR4_EL1 },
+    { "dbgwvr5_el1", MISCREG_DBGWVR5_EL1 },
+    { "dbgwvr6_el1", MISCREG_DBGWVR6_EL1 },
+    { "dbgwvr7_el1", MISCREG_DBGWVR7_EL1 },
+    { "dbgwvr8_el1", MISCREG_DBGWVR8_EL1 },
+    { "dbgwvr9_el1", MISCREG_DBGWVR9_EL1 },
+    { "dbgwvr10_el1", MISCREG_DBGWVR10_EL1 },
+    { "dbgwvr11_el1", MISCREG_DBGWVR11_EL1 },
+    { "dbgwvr12_el1", MISCREG_DBGWVR12_EL1 },
+    { "dbgwvr13_el1", MISCREG_DBGWVR13_EL1 },
+    { "dbgwvr14_el1", MISCREG_DBGWVR14_EL1 },
+    { "dbgwvr15_el1", MISCREG_DBGWVR15_EL1 },
     { "dbgwcr0_el1", MISCREG_DBGWCR0_EL1 },
     { "dbgwcr1_el1", MISCREG_DBGWCR1_EL1 },
     { "dbgwcr2_el1", MISCREG_DBGWCR2_EL1 },
     { "dbgwcr3_el1", MISCREG_DBGWCR3_EL1 },
+    { "dbgwcr4_el1", MISCREG_DBGWCR4_EL1 },
+    { "dbgwcr5_el1", MISCREG_DBGWCR5_EL1 },
+    { "dbgwcr6_el1", MISCREG_DBGWCR6_EL1 },
+    { "dbgwcr7_el1", MISCREG_DBGWCR7_EL1 },
+    { "dbgwcr8_el1", MISCREG_DBGWCR8_EL1 },
+    { "dbgwcr9_el1", MISCREG_DBGWCR9_EL1 },
+    { "dbgwcr10_el1", MISCREG_DBGWCR10_EL1 },
+    { "dbgwcr11_el1", MISCREG_DBGWCR11_EL1 },
+    { "dbgwcr12_el1", MISCREG_DBGWCR12_EL1 },
+    { "dbgwcr13_el1", MISCREG_DBGWCR13_EL1 },
+    { "dbgwcr14_el1", MISCREG_DBGWCR14_EL1 },
+    { "dbgwcr15_el1", MISCREG_DBGWCR15_EL1 },
     { "mdccsr_el0", MISCREG_MDCCSR_EL0 },
     { "mddtr_el0", MISCREG_MDDTR_EL0 },
     { "mddtrtx_el0", MISCREG_MDDTRTX_EL0 },
index 0dd3dac9f3c9023bb280ac34960f66b87ee70ea7..3a5e74151a77085149587fcc8ed87e352866cd80 100644 (file)
@@ -648,6 +648,9 @@ namespace ArmISA
         EC_HW_BREAKPOINT           = 0x30,
         EC_HW_BREAKPOINT_LOWER_EL  = 0x30,
         EC_HW_BREAKPOINT_CURR_EL   = 0x31,
+        EC_WATCHPOINT              = 0x34,
+        EC_WATCHPOINT_LOWER_EL     = 0x34,
+        EC_WATCHPOINT_CURR_EL      = 0x35,
         EC_SOFTWARE_BREAKPOINT     = 0x38,
         EC_SOFTWARE_BREAKPOINT_64  = 0x3C,
     };
index 87e51d97e1015993de39d8d47bb2672c698c5fc4..04403fc5fb0695a4a4b747527f8794ff47979107 100644 (file)
@@ -189,6 +189,7 @@ bool ELIs64(ThreadContext *tc, ExceptionLevel el);
 bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);
 
 ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure);
+
 bool isBigEndian64(const ThreadContext *tc);