diff --git a/src/arch/arm/ArmSystem.py b/src/arch/arm/ArmSystem.py index e220f92168..f66c9c83d2 100644 --- a/src/arch/arm/ArmSystem.py +++ b/src/arch/arm/ArmSystem.py @@ -101,6 +101,9 @@ class ArmExtension(ScopedEnum): "FEAT_FGT", # Armv8.7 "FEAT_HCX", + # Armv8.9 + "FEAT_SCTLR2", + "FEAT_TCR2", # Armv9.2 "FEAT_SME", # Optional in Armv9.2 # Others @@ -258,8 +261,12 @@ class Armv87(Armv86): ] -class Armv92(Armv87): - extensions = Armv87.extensions + ["FEAT_SME"] +class Armv89(Armv87): + extensions = Armv87.extensions + ["FEAT_SCTLR2", "FEAT_TCR2"] + + +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..a395d1a35f 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: @@ -330,6 +332,8 @@ ISA::redirectRegVHE(int misc_reg) return MISCREG_TTBR1_EL1; case MISCREG_TCR_EL12: return MISCREG_TCR_EL1; + case MISCREG_TCR2_EL12: + return MISCREG_TCR2_EL1; case MISCREG_SPSR_EL12: return MISCREG_SPSR_EL1; case MISCREG_ELR_EL12: diff --git a/src/arch/arm/regs/misc.cc b/src/arch/arm/regs/misc.cc index 57d0de1686..039717a8b7 100644 --- a/src/arch/arm/regs/misc.cc +++ b/src/arch/arm/regs/misc.cc @@ -981,7 +981,7 @@ std::unordered_map miscRegNumToIdx{ { MiscRegNum64(3, 0, 0, 7, 0), MISCREG_ID_AA64MMFR0_EL1 }, { MiscRegNum64(3, 0, 0, 7, 1), MISCREG_ID_AA64MMFR1_EL1 }, { MiscRegNum64(3, 0, 0, 7, 2), MISCREG_ID_AA64MMFR2_EL1 }, - { MiscRegNum64(3, 0, 0, 7, 3), MISCREG_RAZ }, + { MiscRegNum64(3, 0, 0, 7, 3), MISCREG_ID_AA64MMFR3_EL1 }, { MiscRegNum64(3, 0, 0, 7, 4), MISCREG_RAZ }, { MiscRegNum64(3, 0, 0, 7, 5), MISCREG_RAZ }, { MiscRegNum64(3, 0, 0, 7, 6), MISCREG_RAZ }, @@ -989,12 +989,14 @@ 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 }, { MiscRegNum64(3, 0, 2, 0, 0), MISCREG_TTBR0_EL1 }, { MiscRegNum64(3, 0, 2, 0, 1), MISCREG_TTBR1_EL1 }, { MiscRegNum64(3, 0, 2, 0, 2), MISCREG_TCR_EL1 }, + { MiscRegNum64(3, 0, 2, 0, 3), MISCREG_TCR2_EL1 }, { MiscRegNum64(3, 0, 2, 1, 0), MISCREG_APIAKeyLo_EL1 }, { MiscRegNum64(3, 0, 2, 1, 1), MISCREG_APIAKeyHi_EL1 }, { MiscRegNum64(3, 0, 2, 1, 2), MISCREG_APIBKeyLo_EL1 }, @@ -1138,6 +1140,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 }, @@ -1153,6 +1156,7 @@ std::unordered_map miscRegNumToIdx{ { MiscRegNum64(3, 4, 2, 0, 0), MISCREG_TTBR0_EL2 }, { MiscRegNum64(3, 4, 2, 0, 1), MISCREG_TTBR1_EL2 }, { MiscRegNum64(3, 4, 2, 0, 2), MISCREG_TCR_EL2 }, + { MiscRegNum64(3, 4, 2, 0, 3), MISCREG_TCR2_EL2 }, { MiscRegNum64(3, 4, 2, 1, 0), MISCREG_VTTBR_EL2 }, { MiscRegNum64(3, 4, 2, 1, 2), MISCREG_VTCR_EL2 }, { MiscRegNum64(3, 4, 2, 6, 0), MISCREG_VSTTBR_EL2 }, @@ -1227,11 +1231,13 @@ 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 }, { MiscRegNum64(3, 5, 2, 0, 1), MISCREG_TTBR1_EL12 }, { MiscRegNum64(3, 5, 2, 0, 2), MISCREG_TCR_EL12 }, + { MiscRegNum64(3, 5, 2, 0, 3), MISCREG_TCR2_EL12 }, { MiscRegNum64(3, 5, 4, 0, 0), MISCREG_SPSR_EL12 }, { MiscRegNum64(3, 5, 4, 0, 1), MISCREG_ELR_EL12 }, { MiscRegNum64(3, 5, 5, 1, 0), MISCREG_AFSR0_EL12 }, @@ -1251,6 +1257,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 +1920,143 @@ 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 +faultTcr2EL1(const MiscRegLUTEntry &entry, + ThreadContext *tc, const MiscRegOp64 &inst) +{ + if (HaveExt(tc, ArmExtension::FEAT_TCR2)) { + 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.tcr2En)) { + return inst.generateTrap(EL2); + } else if (ArmSystem::haveEL(tc, EL3) && !scr.tcr2En) { + return inst.generateTrap(EL3); + } else { + return NoFault; + } + } else { + return inst.undefined(); + } +} + +Fault +faultTcr2EL2(const MiscRegLUTEntry &entry, + ThreadContext *tc, const MiscRegOp64 &inst) +{ + if (HaveExt(tc, ArmExtension::FEAT_TCR2)) { + const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); + if (ArmSystem::haveEL(tc, EL3) && !scr.tcr2En) { + return inst.generateTrap(EL3); + } else { + return NoFault; + } + } else { + return inst.undefined(); + } +} + +Fault +faultTcr2VheEL2(const MiscRegLUTEntry &entry, + ThreadContext *tc, const MiscRegOp64 &inst) +{ + if (HaveExt(tc, ArmExtension::FEAT_TCR2)) { + 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.tcr2En) { + return inst.generateTrap(EL3); + } else { + return NoFault; + } + } else { + return inst.undefined(); + } + } else { + return inst.undefined(); + } +} + +Fault +faultTcr2VheEL3(const MiscRegLUTEntry &entry, + ThreadContext *tc, const MiscRegOp64 &inst) +{ + if (HaveExt(tc, ArmExtension::FEAT_TCR2)) { + const HCR hcr = tc->readMiscRegNoEffect(MISCREG_HCR_EL2); + const bool el2_host = EL2Enabled(tc) && hcr.e2h; + if (el2_host) { + return NoFault; + } else { + return inst.undefined(); + } + } else { + return inst.undefined(); + } +} + template Fault faultCpacrEL1(const MiscRegLUTEntry &entry, @@ -4366,6 +4510,16 @@ ISA::initializeMiscRegMetadata() .faultRead(EL0, faultIdst) .faultRead(EL1, faultHcrEL1<&HCR::tid3>) .allPrivileges().writes(0); + InitReg(MISCREG_ID_AA64MMFR3_EL1) + .reset([p,release=release](){ + AA64MMFR3 mmfr3_el1 = 0; + mmfr3_el1.sctlrx = release->has(ArmExtension::FEAT_SCTLR2) ? 0x1 : 0x0; + mmfr3_el1.tcrx = release->has(ArmExtension::FEAT_TCR2) ? 0x1 : 0x0; + return mmfr3_el1; + }()) + .faultRead(EL0, faultIdst) + .faultRead(EL1, faultHcrEL1<&HCR::tid3>) + .allPrivileges().writes(0); InitReg(MISCREG_APDAKeyHi_EL1) .faultRead(EL1, faultPauthEL1) @@ -4478,6 +4632,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>) @@ -4501,6 +4664,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); @@ -4533,6 +4699,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) @@ -4573,6 +4741,15 @@ ISA::initializeMiscRegMetadata() .fault(EL2, defaultFaultE2H_EL2) .fault(EL3, defaultFaultE2H_EL3) .mapsTo(MISCREG_TTBCR_NS); + InitReg(MISCREG_TCR2_EL1) + .allPrivileges().exceptUserMode() + .faultRead(EL1, faultTcr2EL1) + .faultWrite(EL1, faultTcr2EL1) + .fault(EL2, faultTcr2EL2); + InitReg(MISCREG_TCR2_EL12) + .fault(EL2, faultTcr2VheEL2) + .fault(EL3, faultTcr2VheEL3) + .mapsTo(MISCREG_TCR2_EL1); InitReg(MISCREG_TTBR0_EL2) .hyp().mon() .mapsTo(MISCREG_HTTBR); @@ -4581,6 +4758,9 @@ ISA::initializeMiscRegMetadata() InitReg(MISCREG_TCR_EL2) .hyp().mon() .mapsTo(MISCREG_HTCR); + InitReg(MISCREG_TCR2_EL2) + .hyp().mon() + .fault(EL2, faultTcr2EL2); InitReg(MISCREG_VTTBR_EL2) .hyp().mon() .mapsTo(MISCREG_VTTBR); diff --git a/src/arch/arm/regs/misc.hh b/src/arch/arm/regs/misc.hh index b6aaee0d2f..6a4933c5d6 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, @@ -606,8 +610,11 @@ namespace ArmISA MISCREG_TTBR1_EL12, MISCREG_TCR_EL1, MISCREG_TCR_EL12, + MISCREG_TCR2_EL1, + MISCREG_TCR2_EL12, MISCREG_TTBR0_EL2, MISCREG_TCR_EL2, + MISCREG_TCR2_EL2, MISCREG_VTTBR_EL2, MISCREG_VTCR_EL2, MISCREG_VSTTBR_EL2, @@ -872,6 +879,7 @@ namespace ArmISA MISCREG_TTBR1_EL2, MISCREG_ID_AA64MMFR2_EL1, + MISCREG_ID_AA64MMFR3_EL1, //PAuth Key Regsiters MISCREG_APDAKeyHi_EL1, @@ -2302,10 +2310,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", @@ -2314,6 +2325,7 @@ namespace ArmISA "hstr_el2", "hacr_el2", "sctlr_el3", + "sctlr2_el3", "actlr_el3", "scr_el3", "sder32_el3", @@ -2325,8 +2337,11 @@ namespace ArmISA "ttbr1_el12", "tcr_el1", "tcr_el12", + "tcr2_el1", + "tcr2_el12", "ttbr0_el2", "tcr_el2", + "tcr2_el2", "vttbr_el2", "vtcr_el2", "vsttbr_el2", @@ -2585,6 +2600,7 @@ namespace ArmISA "ttbr1_el2", "id_aa64mmfr2_el1", + "id_aa64mmfr3_el1", "apdakeyhi_el1", "apdakeylo_el1", diff --git a/src/arch/arm/regs/misc_types.hh b/src/arch/arm/regs/misc_types.hh index f9a16c297a..abbe2afa98 100644 --- a/src/arch/arm/regs/misc_types.hh +++ b/src/arch/arm/regs/misc_types.hh @@ -187,6 +187,21 @@ namespace ArmISA Bitfield<3, 0> cnp; EndBitUnion(AA64MMFR2) + BitUnion64(AA64MMFR3) + Bitfield<47, 44> anerr; + Bitfield<43, 40> snerr; + Bitfield<39, 36> d128_2; + Bitfield<35, 32> d128; + Bitfield<31, 28> mec; + Bitfield<27, 24> aie; + Bitfield<23, 20> s2poe; + Bitfield<19, 16> s1poe; + Bitfield<15, 12> s2pie; + Bitfield<11, 8> s1pie; + Bitfield<7, 4> sctlrx; + Bitfield<3, 0> tcrx; + EndBitUnion(AA64MMFR3) + BitUnion64(AA64PFR0) Bitfield<63, 60> csv3; Bitfield<59, 56> csv2; @@ -361,6 +376,8 @@ namespace ArmISA EndBitUnion(NSACR) BitUnion64(SCR) + Bitfield<44> sctlr2En; + Bitfield<43> tcr2En; Bitfield<40> trndr; Bitfield<38> hxen; Bitfield<27> fgten; @@ -1043,6 +1060,11 @@ namespace ArmISA Bitfield<0> afsr0EL1; EndBitUnion(HFGTR) + BitUnion64(HCRX) + Bitfield<15> sctlr2En; + Bitfield<14> tcr2En; + 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)