From e06d4f2658b2817b07ea3d71d5554b02f874fee0 Mon Sep 17 00:00:00 2001 From: Adrian Herrera Date: Tue, 20 Aug 2019 08:33:17 +0100 Subject: 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 Reviewed-by: Marc Mari Barcelo Reviewed-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20258 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg Tested-by: kokoro --- src/dev/arm/smmu_v3.cc | 11 +++++------ src/dev/arm/smmu_v3_caches.cc | 33 +++++++++++++++++++++++++++++---- src/dev/arm/smmu_v3_caches.hh | 5 +++-- 3 files changed, 37 insertions(+), 12 deletions(-) (limited to 'src/dev/arm') diff --git a/src/dev/arm/smmu_v3.cc b/src/dev/arm/smmu_v3.cc index f17ef9578..e278c0e25 100644 --- a/src/dev/arm/smmu_v3.cc +++ b/src/dev/arm/smmu_v3.cc @@ -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; } diff --git a/src/dev/arm/smmu_v3_caches.cc b/src/dev/arm/smmu_v3_caches.cc index 63f0b052b..d92c54480 100644 --- a/src/dev/arm/smmu_v3_caches.cc +++ b/src/dev/arm/smmu_v3_caches.cc @@ -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 diff --git a/src/dev/arm/smmu_v3_caches.hh b/src/dev/arm/smmu_v3_caches.hh index 50b293cf2..22ee394f6 100644 --- a/src/dev/arm/smmu_v3_caches.hh +++ b/src/dev/arm/smmu_v3_caches.hh @@ -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(); -- cgit v1.2.3