diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index e220f92168..febebda50e 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -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): diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 02129266cf..67031a1a9c 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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: diff --git a/src/arch/arm/regs/misc.cc b/src/arch/arm/regs/misc.cc index 9a01c1c89f..5d971f3e20 100644 --- a/src/arch/arm/regs/misc.cc +++ b/src/arch/arm/regs/misc.cc @@ -989,6 +989,7 @@ std::unordered_map 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 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 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 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 +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(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 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) + .faultWrite(EL1, faultSctlr2EL1) + .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) diff --git a/src/arch/arm/regs/misc.hh b/src/arch/arm/regs/misc.hh index 11d5188435..9e4d1cab84 100644 --- a/src/arch/arm/regs/misc.hh +++ b/src/arch/arm/regs/misc.hh @@ -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", diff --git a/src/arch/arm/regs/misc_types.hh b/src/arch/arm/regs/misc_types.hh index befee2a4de..c2cf5356ac 100644 --- a/src/arch/arm/regs/misc_types.hh +++ b/src/arch/arm/regs/misc_types.hh @@ -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 diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index 9051eaa151..926a7e3343 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -1355,5 +1355,16 @@ fgtEnabled(ThreadContext *tc) static_cast(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(tc->readMiscReg(MISCREG_SCR_EL3)).hxen) + return false; + return EL2Enabled(tc); +} + } // namespace ArmISA } // namespace gem5 diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index c231b93bdb..8ccb251fa5 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -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)