summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dev/arm/smmu_v3.cc11
-rw-r--r--src/dev/arm/smmu_v3_caches.cc33
-rw-r--r--src/dev/arm/smmu_v3_caches.hh5
3 files changed, 37 insertions, 12 deletions
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();