dev-arm: Implement invalidateVA/VAA in SMMUv3 WalkCache
authorAdrian Herrera <adrian.herrera@arm.com>
Tue, 20 Aug 2019 07:33:17 +0000 (08:33 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Thu, 5 Sep 2019 16:37:18 +0000 (16:37 +0000)
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>
src/dev/arm/smmu_v3.cc
src/dev/arm/smmu_v3_caches.cc
src/dev/arm/smmu_v3_caches.hh

index f17ef9578739e71d09aa5c094c209f009ed04b9d..e278c0e25e4eea58bfda793f4be6e300de9cc4e7 100644 (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;
         }
 
index 63f0b052b98bb5c78371c9c181ceb533e691f18d..d92c54480dee252e4277b97064299ea88309a1dc 100644 (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
index 50b293cf2fb062e64558b51f03617d54703bed5b..22ee394f624a0751c9ca91442dfea1baabd5ecf1 100644 (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();