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:
Giacomo Travaglini
2022-08-08 08:52:07 +01:00
parent fe6fc29b07
commit f448706dd5
4 changed files with 342 additions and 54 deletions

View File

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

View File

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

View File

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

View File

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