From 458c98082c1cdb75e09c1987847f1c89d1784f7d Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Thu, 28 Dec 2023 09:05:52 +0000 Subject: [PATCH] arch-arm: Replace EL based translation with regimes This is the final step in the transformation process. We limit the use of the "managing Exception Level" for a translation in favour of the more standard "Translation Regime" This greatly simplifies our code, especially with VHE where the managing el (EL2) could handle to different translation regimes (EL and EL2&0). We can therefore remove the isHost flag wherever it got used. That case is automatically handled by the proper regime value (EL2&0) Change-Id: Iafd1d2ce4757cfa6598656759694e5e7b05267ad Signed-off-by: Giacomo Travaglini --- src/arch/arm/insts/misc.cc | 62 +++--- src/arch/arm/insts/misc64.cc | 378 +++++++++++++---------------------- src/arch/arm/mmu.cc | 90 +++------ src/arch/arm/mmu.hh | 15 +- src/arch/arm/pagetable.hh | 45 ++--- src/arch/arm/table_walker.cc | 98 +++------ src/arch/arm/table_walker.hh | 7 +- src/arch/arm/tlb.cc | 22 +- src/arch/arm/tlbi_op.cc | 32 +-- src/arch/arm/tlbi_op.hh | 99 +++++---- src/arch/arm/types.hh | 25 +++ src/arch/arm/utility.cc | 19 ++ src/arch/arm/utility.hh | 6 +- 13 files changed, 365 insertions(+), 533 deletions(-) diff --git a/src/arch/arm/insts/misc.cc b/src/arch/arm/insts/misc.cc index 546d2caebb..9475a6c1c3 100644 --- a/src/arch/arm/insts/misc.cc +++ b/src/arch/arm/insts/misc.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2012-2013, 2017-2018, 2021 Arm Limited + * Copyright (c) 2010, 2012-2013, 2017-2018, 2021, 2023 Arm Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * @@ -411,7 +411,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALL tlbiOp(EL1, secure); + TLBIALL tlbiOp(TranslationRegime::EL10, secure); tlbiOp(tc); return; } @@ -421,7 +421,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALL tlbiOp(EL1, secure); + TLBIALL tlbiOp(TranslationRegime::EL10, secure); tlbiOp.broadcast(tc); return; } @@ -431,7 +431,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - ITLBIALL tlbiOp(EL1, secure); + ITLBIALL tlbiOp(TranslationRegime::EL10, secure); tlbiOp(tc); return; } @@ -441,7 +441,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - DTLBIALL tlbiOp(EL1, secure); + DTLBIALL tlbiOp(TranslationRegime::EL10, secure); tlbiOp(tc); return; } @@ -451,7 +451,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(EL1, + TLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0), @@ -466,7 +466,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(EL1, + TLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0), @@ -481,7 +481,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(EL1, + TLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0), @@ -496,7 +496,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(EL1, + TLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0), @@ -511,7 +511,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIASID tlbiOp(EL1, + TLBIASID tlbiOp(TranslationRegime::EL10, secure, bits(value, 7, 0)); @@ -524,7 +524,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIASID tlbiOp(EL1, + TLBIASID tlbiOp(TranslationRegime::EL10, secure, bits(value, 7, 0)); @@ -537,7 +537,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL1, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), false); tlbiOp(tc); @@ -549,7 +549,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL1, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), true); tlbiOp(tc); @@ -561,7 +561,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL1, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), false); tlbiOp.broadcast(tc); @@ -573,7 +573,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL1, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), true); tlbiOp.broadcast(tc); @@ -585,7 +585,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, mbits(value, 31, 12), false); tlbiOp(tc); @@ -597,7 +597,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, mbits(value, 31, 12), true); tlbiOp(tc); @@ -609,7 +609,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, mbits(value, 31, 12), false); tlbiOp.broadcast(tc); @@ -621,7 +621,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, mbits(value, 31, 12), true); tlbiOp.broadcast(tc); @@ -633,7 +633,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIIPA tlbiOp(EL1, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, false); @@ -648,7 +648,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIIPA tlbiOp(EL1, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, true); @@ -663,7 +663,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIIPA tlbiOp(EL1, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, false); @@ -678,7 +678,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIIPA tlbiOp(EL1, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, true); @@ -692,7 +692,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - ITLBIMVA tlbiOp(EL1, + ITLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0)); @@ -706,7 +706,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - DTLBIMVA tlbiOp(EL1, + DTLBIMVA tlbiOp(TranslationRegime::EL10, secure, mbits(value, 31, 12), bits(value, 7, 0)); @@ -720,7 +720,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - ITLBIASID tlbiOp(EL1, + ITLBIASID tlbiOp(TranslationRegime::EL10, secure, bits(value, 7, 0)); @@ -733,7 +733,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - DTLBIASID tlbiOp(EL1, + DTLBIASID tlbiOp(TranslationRegime::EL10, secure, bits(value, 7, 0)); @@ -743,28 +743,28 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const // TLB Invalidate All, Non-Secure Non-Hyp case MISCREG_TLBIALLNSNH: { - TLBIALLN tlbiOp(EL1); + TLBIALLN tlbiOp(TranslationRegime::EL10); tlbiOp(tc); return; } // TLB Invalidate All, Non-Secure Non-Hyp, Inner Shareable case MISCREG_TLBIALLNSNHIS: { - TLBIALLN tlbiOp(EL1); + TLBIALLN tlbiOp(TranslationRegime::EL10); tlbiOp.broadcast(tc); return; } // TLB Invalidate All, Hyp mode case MISCREG_TLBIALLH: { - TLBIALLN tlbiOp(EL2); + TLBIALLN tlbiOp(TranslationRegime::EL2); tlbiOp(tc); return; } // TLB Invalidate All, Hyp mode, Inner Shareable case MISCREG_TLBIALLHIS: { - TLBIALLN tlbiOp(EL2); + TLBIALLN tlbiOp(TranslationRegime::EL2); tlbiOp.broadcast(tc); return; } diff --git a/src/arch/arm/insts/misc64.cc b/src/arch/arm/insts/misc64.cc index 4cdf5611bb..d22adeee8e 100644 --- a/src/arch/arm/insts/misc64.cc +++ b/src/arch/arm/insts/misc64.cc @@ -258,7 +258,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons // AArch64 TLB Invalidate All, EL3 case MISCREG_TLBI_ALLE3: { - TLBIALLEL tlbiOp(EL3, true); + TLBIALLEL tlbiOp(TranslationRegime::EL3, true); tlbiOp(tc); return; } @@ -269,7 +269,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons // We therefore implement TLBIOS instructions as TLBIIS case MISCREG_TLBI_ALLE3OS: { - TLBIALLEL tlbiOp(EL3, true); + TLBIALLEL tlbiOp(TranslationRegime::EL3, true); tlbiOp.broadcast(tc); return; } @@ -279,7 +279,10 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALLEL tlbiOp(EL2, secure); + auto regime = ELIsInHost(tc, EL2) ? + TranslationRegime::EL20 : TranslationRegime::EL2; + + TLBIALLEL tlbiOp(regime, secure); tlbiOp(tc); return; } @@ -293,7 +296,10 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALLEL tlbiOp(EL2, secure); + auto regime = ELIsInHost(tc, EL2) ? + TranslationRegime::EL20 : TranslationRegime::EL2; + + TLBIALLEL tlbiOp(regime, secure); tlbiOp.broadcast(tc); return; } @@ -303,7 +309,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALLEL tlbiOp(EL1, secure); + TLBIALLEL tlbiOp(TranslationRegime::EL10, secure); tlbiOp(tc); return; } @@ -317,7 +323,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIALLEL tlbiOp(EL1, secure); + TLBIALLEL tlbiOp(TranslationRegime::EL10, secure); tlbiOp.broadcast(tc); return; } @@ -326,7 +332,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIVMALL tlbiOp(EL1, secure, true); + TLBIVMALL tlbiOp(TranslationRegime::EL10, secure, true); tlbiOp(tc); return; } @@ -334,16 +340,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIVMALL tlbiOp(target_el, secure, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIVMALL tlbiOp(regime, secure, false); tlbiOp(tc); return; } @@ -355,7 +356,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIVMALL tlbiOp(EL1, secure, true); + TLBIVMALL tlbiOp(TranslationRegime::EL10, secure, true); tlbiOp.broadcast(tc); return; } @@ -366,16 +367,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIVMALL tlbiOp(target_el, secure, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIVMALL tlbiOp(regime, secure, false); tlbiOp.broadcast(tc); return; } @@ -383,7 +379,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VAE3: { - TLBIMVAA tlbiOp(EL3, true, + TLBIMVAA tlbiOp(TranslationRegime::EL3, true, static_cast(bits(value, 43, 0)) << 12, false); tlbiOp(tc); @@ -393,7 +389,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VALE3: { - TLBIMVAA tlbiOp(EL3, true, + TLBIMVAA tlbiOp(TranslationRegime::EL3, true, static_cast(bits(value, 43, 0)) << 12, true); tlbiOp(tc); @@ -406,7 +402,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons // We therefore implement TLBIOS instructions as TLBIIS case MISCREG_TLBI_VAE3OS: { - TLBIMVAA tlbiOp(EL3, true, + TLBIMVAA tlbiOp(TranslationRegime::EL3, true, static_cast(bits(value, 43, 0)) << 12, false); @@ -420,7 +416,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons // We therefore implement TLBIOS instructions as TLBIIS case MISCREG_TLBI_VALE3OS: { - TLBIMVAA tlbiOp(EL3, true, + TLBIMVAA tlbiOp(TranslationRegime::EL3, true, static_cast(bits(value, 43, 0)) << 12, true); @@ -431,21 +427,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VAE2: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIMVA tlbiOp(EL2, secure, + TLBIMVA tlbiOp(TranslationRegime::EL20, secure, static_cast(bits(value, 43, 0)) << 12, asid, false); tlbiOp(tc); } else { - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, static_cast(bits(value, 43, 0)) << 12, false); tlbiOp(tc); @@ -456,21 +451,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VALE2: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIMVA tlbiOp(EL2, secure, + TLBIMVA tlbiOp(TranslationRegime::EL20, secure, static_cast(bits(value, 43, 0)) << 12, asid, true); tlbiOp(tc); } else { - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, static_cast(bits(value, 43, 0)) << 12, true); tlbiOp(tc); @@ -485,21 +479,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VAE2OS: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIMVA tlbiOp(EL2, secure, + TLBIMVA tlbiOp(TranslationRegime::EL20, secure, static_cast(bits(value, 43, 0)) << 12, asid, false); tlbiOp.broadcast(tc); } else { - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, static_cast(bits(value, 43, 0)) << 12, false); tlbiOp.broadcast(tc); @@ -514,21 +507,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_VALE2OS: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIMVA tlbiOp(EL2, secure, + TLBIMVA tlbiOp(TranslationRegime::EL20, secure, static_cast(bits(value, 43, 0)) << 12, asid, true); tlbiOp.broadcast(tc); } else { - TLBIMVAA tlbiOp(EL2, secure, + TLBIMVAA tlbiOp(TranslationRegime::EL2, secure, static_cast(bits(value, 43, 0)) << 12, true); tlbiOp.broadcast(tc); @@ -542,16 +534,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, asid, false); @@ -565,16 +552,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, asid, true); @@ -592,18 +574,13 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(target_el, secure, - static_cast(bits(value, 43, 0)) << 12, - asid, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVA tlbiOp(regime, secure, + static_cast(bits(value, 43, 0)) << 12, + asid, false); tlbiOp.broadcast(tc); return; @@ -614,18 +591,13 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVA tlbiOp(target_el, secure, - static_cast(bits(value, 43, 0)) << 12, - asid, true); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVA tlbiOp(regime, secure, + static_cast(bits(value, 43, 0)) << 12, + asid, true); tlbiOp.broadcast(tc); return; @@ -637,16 +609,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIASID tlbiOp(target_el, secure, asid); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIASID tlbiOp(regime, secure, asid); tlbiOp(tc); return; } @@ -661,16 +628,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIASID tlbiOp(target_el, secure, asid); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIASID tlbiOp(regime, secure, asid); tlbiOp.broadcast(tc); return; } @@ -679,16 +641,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVAA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, false); @@ -700,16 +657,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVAA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, true); @@ -725,16 +677,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVAA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, false); @@ -752,16 +699,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIMVAA tlbiOp(target_el, secure, + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIMVAA tlbiOp(regime, secure, static_cast(bits(value, 43, 0)) << 12, true); @@ -780,7 +722,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons const int top_bit = ArmSystem::physAddrRange(tc) == 52 ? 39 : 35; - TLBIIPA tlbiOp(EL1, secure, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, top_bit, 0)) << 12, false); @@ -798,7 +740,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIIPA tlbiOp(EL1, secure, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, true); @@ -823,7 +765,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons const int top_bit = ArmSystem::physAddrRange(tc) == 52 ? 39 : 35; - TLBIIPA tlbiOp(EL1, secure, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, top_bit, 0)) << 12, false); @@ -846,7 +788,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIIPA tlbiOp(EL1, secure, + TLBIIPA tlbiOp(TranslationRegime::EL10, secure, static_cast(bits(value, 35, 0)) << 12, true); @@ -860,16 +802,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVA tlbiOp(target_el, secure, value, asid, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVA tlbiOp(regime, secure, value, asid, false); if (tlbiOp.valid()) tlbiOp(tc); @@ -882,16 +819,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVA tlbiOp(target_el, secure, value, asid, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVA tlbiOp(regime, secure, value, asid, false); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -901,16 +833,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVAA tlbiOp(target_el, secure, value, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVAA tlbiOp(regime, secure, value, false); if (tlbiOp.valid()) tlbiOp(tc); @@ -921,16 +848,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVAA tlbiOp(target_el, secure, value, false); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVAA tlbiOp(regime, secure, value, false); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -942,16 +864,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVA tlbiOp(target_el, secure, value, asid, true); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVA tlbiOp(regime, secure, value, asid, true); if (tlbiOp.valid()) tlbiOp(tc); @@ -964,16 +881,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVA tlbiOp(target_el, secure, value, asid, true); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVA tlbiOp(regime, secure, value, asid, true); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -983,16 +895,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVAA tlbiOp(target_el, secure, value, true); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVAA tlbiOp(regime, secure, value, true); if (tlbiOp.valid()) tlbiOp(tc); @@ -1003,16 +910,11 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - ExceptionLevel target_el = EL1; - if (EL2Enabled(tc)) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - if (hcr.tge && hcr.e2h) { - target_el = EL2; - } - } - bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - TLBIRMVAA tlbiOp(target_el, secure, value, true); + auto regime = ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + + TLBIRMVAA tlbiOp(regime, secure, value, true); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -1026,7 +928,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIRIPA tlbiOp(EL1, secure, value, false); + TLBIRIPA tlbiOp(TranslationRegime::EL10, secure, value, false); tlbiOp(tc); } @@ -1040,7 +942,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIRIPA tlbiOp(EL1, secure, value, false); + TLBIRIPA tlbiOp(TranslationRegime::EL10, secure, value, false); tlbiOp.broadcast(tc); } @@ -1054,7 +956,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIRIPA tlbiOp(EL1, secure, value, true); + TLBIRIPA tlbiOp(TranslationRegime::EL10, secure, value, true); tlbiOp(tc); } @@ -1068,7 +970,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons bool secure = release->has(ArmExtension::SECURITY) && !scr.ns && !bits(value, 63); - TLBIRIPA tlbiOp(EL1, secure, value, true); + TLBIRIPA tlbiOp(TranslationRegime::EL10, secure, value, true); tlbiOp.broadcast(tc); } @@ -1077,21 +979,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVAE2: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIRMVA tlbiOp(EL2, secure, value, asid, false); + TLBIRMVA tlbiOp(TranslationRegime::EL20, secure, value, asid, false); if (tlbiOp.valid()) tlbiOp(tc); } else { - TLBIRMVAA tlbiOp(EL2, secure, value, false); + TLBIRMVAA tlbiOp(TranslationRegime::EL2, secure, value, false); if (tlbiOp.valid()) tlbiOp(tc); @@ -1102,21 +1003,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVAE2OS: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIRMVA tlbiOp(EL2, secure, value, asid, false); + TLBIRMVA tlbiOp(TranslationRegime::EL20, secure, value, asid, false); if (tlbiOp.valid()) tlbiOp.broadcast(tc); } else { - TLBIRMVAA tlbiOp(EL2, secure, value, false); + TLBIRMVAA tlbiOp(TranslationRegime::EL2, secure, value, false); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -1126,21 +1026,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVALE2: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIRMVA tlbiOp(EL2, secure, value, asid, true); + TLBIRMVA tlbiOp(TranslationRegime::EL20, secure, value, asid, true); if (tlbiOp.valid()) tlbiOp(tc); } else { - TLBIRMVAA tlbiOp(EL2, secure, value, true); + TLBIRMVAA tlbiOp(TranslationRegime::EL2, secure, value, true); if (tlbiOp.valid()) tlbiOp(tc); @@ -1151,21 +1050,20 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVALE2OS: { SCR scr = tc->readMiscReg(MISCREG_SCR_EL3); - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); bool secure = release->has(ArmExtension::SECURITY) && !scr.ns; - if (hcr.e2h) { + if (ELIsInHost(tc, EL2)) { // The asid will only be used when e2h == 1 auto asid = asid_16bits ? bits(value, 63, 48) : bits(value, 55, 48); - TLBIRMVA tlbiOp(EL2, secure, value, asid, true); + TLBIRMVA tlbiOp(TranslationRegime::EL20, secure, value, asid, true); if (tlbiOp.valid()) tlbiOp.broadcast(tc); } else { - TLBIRMVAA tlbiOp(EL2, secure, value, true); + TLBIRMVAA tlbiOp(TranslationRegime::EL2, secure, value, true); if (tlbiOp.valid()) tlbiOp.broadcast(tc); @@ -1174,7 +1072,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons } case MISCREG_TLBI_RVAE3: { - TLBIRMVAA tlbiOp(EL3, true, value, false); + TLBIRMVAA tlbiOp(TranslationRegime::EL3, true, value, false); if (tlbiOp.valid()) tlbiOp(tc); return; @@ -1182,14 +1080,14 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVAE3IS: case MISCREG_TLBI_RVAE3OS: { - TLBIRMVAA tlbiOp(EL3, true, value, false); + TLBIRMVAA tlbiOp(TranslationRegime::EL3, true, value, false); if (tlbiOp.valid()) tlbiOp.broadcast(tc); return; } case MISCREG_TLBI_RVALE3: { - TLBIRMVAA tlbiOp(EL3, true, value, true); + TLBIRMVAA tlbiOp(TranslationRegime::EL3, true, value, true); if (tlbiOp.valid()) tlbiOp(tc); return; @@ -1197,7 +1095,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons case MISCREG_TLBI_RVALE3IS: case MISCREG_TLBI_RVALE3OS: { - TLBIRMVAA tlbiOp(EL3, true, value, true); + TLBIRMVAA tlbiOp(TranslationRegime::EL3, true, value, true); if (tlbiOp.valid()) tlbiOp.broadcast(tc); return; diff --git a/src/arch/arm/mmu.cc b/src/arch/arm/mmu.cc index 604f2ee43b..2df2d9f932 100644 --- a/src/arch/arm/mmu.cc +++ b/src/arch/arm/mmu.cc @@ -180,8 +180,7 @@ MMU::translateFunctional(ThreadContext *tc, Addr va, Addr &pa) lookup_data.vmid = state.vmid; lookup_data.secure = state.isSecure; lookup_data.functional = true; - lookup_data.targetEL = state.aarch64EL; - lookup_data.inHost = false; + lookup_data.targetRegime = state.currRegime; lookup_data.mode = BaseMMU::Read; TlbEntry *e = tlb->multiLookup(lookup_data); @@ -638,8 +637,8 @@ MMU::s1PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode, return std::make_pair(false, false); } - ExceptionLevel regime = !is_priv ? EL0 : state.aarch64EL; - if (hasUnprivRegime(regime, state)) { + TranslationRegime regime = !is_priv ? TranslationRegime::EL10 : state.currRegime; + if (hasUnprivRegime(regime)) { bool pr = false; bool pw = false; bool ur = false; @@ -701,28 +700,17 @@ MMU::s1PermBits64(TlbEntry *te, const RequestPtr &req, Mode mode, } bool -MMU::hasUnprivRegime(ExceptionLevel el, bool e2h) +MMU::hasUnprivRegime(TranslationRegime regime) { - switch (el) { - case EL0: - case EL1: - // EL1&0 + switch (regime) { + case TranslationRegime::EL10: + case TranslationRegime::EL20: return true; - case EL2: - // EL2&0 or EL2 - return e2h; - case EL3: default: return false; } } -bool -MMU::hasUnprivRegime(ExceptionLevel el, CachedState &state) -{ - return hasUnprivRegime(el, state.hcr.e2h); -} - bool MMU::faultPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode, const bool is_priv, CachedState &state) @@ -778,7 +766,8 @@ MMU::checkPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode, } Addr -MMU::purifyTaggedAddr(Addr vaddr_tainted, ThreadContext *tc, ExceptionLevel el, +MMU::purifyTaggedAddr(Addr vaddr_tainted, ThreadContext *tc, + ExceptionLevel el, TCR tcr, bool is_inst, CachedState& state) { const bool selbit = bits(vaddr_tainted, 55); @@ -1210,37 +1199,15 @@ MMU::CachedState::updateMiscReg(ThreadContext *tc, !(tran_type & HypMode) && !(tran_type & S1S2NsTran); aarch64EL = tranTypeEL(cpsr, scr, tran_type); + currRegime = translationRegime(tc, aarch64EL); aarch64 = isStage2 ? ELIs64(tc, EL2) : ELIs64(tc, aarch64EL == EL0 ? EL1 : aarch64EL); if (aarch64) { // AArch64 // determine EL we need to translate in - switch (aarch64EL) { - case EL0: - if (HaveExt(tc, ArmExtension::FEAT_VHE) && - hcr.tge == 1 && hcr.e2h == 1) { - // VHE code for EL2&0 regime - sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2); - ttbcr = tc->readMiscReg(MISCREG_TCR_EL2); - uint64_t ttbr_asid = ttbcr.a1 ? - tc->readMiscReg(MISCREG_TTBR1_EL2) : - tc->readMiscReg(MISCREG_TTBR0_EL2); - asid = bits(ttbr_asid, - (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48); - - } else { - sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1); - ttbcr = tc->readMiscReg(MISCREG_TCR_EL1); - uint64_t ttbr_asid = ttbcr.a1 ? - tc->readMiscReg(MISCREG_TTBR1_EL1) : - tc->readMiscReg(MISCREG_TTBR0_EL1); - asid = bits(ttbr_asid, - (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48); - - } - break; - case EL1: + switch (currRegime) { + case TranslationRegime::EL10: { sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1); ttbcr = tc->readMiscReg(MISCREG_TCR_EL1); @@ -1251,21 +1218,24 @@ MMU::CachedState::updateMiscReg(ThreadContext *tc, (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48); } break; - case EL2: - sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2); - ttbcr = tc->readMiscReg(MISCREG_TCR_EL2); - if (hcr.e2h == 1) { + case TranslationRegime::EL20: + { // VHE code for EL2&0 regime + sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2); + ttbcr = tc->readMiscReg(MISCREG_TCR_EL2); uint64_t ttbr_asid = ttbcr.a1 ? tc->readMiscReg(MISCREG_TTBR1_EL2) : tc->readMiscReg(MISCREG_TTBR0_EL2); asid = bits(ttbr_asid, (mmu->haveLargeAsid64 && ttbcr.as) ? 63 : 55, 48); - } else { - asid = -1; } break; - case EL3: + case TranslationRegime::EL2: + sctlr = tc->readMiscReg(MISCREG_SCTLR_EL2); + ttbcr = tc->readMiscReg(MISCREG_TCR_EL2); + asid = -1; + break; + case TranslationRegime::EL3: sctlr = tc->readMiscReg(MISCREG_SCTLR_EL3); ttbcr = tc->readMiscReg(MISCREG_TCR_EL3); asid = -1; @@ -1399,8 +1369,8 @@ MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode, TlbEntry* MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool secure, - bool functional, bool ignore_asn, ExceptionLevel target_el, - bool in_host, bool stage2, BaseMMU::Mode mode) + bool functional, bool ignore_asn, TranslationRegime regime, + bool stage2, BaseMMU::Mode mode) { TLB *tlb = getTlb(mode, stage2); @@ -1412,8 +1382,7 @@ MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool secure, lookup_data.vmid = vmid; lookup_data.secure = secure; lookup_data.functional = functional; - lookup_data.targetEL = target_el; - lookup_data.inHost = in_host; + lookup_data.targetRegime = regime; lookup_data.mode = mode; return tlb->multiLookup(lookup_data); @@ -1433,16 +1402,17 @@ MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode, Addr vaddr_tainted = req->getVaddr(); Addr vaddr = 0; - ExceptionLevel target_el = state.aarch64EL; + TranslationRegime regime = state.currRegime; + if (state.aarch64) { - vaddr = purifyTaggedAddr(vaddr_tainted, tc, target_el, + vaddr = purifyTaggedAddr(vaddr_tainted, tc, state.aarch64EL, static_cast(state.ttbcr), mode==Execute, state); } else { vaddr = vaddr_tainted; } *te = lookup(vaddr, state.asid, state.vmid, is_secure, false, - false, target_el, false, state.isStage2, mode); + false, regime, state.isStage2, mode); if (!isCompleteTranslation(*te)) { if (req->isPrefetch()) { @@ -1472,7 +1442,7 @@ MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode, } *te = lookup(vaddr, state.asid, state.vmid, is_secure, - true, false, target_el, false, state.isStage2, mode); + true, false, regime, state.isStage2, mode); assert(*te); } return NoFault; diff --git a/src/arch/arm/mmu.hh b/src/arch/arm/mmu.hh index 9c59cd0026..5173c54c68 100644 --- a/src/arch/arm/mmu.hh +++ b/src/arch/arm/mmu.hh @@ -144,7 +144,8 @@ class MMU : public BaseMMU isStage2 = rhs.isStage2; cpsr = rhs.cpsr; aarch64 = rhs.aarch64; - aarch64EL = EL0; + aarch64EL = rhs.aarch64EL; + currRegime = rhs.currRegime; sctlr = rhs.sctlr; scr = rhs.scr; isPriv = rhs.isPriv; @@ -179,6 +180,7 @@ class MMU : public BaseMMU CPSR cpsr = 0; bool aarch64 = false; ExceptionLevel aarch64EL = EL0; + TranslationRegime currRegime = TranslationRegime::EL10; SCTLR sctlr = 0; SCR scr = 0; bool isPriv = false; @@ -388,7 +390,7 @@ class MMU : public BaseMMU */ static ExceptionLevel tranTypeEL(CPSR cpsr, SCR scr, ArmTranslationType type); - static bool hasUnprivRegime(ExceptionLevel el, bool e2h); + static bool hasUnprivRegime(TranslationRegime regime); public: /** Lookup an entry in the TLB @@ -398,15 +400,14 @@ class MMU : public BaseMMU * @param secure if the lookup is secure * @param functional if the lookup should modify state * @param ignore_asn if on lookup asn should be ignored - * @param target_el selecting the translation regime - * @param in_host if we are in host (EL2&0 regime) + * @param target_regime selecting the translation regime * @param mode to differentiate between read/writes/fetches. * @return pointer to TLB entry if it exists */ TlbEntry *lookup(Addr vpn, uint16_t asn, vmid_t vmid, bool secure, bool functional, - bool ignore_asn, ExceptionLevel target_el, - bool in_host, bool stage2, BaseMMU::Mode mode); + bool ignore_asn, TranslationRegime target_regime, + bool stage2, BaseMMU::Mode mode); Fault getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode mode, @@ -445,8 +446,6 @@ class MMU : public BaseMMU bool faultPAN(ThreadContext *tc, uint8_t ap, const RequestPtr &req, Mode mode, const bool is_priv, CachedState &state); - bool hasUnprivRegime(ExceptionLevel el, CachedState &state); - std::pair s1PermBits64( TlbEntry *te, const RequestPtr &req, Mode mode, ThreadContext *tc, CachedState &state, bool r, bool w, bool x); diff --git a/src/arch/arm/pagetable.hh b/src/arch/arm/pagetable.hh index 45652c4a1d..af70adb2ba 100644 --- a/src/arch/arm/pagetable.hh +++ b/src/arch/arm/pagetable.hh @@ -203,9 +203,7 @@ struct TlbEntry : public Serializable // if the lookup should modify state bool functional = false; // selecting the translation regime - ExceptionLevel targetEL = EL0; - // if we are in host (EL2&0 regime) - bool inHost = false; + TranslationRegime targetRegime = TranslationRegime::EL10; // mode to differentiate between read/writes/fetches. BaseMMU::Mode mode = BaseMMU::Read; }; @@ -243,8 +241,8 @@ struct TlbEntry : public Serializable bool ns; // True if the entry was brought in from a non-secure page table bool nstid; - // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1 - ExceptionLevel el; + // Translation regime on insert, AARCH64 EL0&1, AARCH32 -> el=1 + TranslationRegime regime; // This is used to distinguish between instruction and data entries // in unified TLBs TypeTLB type; @@ -271,8 +269,8 @@ struct TlbEntry : public Serializable innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3), domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), longDescFormat(false), global(false), valid(true), - ns(true), nstid(true), el(EL0), type(TypeTLB::unified), - partial(false), + ns(true), nstid(true), regime(TranslationRegime::EL10), + type(TypeTLB::unified), partial(false), nonCacheable(uncacheable), shareable(false), outerShareable(false), xn(0), pxn(0) { @@ -289,8 +287,8 @@ struct TlbEntry : public Serializable innerAttrs(0), outerAttrs(0), ap(0), hap(0x3), domain(DomainType::Client), mtype(MemoryType::StronglyOrdered), longDescFormat(false), global(false), valid(false), - ns(true), nstid(true), el(EL0), type(TypeTLB::unified), - partial(false), nonCacheable(false), + ns(true), nstid(true), regime(TranslationRegime::EL10), + type(TypeTLB::unified), partial(false), nonCacheable(false), shareable(false), outerShareable(false), xn(0), pxn(0) { // no restrictions by default, hap = 0x3 @@ -329,14 +327,14 @@ struct TlbEntry : public Serializable { bool match = false; if (valid && matchAddress(lookup) && - lookup.secure == !nstid) + (lookup.secure == !nstid)) { - match = checkELMatch(lookup.targetEL, lookup.inHost); + match = checkRegime(lookup.targetRegime); if (match && !lookup.ignoreAsn) { match = global || (lookup.asn == asid); } - if (match && useVMID(lookup.targetEL, lookup.inHost)) { + if (match && useVMID(lookup.targetRegime)) { match = lookup.vmid == vmid; } } @@ -344,21 +342,9 @@ struct TlbEntry : public Serializable } bool - checkELMatch(ExceptionLevel target_el, bool in_host) const + checkRegime(TranslationRegime target_regime) const { - switch (target_el) { - case EL3: - return el == EL3; - case EL2: - { - return el == EL2 || (el == EL0 && in_host); - } - case EL1: - case EL0: - return (el == EL0) || (el == EL1); - default: - return false; - } + return regime == target_regime; } Addr @@ -419,9 +405,10 @@ struct TlbEntry : public Serializable std::string print() const { - return csprintf("%#x, asn %d vmn %d hyp %d ppn %#x size: %#x ap:%d " - "ns:%d nstid:%d g:%d el:%d", vpn << N, asid, vmid, - el == EL2, pfn << N, size, ap, ns, nstid, global, el); + return csprintf("%#x, asn %d vmn %d ppn %#x size: %#x ap:%d " + "ns:%d nstid:%d g:%d regime:%s", vpn << N, asid, vmid, + pfn << N, size, ap, ns, nstid, global, + regimeToStr(regime)); } void diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 261c0d6c60..fa95e529c9 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -123,7 +123,8 @@ TableWalker::setMmu(MMU *_mmu) } TableWalker::WalkerState::WalkerState() : - tc(nullptr), aarch64(false), el(EL0), physAddrRange(0), req(nullptr), + tc(nullptr), aarch64(false), regime(TranslationRegime::EL10), + physAddrRange(0), req(nullptr), asid(0), vmid(0), transState(nullptr), vaddr(0), vaddr_tainted(0), sctlr(0), scr(0), cpsr(0), tcr(0), @@ -336,12 +337,15 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid, // even AArch32 EL0 will use AArch64 translation if EL1 is in AArch64. if (isStage2) { currState->el = EL1; + currState->regime = TranslationRegime::EL10; currState->aarch64 = ELIs64(_tc, EL2); } else { currState->el = MMU::tranTypeEL(_tc->readMiscReg(MISCREG_CPSR), _tc->readMiscReg(MISCREG_SCR_EL3), tranType); + currState->regime = + translationRegime(_tc, currState->el); currState->aarch64 = ELIs64(_tc, currState->el == EL0 ? EL1 : currState->el); } @@ -383,33 +387,24 @@ TableWalker::walk(const RequestPtr &_req, ThreadContext *_tc, uint16_t _asid, currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR_EL2); } - } else switch (currState->el) { - case EL0: - if (HaveExt(currState->tc, ArmExtension::FEAT_VHE) && - currState->hcr.tge == 1 && currState->hcr.e2h ==1) { - currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2); - currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2); - } else { - currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1); - currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1); - } - break; - case EL1: + } else switch (currState->regime) { + case TranslationRegime::EL10: currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL1); currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL1); break; - case EL2: + case TranslationRegime::EL20: + case TranslationRegime::EL2: assert(release->has(ArmExtension::VIRTUALIZATION)); currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL2); currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL2); break; - case EL3: + case TranslationRegime::EL3: assert(release->has(ArmExtension::SECURITY)); currState->sctlr = currState->tc->readMiscReg(MISCREG_SCTLR_EL3); currState->tcr = currState->tc->readMiscReg(MISCREG_TCR_EL3); break; default: - panic("Invalid exception level"); + panic("Invalid translation regime"); break; } } else { @@ -495,7 +490,7 @@ TableWalker::processWalkWrapper() // @TODO Should this always be the TLB or should we look in the stage2 TLB? TlbEntry* te = mmu->lookup(currState->vaddr, currState->asid, currState->vmid, currState->isSecure, true, false, - currState->el, false, isStage2, currState->mode); + currState->regime, isStage2, currState->mode); // Check if we still need to have a walk for this request. If the requesting // instruction has been squashed, or a previous walk has filled the TLB with @@ -567,7 +562,7 @@ TableWalker::processWalkWrapper() currState = pendingQueue.front(); te = mmu->lookup(currState->vaddr, currState->asid, currState->vmid, currState->isSecure, true, - false, currState->el, false, isStage2, currState->mode); + false, currState->regime, isStage2, currState->mode); } else { // Terminate the loop, nothing more to do currState = NULL; @@ -913,55 +908,8 @@ TableWalker::processWalkAArch64() currState->el); bool vaddr_fault = false; - switch (currState->el) { - case EL0: - { - Addr ttbr0; - Addr ttbr1; - if (HaveExt(currState->tc, ArmExtension::FEAT_VHE) && - currState->hcr.tge==1 && currState->hcr.e2h == 1) { - // VHE code for EL2&0 regime - ttbr0 = currState->tc->readMiscReg(MISCREG_TTBR0_EL2); - ttbr1 = currState->tc->readMiscReg(MISCREG_TTBR1_EL2); - } else { - ttbr0 = currState->tc->readMiscReg(MISCREG_TTBR0_EL1); - ttbr1 = currState->tc->readMiscReg(MISCREG_TTBR1_EL1); - } - switch (bits(currState->vaddr, 63,48)) { - case 0: - DPRINTF(TLB, " - Selecting TTBR0 (AArch64)\n"); - ttbr = ttbr0; - tsz = 64 - currState->tcr.t0sz; - tg = GrainMap_tg0[currState->tcr.tg0]; - currState->hpd = currState->tcr.hpd0; - currState->isUncacheable = currState->tcr.irgn0 == 0; - vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, - top_bit, tg, tsz, true); - - if (vaddr_fault || currState->tcr.epd0) - fault = true; - break; - case 0xffff: - DPRINTF(TLB, " - Selecting TTBR1 (AArch64)\n"); - ttbr = ttbr1; - tsz = 64 - currState->tcr.t1sz; - tg = GrainMap_tg1[currState->tcr.tg1]; - currState->hpd = currState->tcr.hpd1; - currState->isUncacheable = currState->tcr.irgn1 == 0; - vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, - top_bit, tg, tsz, false); - - if (vaddr_fault || currState->tcr.epd1) - fault = true; - break; - default: - // top two bytes must be all 0s or all 1s, else invalid addr - fault = true; - } - ps = currState->tcr.ips; - } - break; - case EL1: + switch (currState->regime) { + case TranslationRegime::EL10: if (isStage2) { if (currState->secureLookup) { DPRINTF(TLB, " - Selecting VSTTBR_EL2 (AArch64 stage 2)\n"); @@ -1010,7 +958,8 @@ TableWalker::processWalkAArch64() ps = currState->tcr.ips; } break; - case EL2: + case TranslationRegime::EL2: + case TranslationRegime::EL20: switch(bits(currState->vaddr, top_bit)) { case 0: DPRINTF(TLB, " - Selecting TTBR0_EL2 (AArch64)\n"); @@ -1047,7 +996,7 @@ TableWalker::processWalkAArch64() } ps = currState->hcr.e2h ? currState->tcr.ips: currState->tcr.ps; break; - case EL3: + case TranslationRegime::EL3: switch(bits(currState->vaddr, top_bit)) { case 0: DPRINTF(TLB, " - Selecting TTBR0_EL3 (AArch64)\n"); @@ -2302,8 +2251,7 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor) te.partial = true; // The entry is global if there is no address space identifier // to differentiate translation contexts - te.global = !mmu->hasUnprivRegime( - currState->el, currState->hcr.e2h); + te.global = !mmu->hasUnprivRegime(currState->regime); te.asid = currState->asid; te.vmid = currState->vmid; te.N = descriptor.offsetBits(); @@ -2317,7 +2265,7 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor) te.nstid = !currState->isSecure; te.type = TypeTLB::unified; - te.el = currState->el; + te.regime = currState->regime; te.xn = currState->xnTable; te.pxn = currState->pxnTable; @@ -2328,9 +2276,9 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor) DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n", te.N, te.pfn, te.size, te.global, te.valid); DPRINTF(TLB, " - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d " - "vmid:%d hyp:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn, + "vmid:%d nc:%d ns:%d\n", te.vpn, te.xn, te.pxn, te.ap, static_cast(te.domain), te.asid, te.vmid, - te.el == EL2, te.nonCacheable, te.ns); + te.nonCacheable, te.ns); DPRINTF(TLB, " - domain from L%d desc:%d data:%#x\n", descriptor.lookupLevel, static_cast(descriptor.domain()), descriptor.getRawData()); @@ -2362,7 +2310,7 @@ TableWalker::insertTableEntry(DescriptorBase &descriptor, bool long_descriptor) te.type = currState->mode == BaseMMU::Execute ? TypeTLB::instruction : TypeTLB::data; - te.el = currState->el; + te.regime = currState->regime; stats.pageSizes[pageSizeNtoStatBin(te.N)]++; stats.requestOrigin[COMPLETED][currState->isFetch]++; diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index 66a276d661..c970d04268 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2016, 2019, 2021-2022 Arm Limited + * Copyright (c) 2010-2016, 2019, 2021-2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -647,7 +647,7 @@ class TableWalker : public ClockedObject !currState->secureLookup)) { return false; // ARM ARM issue C B3.6.3 } else if (currState->aarch64) { - if (!MMU::hasUnprivRegime(currState->el, currState->hcr.e2h)) { + if (!MMU::hasUnprivRegime(currState->regime)) { // By default translations are treated as global // in AArch64 for regimes without an unpriviledged // component @@ -810,6 +810,9 @@ class TableWalker : public ClockedObject /** Current exception level */ ExceptionLevel el; + /** Current translation regime */ + TranslationRegime regime; + /** Current physical address range in bits */ int physAddrRange; diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc index a594766d25..4bceb28383 100644 --- a/src/arch/arm/tlb.cc +++ b/src/arch/arm/tlb.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2013, 2016-2022 Arm Limited + * Copyright (c) 2010-2013, 2016-2023 Arm Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -160,17 +160,17 @@ TLB::lookup(const Lookup &lookup_data) TlbEntry *retval = match(lookup_data); - DPRINTF(TLBVerbose, "Lookup %#x, asn %#x -> %s vmn 0x%x hyp %d secure %d " + DPRINTF(TLBVerbose, "Lookup %#x, asn %#x -> %s vmn 0x%x secure %d " "ppn %#x size: %#x pa: %#x ap:%d ns:%d nstid:%d g:%d asid: %d " - "el: %d\n", + "regime: %s\n", lookup_data.va, lookup_data.asn, retval ? "hit" : "miss", - lookup_data.vmid, lookup_data.targetEL == EL2, lookup_data.secure, + lookup_data.vmid, lookup_data.secure, retval ? retval->pfn : 0, retval ? retval->size : 0, retval ? retval->pAddr(lookup_data.va) : 0, retval ? retval->ap : 0, retval ? retval->ns : 0, retval ? retval->nstid : 0, retval ? retval->global : 0, retval ? retval->asid : 0, - retval ? retval->el : 0); + retval ? regimeToStr(retval->regime) : 0); // Updating stats if this was not a functional lookup if (!lookup_data.functional) { @@ -242,20 +242,20 @@ TLB::insert(TlbEntry &entry) { DPRINTF(TLB, "Inserting entry into TLB with pfn:%#x size:%#x vpn: %#x" " asid:%d vmid:%d N:%d global:%d valid:%d nc:%d xn:%d" - " ap:%#x domain:%#x ns:%d nstid:%d isHyp:%d\n", entry.pfn, + " ap:%#x domain:%#x ns:%d nstid:%d, regime: %s\n", entry.pfn, entry.size, entry.vpn, entry.asid, entry.vmid, entry.N, entry.global, entry.valid, entry.nonCacheable, entry.xn, - entry.ap, static_cast(entry.domain), entry.ns, entry.nstid, - entry.el == EL2); + entry.ap, static_cast(entry.domain), entry.ns, + entry.nstid, regimeToStr(entry.regime)); if (table[size - 1].valid) DPRINTF(TLB, " - Replacing Valid entry %#x, asn %d vmn %d ppn %#x " - "size: %#x ap:%d ns:%d nstid:%d g:%d isHyp: %d el: %d\n", + "size: %#x ap:%d ns:%d nstid:%d g:%d regime: %s\n", table[size-1].vpn << table[size-1].N, table[size-1].asid, table[size-1].vmid, table[size-1].pfn << table[size-1].N, table[size-1].size, table[size-1].ap, table[size-1].ns, - table[size-1].nstid, table[size-1].global, table[size-1].el == EL2, - table[size-1].el); + table[size-1].nstid, table[size-1].global, + regimeToStr(table[size-1].regime)); // inserting to MRU position and evicting the LRU one for (int i = size - 1; i > 0; --i) diff --git a/src/arch/arm/tlbi_op.cc b/src/arch/arm/tlbi_op.cc index 1e945cf33a..1080a64e4b 100644 --- a/src/arch/arm/tlbi_op.cc +++ b/src/arch/arm/tlbi_op.cc @@ -48,8 +48,6 @@ namespace ArmISA { void TLBIALL::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); el2Enabled = EL2Enabled(tc); currentEL = currEL(tc); @@ -67,7 +65,7 @@ TLBIALL::match(TlbEntry* te, vmid_t vmid) const { return te->valid && secureLookup == !te->nstid && (te->vmid == vmid || el2Enabled) && - te->checkELMatch(targetEL, inHost); + te->checkRegime(targetRegime); } void @@ -99,8 +97,6 @@ DTLBIALL::match(TlbEntry* te, vmid_t vmid) const void TLBIALLEL::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); getMMUPtr(tc)->flush(*this); // If CheckerCPU is connected, need to notify it of a flush @@ -114,14 +110,12 @@ bool TLBIALLEL::match(TlbEntry* te, vmid_t vmid) const { return te->valid && secureLookup == !te->nstid && - te->checkELMatch(targetEL, inHost); + te->checkRegime(targetRegime); } void TLBIVMALL::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->flush(*this); @@ -137,15 +131,13 @@ bool TLBIVMALL::match(TlbEntry* te, vmid_t vmid) const { return te->valid && secureLookup == !te->nstid && - te->checkELMatch(targetEL, inHost) && - (te->vmid == vmid || !el2Enabled || (!stage2Flush() && inHost)); + te->checkRegime(targetRegime) && + (te->vmid == vmid || !el2Enabled || !useVMID(targetRegime)); } void TLBIASID::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); el2Enabled = EL2Enabled(tc); getMMUPtr(tc)->flushStage1(*this); @@ -160,8 +152,8 @@ TLBIASID::match(TlbEntry* te, vmid_t vmid) const { return te->valid && te->asid == asid && secureLookup == !te->nstid && - te->checkELMatch(targetEL, inHost) && - (te->vmid == vmid || !el2Enabled || inHost); + te->checkRegime(targetRegime) && + (te->vmid == vmid || !el2Enabled || !useVMID(targetRegime)); } void @@ -205,7 +197,7 @@ bool TLBIALLN::match(TlbEntry* te, vmid_t vmid) const { return te->valid && te->nstid && - te->checkELMatch(targetEL, false); + te->checkRegime(targetRegime); } TlbEntry::Lookup @@ -217,8 +209,7 @@ TLBIMVAA::lookupGen(vmid_t vmid) const lookup_data.vmid = vmid; lookup_data.secure = secureLookup; lookup_data.functional = true; - lookup_data.targetEL = targetEL; - lookup_data.inHost = inHost; + lookup_data.targetRegime = targetRegime; lookup_data.mode = BaseMMU::Read; return lookup_data; } @@ -226,8 +217,6 @@ TLBIMVAA::lookupGen(vmid_t vmid) const void TLBIMVAA::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); getMMUPtr(tc)->flushStage1(*this); CheckerCPU *checker = tc->getCheckerCpuPtr(); @@ -254,8 +243,7 @@ TLBIMVA::lookupGen(vmid_t vmid) const lookup_data.vmid = vmid; lookup_data.secure = secureLookup; lookup_data.functional = true; - lookup_data.targetEL = targetEL; - lookup_data.inHost = inHost; + lookup_data.targetRegime = targetRegime; lookup_data.mode = BaseMMU::Read; return lookup_data; @@ -264,8 +252,6 @@ TLBIMVA::lookupGen(vmid_t vmid) const void TLBIMVA::operator()(ThreadContext* tc) { - HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2); - inHost = (hcr.tge == 1 && hcr.e2h == 1); getMMUPtr(tc)->flushStage1(*this); CheckerCPU *checker = tc->getCheckerCpuPtr(); diff --git a/src/arch/arm/tlbi_op.hh b/src/arch/arm/tlbi_op.hh index 38e8252869..c74a998e48 100644 --- a/src/arch/arm/tlbi_op.hh +++ b/src/arch/arm/tlbi_op.hh @@ -57,8 +57,8 @@ namespace ArmISA { class TLBIOp { public: - TLBIOp(ExceptionLevel _targetEL, bool _secure) - : secureLookup(_secure), targetEL(_targetEL) + TLBIOp(TranslationRegime _target_regime, bool _secure) + : secureLookup(_secure), targetRegime(_target_regime) {} virtual ~TLBIOp() {} @@ -101,15 +101,15 @@ class TLBIOp } bool secureLookup; - ExceptionLevel targetEL; + TranslationRegime targetRegime; }; /** TLB Invalidate All */ class TLBIALL : public TLBIOp { public: - TLBIALL(ExceptionLevel _targetEL, bool _secure) - : TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false), + TLBIALL(TranslationRegime _target_regime, bool _secure) + : TLBIOp(_target_regime, _secure), el2Enabled(false), currentEL(EL0) {} @@ -128,10 +128,9 @@ class TLBIALL : public TLBIOp TLBIALL makeStage2() const { - return TLBIALL(EL1, secureLookup); + return TLBIALL(targetRegime, secureLookup); } - bool inHost; bool el2Enabled; ExceptionLevel currentEL; }; @@ -140,8 +139,8 @@ class TLBIALL : public TLBIOp class ITLBIALL : public TLBIALL { public: - ITLBIALL(ExceptionLevel _targetEL, bool _secure) - : TLBIALL(_targetEL, _secure) + ITLBIALL(TranslationRegime _target_regime, bool _secure) + : TLBIALL(_target_regime, _secure) {} void broadcast(ThreadContext *tc) = delete; @@ -155,8 +154,8 @@ class ITLBIALL : public TLBIALL class DTLBIALL : public TLBIALL { public: - DTLBIALL(ExceptionLevel _targetEL, bool _secure) - : TLBIALL(_targetEL, _secure) + DTLBIALL(TranslationRegime _target_regime, bool _secure) + : TLBIALL(_target_regime, _secure) {} void broadcast(ThreadContext *tc) = delete; @@ -170,8 +169,8 @@ class DTLBIALL : public TLBIALL class TLBIALLEL : public TLBIOp { public: - TLBIALLEL(ExceptionLevel _targetEL, bool _secure) - : TLBIOp(_targetEL, _secure), inHost(false) + TLBIALLEL(TranslationRegime _target_regime, bool _secure) + : TLBIOp(_target_regime, _secure) {} void operator()(ThreadContext* tc) override; @@ -182,24 +181,24 @@ class TLBIALLEL : public TLBIOp stage2Flush() const override { // If we're targeting EL1 then flush stage2 as well - return targetEL == EL1; + return targetRegime == TranslationRegime::EL10 || + targetRegime == TranslationRegime::EL20; } TLBIALLEL makeStage2() const { - return TLBIALLEL(EL1, secureLookup); + return TLBIALLEL(targetRegime, secureLookup); } - bool inHost; }; /** Implementaton of AArch64 TLBI VMALLE1(IS)/VMALLS112E1(IS) instructions */ class TLBIVMALL : public TLBIOp { public: - TLBIVMALL(ExceptionLevel _targetEL, bool _secure, bool _stage2) - : TLBIOp(_targetEL, _secure), inHost(false), el2Enabled(false), + TLBIVMALL(TranslationRegime _target_regime, bool _secure, bool _stage2) + : TLBIOp(_target_regime, _secure), el2Enabled(false), stage2(_stage2) {} @@ -216,10 +215,9 @@ class TLBIVMALL : public TLBIOp TLBIVMALL makeStage2() const { - return TLBIVMALL(EL1, secureLookup, false); + return TLBIVMALL(targetRegime, secureLookup, false); } - bool inHost; bool el2Enabled; bool stage2; }; @@ -228,8 +226,8 @@ class TLBIVMALL : public TLBIOp class TLBIASID : public TLBIOp { public: - TLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid) - : TLBIOp(_targetEL, _secure), asid(_asid), inHost(false), + TLBIASID(TranslationRegime _target_regime, bool _secure, uint16_t _asid) + : TLBIOp(_target_regime, _secure), asid(_asid), el2Enabled(false) {} @@ -238,7 +236,6 @@ class TLBIASID : public TLBIOp bool match(TlbEntry *entry, vmid_t curr_vmid) const override; uint16_t asid; - bool inHost; bool el2Enabled; }; @@ -246,8 +243,8 @@ class TLBIASID : public TLBIOp class ITLBIASID : public TLBIASID { public: - ITLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid) - : TLBIASID(_targetEL, _secure, _asid) + ITLBIASID(TranslationRegime _target_regime, bool _secure, uint16_t _asid) + : TLBIASID(_target_regime, _secure, _asid) {} void broadcast(ThreadContext *tc) = delete; @@ -261,8 +258,8 @@ class ITLBIASID : public TLBIASID class DTLBIASID : public TLBIASID { public: - DTLBIASID(ExceptionLevel _targetEL, bool _secure, uint16_t _asid) - : TLBIASID(_targetEL, _secure, _asid) + DTLBIASID(TranslationRegime _target_regime, bool _secure, uint16_t _asid) + : TLBIASID(_target_regime, _secure, _asid) {} void broadcast(ThreadContext *tc) = delete; @@ -276,8 +273,8 @@ class DTLBIASID : public TLBIASID class TLBIALLN : public TLBIOp { public: - TLBIALLN(ExceptionLevel _targetEL) - : TLBIOp(_targetEL, false) + TLBIALLN(TranslationRegime _target_regime) + : TLBIOp(_target_regime, false) {} void operator()(ThreadContext* tc) override; @@ -287,13 +284,13 @@ class TLBIALLN : public TLBIOp bool stage2Flush() const override { - return targetEL != EL2; + return targetRegime != TranslationRegime::EL2; } TLBIALLN makeStage2() const { - return TLBIALLN(EL1); + return TLBIALLN(targetRegime); } }; @@ -303,9 +300,9 @@ class TLBIMVAA : public TLBIOp protected: TlbEntry::Lookup lookupGen(vmid_t vmid) const; public: - TLBIMVAA(ExceptionLevel _targetEL, bool _secure, + TLBIMVAA(TranslationRegime _target_regime, bool _secure, Addr _addr, bool last_level) - : TLBIOp(_targetEL, _secure), addr(_addr), inHost(false), + : TLBIOp(_target_regime, _secure), addr(_addr), lastLevel(last_level) {} @@ -314,7 +311,6 @@ class TLBIMVAA : public TLBIOp bool match(TlbEntry *entry, vmid_t curr_vmid) const override; Addr addr; - bool inHost; bool lastLevel; }; @@ -325,10 +321,10 @@ class TLBIMVA : public TLBIOp TlbEntry::Lookup lookupGen(vmid_t vmid) const; public: - TLBIMVA(ExceptionLevel _targetEL, bool _secure, + TLBIMVA(TranslationRegime _target_regime, bool _secure, Addr _addr, uint16_t _asid, bool last_level) - : TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid), - inHost(false), lastLevel(last_level) + : TLBIOp(_target_regime, _secure), addr(_addr), asid(_asid), + lastLevel(last_level) {} void operator()(ThreadContext* tc) override; @@ -337,7 +333,6 @@ class TLBIMVA : public TLBIOp Addr addr; uint16_t asid; - bool inHost; bool lastLevel; }; @@ -345,9 +340,9 @@ class TLBIMVA : public TLBIOp class ITLBIMVA : public TLBIMVA { public: - ITLBIMVA(ExceptionLevel _targetEL, bool _secure, + ITLBIMVA(TranslationRegime _target_regime, bool _secure, Addr _addr, uint16_t _asid) - : TLBIMVA(_targetEL, _secure, _addr, _asid, false) + : TLBIMVA(_target_regime, _secure, _addr, _asid, false) {} void broadcast(ThreadContext *tc) = delete; @@ -361,9 +356,9 @@ class ITLBIMVA : public TLBIMVA class DTLBIMVA : public TLBIMVA { public: - DTLBIMVA(ExceptionLevel _targetEL, bool _secure, + DTLBIMVA(TranslationRegime _target_regime, bool _secure, Addr _addr, uint16_t _asid) - : TLBIMVA(_targetEL, _secure, _addr, _asid, false) + : TLBIMVA(_target_regime, _secure, _addr, _asid, false) {} void broadcast(ThreadContext *tc) = delete; @@ -432,9 +427,9 @@ class TLBIRange class TLBIIPA : public TLBIOp { public: - TLBIIPA(ExceptionLevel _targetEL, bool _secure, Addr _addr, + TLBIIPA(TranslationRegime _target_regime, bool _secure, Addr _addr, bool last_level) - : TLBIOp(_targetEL, _secure), addr(_addr), lastLevel(last_level) + : TLBIOp(_target_regime, _secure), addr(_addr), lastLevel(last_level) {} void operator()(ThreadContext* tc) override; @@ -455,7 +450,7 @@ class TLBIIPA : public TLBIOp virtual TLBIMVAA makeStage2() const { - return TLBIMVAA(EL1, secureLookup, addr, lastLevel); + return TLBIMVAA(targetRegime, secureLookup, addr, lastLevel); } Addr addr; @@ -466,10 +461,10 @@ class TLBIIPA : public TLBIOp class TLBIRMVA : public TLBIRange, public TLBIMVA { public: - TLBIRMVA(ExceptionLevel _targetEL, bool _secure, + TLBIRMVA(TranslationRegime _target_regime, bool _secure, RegVal val, uint16_t _asid, bool last_level) : TLBIRange(val), - TLBIMVA(_targetEL, _secure, startAddress(), _asid, last_level) + TLBIMVA(_target_regime, _secure, startAddress(), _asid, last_level) {} bool match(TlbEntry *entry, vmid_t curr_vmid) const override; @@ -479,10 +474,10 @@ class TLBIRMVA : public TLBIRange, public TLBIMVA class TLBIRMVAA : public TLBIRange, public TLBIMVAA { public: - TLBIRMVAA(ExceptionLevel _targetEL, bool _secure, + TLBIRMVAA(TranslationRegime _target_regime, bool _secure, RegVal val, bool last_level) : TLBIRange(val), - TLBIMVAA(_targetEL, _secure, startAddress(), last_level) + TLBIMVAA(_target_regime, _secure, startAddress(), last_level) {} bool match(TlbEntry *entry, vmid_t curr_vmid) const override; @@ -492,16 +487,16 @@ class TLBIRMVAA : public TLBIRange, public TLBIMVAA class TLBIRIPA : public TLBIRange, public TLBIIPA { public: - TLBIRIPA(ExceptionLevel _targetEL, bool _secure, + TLBIRIPA(TranslationRegime _target_regime, bool _secure, RegVal val, bool last_level) : TLBIRange(val), - TLBIIPA(_targetEL, _secure, startAddress(), last_level) + TLBIIPA(_target_regime, _secure, startAddress(), last_level) {} virtual TLBIMVAA makeStage2() const { - return TLBIRMVAA(EL1, secureLookup, rangeData, lastLevel); + return TLBIRMVAA(targetRegime, secureLookup, rangeData, lastLevel); } }; diff --git a/src/arch/arm/types.hh b/src/arch/arm/types.hh index f7b6cbf86b..8d12356ec5 100644 --- a/src/arch/arm/types.hh +++ b/src/arch/arm/types.hh @@ -276,6 +276,14 @@ namespace ArmISA EL3 }; + enum class TranslationRegime + { + EL10, + EL20, + EL2, + EL3 + }; + enum OperatingMode { MODE_EL0T = 0x0, @@ -462,6 +470,23 @@ namespace ArmISA } } + static inline const char* + regimeToStr(TranslationRegime regime) + { + switch (regime) { + case TranslationRegime::EL10: + return "EL10"; + case TranslationRegime::EL20: + return "EL20"; + case TranslationRegime::EL2: + return "EL2"; + case TranslationRegime::EL3: + return "EL3"; + default: + GEM5_UNREACHABLE; + } + } + constexpr unsigned MaxSveVecLenInBits = 2048; static_assert(MaxSveVecLenInBits >= 128 && MaxSveVecLenInBits <= 2048 && diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index 926a7e3343..6966f15934 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -1366,5 +1366,24 @@ isHcrxEL2Enabled(ThreadContext *tc) return EL2Enabled(tc); } +TranslationRegime +translationRegime(ThreadContext *tc, ExceptionLevel el) +{ + switch (el) { + case EL3: + return TranslationRegime::EL3; + case EL2: + return ELIsInHost(tc, EL2) ? + TranslationRegime::EL20 : TranslationRegime::EL2; + case EL1: + return TranslationRegime::EL10; + case EL0: + return ELIsInHost(tc, EL0) ? + TranslationRegime::EL20 : TranslationRegime::EL10; + default: + panic("Invalid ExceptionLevel\n"); + } +} + } // namespace ArmISA } // namespace gem5 diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 8ccb251fa5..a1464e6a63 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -367,10 +367,12 @@ void syncVecElemsToRegs(ThreadContext *tc); bool fgtEnabled(ThreadContext *tc); bool isHcrxEL2Enabled(ThreadContext *tc); +TranslationRegime translationRegime(ThreadContext *tc, ExceptionLevel el); + static inline bool -useVMID(ExceptionLevel el, bool in_host) +useVMID(TranslationRegime regime) { - return el == EL1 || (el == EL0 && !in_host); + return regime == TranslationRegime::EL10; } } // namespace ArmISA