arch-arm: Properly implement last level TLBIs
Prior to gem5 v21.2, partial translation entries were not cached within the TLB, therefore Last Level (only) TLBI instructions were invalidating every entry. Now that we store translations from several lookup levels we are currently over-invalidating partial translations. This patch is adding a boolean flag to TLBIMVAA and TLBIMVA, allowing to discard a match if the TLBI is targeting complete translations only and the entry holds a partial translation Change-Id: I86fa39c962355d9c566ee8aa29bebcd9967c8c57 Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/62453 Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -446,10 +446,21 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA
|
||||
// mcr tlbimval(is) is invalidating all matching entries
|
||||
// regardless of the level of lookup, since in gem5 we cache
|
||||
// in the tlb the last level of lookup only.
|
||||
case MISCREG_TLBIMVA:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
false);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Last Level
|
||||
case MISCREG_TLBIMVAL:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -458,13 +469,28 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0),
|
||||
true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Inner Shareable
|
||||
case MISCREG_TLBIMVAIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7, 0),
|
||||
false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Last Level, Inner Shareable
|
||||
case MISCREG_TLBIMVALIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -473,7 +499,8 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
TLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0),
|
||||
true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
@@ -486,7 +513,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
@@ -499,74 +526,123 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// mcr tlbimvaal(is) is invalidating all matching entries
|
||||
// regardless of the level of lookup, since in gem5 we cache
|
||||
// in the tlb the last level of lookup only.
|
||||
// TLB Invalidate by VA, All ASID
|
||||
case MISCREG_TLBIMVAA:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Last Level, All ASID
|
||||
case MISCREG_TLBIMVAAL:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31,12));
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, All ASID, Inner Shareable
|
||||
case MISCREG_TLBIMVAAIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, All ASID, Last Level, Inner Shareable
|
||||
case MISCREG_TLBIMVAALIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL1, secure,
|
||||
mbits(value, 31,12));
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// mcr tlbimvalh(is) is invalidating all matching entries
|
||||
// regardless of the level of lookup, since in gem5 we cache
|
||||
// in the tlb the last level of lookup only.
|
||||
// TLB Invalidate by VA, Hyp mode
|
||||
case MISCREG_TLBIMVAH:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Last Level, Hyp mode
|
||||
case MISCREG_TLBIMVALH:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31,12));
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Hyp mode, Inner Shareable
|
||||
case MISCREG_TLBIMVAHIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31, 12), false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by VA, Hyp mode, Last Level, Inner Shareable
|
||||
case MISCREG_TLBIMVALHIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
mbits(value, 31,12));
|
||||
mbits(value, 31, 12), true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// mcr tlbiipas2l(is) is invalidating all matching entries
|
||||
// regardless of the level of lookup, since in gem5 we cache
|
||||
// in the tlb the last level of lookup only.
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2
|
||||
case MISCREG_TLBIIPAS2:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2,
|
||||
// Last Level
|
||||
case MISCREG_TLBIIPAS2L:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -574,7 +650,8 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
@@ -582,6 +659,20 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2,
|
||||
// Inner Shareable
|
||||
case MISCREG_TLBIIPAS2IS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// TLB Invalidate by Intermediate Physical Address, Stage 2,
|
||||
// Last Level, Inner Shareable
|
||||
case MISCREG_TLBIIPAS2LIS:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -589,7 +680,8 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIIPA tlbiOp(EL1,
|
||||
secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
@@ -603,7 +695,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
ITLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
@@ -617,7 +709,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
DTLBIMVA tlbiOp(EL1,
|
||||
secure,
|
||||
mbits(value, 31, 12),
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
@@ -630,7 +722,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
ITLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
@@ -643,7 +735,7 @@ TlbiOp::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) const
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
DTLBIASID tlbiOp(EL1,
|
||||
secure,
|
||||
bits(value, 7,0));
|
||||
bits(value, 7, 0));
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
|
||||
@@ -338,31 +338,72 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// VAEx(IS) and VALEx(IS) are the same because TLBs
|
||||
// only store entries
|
||||
// from the last level of translation table walks
|
||||
// AArch64 TLB Invalidate by VA, EL3
|
||||
case MISCREG_TLBI_VAE3_Xt:
|
||||
{
|
||||
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, EL3
|
||||
case MISCREG_TLBI_VALE3_Xt:
|
||||
{
|
||||
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_VAE3IS_Xt:
|
||||
{
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, EL3, Inner Shareable
|
||||
case MISCREG_TLBI_VALE3IS_Xt:
|
||||
{
|
||||
TLBIMVAA tlbiOp(EL3, true,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2
|
||||
case MISCREG_TLBI_VAE2_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// 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,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid, false);
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, EL2
|
||||
case MISCREG_TLBI_VALE2_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -377,17 +418,42 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
asid, true);
|
||||
tlbiOp(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_VAE2IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
|
||||
if (hcr.e2h) {
|
||||
// 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,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid, false);
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, EL2, Inner Shareable
|
||||
case MISCREG_TLBI_VALE2IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -402,17 +468,40 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
|
||||
TLBIMVA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
asid, true);
|
||||
tlbiOp.broadcast(tc);
|
||||
} else {
|
||||
TLBIMVAA tlbiOp(EL2, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL1
|
||||
case MISCREG_TLBI_VAE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
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);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, EL1
|
||||
case MISCREG_TLBI_VALE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -430,13 +519,34 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
asid, true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_VAE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
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);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
case MISCREG_TLBI_VALE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -454,7 +564,7 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
asid);
|
||||
asid, true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
@@ -499,10 +609,28 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// VAAE1(IS) and VAALE1(IS) are the same because TLBs only store
|
||||
// entries from the last level of translation table walks
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1
|
||||
case MISCREG_TLBI_VAAE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
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,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, Last Level, All ASID, EL1
|
||||
case MISCREG_TLBI_VAALE1_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -517,13 +645,35 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, All ASID, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_VAAE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
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,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by VA, All ASID,
|
||||
// Last Level, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_VAALE1IS_Xt:
|
||||
{
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
@@ -538,7 +688,8 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) && !scr.ns;
|
||||
TLBIMVAA tlbiOp(target_el, secure,
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 43, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
return;
|
||||
@@ -546,6 +697,25 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
// AArch64 TLB Invalidate by Intermediate Physical Address,
|
||||
// Stage 2, EL1
|
||||
case MISCREG_TLBI_IPAS2E1_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
const int top_bit = ArmSystem::physAddrRange(tc) == 52 ?
|
||||
39 : 35;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, top_bit, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by Intermediate Physical Address,
|
||||
// Stage 2, Last Level EL1
|
||||
case MISCREG_TLBI_IPAS2LE1_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
@@ -555,7 +725,8 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp(tc);
|
||||
}
|
||||
@@ -564,6 +735,25 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
// AArch64 TLB Invalidate by Intermediate Physical Address,
|
||||
// Stage 2, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_IPAS2E1IS_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
SCR scr = tc->readMiscReg(MISCREG_SCR);
|
||||
|
||||
bool secure = release->has(ArmExtension::SECURITY) &&
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
const int top_bit = ArmSystem::physAddrRange(tc) == 52 ?
|
||||
39 : 35;
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, top_bit, 0)) << 12,
|
||||
false);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// AArch64 TLB Invalidate by Intermediate Physical Address,
|
||||
// Stage 2, Last Level, EL1, Inner Shareable
|
||||
case MISCREG_TLBI_IPAS2LE1IS_Xt:
|
||||
{
|
||||
if (EL2Enabled(tc)) {
|
||||
@@ -573,7 +763,8 @@ TlbiOp64::performTlbi(ExecContext *xc, MiscRegIndex dest_idx, RegVal value) cons
|
||||
!scr.ns && !bits(value, 63);
|
||||
|
||||
TLBIIPA tlbiOp(EL1, secure,
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12);
|
||||
static_cast<Addr>(bits(value, 35, 0)) << 12,
|
||||
true);
|
||||
|
||||
tlbiOp.broadcast(tc);
|
||||
}
|
||||
|
||||
@@ -236,7 +236,7 @@ TLBIMVAA::match(TlbEntry* te, vmid_t vmid) const
|
||||
lookup_data.inHost = inHost;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
|
||||
return te->match(lookup_data);
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -267,7 +267,7 @@ TLBIMVA::match(TlbEntry* te, vmid_t vmid) const
|
||||
lookup_data.inHost = inHost;
|
||||
lookup_data.mode = BaseMMU::Read;
|
||||
|
||||
return te->match(lookup_data);
|
||||
return te->match(lookup_data) && (!lastLevel || !te->partial);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -302,8 +302,9 @@ class TLBIMVAA : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIMVAA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr)
|
||||
: TLBIOp(_targetEL, _secure), addr(_addr), inHost(false)
|
||||
Addr _addr, bool last_level)
|
||||
: TLBIOp(_targetEL, _secure), addr(_addr), inHost(false),
|
||||
lastLevel(last_level)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -312,6 +313,7 @@ class TLBIMVAA : public TLBIOp
|
||||
|
||||
Addr addr;
|
||||
bool inHost;
|
||||
bool lastLevel;
|
||||
};
|
||||
|
||||
/** TLB Invalidate by VA */
|
||||
@@ -319,9 +321,9 @@ class TLBIMVA : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIMVA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr, uint16_t _asid)
|
||||
Addr _addr, uint16_t _asid, bool last_level)
|
||||
: TLBIOp(_targetEL, _secure), addr(_addr), asid(_asid),
|
||||
inHost(false)
|
||||
inHost(false), lastLevel(last_level)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -331,6 +333,7 @@ class TLBIMVA : public TLBIOp
|
||||
Addr addr;
|
||||
uint16_t asid;
|
||||
bool inHost;
|
||||
bool lastLevel;
|
||||
};
|
||||
|
||||
/** Instruction TLB Invalidate by VA */
|
||||
@@ -339,7 +342,7 @@ class ITLBIMVA : public TLBIMVA
|
||||
public:
|
||||
ITLBIMVA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr, uint16_t _asid)
|
||||
: TLBIMVA(_targetEL, _secure, _addr, _asid)
|
||||
: TLBIMVA(_targetEL, _secure, _addr, _asid, false)
|
||||
{}
|
||||
|
||||
void broadcast(ThreadContext *tc) = delete;
|
||||
@@ -355,7 +358,7 @@ class DTLBIMVA : public TLBIMVA
|
||||
public:
|
||||
DTLBIMVA(ExceptionLevel _targetEL, bool _secure,
|
||||
Addr _addr, uint16_t _asid)
|
||||
: TLBIMVA(_targetEL, _secure, _addr, _asid)
|
||||
: TLBIMVA(_targetEL, _secure, _addr, _asid, false)
|
||||
{}
|
||||
|
||||
void broadcast(ThreadContext *tc) = delete;
|
||||
@@ -369,8 +372,9 @@ class DTLBIMVA : public TLBIMVA
|
||||
class TLBIIPA : public TLBIOp
|
||||
{
|
||||
public:
|
||||
TLBIIPA(ExceptionLevel _targetEL, bool _secure, Addr _addr)
|
||||
: TLBIOp(_targetEL, _secure), addr(_addr)
|
||||
TLBIIPA(ExceptionLevel _targetEL, bool _secure, Addr _addr,
|
||||
bool last_level)
|
||||
: TLBIOp(_targetEL, _secure), addr(_addr), lastLevel(last_level)
|
||||
{}
|
||||
|
||||
void operator()(ThreadContext* tc) override;
|
||||
@@ -391,10 +395,11 @@ class TLBIIPA : public TLBIOp
|
||||
TLBIMVAA
|
||||
makeStage2() const
|
||||
{
|
||||
return TLBIMVAA(EL1, secureLookup, addr);
|
||||
return TLBIMVAA(EL1, secureLookup, addr, lastLevel);
|
||||
}
|
||||
|
||||
Addr addr;
|
||||
bool lastLevel;
|
||||
};
|
||||
|
||||
} // namespace ArmISA
|
||||
|
||||
Reference in New Issue
Block a user