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 <giacomo.travaglini@arm.com>
This commit is contained in:
Giacomo Travaglini
2023-12-28 09:05:52 +00:00
parent e333a77c12
commit 458c98082c
13 changed files with 365 additions and 533 deletions

View File

@@ -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<Addr>(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<Addr>(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<Addr>(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<Addr>(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;
}

View File

@@ -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<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, false);
tlbiOp(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
static_cast<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, true);
tlbiOp(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
static_cast<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, false);
tlbiOp.broadcast(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
static_cast<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, true);
tlbiOp.broadcast(tc);
} else {
TLBIMVAA tlbiOp(EL2, secure,
TLBIMVAA tlbiOp(TranslationRegime::EL2, secure,
static_cast<Addr>(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<Addr>(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<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, false);
auto regime = ELIsInHost(tc, EL0) ?
TranslationRegime::EL20 : TranslationRegime::EL10;
TLBIMVA tlbiOp(regime, secure,
static_cast<Addr>(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<Addr>(bits(value, 43, 0)) << 12,
asid, true);
auto regime = ELIsInHost(tc, EL0) ?
TranslationRegime::EL20 : TranslationRegime::EL10;
TLBIMVA tlbiOp(regime, secure,
static_cast<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(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<Addr>(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;

View File

@@ -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<TCR>(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;

View File

@@ -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<bool, bool> s1PermBits64(
TlbEntry *te, const RequestPtr &req, Mode mode,
ThreadContext *tc, CachedState &state, bool r, bool w, bool x);

View File

@@ -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

View File

@@ -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<uint8_t>(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<uint8_t>(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]++;

View File

@@ -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;

View File

@@ -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<uint8_t>(entry.domain), entry.ns, entry.nstid,
entry.el == EL2);
entry.ap, static_cast<uint8_t>(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)

View File

@@ -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();

View File

@@ -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);
}
};

View File

@@ -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 &&

View File

@@ -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

View File

@@ -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