From: Jordi Vaquero Date: Tue, 29 Oct 2019 15:01:56 +0000 (+0100) Subject: arch-arm: Implementation of ARMv8 SelfDebug Watchpoints X-Git-Tag: v20.1.0.0~520 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3db58b4fc0e342587b824df438849577affe898c;p=gem5.git arch-arm: Implementation of ARMv8 SelfDebug Watchpoints 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 Tested-by: kokoro Reviewed-by: Giacomo Travaglini --- diff --git a/src/arch/arm/ArmISA.py b/src/arch/arm/ArmISA.py index b030e6c94..f701f7d15 100644 --- a/src/arch/arm/ArmISA.py +++ b/src/arch/arm/ArmISA.py @@ -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, diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index ba8369ac5..ce9675aee 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -285,6 +285,10 @@ template<> ArmFault::FaultVals ArmFaultVals::vals( "Hardware Breakpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, 0, 0, 0, 0, true, false, false, EC_HW_BREAKPOINT ); +template<> ArmFault::FaultVals ArmFaultVals::vals( + "Watchpoint", 0x000, 0x000, 0x200, 0x400, 0x600, MODE_SVC, + 0, 0, 0, 0, true, false, false, EC_WATCHPOINT +); template<> ArmFault::FaultVals ArmFaultVals::vals( // Some dummy values "ArmSev Flush", 0x000, 0x000, 0x000, 0x000, 0x000, MODE_SVC, @@ -1084,6 +1088,9 @@ AbortFault::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(_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::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::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; template class ArmFaultVals; template class ArmFaultVals; template class ArmFaultVals; +template class ArmFaultVals; +template class ArmFaultVals; template class ArmFaultVals; template class AbortFault; template class AbortFault; diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 2db0e8d40..2e1f3387b 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -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 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(_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 ExceptionClass ec(ThreadContext *tc) const override; }; +class Watchpoint : public ArmFaultVals +{ + 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 { @@ -652,6 +673,7 @@ template<> ArmFault::FaultVals ArmFaultVals::vals; template<> ArmFault::FaultVals ArmFaultVals::vals; template<> ArmFault::FaultVals ArmFaultVals::vals; template<> ArmFault::FaultVals ArmFaultVals::vals; +template<> ArmFault::FaultVals ArmFaultVals::vals; template<> ArmFault::FaultVals ArmFaultVals::vals; /** diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index a48b3495f..07713be8a 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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 diff --git a/src/arch/arm/miscregs.cc b/src/arch/arm/miscregs.cc index 2bdbaa48d..2dd1d78e3 100644 --- a/src/arch/arm/miscregs.cc +++ b/src/arch/arm/miscregs.cc @@ -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); diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 1f053e35d..ac5d68fa5 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -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", diff --git a/src/arch/arm/miscregs_types.hh b/src/arch/arm/miscregs_types.hh index 642fa6eed..301d6fb2e 100644 --- a/src/arch/arm/miscregs_types.hh +++ b/src/arch/arm/miscregs_types.hh @@ -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; diff --git a/src/arch/arm/self_debug.cc b/src/arch/arm/self_debug.cc index 5234be44e..85c6656bb 100644 --- a/src/arch/arm/self_debug.cc +++ b/src/arch/arm/self_debug.cc @@ -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(vaddr, + TlbEntry::DomainType::NoAccess, + write, ArmFault::DebugEvent, cm, + ArmFault::UnknownTran, d); + } else { + return std::make_shared(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 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; + } +} + diff --git a/src/arch/arm/self_debug.hh b/src/arch/arm/self_debug.hh index 4453e7c9f..c8ae711c1 100644 --- a/src/arch/arm/self_debug.hh +++ b/src/arch/arm/self_debug.hh @@ -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 arBrkPoints; + std::vector 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; diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index a00cba857..fc7a7545b 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -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; diff --git a/src/arch/arm/tracers/tarmac_parser.cc b/src/arch/arm/tracers/tarmac_parser.cc index fa7f1be84..9ed5bf40e 100644 --- a/src/arch/arm/tracers/tarmac_parser.cc +++ b/src/arch/arm/tracers/tarmac_parser.cc @@ -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 }, diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index 0dd3dac9f..3a5e74151 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -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, }; diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 87e51d97e..04403fc5f 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -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);