summaryrefslogtreecommitdiff
path: root/src/dev/arm
diff options
context:
space:
mode:
authorGiacomo Travaglini <giacomo.travaglini@arm.com>2019-07-23 09:58:39 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-07-25 12:49:27 +0000
commit15c736b2c54d78d7f18c23b09d1c9f2b25687106 (patch)
tree73208f25b20c0873ea7bd7b4a6f9983db23bdc0c /src/dev/arm
parentaf1838be8d1efbbbb7133262f23f9f757033589d (diff)
downloadgem5-15c736b2c54d78d7f18c23b09d1c9f2b25687106.tar.xz
dev-arm: Polish SMMUv3 CMDQ setup
The patch is aiming to be spec compliant when it comes to setup the SMMU command queue (while CR0.CMDQEN = 0), in the following ways: * Writes to CMDQ_CONS (read index) are allowed during initialization * Writes to CMDQ_BASE (cmdq pointer) are allowed during initialization According to spec, If they happen when the command queue is in fuction (CR0.CMDQEN = 1), behaviour is constrained unpredictable, with the following options 1) The write is ignored 2) The register takes the value and it is unpredictable whether it affects the SMMU command queue internal state. In the model/patch we go for option 1. Change-Id: I1c55bc571a8b3a1c0b0a525e429ab7b1480544ff 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/+/19633 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')
-rw-r--r--src/dev/arm/smmu_v3.cc23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/dev/arm/smmu_v3.cc b/src/dev/arm/smmu_v3.cc
index 7c4bd3673..2c974b57b 100644
--- a/src/dev/arm/smmu_v3.cc
+++ b/src/dev/arm/smmu_v3.cc
@@ -604,6 +604,16 @@ SMMUv3::writeControl(PacketPtr pkt)
pkt->getLE<uint32_t>();
break;
+ case offsetof(SMMURegs, cmdq_cons):
+ assert(pkt->getSize() == sizeof(uint32_t));
+ if (regs.cr0 & CR0_CMDQEN_MASK) {
+ warn("CMDQ is enabled: ignoring write to CMDQ_CONS\n");
+ } else {
+ *reinterpret_cast<uint32_t *>(regs.data + offset) =
+ pkt->getLE<uint32_t>();
+ }
+ break;
+
case offsetof(SMMURegs, cmdq_prod):
assert(pkt->getSize() == sizeof(uint32_t));
*reinterpret_cast<uint32_t *>(regs.data + offset) =
@@ -620,13 +630,16 @@ SMMUv3::writeControl(PacketPtr pkt)
case offsetof(SMMURegs, cmdq_base):
assert(pkt->getSize() == sizeof(uint64_t));
- *reinterpret_cast<uint64_t *>(regs.data + offset) =
- pkt->getLE<uint64_t>();
- regs.cmdq_cons = 0;
- regs.cmdq_prod = 0;
+ if (regs.cr0 & CR0_CMDQEN_MASK) {
+ warn("CMDQ is enabled: ignoring write to CMDQ_BASE\n");
+ } else {
+ *reinterpret_cast<uint64_t *>(regs.data + offset) =
+ pkt->getLE<uint64_t>();
+ regs.cmdq_cons = 0;
+ regs.cmdq_prod = 0;
+ }
break;
-
case offsetof(SMMURegs, eventq_base):
assert(pkt->getSize() == sizeof(uint64_t));
*reinterpret_cast<uint64_t *>(regs.data + offset) =