arch-arm: Implement FEAT_SCTLR2

Change-Id: Ifb8c8dc1729cc21007842b950273fe38129d9539
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
Giacomo Travaglini
2023-05-10 15:18:53 +01:00
parent c4c5d2e172
commit 49cbb24351
7 changed files with 116 additions and 2 deletions

View File

@@ -101,6 +101,8 @@ class ArmExtension(ScopedEnum):
"FEAT_FGT",
# Armv8.7
"FEAT_HCX",
# Armv8.9
"FEAT_SCTLR2",
# Armv9.2
"FEAT_SME", # Optional in Armv9.2
# Others
@@ -258,8 +260,14 @@ class Armv87(Armv86):
]
class Armv92(Armv87):
extensions = Armv87.extensions + ["FEAT_SME"]
class Armv89(Armv87):
extensions = Armv87.extensions + [
"FEAT_SCTLR2",
]
class Armv92(Armv89):
extensions = Armv89.extensions + ["FEAT_SME"]
class ArmAllRelease(ArmRelease):

View File

@@ -320,6 +320,8 @@ ISA::redirectRegVHE(int misc_reg)
return ELIsInHost(tc, currEL()) ? MISCREG_CNTPCT_EL0 : misc_reg;
case MISCREG_SCTLR_EL12:
return MISCREG_SCTLR_EL1;
case MISCREG_SCTLR2_EL12:
return MISCREG_SCTLR2_EL1;
case MISCREG_CPACR_EL12:
return MISCREG_CPACR_EL1;
case MISCREG_ZCR_EL12:

View File

