diff options
author | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-07-24 12:22:05 +0100 |
---|---|---|
committer | Giacomo Travaglini <giacomo.travaglini@arm.com> | 2019-07-30 12:05:33 +0000 |
commit | 55580e6a8810e9d31b01a2efdf58b13d09f30f58 (patch) | |
tree | b331ab1207099cc5e624a6cb7b68b918010eca34 /src/dev/arm/smmu_v3.cc | |
parent | 9871b73329be93c5749ef45d49079072ecbd9685 (diff) | |
download | gem5-55580e6a8810e9d31b01a2efdf58b13d09f30f58.tar.xz |
dev-arm: Rewrite SMMUv3 Commands
This patch is rewriting the SMMUv3::processCommand method for the
following reasons:
* Command names were not matching spec
* Command encoding/opcode was wrong
The patch is not adding any new command: there is still a subset of
unimplemented commands; those are:
* CMD_TLBI_EL3_ALL
* CMD_TLBI_EL3_VA
* CMD_TLBI_EL2_ALL
* CMD_TLBI_EL2_VA
* CMD_TLBI_EL2_VAA
* CMD_TLBI_EL2_ASID
which require StreamWorld support, and
* CMD_ATC_INV
* CMD_PRI_RESP
* CMD_RESUME
* CMD_STALL_TERM
which require in sequence: ATS, PRI, Stall Model support
Change-Id: Ia2dd47b5588738402d9584a00cfc88c94c253ad0
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Michiel van Tol <michiel.vantol@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19668
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/dev/arm/smmu_v3.cc')
-rw-r--r-- | src/dev/arm/smmu_v3.cc | 180 |
1 files changed, 94 insertions, 86 deletions
diff --git a/src/dev/arm/smmu_v3.cc b/src/dev/arm/smmu_v3.cc index 2c974b57b..28539297c 100644 --- a/src/dev/arm/smmu_v3.cc +++ b/src/dev/arm/smmu_v3.cc @@ -383,7 +383,7 @@ SMMUv3::processCommands() void SMMUv3::processCommand(const SMMUCommand &cmd) { - switch (cmd.type) { + switch (cmd.dw0.type) { case CMD_PRF_CONFIG: DPRINTF(SMMUv3, "CMD_PREFETCH_CONFIG - ignored\n"); break; @@ -392,137 +392,145 @@ SMMUv3::processCommand(const SMMUCommand &cmd) DPRINTF(SMMUv3, "CMD_PREFETCH_ADDR - ignored\n"); break; - case CMD_INV_STE: - DPRINTF(SMMUv3, "CMD_INV_STE sid=%#x\n", cmd.data[0]); - configCache.invalidateSID(cmd.data[0]); + case CMD_CFGI_STE: { + DPRINTF(SMMUv3, "CMD_CFGI_STE sid=%#x\n", cmd.dw0.sid); + configCache.invalidateSID(cmd.dw0.sid); break; + } - case CMD_INV_CD: - DPRINTF(SMMUv3, "CMD_INV_CD sid=%#x ssid=%#x\n", - cmd.data[0], cmd.data[1]); - configCache.invalidateSSID(cmd.data[0], cmd.data[1]); + case CMD_CFGI_STE_RANGE: { + const auto range = cmd.dw1.range; + if (range == 31) { + // CMD_CFGI_ALL is an alias of CMD_CFGI_STE_RANGE with + // range = 31 + DPRINTF(SMMUv3, "CMD_CFGI_ALL\n"); + configCache.invalidateAll(); + } else { + DPRINTF(SMMUv3, "CMD_CFGI_STE_RANGE\n"); + const auto start_sid = cmd.dw0.sid & ~((1 << (range + 1)) - 1); + const auto end_sid = start_sid + (1 << (range + 1)) - 1; + for (auto sid = start_sid; sid <= end_sid; sid++) + configCache.invalidateSID(sid); + } break; + } - case CMD_INV_CD_ALL: - DPRINTF(SMMUv3, "CMD_INV_CD_ALL sid=%#x\n", cmd.data[0]); - configCache.invalidateSID(cmd.data[0]); + case CMD_CFGI_CD: { + DPRINTF(SMMUv3, "CMD_CFGI_CD sid=%#x ssid=%#x\n", + cmd.dw0.sid, cmd.dw0.ssid); + configCache.invalidateSSID(cmd.dw0.sid, cmd.dw0.ssid); break; + } - case CMD_INV_ALL: - DPRINTF(SMMUv3, "CMD_INV_ALL\n"); - configCache.invalidateAll(); + case CMD_CFGI_CD_ALL: { + DPRINTF(SMMUv3, "CMD_CFGI_CD_ALL sid=%#x\n", cmd.dw0.sid); + configCache.invalidateSID(cmd.dw0.sid); break; + } - case CMD_TLBI_ALL: - DPRINTF(SMMUv3, "CMD_TLBI_ALL\n"); + case CMD_TLBI_NH_ALL: { + DPRINTF(SMMUv3, "CMD_TLBI_NH_ALL vmid=%#x\n", cmd.dw0.vmid); for (auto slave_interface : slaveInterfaces) { - slave_interface->microTLB->invalidateAll(); - slave_interface->mainTLB->invalidateAll(); + slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid); + slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid); } - tlb.invalidateAll(); - ipaCache.invalidateAll(); - walkCache.invalidateAll(); + tlb.invalidateVMID(cmd.dw0.vmid); + walkCache.invalidateVMID(cmd.dw0.vmid); break; + } - case CMD_TLBI_ASID: - DPRINTF(SMMUv3, "CMD_TLBI_ASID asid=%#x vmid=%#x\n", - cmd.data[0], cmd.data[1]); + case CMD_TLBI_NH_ASID: { + DPRINTF(SMMUv3, "CMD_TLBI_NH_ASID asid=%#x vmid=%#x\n", + cmd.dw0.asid, cmd.dw0.vmid); for (auto slave_interface : slaveInterfaces) { slave_interface->microTLB->invalidateASID( - cmd.data[0], cmd.data[1]); + cmd.dw0.asid, cmd.dw0.vmid); slave_interface->mainTLB->invalidateASID( - cmd.data[0], cmd.data[1]); + cmd.dw0.asid, cmd.dw0.vmid); } - tlb.invalidateASID(cmd.data[0], cmd.data[1]); - walkCache.invalidateASID(cmd.data[0], cmd.data[1]); + tlb.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid); + walkCache.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid); break; + } - case CMD_TLBI_VAAL: - DPRINTF(SMMUv3, "CMD_TLBI_VAAL va=%#08x vmid=%#x\n", - cmd.data[0], cmd.data[1]); + case CMD_TLBI_NH_VAA: { + const Addr addr = cmd.addr(); + DPRINTF(SMMUv3, "CMD_TLBI_NH_VAA va=%#08x vmid=%#x\n", + addr, cmd.dw0.vmid); for (auto slave_interface : slaveInterfaces) { slave_interface->microTLB->invalidateVAA( - cmd.data[0], cmd.data[1]); + addr, cmd.dw0.vmid); slave_interface->mainTLB->invalidateVAA( - cmd.data[0], cmd.data[1]); + addr, cmd.dw0.vmid); } - tlb.invalidateVAA(cmd.data[0], cmd.data[1]); - break; + tlb.invalidateVAA(addr, cmd.dw0.vmid); - case CMD_TLBI_VAA: - DPRINTF(SMMUv3, "CMD_TLBI_VAA va=%#08x vmid=%#x\n", - cmd.data[0], cmd.data[1]); - for (auto slave_interface : slaveInterfaces) { - slave_interface->microTLB->invalidateVAA( - cmd.data[0], cmd.data[1]); - slave_interface->mainTLB->invalidateVAA( - cmd.data[0], cmd.data[1]); - } - tlb.invalidateVAA(cmd.data[0], cmd.data[1]); - walkCache.invalidateVAA(cmd.data[0], cmd.data[1]); + if (!cmd.dw1.leaf) + walkCache.invalidateVAA(addr, cmd.dw0.vmid); break; + } - case CMD_TLBI_VAL: - DPRINTF(SMMUv3, "CMD_TLBI_VAL va=%#08x asid=%#x vmid=%#x\n", - cmd.data[0], cmd.data[1], cmd.data[2]); + case CMD_TLBI_NH_VA: { + const Addr addr = cmd.addr(); + DPRINTF(SMMUv3, "CMD_TLBI_NH_VA va=%#08x asid=%#x vmid=%#x\n", + addr, cmd.dw0.asid, cmd.dw0.vmid); for (auto slave_interface : slaveInterfaces) { slave_interface->microTLB->invalidateVA( - cmd.data[0], cmd.data[1], cmd.data[2]); + addr, cmd.dw0.asid, cmd.dw0.vmid); slave_interface->mainTLB->invalidateVA( - cmd.data[0], cmd.data[1], cmd.data[2]); + addr, cmd.dw0.asid, cmd.dw0.vmid); } - tlb.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]); - break; + tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid); - case CMD_TLBI_VA: - DPRINTF(SMMUv3, "CMD_TLBI_VA va=%#08x asid=%#x vmid=%#x\n", - cmd.data[0], cmd.data[1], cmd.data[2]); - for (auto slave_interface : slaveInterfaces) { - slave_interface->microTLB->invalidateVA( - cmd.data[0], cmd.data[1], cmd.data[2]); - slave_interface->mainTLB->invalidateVA( - cmd.data[0], cmd.data[1], cmd.data[2]); - } - tlb.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]); - walkCache.invalidateVA(cmd.data[0], cmd.data[1], cmd.data[2]); + if (!cmd.dw1.leaf) + walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid); break; + } - case CMD_TLBI_VM_IPAL: - DPRINTF(SMMUv3, "CMD_TLBI_VM_IPAL ipa=%#08x vmid=%#x\n", - cmd.data[0], cmd.data[1]); + case CMD_TLBI_S2_IPA: { + const Addr addr = cmd.addr(); + DPRINTF(SMMUv3, "CMD_TLBI_S2_IPA ipa=%#08x vmid=%#x\n", + addr, cmd.dw0.vmid); // This does not invalidate TLBs containing // combined Stage1 + Stage2 translations, as per the spec. - ipaCache.invalidateIPA(cmd.data[0], cmd.data[1]); - walkCache.invalidateVMID(cmd.data[1]); + ipaCache.invalidateIPA(addr, cmd.dw0.vmid); + + if (!cmd.dw1.leaf) + walkCache.invalidateVMID(cmd.dw0.vmid); break; + } - case CMD_TLBI_VM_IPA: - DPRINTF(SMMUv3, "CMD_TLBI_VM_IPA ipa=%#08x vmid=%#x\n", - cmd.data[0], cmd.data[1]); - // This does not invalidate TLBs containing - // combined Stage1 + Stage2 translations, as per the spec. - ipaCache.invalidateIPA(cmd.data[0], cmd.data[1]); - walkCache.invalidateVMID(cmd.data[1]); + case CMD_TLBI_S12_VMALL: { + DPRINTF(SMMUv3, "CMD_TLBI_S12_VMALL vmid=%#x\n", cmd.dw0.vmid); + for (auto slave_interface : slaveInterfaces) { + slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid); + slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid); + } + tlb.invalidateVMID(cmd.dw0.vmid); + ipaCache.invalidateVMID(cmd.dw0.vmid); + walkCache.invalidateVMID(cmd.dw0.vmid); break; + } - case CMD_TLBI_VM_S12: - DPRINTF(SMMUv3, "CMD_TLBI_VM_S12 vmid=%#x\n", cmd.data[0]); + case CMD_TLBI_NSNH_ALL: { + DPRINTF(SMMUv3, "CMD_TLBI_NSNH_ALL\n"); for (auto slave_interface : slaveInterfaces) { - slave_interface->microTLB->invalidateVMID(cmd.data[0]); - slave_interface->mainTLB->invalidateVMID(cmd.data[0]); + slave_interface->microTLB->invalidateAll(); + slave_interface->mainTLB->invalidateAll(); } - tlb.invalidateVMID(cmd.data[0]); - ipaCache.invalidateVMID(cmd.data[0]); - walkCache.invalidateVMID(cmd.data[0]); + tlb.invalidateAll(); + ipaCache.invalidateAll(); + walkCache.invalidateAll(); break; + } - case CMD_RESUME_S: - DPRINTF(SMMUv3, "CMD_RESUME_S\n"); + case CMD_RESUME: + DPRINTF(SMMUv3, "CMD_RESUME\n"); panic("resume unimplemented"); break; default: - warn("Unimplemented command %#x\n", cmd.type); + warn("Unimplemented command %#x\n", cmd.dw0.type); break; } } |