diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dev/arm/smmu_v3.cc | 11 | ||||
-rw-r--r-- | src/dev/arm/smmu_v3_caches.cc | 33 | ||||
-rw-r--r-- | src/dev/arm/smmu_v3_caches.hh | 5 |
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(); |