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,
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')
"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,
} 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);
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;
}
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");
UnknownTran
};
+ enum DebugType
+ {
+ NODEBUG = 0,
+ BRKPOINT,
+ };
+
struct FaultVals
{
const FaultName name;
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;
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;
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>
{
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;
/**
} else {
// Execute AArch32 Software Breakpoint
return std::make_shared<PrefetchAbort>(readPC(xc),
- ArmFault::DebugEvent);
+ ArmFault::DebugEvent,
+ false,
+ ArmFault::UnknownTran,
+ ArmFault::BRKPOINT);
}
}
#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"
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)
uint32_t bitMask = 0;
+ if (affectState && byteMask==0xF){
+ activateBreakpoint(tc);
+ }
if (bits(byteMask, 3)) {
unsigned lowIdx = affectState ? 24 : 27;
bitMask = bitMask | mask(31, lowIdx);
#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"
const_cast<Enums::VecRegRenameMode&>(_vecRegRenameMode) =
highestELIs64 ? Enums::Full : Enums::Elem;
+ selfDebug = new SelfDebug();
initializeMiscRegMetadata();
preUnflattenMiscReg();
setupThreadContext();
afterStartup = true;
+ selfDebug->init(tc);
}
void
*/
return 0x5 << 16;
case MISCREG_DBGDSCRint:
- return 0;
+ return readMiscRegNoEffect(MISCREG_DBGDSCRint);
case MISCREG_ISR:
{
auto ic = dynamic_cast<ArmISA::Interrupts *>(
(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
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:
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;
case MISCREG_SPSR_EL1:
{
RegVal spsr_mask = havePAN ?
- ~(0x5 << 21) : ~(0x7 << 21);
+ ~(0x2 << 22) : ~(0x3 << 22);
newVal = val & spsr_mask;
break;
#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"
bool afterStartup;
+ SelfDebug * selfDebug;
+
/** MiscReg metadata **/
struct MiscRegLUTEntry {
uint32_t lower; // Lower half mapped to this register
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);
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:
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:
case 2:
return MISCREG_NSACR;
}
+ } else if (crm == 3) {
+ if ( opc2 == 1)
+ return MISCREG_SDCR;
}
} else if (opc1 == 4) {
if (crm == 0) {
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;
}
.unimplemented()
.allPrivileges();
InitReg(MISCREG_DBGDSCRext)
- .unimplemented()
- .warnNotFail()
.allPrivileges();
InitReg(MISCREG_DBGDTRTXext)
.unimplemented()
.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();
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()
.secure().exceptUserMode();
InitReg(MISCREG_CPACR)
.allPrivileges().exceptUserMode();
+ InitReg(MISCREG_SDCR)
+ .mon();
InitReg(MISCREG_SCR)
.mon().secure().exceptUserMode()
.res0(0xff40) // [31:16], [6]
.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);
InitReg(MISCREG_CPTR_EL3)
.mon();
InitReg(MISCREG_MDCR_EL3)
- .mon();
+ .mon()
+ .mapsTo(MISCREG_SDCR);
InitReg(MISCREG_TTBR0_EL1)
.allPrivileges().exceptUserMode()
.mapsTo(MISCREG_TTBR0_NS);
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,
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,
MISCREG_ACTLR_NS,
MISCREG_ACTLR_S,
MISCREG_CPACR,
+ MISCREG_SDCR,
MISCREG_SCR,
MISCREG_SDER,
MISCREG_NSACR,
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,
"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",
"dbgwcr2",
"dbgwcr3",
"dbgdrar",
+ "dbgbxvr0",
+ "dbgbxvr1",
+ "dbgbxvr2",
+ "dbgbxvr3",
"dbgbxvr4",
"dbgbxvr5",
+ "dbgbxvr6",
+ "dbgbxvr7",
+ "dbgbxvr8",
+ "dbgbxvr9",
+ "dbgbxvr10",
+ "dbgbxvr11",
+ "dbgbxvr12",
+ "dbgbxvr13",
+ "dbgbxvr14",
+ "dbgbxvr15",
"dbgoslar",
"dbgoslsr",
"dbgosdlr",
"actlr_ns",
"actlr_s",
"cpacr",
+ "sdrc",
"scr",
"sder",
"nsacr",
"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",
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__
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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
#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"
}
}
+ 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
{ "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 },
{ "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 },
{ "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 },
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,
};
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)
{
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);
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) {
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)
{
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);
*/
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
bool inSecureState(ThreadContext *tc);
+bool isSecureBelowEL3(ThreadContext *tc);
+
bool longDescFormatInUse(ThreadContext *tc);
/** This helper function is either returing the value of