dev-arm: Implement invalidateVA/VAA in SMMUv3 WalkCache

This patch implements VA/VAA invalidations in the SMMUv3 model.

As per SMMUv3.0 spec, if leaf bit is specified in the invalidation
command, only leaf entries within the walk cache need to be invalidated,
otherwise entries with intermediate translations are also invalidated.

Change-Id: I0eb1e1f1d8c00671a3c23d2a8fb756f2020d8d46
Reviewed-by: Michiel van Tol <michiel.vantol@arm.com>
Reviewed-by: Marc Mari Barcelo <marc.maribarcelo@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20258
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Adrian Herrera
2019-08-20 08:33:17 +01:00
committed by Giacomo Travaglini
parent 8d439c29ed
commit e06d4f2658
3 changed files with 37 additions and 12 deletions

View File

@@ -492,9 +492,8 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
addr, cmd.dw0.vmid);
}
tlb.invalidateVAA(addr, cmd.dw0.vmid);
if (!cmd.dw1.leaf)
walkCache.invalidateVAA(addr, cmd.dw0.vmid);
const bool leaf_only = cmd.dw1.leaf ? true : false;
walkCache.invalidateVAA(addr, cmd.dw0.vmid, leaf_only);
break;
}
@@ -509,9 +508,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
addr, cmd.dw0.asid, cmd.dw0.vmid);
}
tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
if (!cmd.dw1.leaf)
walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
const bool leaf_only = cmd.dw1.leaf ? true : false;
walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid,
leaf_only);
break;
}

View File

@@ -1083,15 +1083,40 @@ WalkCache::store(const Entry &incoming)
}
void
WalkCache::invalidateVA(Addr va, uint16_t asid, uint16_t vmid)
WalkCache::invalidateVA(Addr va, uint16_t asid, uint16_t vmid,
const bool leaf_only)
{
panic("%s unimplemented\n", __func__);
for (size_t s = 0; s < sets.size(); s++) {
Set &set = sets[s];
for (size_t i = 0; i < set.size(); i++) {
Entry &e = set[i];
if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
&& e.asid == asid && e.vmid == vmid)
{
e.valid = false;
}
}
}
}
void
WalkCache::invalidateVAA(Addr va, uint16_t vmid)
WalkCache::invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only)
{
panic("%s unimplemented\n", __func__);
for (size_t s = 0; s < sets.size(); s++) {
Set &set = sets[s];
for (size_t i = 0; i < set.size(); i++) {
Entry &e = set[i];
if ((!leaf_only || e.leaf) && (e.va & e.vaMask) == (va & e.vaMask)
&& e.vmid == vmid)
{
e.valid = false;
}
}
}
}
void

View File

@@ -310,8 +310,9 @@ class WalkCache : public SMMUv3BaseCache
unsigned stage, unsigned level, bool updStats=true);
void store(const Entry &incoming);
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid);
void invalidateVAA(Addr va, uint16_t vmid);
void invalidateVA(Addr va, uint16_t asid, uint16_t vmid,
const bool leaf_only);
void invalidateVAA(Addr va, uint16_t vmid, const bool leaf_only);
void invalidateASID(uint16_t asid, uint16_t vmid);
void invalidateVMID(uint16_t vmid);
void invalidateAll();