@@ -989,6 +989,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 0, 1, 0, 0), MISCREG_SCTLR_EL1 },
{ MiscRegNum64(3, 0, 1, 0, 1), MISCREG_ACTLR_EL1 },
{ MiscRegNum64(3, 0, 1, 0, 2), MISCREG_CPACR_EL1 },
{ MiscRegNum64(3, 0, 1, 0, 3), MISCREG_SCTLR2_EL1 },
{ MiscRegNum64(3, 0, 1, 2, 0), MISCREG_ZCR_EL1 },
{ MiscRegNum64(3, 0, 1, 2, 4), MISCREG_SMPRI_EL1 },
{ MiscRegNum64(3, 0, 1, 2, 6), MISCREG_SMCR_EL1 },
@@ -1138,6 +1139,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 4, 0, 0, 5), MISCREG_VMPIDR_EL2 },
{ MiscRegNum64(3, 4, 1, 0, 0), MISCREG_SCTLR_EL2 },
{ MiscRegNum64(3, 4, 1, 0, 1), MISCREG_ACTLR_EL2 },
{ MiscRegNum64(3, 4, 1, 0, 3), MISCREG_SCTLR2_EL2 },
{ MiscRegNum64(3, 4, 1, 1, 0), MISCREG_HCR_EL2 },
{ MiscRegNum64(3, 4, 1, 1, 1), MISCREG_MDCR_EL2 },
{ MiscRegNum64(3, 4, 1, 1, 2), MISCREG_CPTR_EL2 },
@@ -1227,6 +1229,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 4, 14, 5, 2), MISCREG_CNTHPS_CVAL_EL2 },
{ MiscRegNum64(3, 5, 1, 0, 0), MISCREG_SCTLR_EL12 },
{ MiscRegNum64(3, 5, 1, 0, 2), MISCREG_CPACR_EL12 },
{ MiscRegNum64(3, 5, 1, 0, 3), MISCREG_SCTLR2_EL12 },
{ MiscRegNum64(3, 5, 1, 2, 0), MISCREG_ZCR_EL12 },
{ MiscRegNum64(3, 5, 1, 2, 6), MISCREG_SMCR_EL12 },
{ MiscRegNum64(3, 5, 2, 0, 0), MISCREG_TTBR0_EL12 },
@@ -1251,6 +1254,7 @@ std::unordered_map<MiscRegNum64, MiscRegIndex> miscRegNumToIdx{
{ MiscRegNum64(3, 5, 14, 3, 2), MISCREG_CNTV_CVAL_EL02 },
{ MiscRegNum64(3, 6, 1, 0, 0), MISCREG_SCTLR_EL3 },
{ MiscRegNum64(3, 6, 1, 0, 1), MISCREG_ACTLR_EL3 },
{ MiscRegNum64(3, 6, 1, 0, 3), MISCREG_SCTLR2_EL3 },
{ MiscRegNum64(3, 6, 1, 1, 0), MISCREG_SCR_EL3 },
{ MiscRegNum64(3, 6, 1, 1, 1), MISCREG_SDER32_EL3 },
{ MiscRegNum64(3, 6, 1, 1, 2), MISCREG_CPTR_EL3 },
@@ -1913,6 +1917,66 @@ faultIccSgiEL2(const MiscRegLUTEntry &entry,
}
}
template<bool read, auto g_bitfield>
Fault
faultSctlr2EL1(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_SCTLR2)) {
const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
const HCRX hcrx = tc->readMiscReg(MISCREG_HCRX_EL2);
if (auto fault = faultHcrFgtEL1<read, g_bitfield, &HFGTR::sctlrEL1>(entry, tc, inst);
fault != NoFault) {
return fault;
} else if (EL2Enabled(tc) && (!isHcrxEL2Enabled(tc) || !hcrx.sctlr2En)) {
return inst.generateTrap(EL2);
} else if (ArmSystem::haveEL(tc, EL3) && !scr.sctlr2En) {
return inst.generateTrap(EL3);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultSctlr2EL2(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_SCTLR2)) {
const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
if (ArmSystem::haveEL(tc, EL3) && !scr.sctlr2En) {
return inst.generateTrap(EL3);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
}
Fault
faultSctlr2VheEL2(const MiscRegLUTEntry &entry,
ThreadContext *tc, const MiscRegOp64 &inst)
{
if (HaveExt(tc, ArmExtension::FEAT_SCTLR2)) {
const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2);
const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
if (hcr.e2h) {
if (ArmSystem::haveEL(tc, EL3) && !scr.sctlr2En) {
return inst.generateTrap(EL3);
} else {
return NoFault;
}
} else {
return inst.undefined();
}
} else {
return inst.undefined();
}
}
template<bool read, auto r_bitfield>
Fault
faultCpacrEL1(const MiscRegLUTEntry &entry,
@@ -4369,6 +4433,7 @@ ISA::initializeMiscRegMetadata()
InitReg(MISCREG_ID_AA64MMFR3_EL1)
.reset([p,release=release](){
AA64MMFR3 mmfr3_el1 = 0;
mmfr3_el1.sctlrx = release->has(ArmExtension::FEAT_SCTLR2) ? 0x1 : 0x0;
return mmfr3_el1;
}())
.faultRead(EL0, faultIdst)
@@ -4486,6 +4551,15 @@ ISA::initializeMiscRegMetadata()
| (nTLSMD ? 0 : 0x8000000)
| (LSMAOE ? 0 : 0x10000000))
.mapsTo(MISCREG_SCTLR_EL1);
InitReg(MISCREG_SCTLR2_EL1)
.allPrivileges().exceptUserMode()
.faultRead(EL1, faultSctlr2EL1<true, &HCR::trvm>)
.faultWrite(EL1, faultSctlr2EL1<false, &HCR::tvm>)
.fault(EL2,faultSctlr2EL2);
InitReg(MISCREG_SCTLR2_EL12)
.fault(EL2, faultSctlr2VheEL2)
.fault(EL3, defaultFaultE2H_EL3)
.mapsTo(MISCREG_SCTLR2_EL1);
InitReg(MISCREG_ACTLR_EL1)
.allPrivileges().exceptUserMode()
.fault(EL1, faultHcrEL1<&HCR::tacr>)
@@ -4509,6 +4583,9 @@ ISA::initializeMiscRegMetadata()
| (EnIA ? 0 : 0x80000000))
.res1(0x30c50830)
.mapsTo(MISCREG_HSCTLR);
InitReg(MISCREG_SCTLR2_EL2)
.hyp().mon()
.fault(EL2, faultSctlr2EL2);
InitReg(MISCREG_ACTLR_EL2)
.hyp().mon()
.mapsTo(MISCREG_HACTLR);
@@ -4541,6 +4618,8 @@ ISA::initializeMiscRegMetadata()
| (EnIB ? 0 : 0x40000000)
| (EnIA ? 0 : 0x80000000))
.res1(0x30c50830);
InitReg(MISCREG_SCTLR2_EL3)
.mon();
InitReg(MISCREG_ACTLR_EL3)
.mon();
InitReg(MISCREG_SCR_EL3)

