arch-arm: GenericTimer arch regs, perms/trapping
This patch enhances the Generic Timer architected registers handling:
- Reordering of miscregs for easier switch/case ranges
- Implement _EL12 reg versions for E2H environments
- AArch32/64 EL0/EL1/EL2 arch compliant trapping for all registers
+ Rely on CNTKCTL and CNTHCTL access controls
- UNDEFINED behaviour from EL0(NS)
- EL1(S) timer traps to EL3 when SCR.ST == 0
Change-Id: I4f018e103cf8f7323060516121838f90278b1c3e
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25307
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Giacomo Travaglini
parent
81fc073768
commit
6e06d231ec
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013,2017-2019 ARM Limited
|
||||
* Copyright (c) 2011-2013,2017-2020 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -125,6 +125,11 @@ MiscRegOp64::checkEL1Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
|
||||
immediate = 0x1E00000;
|
||||
}
|
||||
break;
|
||||
// Generic Timer
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
|
||||
trap_to_sup = el == EL0 &&
|
||||
isGenericTimerSystemAccessTrapEL1(misc_reg, tc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -292,6 +297,11 @@ MiscRegOp64::checkEL2Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
|
||||
trap_to_hyp = hcr.imo && el == EL1;
|
||||
}
|
||||
break;
|
||||
// Generic Timer
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
|
||||
trap_to_hyp = el <= EL1 &&
|
||||
isGenericTimerSystemAccessTrapEL2(misc_reg, tc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -340,6 +350,11 @@ MiscRegOp64::checkEL3Trap(ThreadContext *tc, const MiscRegIndex misc_reg,
|
||||
case MISCREG_APIBKeyLo_EL1:
|
||||
trap_to_mon = (el==EL1 || el==EL2) && scr.apk==0 && ELIs64(tc, EL3);
|
||||
break;
|
||||
// Generic Timer
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
|
||||
trap_to_mon = el == EL1 &&
|
||||
isGenericTimerSystemAccessTrapEL3(misc_reg, tc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -749,13 +749,8 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
|
||||
return 0; // bits [63:0] RES0 (reserved for future use)
|
||||
|
||||
// Generic Timer registers
|
||||
case MISCREG_CNTHV_CTL_EL2:
|
||||
case MISCREG_CNTHV_CVAL_EL2:
|
||||
case MISCREG_CNTHV_TVAL_EL2:
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
|
||||
case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
|
||||
case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
|
||||
case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
|
||||
return getGenericTimer(tc).readMiscReg(misc_reg);
|
||||
|
||||
case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
|
||||
@@ -2085,13 +2080,8 @@ ISA::setMiscReg(int misc_reg, RegVal val, ThreadContext *tc)
|
||||
break;
|
||||
|
||||
// Generic Timer registers
|
||||
case MISCREG_CNTHV_CTL_EL2:
|
||||
case MISCREG_CNTHV_CVAL_EL2:
|
||||
case MISCREG_CNTHV_TVAL_EL2:
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTHP_CTL:
|
||||
case MISCREG_CNTPCT ... MISCREG_CNTHP_CVAL:
|
||||
case MISCREG_CNTKCTL_EL1 ... MISCREG_CNTV_CVAL_EL0:
|
||||
case MISCREG_CNTVOFF_EL2 ... MISCREG_CNTPS_CVAL_EL1:
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTVOFF_EL2:
|
||||
getGenericTimer(tc).setMiscReg(misc_reg, newVal);
|
||||
break;
|
||||
case MISCREG_ICC_AP0R0 ... MISCREG_ICH_LRC15:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// -*- mode:c++ -*-
|
||||
|
||||
// Copyright (c) 2010-2013,2017-2019 ARM Limited
|
||||
// Copyright (c) 2010-2013,2017-2020 ARM Limited
|
||||
// All rights reserved
|
||||
//
|
||||
// The license below extends only to copyright in the software and shall
|
||||
@@ -867,7 +867,8 @@ let {{
|
||||
MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, op1)).index();
|
||||
bool can_read, undefined;
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
if (!can_read || undefined) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
@@ -892,7 +893,8 @@ let {{
|
||||
MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenRegId(
|
||||
RegId(MiscRegClass, dest)).index();
|
||||
bool can_write, undefined;
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
if (undefined || !can_write) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
@@ -918,21 +920,21 @@ let {{
|
||||
xc->tcBase()->flattenRegId(RegId(MiscRegClass,
|
||||
preFlatOp1)).index();
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, xc->tcBase(), imm);
|
||||
Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
|
||||
|
||||
bool can_read, undefined;
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
// if we're in non secure PL1 mode then we can trap regargless of whether
|
||||
// the register is accessable, in other modes we trap if only if the register
|
||||
// IS accessable.
|
||||
if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
|
||||
if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
|
||||
!inSecureState(Scr, Cpsr)))) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
if (fault != NoFault) {
|
||||
return fault;
|
||||
}
|
||||
Dest = MiscNsBankedOp1;
|
||||
'''
|
||||
@@ -951,22 +953,22 @@ let {{
|
||||
xc->tcBase()->flattenRegId(RegId(MiscRegClass,
|
||||
preFlatDest)).index();
|
||||
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, xc->tcBase(), imm);
|
||||
Fault fault = mcrMrc15Trap(miscReg, machInst, xc->tcBase(), imm);
|
||||
|
||||
bool can_write, undefined;
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
|
||||
// if we're in non secure PL1 mode then we can trap regargless of whether
|
||||
// the register is accessable, in other modes we trap if only if the register
|
||||
// IS accessable.
|
||||
if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
|
||||
if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
|
||||
!inSecureState(Scr, Cpsr)))) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm,
|
||||
EC_TRAPPED_CP15_MCR_MRC);
|
||||
if (fault != NoFault) {
|
||||
return fault;
|
||||
}
|
||||
MiscNsBankedDest = Op1;
|
||||
'''
|
||||
@@ -984,20 +986,22 @@ let {{
|
||||
MiscRegIndex miscReg = (MiscRegIndex)
|
||||
xc->tcBase()->flattenRegId(RegId(MiscRegClass,
|
||||
preFlatOp1)).index();
|
||||
bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
|
||||
|
||||
Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
|
||||
|
||||
bool can_read, undefined;
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
// if we're in non secure PL1 mode then we can trap regargless of whether
|
||||
// the register is accessable, in other modes we trap if only if the register
|
||||
// IS accessable.
|
||||
if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) &&
|
||||
if (undefined || (!can_read && !(fault != NoFault && !inUserMode(Cpsr) &&
|
||||
!inSecureState(Scr, Cpsr)))) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm,
|
||||
EC_TRAPPED_CP15_MCRR_MRRC);
|
||||
if (fault != NoFault) {
|
||||
return fault;
|
||||
}
|
||||
Dest = bits(MiscNsBankedOp164, 63, 32);
|
||||
Dest2 = bits(MiscNsBankedOp164, 31, 0);
|
||||
@@ -1015,21 +1019,23 @@ let {{
|
||||
MiscRegIndex miscReg = (MiscRegIndex)
|
||||
xc->tcBase()->flattenRegId(RegId(MiscRegClass,
|
||||
preFlatDest)).index();
|
||||
bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm);
|
||||
|
||||
Fault fault = mcrrMrrc15Trap(miscReg, machInst, xc->tcBase(), imm);
|
||||
|
||||
bool can_write, undefined;
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
|
||||
// if we're in non secure PL1 mode then we can trap regargless of whether
|
||||
// the register is accessable, in other modes we trap if only if the register
|
||||
// IS accessable.
|
||||
if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) &&
|
||||
if (undefined || (!can_write && !(fault != NoFault && !inUserMode(Cpsr) &&
|
||||
!inSecureState(Scr, Cpsr)))) {
|
||||
return std::make_shared<UndefinedInstruction>(machInst, false,
|
||||
mnemonic);
|
||||
}
|
||||
if (hypTrap) {
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm,
|
||||
EC_TRAPPED_CP15_MCRR_MRRC);
|
||||
if (fault != NoFault) {
|
||||
return fault;
|
||||
}
|
||||
MiscNsBankedDest64 = ((uint64_t) Op1 << 32) | Op2;
|
||||
'''
|
||||
@@ -1095,7 +1101,8 @@ let {{
|
||||
bool hypTrap = mcrMrc15TrapToHyp(miscReg, xc->tcBase(), imm);
|
||||
|
||||
bool can_write, undefined;
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr);
|
||||
std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr,
|
||||
xc->tcBase());
|
||||
|
||||
// if we're in non secure PL1 mode then we can trap regardless
|
||||
// of whether the register is accessible, in other modes we
|
||||
|
||||
@@ -984,7 +984,7 @@ decodeCP15Reg64(unsigned crm, unsigned opc1)
|
||||
}
|
||||
|
||||
std::tuple<bool, bool>
|
||||
canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr)
|
||||
canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
|
||||
{
|
||||
bool secure = !scr.ns;
|
||||
bool canRead = false;
|
||||
@@ -1014,13 +1014,23 @@ canReadCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr)
|
||||
default:
|
||||
undefined = true;
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
if (!undefined)
|
||||
undefined = AArch32isUndefinedGenericTimer(reg, tc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// can't do permissions checkes on the root of a banked pair of regs
|
||||
assert(!miscRegInfo[reg][MISCREG_BANKED]);
|
||||
return std::make_tuple(canRead, undefined);
|
||||
}
|
||||
|
||||
std::tuple<bool, bool>
|
||||
canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr)
|
||||
canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
|
||||
{
|
||||
bool secure = !scr.ns;
|
||||
bool canWrite = false;
|
||||
@@ -1050,11 +1060,33 @@ canWriteCoprocReg(MiscRegIndex reg, SCR scr, CPSR cpsr)
|
||||
default:
|
||||
undefined = true;
|
||||
}
|
||||
|
||||
switch (reg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
if (!undefined)
|
||||
undefined = AArch32isUndefinedGenericTimer(reg, tc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// can't do permissions checkes on the root of a banked pair of regs
|
||||
assert(!miscRegInfo[reg][MISCREG_BANKED]);
|
||||
return std::make_tuple(canWrite, undefined);
|
||||
}
|
||||
|
||||
bool
|
||||
AArch32isUndefinedGenericTimer(MiscRegIndex reg, ThreadContext *tc)
|
||||
{
|
||||
if (currEL(tc) == EL0 && ELIs32(tc, EL1)) {
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond = condGenericTimerSystemAccessTrapEL1(reg, tc);
|
||||
if (trap_cond && (!EL2Enabled(tc) || !hcr.tge))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int
|
||||
snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
|
||||
{
|
||||
@@ -2794,6 +2826,36 @@ decodeAArch64SysReg(unsigned op0, unsigned op1,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
switch (crm) {
|
||||
case 1:
|
||||
switch (op2) {
|
||||
case 0:
|
||||
return MISCREG_CNTKCTL_EL12;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (op2) {
|
||||
case 0:
|
||||
return MISCREG_CNTP_TVAL_EL02;
|
||||
case 1:
|
||||
return MISCREG_CNTP_CTL_EL02;
|
||||
case 2:
|
||||
return MISCREG_CNTP_CVAL_EL02;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
switch (op2) {
|
||||
case 0:
|
||||
return MISCREG_CNTV_TVAL_EL02;
|
||||
case 1:
|
||||
return MISCREG_CNTV_CTL_EL02;
|
||||
case 2:
|
||||
return MISCREG_CNTV_CVAL_EL02;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
switch (crm) {
|
||||
case 2:
|
||||
@@ -3702,42 +3764,78 @@ ISA::initializeMiscRegMetadata()
|
||||
.secure().exceptUserMode();
|
||||
InitReg(MISCREG_HTPIDR)
|
||||
.hyp().monNonSecure();
|
||||
// BEGIN Generic Timer (AArch32)
|
||||
InitReg(MISCREG_CNTFRQ)
|
||||
.reads(1)
|
||||
.highest(system)
|
||||
.privSecureWrite(aarch32EL3);
|
||||
InitReg(MISCREG_CNTKCTL)
|
||||
.allPrivileges().exceptUserMode();
|
||||
InitReg(MISCREG_CNTP_TVAL)
|
||||
.banked();
|
||||
InitReg(MISCREG_CNTP_TVAL_NS)
|
||||
.bankedChild()
|
||||
.allPrivileges()
|
||||
.privSecure(!aarch32EL3)
|
||||
.monSecure(0);
|
||||
InitReg(MISCREG_CNTP_TVAL_S)
|
||||
.bankedChild()
|
||||
.secure().user(1);
|
||||
InitReg(MISCREG_CNTPCT)
|
||||
.unverifiable()
|
||||
.reads(1);
|
||||
InitReg(MISCREG_CNTVCT)
|
||||
.unverifiable()
|
||||
.reads(1);
|
||||
InitReg(MISCREG_CNTP_CTL)
|
||||
.banked();
|
||||
InitReg(MISCREG_CNTP_CTL_NS)
|
||||
.bankedChild()
|
||||
.allPrivileges()
|
||||
.nonSecure()
|
||||
.privSecure(!aarch32EL3)
|
||||
.monSecure(0);
|
||||
.res0(0xfffffff8);
|
||||
InitReg(MISCREG_CNTP_CTL_S)
|
||||
.bankedChild()
|
||||
.secure().user(1);
|
||||
.secure()
|
||||
.privSecure(aarch32EL3)
|
||||
.res0(0xfffffff8);
|
||||
InitReg(MISCREG_CNTP_CVAL)
|
||||
.banked();
|
||||
InitReg(MISCREG_CNTP_CVAL_NS)
|
||||
.bankedChild()
|
||||
.nonSecure()
|
||||
.privSecure(!aarch32EL3);
|
||||
InitReg(MISCREG_CNTP_CVAL_S)
|
||||
.bankedChild()
|
||||
.secure()
|
||||
.privSecure(aarch32EL3);
|
||||
InitReg(MISCREG_CNTP_TVAL)
|
||||
.banked();
|
||||
InitReg(MISCREG_CNTP_TVAL_NS)
|
||||
.bankedChild()
|
||||
.nonSecure()
|
||||
.privSecure(!aarch32EL3);
|
||||
InitReg(MISCREG_CNTP_TVAL_S)
|
||||
.bankedChild()
|
||||
.secure()
|
||||
.privSecure(aarch32EL3);
|
||||
InitReg(MISCREG_CNTV_CTL)
|
||||
.allPrivileges()
|
||||
.res0(0xfffffff8);
|
||||
InitReg(MISCREG_CNTV_CVAL)
|
||||
.allPrivileges();
|
||||
InitReg(MISCREG_CNTV_TVAL)
|
||||
.allPrivileges();
|
||||
InitReg(MISCREG_CNTV_CTL)
|
||||
.allPrivileges();
|
||||
InitReg(MISCREG_CNTKCTL)
|
||||
.allPrivileges()
|
||||
.exceptUserMode()
|
||||
.res0(0xfffdfc00);
|
||||
InitReg(MISCREG_CNTHCTL)
|
||||
.hypWrite().monNonSecureRead();
|
||||
InitReg(MISCREG_CNTHP_TVAL)
|
||||
.hypWrite().monNonSecureRead();
|
||||
.monNonSecure()
|
||||
.hyp()
|
||||
.res0(0xfffdff00);
|
||||
InitReg(MISCREG_CNTHP_CTL)
|
||||
.hypWrite().monNonSecureRead();
|
||||
.monNonSecure()
|
||||
.hyp()
|
||||
.res0(0xfffffff8);
|
||||
InitReg(MISCREG_CNTHP_CVAL)
|
||||
.monNonSecure()
|
||||
.hyp();
|
||||
InitReg(MISCREG_CNTHP_TVAL)
|
||||
.monNonSecure()
|
||||
.hyp();
|
||||
InitReg(MISCREG_CNTVOFF)
|
||||
.monNonSecure()
|
||||
.hyp();
|
||||
// END Generic Timer (AArch32)
|
||||
InitReg(MISCREG_IL1DATA0)
|
||||
.unimplemented()
|
||||
.allPrivileges().exceptUserMode();
|
||||
@@ -3778,27 +3876,6 @@ ISA::initializeMiscRegMetadata()
|
||||
.hyp().monNonSecure();
|
||||
InitReg(MISCREG_VTTBR)
|
||||
.hyp().monNonSecure();
|
||||
InitReg(MISCREG_CNTPCT)
|
||||
.reads(1);
|
||||
InitReg(MISCREG_CNTVCT)
|
||||
.unverifiable()
|
||||
.reads(1);
|
||||
InitReg(MISCREG_CNTP_CVAL)
|
||||
.banked();
|
||||
InitReg(MISCREG_CNTP_CVAL_NS)
|
||||
.bankedChild()
|
||||
.allPrivileges()
|
||||
.privSecure(!aarch32EL3)
|
||||
.monSecure(0);
|
||||
InitReg(MISCREG_CNTP_CVAL_S)
|
||||
.bankedChild()
|
||||
.secure().user(1);
|
||||
InitReg(MISCREG_CNTV_CVAL)
|
||||
.allPrivileges();
|
||||
InitReg(MISCREG_CNTVOFF)
|
||||
.hyp().monNonSecure();
|
||||
InitReg(MISCREG_CNTHP_CVAL)
|
||||
.hypWrite().monNonSecureRead();
|
||||
InitReg(MISCREG_CPUMERRSR)
|
||||
.unimplemented()
|
||||
.allPrivileges().exceptUserMode();
|
||||
@@ -4446,39 +4523,128 @@ ISA::initializeMiscRegMetadata()
|
||||
.mapsTo(MISCREG_HTPIDR);
|
||||
InitReg(MISCREG_TPIDR_EL3)
|
||||
.mon();
|
||||
InitReg(MISCREG_CNTKCTL_EL1)
|
||||
.allPrivileges().exceptUserMode()
|
||||
.mapsTo(MISCREG_CNTKCTL);
|
||||
// BEGIN Generic Timer (AArch64)
|
||||
InitReg(MISCREG_CNTFRQ_EL0)
|
||||
.reads(1)
|
||||
.highest(system)
|
||||
.privSecureWrite(aarch32EL3)
|
||||
.mapsTo(MISCREG_CNTFRQ);
|
||||
InitReg(MISCREG_CNTPCT_EL0)
|
||||
.unverifiable()
|
||||
.reads(1)
|
||||
.mapsTo(MISCREG_CNTPCT); /* 64b */
|
||||
.mapsTo(MISCREG_CNTPCT);
|
||||
InitReg(MISCREG_CNTVCT_EL0)
|
||||
.unverifiable()
|
||||
.reads(1)
|
||||
.mapsTo(MISCREG_CNTVCT); /* 64b */
|
||||
InitReg(MISCREG_CNTP_TVAL_EL0)
|
||||
.allPrivileges()
|
||||
.mapsTo(MISCREG_CNTP_TVAL_NS);
|
||||
.mapsTo(MISCREG_CNTVCT);
|
||||
InitReg(MISCREG_CNTP_CTL_EL0)
|
||||
.allPrivileges()
|
||||
.res0(0xfffffffffffffff8)
|
||||
.mapsTo(MISCREG_CNTP_CTL_NS);
|
||||
InitReg(MISCREG_CNTP_CVAL_EL0)
|
||||
.allPrivileges()
|
||||
.mapsTo(MISCREG_CNTP_CVAL_NS); /* 64b */
|
||||
InitReg(MISCREG_CNTV_TVAL_EL0)
|
||||
.mapsTo(MISCREG_CNTP_CVAL_NS);
|
||||
InitReg(MISCREG_CNTP_TVAL_EL0)
|
||||
.allPrivileges()
|
||||
.mapsTo(MISCREG_CNTV_TVAL);
|
||||
.res0(0xffffffff00000000)
|
||||
.mapsTo(MISCREG_CNTP_TVAL_NS);
|
||||
InitReg(MISCREG_CNTV_CTL_EL0)
|
||||
.allPrivileges()
|
||||
.res0(0xfffffffffffffff8)
|
||||
.mapsTo(MISCREG_CNTV_CTL);
|
||||
InitReg(MISCREG_CNTV_CVAL_EL0)
|
||||
.allPrivileges()
|
||||
.mapsTo(MISCREG_CNTV_CVAL); /* 64b */
|
||||
.mapsTo(MISCREG_CNTV_CVAL);
|
||||
InitReg(MISCREG_CNTV_TVAL_EL0)
|
||||
.allPrivileges()
|
||||
.res0(0xffffffff00000000)
|
||||
.mapsTo(MISCREG_CNTV_TVAL);
|
||||
InitReg(MISCREG_CNTP_CTL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.res0(0xfffffffffffffff8)
|
||||
.mapsTo(MISCREG_CNTP_CTL_NS);
|
||||
InitReg(MISCREG_CNTP_CVAL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.mapsTo(MISCREG_CNTP_CVAL_NS);
|
||||
InitReg(MISCREG_CNTP_TVAL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.res0(0xffffffff00000000)
|
||||
.mapsTo(MISCREG_CNTP_TVAL_NS);
|
||||
InitReg(MISCREG_CNTV_CTL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.res0(0xfffffffffffffff8)
|
||||
.mapsTo(MISCREG_CNTV_CTL);
|
||||
InitReg(MISCREG_CNTV_CVAL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.mapsTo(MISCREG_CNTV_CVAL);
|
||||
InitReg(MISCREG_CNTV_TVAL_EL02)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.res0(0xffffffff00000000)
|
||||
.mapsTo(MISCREG_CNTV_TVAL);
|
||||
InitReg(MISCREG_CNTKCTL_EL1)
|
||||
.allPrivileges()
|
||||
.exceptUserMode()
|
||||
.res0(0xfffffffffffdfc00)
|
||||
.mapsTo(MISCREG_CNTKCTL);
|
||||
InitReg(MISCREG_CNTKCTL_EL12)
|
||||
.monE2H()
|
||||
.hypE2H()
|
||||
.res0(0xfffffffffffdfc00)
|
||||
.mapsTo(MISCREG_CNTKCTL);
|
||||
InitReg(MISCREG_CNTPS_CTL_EL1)
|
||||
.mon()
|
||||
.privSecure()
|
||||
.res0(0xfffffffffffffff8);
|
||||
InitReg(MISCREG_CNTPS_CVAL_EL1)
|
||||
.mon()
|
||||
.privSecure();
|
||||
InitReg(MISCREG_CNTPS_TVAL_EL1)
|
||||
.mon()
|
||||
.privSecure()
|
||||
.res0(0xffffffff00000000);
|
||||
InitReg(MISCREG_CNTHCTL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.res0(0xfffffffffffc0000)
|
||||
.mapsTo(MISCREG_CNTHCTL);
|
||||
InitReg(MISCREG_CNTHP_CTL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.res0(0xfffffffffffffff8)
|
||||
.mapsTo(MISCREG_CNTHP_CTL);
|
||||
InitReg(MISCREG_CNTHP_CVAL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.mapsTo(MISCREG_CNTHP_CVAL);
|
||||
InitReg(MISCREG_CNTHP_TVAL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.res0(0xffffffff00000000)
|
||||
.mapsTo(MISCREG_CNTHP_TVAL);
|
||||
// IF Armv8.1-VHE
|
||||
InitReg(MISCREG_CNTHV_CTL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.res0(0xfffffffffffffff8);
|
||||
InitReg(MISCREG_CNTHV_CVAL_EL2)
|
||||
.mon()
|
||||
.hyp();
|
||||
InitReg(MISCREG_CNTHV_TVAL_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.res0(0xffffffff00000000);
|
||||
// ENDIF Armv8.1-VHE
|
||||
InitReg(MISCREG_CNTVOFF_EL2)
|
||||
.mon()
|
||||
.hyp()
|
||||
.mapsTo(MISCREG_CNTVOFF);
|
||||
// END Generic Timer (AArch64)
|
||||
InitReg(MISCREG_PMEVCNTR0_EL0)
|
||||
.allPrivileges();
|
||||
// .mapsTo(MISCREG_PMEVCNTR0);
|
||||
@@ -4515,27 +4681,6 @@ ISA::initializeMiscRegMetadata()
|
||||
InitReg(MISCREG_PMEVTYPER5_EL0)
|
||||
.allPrivileges();
|
||||
// .mapsTo(MISCREG_PMEVTYPER5);
|
||||
InitReg(MISCREG_CNTVOFF_EL2)
|
||||
.hyp().mon()
|
||||
.mapsTo(MISCREG_CNTVOFF); /* 64b */
|
||||
InitReg(MISCREG_CNTHCTL_EL2)
|
||||
.mon().hyp()
|
||||
.mapsTo(MISCREG_CNTHCTL);
|
||||
InitReg(MISCREG_CNTHP_TVAL_EL2)
|
||||
.mon().hyp()
|
||||
.mapsTo(MISCREG_CNTHP_TVAL);
|
||||
InitReg(MISCREG_CNTHP_CTL_EL2)
|
||||
.mon().hyp()
|
||||
.mapsTo(MISCREG_CNTHP_CTL);
|
||||
InitReg(MISCREG_CNTHP_CVAL_EL2)
|
||||
.mon().hyp()
|
||||
.mapsTo(MISCREG_CNTHP_CVAL); /* 64b */
|
||||
InitReg(MISCREG_CNTPS_TVAL_EL1)
|
||||
.mon().privSecure();
|
||||
InitReg(MISCREG_CNTPS_CTL_EL1)
|
||||
.mon().privSecure();
|
||||
InitReg(MISCREG_CNTPS_CVAL_EL1)
|
||||
.mon().privSecure();
|
||||
InitReg(MISCREG_IL1DATA0_EL1)
|
||||
.allPrivileges().exceptUserMode();
|
||||
InitReg(MISCREG_IL1DATA1_EL1)
|
||||
@@ -5040,13 +5185,6 @@ ISA::initializeMiscRegMetadata()
|
||||
.mapsTo(MISCREG_ICH_LR15)
|
||||
.hyp().mon();
|
||||
|
||||
InitReg(MISCREG_CNTHV_CTL_EL2)
|
||||
.mon().hyp();
|
||||
InitReg(MISCREG_CNTHV_CVAL_EL2)
|
||||
.mon().hyp();
|
||||
InitReg(MISCREG_CNTHV_TVAL_EL2)
|
||||
.mon().hyp();
|
||||
|
||||
// SVE
|
||||
InitReg(MISCREG_ID_AA64ZFR0_EL1)
|
||||
.allPrivileges().exceptUserMode().writes(0);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#include "arch/arm/miscregs_types.hh"
|
||||
#include "base/compiler.hh"
|
||||
#include "dev/arm/generic_timer_miscregs_types.hh"
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
@@ -343,19 +344,29 @@ namespace ArmISA
|
||||
MISCREG_TPIDRPRW_NS,
|
||||
MISCREG_TPIDRPRW_S,
|
||||
MISCREG_HTPIDR,
|
||||
// BEGIN Generic Timer (AArch32)
|
||||
MISCREG_CNTFRQ,
|
||||
MISCREG_CNTKCTL,
|
||||
MISCREG_CNTP_TVAL,
|
||||
MISCREG_CNTP_TVAL_NS,
|
||||
MISCREG_CNTP_TVAL_S,
|
||||
MISCREG_CNTPCT,
|
||||
MISCREG_CNTVCT,
|
||||
MISCREG_CNTP_CTL,
|
||||
MISCREG_CNTP_CTL_NS,
|
||||
MISCREG_CNTP_CTL_S,
|
||||
MISCREG_CNTV_TVAL,
|
||||
MISCREG_CNTP_CVAL,
|
||||
MISCREG_CNTP_CVAL_NS,
|
||||
MISCREG_CNTP_CVAL_S,
|
||||
MISCREG_CNTP_TVAL,
|
||||
MISCREG_CNTP_TVAL_NS,
|
||||
MISCREG_CNTP_TVAL_S,
|
||||
MISCREG_CNTV_CTL,
|
||||
MISCREG_CNTV_CVAL,
|
||||
MISCREG_CNTV_TVAL,
|
||||
MISCREG_CNTKCTL,
|
||||
MISCREG_CNTHCTL,
|
||||
MISCREG_CNTHP_TVAL,
|
||||
MISCREG_CNTHP_CTL,
|
||||
MISCREG_CNTHP_CVAL,
|
||||
MISCREG_CNTHP_TVAL,
|
||||
MISCREG_CNTVOFF,
|
||||
// END Generic Timer (AArch32)
|
||||
MISCREG_IL1DATA0,
|
||||
MISCREG_IL1DATA1,
|
||||
MISCREG_IL1DATA2,
|
||||
@@ -370,14 +381,6 @@ namespace ArmISA
|
||||
MISCREG_CBAR,
|
||||
MISCREG_HTTBR,
|
||||
MISCREG_VTTBR,
|
||||
MISCREG_CNTPCT,
|
||||
MISCREG_CNTVCT,
|
||||
MISCREG_CNTP_CVAL,
|
||||
MISCREG_CNTP_CVAL_NS,
|
||||
MISCREG_CNTP_CVAL_S,
|
||||
MISCREG_CNTV_CVAL,
|
||||
MISCREG_CNTVOFF,
|
||||
MISCREG_CNTHP_CVAL,
|
||||
MISCREG_CPUMERRSR,
|
||||
MISCREG_L2MERRSR,
|
||||
|
||||
@@ -618,16 +621,38 @@ namespace ArmISA
|
||||
MISCREG_TPIDRRO_EL0,
|
||||
MISCREG_TPIDR_EL2,
|
||||
MISCREG_TPIDR_EL3,
|
||||
MISCREG_CNTKCTL_EL1,
|
||||
// BEGIN Generic Timer (AArch64)
|
||||
MISCREG_CNTFRQ_EL0,
|
||||
MISCREG_CNTPCT_EL0,
|
||||
MISCREG_CNTVCT_EL0,
|
||||
MISCREG_CNTP_TVAL_EL0,
|
||||
MISCREG_CNTP_CTL_EL0,
|
||||
MISCREG_CNTP_CVAL_EL0,
|
||||
MISCREG_CNTV_TVAL_EL0,
|
||||
MISCREG_CNTP_TVAL_EL0,
|
||||
MISCREG_CNTV_CTL_EL0,
|
||||
MISCREG_CNTV_CVAL_EL0,
|
||||
MISCREG_CNTV_TVAL_EL0,
|
||||
MISCREG_CNTP_CTL_EL02,
|
||||
MISCREG_CNTP_CVAL_EL02,
|
||||
MISCREG_CNTP_TVAL_EL02,
|
||||
MISCREG_CNTV_CTL_EL02,
|
||||
MISCREG_CNTV_CVAL_EL02,
|
||||
MISCREG_CNTV_TVAL_EL02,
|
||||
MISCREG_CNTKCTL_EL1,
|
||||
MISCREG_CNTKCTL_EL12,
|
||||
MISCREG_CNTPS_CTL_EL1,
|
||||
MISCREG_CNTPS_CVAL_EL1,
|
||||
MISCREG_CNTPS_TVAL_EL1,
|
||||
MISCREG_CNTHCTL_EL2,
|
||||
MISCREG_CNTHP_CTL_EL2,
|
||||
MISCREG_CNTHP_CVAL_EL2,
|
||||
MISCREG_CNTHP_TVAL_EL2,
|
||||
// IF Armv8.1-VHE
|
||||
MISCREG_CNTHV_CTL_EL2,
|
||||
MISCREG_CNTHV_CVAL_EL2,
|
||||
MISCREG_CNTHV_TVAL_EL2,
|
||||
// ENDIF Armv8.1-VHE
|
||||
MISCREG_CNTVOFF_EL2,
|
||||
// END Generic Timer (AArch64)
|
||||
MISCREG_PMEVCNTR0_EL0,
|
||||
MISCREG_PMEVCNTR1_EL0,
|
||||
MISCREG_PMEVCNTR2_EL0,
|
||||
@@ -640,14 +665,6 @@ namespace ArmISA
|
||||
MISCREG_PMEVTYPER3_EL0,
|
||||
MISCREG_PMEVTYPER4_EL0,
|
||||
MISCREG_PMEVTYPER5_EL0,
|
||||
MISCREG_CNTVOFF_EL2,
|
||||
MISCREG_CNTHCTL_EL2,
|
||||
MISCREG_CNTHP_TVAL_EL2,
|
||||
MISCREG_CNTHP_CTL_EL2,
|
||||
MISCREG_CNTHP_CVAL_EL2,
|
||||
MISCREG_CNTPS_TVAL_EL1,
|
||||
MISCREG_CNTPS_CTL_EL1,
|
||||
MISCREG_CNTPS_CVAL_EL1,
|
||||
MISCREG_IL1DATA0_EL1,
|
||||
MISCREG_IL1DATA1_EL1,
|
||||
MISCREG_IL1DATA2_EL1,
|
||||
@@ -667,9 +684,6 @@ namespace ArmISA
|
||||
|
||||
// Introduced in ARMv8.1
|
||||
MISCREG_TTBR1_EL2,
|
||||
MISCREG_CNTHV_CTL_EL2,
|
||||
MISCREG_CNTHV_CVAL_EL2,
|
||||
MISCREG_CNTHV_TVAL_EL2,
|
||||
|
||||
MISCREG_ID_AA64MMFR2_EL1,
|
||||
|
||||
@@ -1308,18 +1322,26 @@ namespace ArmISA
|
||||
"tpidrprw_s",
|
||||
"htpidr",
|
||||
"cntfrq",
|
||||
"cntkctl",
|
||||
"cntp_tval",
|
||||
"cntp_tval_ns",
|
||||
"cntp_tval_s",
|
||||
"cntpct",
|
||||
"cntvct",
|
||||
"cntp_ctl",
|
||||
"cntp_ctl_ns",
|
||||
"cntp_ctl_s",
|
||||
"cntv_tval",
|
||||
"cntp_cval",
|
||||
"cntp_cval_ns",
|
||||
"cntp_cval_s",
|
||||
"cntp_tval",
|
||||
"cntp_tval_ns",
|
||||
"cntp_tval_s",
|
||||
"cntv_ctl",
|
||||
"cntv_cval",
|
||||
"cntv_tval",
|
||||
"cntkctl",
|
||||
"cnthctl",
|
||||
"cnthp_tval",
|
||||
"cnthp_ctl",
|
||||
"cnthp_cval",
|
||||
"cnthp_tval",
|
||||
"cntvoff",
|
||||
"il1data0",
|
||||
"il1data1",
|
||||
"il1data2",
|
||||
@@ -1334,14 +1356,6 @@ namespace ArmISA
|
||||
"cbar",
|
||||
"httbr",
|
||||
"vttbr",
|
||||
"cntpct",
|
||||
"cntvct",
|
||||
"cntp_cval",
|
||||
"cntp_cval_ns",
|
||||
"cntp_cval_s",
|
||||
"cntv_cval",
|
||||
"cntvoff",
|
||||
"cnthp_cval",
|
||||
"cpumerrsr",
|
||||
"l2merrsr",
|
||||
|
||||
@@ -1582,16 +1596,34 @@ namespace ArmISA
|
||||
"tpidrro_el0",
|
||||
"tpidr_el2",
|
||||
"tpidr_el3",
|
||||
"cntkctl_el1",
|
||||
"cntfrq_el0",
|
||||
"cntpct_el0",
|
||||
"cntvct_el0",
|
||||
"cntp_tval_el0",
|
||||
"cntp_ctl_el0",
|
||||
"cntp_cval_el0",
|
||||
"cntv_tval_el0",
|
||||
"cntp_tval_el0",
|
||||
"cntv_ctl_el0",
|
||||
"cntv_cval_el0",
|
||||
"cntv_tval_el0",
|
||||
"cntp_ctl_el02",
|
||||
"cntp_cval_el02",
|
||||
"cntp_tval_el02",
|
||||
"cntv_ctl_el02",
|
||||
"cntv_cval_el02",
|
||||
"cntv_tval_el02",
|
||||
"cntkctl_el1",
|
||||
"cntkctl_el12",
|
||||
"cntps_ctl_el1",
|
||||
"cntps_cval_el1",
|
||||
"cntps_tval_el1",
|
||||
"cnthctl_el2",
|
||||
"cnthp_ctl_el2",
|
||||
"cnthp_cval_el2",
|
||||
"cnthp_tval_el2",
|
||||
"cnthv_ctl_el2",
|
||||
"cnthv_cval_el2",
|
||||
"cnthv_tval_el2",
|
||||
"cntvoff_el2",
|
||||
"pmevcntr0_el0",
|
||||
"pmevcntr1_el0",
|
||||
"pmevcntr2_el0",
|
||||
@@ -1604,14 +1636,6 @@ namespace ArmISA
|
||||
"pmevtyper3_el0",
|
||||
"pmevtyper4_el0",
|
||||
"pmevtyper5_el0",
|
||||
"cntvoff_el2",
|
||||
"cnthctl_el2",
|
||||
"cnthp_tval_el2",
|
||||
"cnthp_ctl_el2",
|
||||
"cnthp_cval_el2",
|
||||
"cntps_tval_el1",
|
||||
"cntps_ctl_el1",
|
||||
"cntps_cval_el1",
|
||||
"il1data0_el1",
|
||||
"il1data1_el1",
|
||||
"il1data2_el1",
|
||||
@@ -1630,9 +1654,6 @@ namespace ArmISA
|
||||
"contextidr_el2",
|
||||
|
||||
"ttbr1_el2",
|
||||
"cnthv_ctl_el2",
|
||||
"cnthv_cval_el2",
|
||||
"cnthv_tval_el2",
|
||||
"id_aa64mmfr2_el1",
|
||||
|
||||
"apdakeyhi_el1",
|
||||
@@ -1931,10 +1952,11 @@ namespace ArmISA
|
||||
* @param the misc reg indicating the coprocessor
|
||||
* @param the SCR
|
||||
* @param the CPSR
|
||||
* @param the thread context on the core
|
||||
* @return a tuple of booleans: can_read, undefined
|
||||
*/
|
||||
std::tuple<bool, bool> canReadCoprocReg(MiscRegIndex reg, SCR scr,
|
||||
CPSR cpsr);
|
||||
CPSR cpsr, ThreadContext *tc);
|
||||
|
||||
/**
|
||||
* Check for permission to write coprocessor registers.
|
||||
@@ -1947,10 +1969,15 @@ namespace ArmISA
|
||||
* @param the misc reg indicating the coprocessor
|
||||
* @param the SCR
|
||||
* @param the CPSR
|
||||
* @param the thread context on the core
|
||||
* @return a tuple of booleans: can_write, undefined
|
||||
*/
|
||||
std::tuple<bool, bool> canWriteCoprocReg(MiscRegIndex reg, SCR scr,
|
||||
CPSR cpsr);
|
||||
CPSR cpsr, ThreadContext *tc);
|
||||
|
||||
// Checks for UNDEFINED behaviours when accessing AArch32
|
||||
// Generic Timer system registers
|
||||
bool AArch32isUndefinedGenericTimer(MiscRegIndex reg, ThreadContext *tc);
|
||||
|
||||
// Checks read access permissions to AArch64 system registers
|
||||
bool canReadAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2014, 2016-2019 ARM Limited
|
||||
* Copyright (c) 2009-2014, 2016-2020 ARM Limited
|
||||
* All rights reserved.
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -511,8 +511,19 @@ roundPage(Addr addr)
|
||||
return (addr + PageBytes - 1) & ~(PageBytes - 1);
|
||||
}
|
||||
|
||||
Fault
|
||||
mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
|
||||
ThreadContext *tc, uint32_t imm)
|
||||
{
|
||||
ExceptionClass ec = EC_TRAPPED_CP15_MCR_MRC;
|
||||
if (mcrMrc15TrapToHyp(miscReg, tc, imm, &ec))
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm, ec);
|
||||
return AArch64AArch32SystemAccessTrap(miscReg, machInst, tc, imm, ec);
|
||||
}
|
||||
|
||||
bool
|
||||
mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss)
|
||||
mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss,
|
||||
ExceptionClass *ec)
|
||||
{
|
||||
bool isRead;
|
||||
uint32_t crm;
|
||||
@@ -647,6 +658,14 @@ mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss)
|
||||
trapToHype = hcr.imo;
|
||||
}
|
||||
break;
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTV_TVAL:
|
||||
// CNTFRQ may be trapped only on reads
|
||||
// CNTPCT and CNTVCT are read-only
|
||||
if (MISCREG_CNTFRQ <= miscReg && miscReg <= MISCREG_CNTVCT &&
|
||||
!isRead)
|
||||
break;
|
||||
trapToHype = isGenericTimerHypTrap(miscReg, tc, ec);
|
||||
break;
|
||||
// No default action needed
|
||||
default:
|
||||
break;
|
||||
@@ -707,9 +726,19 @@ mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
|
||||
return trapToHype;
|
||||
}
|
||||
|
||||
Fault
|
||||
mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
|
||||
ThreadContext *tc, uint32_t imm)
|
||||
{
|
||||
ExceptionClass ec = EC_TRAPPED_CP15_MCRR_MRRC;
|
||||
if (mcrrMrrc15TrapToHyp(miscReg, tc, imm, &ec))
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm, ec);
|
||||
return AArch64AArch32SystemAccessTrap(miscReg, machInst, tc, imm, ec);
|
||||
}
|
||||
|
||||
bool
|
||||
mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
|
||||
HCR hcr, uint32_t iss)
|
||||
mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
uint32_t iss, ExceptionClass *ec)
|
||||
{
|
||||
uint32_t crm;
|
||||
IntRegIndex rt;
|
||||
@@ -719,6 +748,11 @@ mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
|
||||
bool isRead;
|
||||
bool trapToHype = false;
|
||||
|
||||
const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR);
|
||||
const SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
const HSTR hstr = tc->readMiscReg(MISCREG_HSTR);
|
||||
|
||||
if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
|
||||
// This is technically the wrong function, but we can re-use it for
|
||||
// the moment because we only need one field, which overlaps with the
|
||||
@@ -746,6 +780,14 @@ mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
|
||||
case MISCREG_CONTEXTIDR:
|
||||
trapToHype = hcr.tvm & !isRead;
|
||||
break;
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTV_TVAL:
|
||||
// CNTFRQ may be trapped only on reads
|
||||
// CNTPCT and CNTVCT are read-only
|
||||
if (MISCREG_CNTFRQ <= miscReg && miscReg <= MISCREG_CNTVCT &&
|
||||
!isRead)
|
||||
break;
|
||||
trapToHype = isGenericTimerHypTrap(miscReg, tc, ec);
|
||||
break;
|
||||
// No default action needed
|
||||
default:
|
||||
break;
|
||||
@@ -755,6 +797,337 @@ mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
|
||||
return trapToHype;
|
||||
}
|
||||
|
||||
Fault
|
||||
AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg,
|
||||
ExtMachInst machInst, ThreadContext *tc,
|
||||
uint32_t imm, ExceptionClass ec)
|
||||
{
|
||||
if (currEL(tc) <= EL1 && !ELIs32(tc, EL1) &&
|
||||
isAArch64AArch32SystemAccessTrapEL1(miscReg, tc))
|
||||
return std::make_shared<SupervisorTrap>(machInst, imm, ec);
|
||||
if (currEL(tc) <= EL2 && EL2Enabled(tc) && !ELIs32(tc, EL2) &&
|
||||
isAArch64AArch32SystemAccessTrapEL2(miscReg, tc))
|
||||
return std::make_shared<HypervisorTrap>(machInst, imm, ec);
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
bool
|
||||
isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
return currEL(tc) == EL0 &&
|
||||
isGenericTimerSystemAccessTrapEL1(miscReg, tc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec)
|
||||
{
|
||||
if (currEL(tc) <= EL2 && EL2Enabled(tc) && ELIs32(tc, EL2)) {
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTV_TVAL:
|
||||
if (currEL(tc) == EL0 &&
|
||||
isGenericTimerCommonEL0HypTrap(miscReg, tc, ec))
|
||||
return true;
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
return currEL(tc) <= EL1 &&
|
||||
isGenericTimerPhysHypTrap(miscReg, tc, ec);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond = condGenericTimerSystemAccessTrapEL1(miscReg, tc);
|
||||
if (ELIs32(tc, EL1) && trap_cond && hcr.tge) {
|
||||
// As per the architecture, this hyp trap should have uncategorized
|
||||
// exception class
|
||||
if (ec)
|
||||
*ec = EC_UNKNOWN;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec)
|
||||
{
|
||||
return condGenericTimerPhysHypTrap(miscReg, tc);
|
||||
}
|
||||
|
||||
bool
|
||||
condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc)
|
||||
{
|
||||
const CNTHCTL cnthctl = tc->readMiscReg(MISCREG_CNTHCTL_EL2);
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
return !cnthctl.el1pcten;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
return !cnthctl.el1pcen;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond = condGenericTimerSystemAccessTrapEL1(miscReg, tc);
|
||||
return !(EL2Enabled(tc) && hcr.e2h && hcr.tge) && trap_cond &&
|
||||
!(EL2Enabled(tc) && !ELIs32(tc, EL2) && hcr.tge);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const CNTKCTL cntkctl = tc->readMiscReg(MISCREG_CNTKCTL_EL1);
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ:
|
||||
case MISCREG_CNTFRQ_EL0:
|
||||
return !cntkctl.el0pcten && !cntkctl.el0vcten;
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
return !cntkctl.el0pcten;
|
||||
case MISCREG_CNTVCT:
|
||||
case MISCREG_CNTVCT_EL0:
|
||||
return !cntkctl.el0vcten;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return !cntkctl.el0pten;
|
||||
case MISCREG_CNTV_CTL ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTV_CTL_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
return !cntkctl.el0vten;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTVOFF:
|
||||
return currEL(tc) <= EL1 &&
|
||||
isGenericTimerSystemAccessTrapEL2(miscReg, tc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTFRQ_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
if (currEL(tc) == EL0 &&
|
||||
isGenericTimerCommonEL0SystemAccessTrapEL2(miscReg, tc))
|
||||
return true;
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return (currEL(tc) == EL0 &&
|
||||
isGenericTimerPhysEL0SystemAccessTrapEL2(miscReg, tc)) ||
|
||||
(currEL(tc) == EL1 &&
|
||||
isGenericTimerPhysEL1SystemAccessTrapEL2(miscReg, tc));
|
||||
case MISCREG_CNTVCT:
|
||||
case MISCREG_CNTVCT_EL0:
|
||||
case MISCREG_CNTV_CTL ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTV_CTL_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
return isGenericTimerVirtSystemAccessTrapEL2(miscReg, tc);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond_el1 = condGenericTimerSystemAccessTrapEL1(miscReg, tc);
|
||||
bool trap_cond_el2 = condGenericTimerCommonEL0SystemAccessTrapEL2(miscReg,
|
||||
tc);
|
||||
return (!ELIs32(tc, EL1) && !hcr.e2h && trap_cond_el1 && hcr.tge) ||
|
||||
(ELIs32(tc, EL1) && trap_cond_el1 && hcr.tge) ||
|
||||
(hcr.e2h && hcr.tge && trap_cond_el2);
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond_0 = condGenericTimerPhysEL1SystemAccessTrapEL2(miscReg, tc);
|
||||
bool trap_cond_1 = condGenericTimerCommonEL1SystemAccessTrapEL2(miscReg,
|
||||
tc);
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
return !hcr.e2h && trap_cond_1;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return (!hcr.e2h && trap_cond_0) ||
|
||||
(hcr.e2h && !hcr.tge && trap_cond_1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond_0 = condGenericTimerPhysEL1SystemAccessTrapEL2(miscReg, tc);
|
||||
bool trap_cond_1 = condGenericTimerCommonEL1SystemAccessTrapEL2(miscReg,
|
||||
tc);
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
return trap_cond_1;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return (!hcr.e2h && trap_cond_0) ||
|
||||
(hcr.e2h && trap_cond_1);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
bool trap_cond = condGenericTimerCommonEL1SystemAccessTrapEL2(miscReg, tc);
|
||||
return !ELIs32(tc, EL1) && !(hcr.e2h && hcr.tge) && trap_cond;
|
||||
}
|
||||
|
||||
bool
|
||||
condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const CNTHCTL_E2H cnthctl = tc->readMiscReg(MISCREG_CNTHCTL_EL2);
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTFRQ:
|
||||
case MISCREG_CNTFRQ_EL0:
|
||||
return !cnthctl.el0pcten && !cnthctl.el0vcten;
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
return !cnthctl.el0pcten;
|
||||
case MISCREG_CNTVCT:
|
||||
case MISCREG_CNTVCT_EL0:
|
||||
return !cnthctl.el0vcten;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return !cnthctl.el0pten;
|
||||
case MISCREG_CNTV_CTL ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTV_CTL_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
return !cnthctl.el0vten;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
const RegVal cnthctl_val = tc->readMiscReg(MISCREG_CNTHCTL_EL2);
|
||||
const CNTHCTL cnthctl = cnthctl_val;
|
||||
const CNTHCTL_E2H cnthctl_e2h = cnthctl_val;
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPCT:
|
||||
case MISCREG_CNTPCT_EL0:
|
||||
return hcr.e2h ? !cnthctl_e2h.el1pcten : !cnthctl.el1pcten;
|
||||
case MISCREG_CNTVCT:
|
||||
case MISCREG_CNTVCT_EL0:
|
||||
return hcr.e2h ? cnthctl_e2h.el1tvct : cnthctl.el1tvct;
|
||||
case MISCREG_CNTP_CTL ... MISCREG_CNTP_TVAL_S:
|
||||
case MISCREG_CNTP_CTL_EL0 ... MISCREG_CNTP_TVAL_EL0:
|
||||
return hcr.e2h ? !cnthctl_e2h.el1pten : false;
|
||||
case MISCREG_CNTV_CTL ... MISCREG_CNTV_TVAL:
|
||||
case MISCREG_CNTV_CTL_EL0 ... MISCREG_CNTV_TVAL_EL0:
|
||||
return hcr.e2h ? cnthctl_e2h.el1tvt : cnthctl.el1tvt;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
const CNTHCTL cnthctl = tc->readMiscReg(MISCREG_CNTHCTL_EL2);
|
||||
return !cnthctl.el1pcen;
|
||||
}
|
||||
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc)
|
||||
{
|
||||
switch (miscReg) {
|
||||
case MISCREG_CNTPS_CTL_EL1 ... MISCREG_CNTPS_TVAL_EL1:
|
||||
{
|
||||
const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
|
||||
return currEL(tc) == EL1 && !scr.ns && !scr.st;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int ®Idx,
|
||||
CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2012-2013, 2016-2019 ARM Limited
|
||||
* Copyright (c) 2010, 2012-2013, 2016-2020 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
@@ -307,15 +307,80 @@ msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn,
|
||||
(op0 << 20);
|
||||
}
|
||||
|
||||
Fault
|
||||
mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
|
||||
ThreadContext *tc, uint32_t imm);
|
||||
bool
|
||||
mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss);
|
||||
mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss,
|
||||
ExceptionClass *ec = nullptr);
|
||||
|
||||
bool
|
||||
mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
|
||||
HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss);
|
||||
|
||||
Fault
|
||||
mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
|
||||
ThreadContext *tc, uint32_t imm);
|
||||
bool
|
||||
mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
|
||||
HCR hcr, uint32_t iss);
|
||||
mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
uint32_t iss, ExceptionClass *ec = nullptr);
|
||||
|
||||
Fault
|
||||
AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg,
|
||||
ExtMachInst machInst, ThreadContext *tc,
|
||||
uint32_t imm, ExceptionClass ec);
|
||||
bool
|
||||
isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec);
|
||||
bool condGenericTimerPhysHypTrap(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec);
|
||||
bool
|
||||
isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
|
||||
ExceptionClass *ec);
|
||||
bool
|
||||
condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
bool
|
||||
isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg,
|
||||
ThreadContext *tc);
|
||||
|
||||
bool SPAlignmentCheckEnabled(ThreadContext* tc);
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
namespace ArmISA
|
||||
{
|
||||
BitUnion64(CNTKCTL)
|
||||
// IF Armv8.6-ECV
|
||||
Bitfield<17> evntis;
|
||||
// ENDIF Armv8.6-ECV
|
||||
Bitfield<9> el0pten;
|
||||
Bitfield<8> el0vten;
|
||||
Bitfield<7,4> evnti;
|
||||
@@ -53,14 +56,30 @@ namespace ArmISA
|
||||
EndBitUnion(CNTKCTL)
|
||||
|
||||
BitUnion64(CNTHCTL)
|
||||
// IF Armv8.6-ECV
|
||||
Bitfield<17> evntis;
|
||||
Bitfield<16> el1nvvct;
|
||||
Bitfield<15> el1nvpct;
|
||||
Bitfield<14> el1tvct;
|
||||
Bitfield<13> el1tvt;
|
||||
Bitfield<12> ecv;
|
||||
// ENDIF Armv8.6-ECV
|
||||
Bitfield<7,4> evnti;
|
||||
Bitfield<3> evntdir;
|
||||
Bitfield<2> evnten;
|
||||
Bitfield<1> el1pcen;
|
||||
Bitfield<0> el1pcten;
|
||||
EndBitUnion(CNTHCTL)
|
||||
// If Armv8.1-VHE && HCR_EL2.E2H == 1
|
||||
// IF Armv8.1-VHE && HCR_EL2.E2H == 1
|
||||
BitUnion64(CNTHCTL_E2H)
|
||||
// IF Armv8.6-ECV
|
||||
Bitfield<17> evntis;
|
||||
Bitfield<16> el1nvvct;
|
||||
Bitfield<15> el1nvpct;
|
||||
Bitfield<14> el1tvct;
|
||||
Bitfield<13> el1tvt;
|
||||
Bitfield<12> ecv;
|
||||
// ENDIF Armv8.6-ECV
|
||||
Bitfield<11> el1pten;
|
||||
Bitfield<10> el1pcten;
|
||||
Bitfield<9> el0pten;
|
||||
@@ -71,6 +90,7 @@ namespace ArmISA
|
||||
Bitfield<1> el0vcten;
|
||||
Bitfield<0> el0pcten;
|
||||
EndBitUnion(CNTHCTL_E2H)
|
||||
// ENDIF Armv8.1-VHE && HCR_EL2.E2H == 1
|
||||
}
|
||||
|
||||
#endif // __DEV_ARM_GENERIC_TIMER_MISCREGS_TYPES_HH__
|
||||
|
||||
Reference in New Issue
Block a user