View File

@@ -583,10 +583,13 @@ namespace ArmISA
MISCREG_VMPIDR_EL2,
MISCREG_SCTLR_EL1,
MISCREG_SCTLR_EL12,
MISCREG_SCTLR2_EL1,
MISCREG_SCTLR2_EL12,
MISCREG_ACTLR_EL1,
MISCREG_CPACR_EL1,
MISCREG_CPACR_EL12,
MISCREG_SCTLR_EL2,
MISCREG_SCTLR2_EL2,
MISCREG_ACTLR_EL2,
MISCREG_HCR_EL2,
MISCREG_HCRX_EL2,
@@ -595,6 +598,7 @@ namespace ArmISA
MISCREG_HSTR_EL2,
MISCREG_HACR_EL2,
MISCREG_SCTLR_EL3,
MISCREG_SCTLR2_EL3,
MISCREG_ACTLR_EL3,
MISCREG_SCR_EL3,
MISCREG_SDER32_EL3,
@@ -2303,10 +2307,13 @@ namespace ArmISA
"vmpidr_el2",
"sctlr_el1",
"sctlr_el12",
"sctlr2_el1",
"sctlr2_el12",
"actlr_el1",
"cpacr_el1",
"cpacr_el12",
"sctlr_el2",
"sctlr2_el2",
"actlr_el2",
"hcr_el2",
"hcrx_el2",
@@ -2315,6 +2322,7 @@ namespace ArmISA
"hstr_el2",
"hacr_el2",
"sctlr_el3",
"sctlr2_el3",
"actlr_el3",
"scr_el3",
"sder32_el3",

View File

@@ -376,6 +376,7 @@ namespace ArmISA
EndBitUnion(NSACR)
BitUnion64(SCR)
Bitfield<44> sctlr2En;
Bitfield<40> trndr;
Bitfield<38> hxen;
Bitfield<27> fgten;
@@ -1058,6 +1059,10 @@ namespace ArmISA
Bitfield<0> afsr0EL1;
EndBitUnion(HFGTR)
BitUnion64(HCRX)
Bitfield<15> sctlr2En;
EndBitUnion(HCRX)
} // namespace ArmISA
} // namespace gem5

View File

@@ -1355,5 +1355,16 @@ fgtEnabled(ThreadContext *tc)
static_cast<SCR>(tc->readMiscReg(MISCREG_SCR_EL3)).fgten);
}
bool
isHcrxEL2Enabled(ThreadContext *tc)
{
if (!ArmSystem::has(ArmExtension::FEAT_HCX, tc))
return false;
if (ArmSystem::haveEL(tc, EL3) &&
!static_cast<SCR>(tc->readMiscReg(MISCREG_SCR_EL3)).hxen)
return false;
return EL2Enabled(tc);
}
} // namespace ArmISA
} // namespace gem5

View File

@@ -365,6 +365,7 @@ void syncVecRegsToElems(ThreadContext *tc);
void syncVecElemsToRegs(ThreadContext *tc);
bool fgtEnabled(ThreadContext *tc);
bool isHcrxEL2Enabled(ThreadContext *tc);
static inline bool
useVMID(ExceptionLevel el, bool in_host)