summaryrefslogtreecommitdiff
path: root/src/dev/arm
diff options
context:
space:
mode:
authorAdrian Herrera <adrian.herrera@arm.com>2019-06-18 16:56:18 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-06-26 11:58:55 +0000
commitf82f1dd81b9e2342e1c43fe5c413626c1cde996f (patch)
treed810f41a89ce7ad81a12a2762ddf48a8da7ced6e /src/dev/arm
parent09bc8b6f1177df5fe5de9d2984781cc1fb8b75b4 (diff)
downloadgem5-f82f1dd81b9e2342e1c43fe5c413626c1cde996f.tar.xz
dev-arm: drain implementation for SMMUv3
SMMUv3 is drained when (1) no SMMU translations are pending on any of its slave interfaces and (2) no commands are stored in the Command Queue waiting to be processed. Change-Id: I81cef5fd821fa5e509e130af02aece5239493df5 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/19309 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.cc6
-rw-r--r--src/dev/arm/smmu_v3_cmdexec.cc2
-rw-r--r--src/dev/arm/smmu_v3_slaveifc.cc10
-rw-r--r--src/dev/arm/smmu_v3_slaveifc.hh11
-rw-r--r--src/dev/arm/smmu_v3_transl.cc5
5 files changed, 33 insertions, 1 deletions
diff --git a/src/dev/arm/smmu_v3.cc b/src/dev/arm/smmu_v3.cc
index 25176491e..d913d55a0 100644
--- a/src/dev/arm/smmu_v3.cc
+++ b/src/dev/arm/smmu_v3.cc
@@ -741,7 +741,11 @@ SMMUv3::regStats()
DrainState
SMMUv3::drain()
{
- panic("SMMUv3 doesn't support draining\n");
+ // Wait until the Command Executor is not busy
+ if (commandExecutor.isBusy()) {
+ return DrainState::Draining;
+ }
+ return DrainState::Drained;
}
void
diff --git a/src/dev/arm/smmu_v3_cmdexec.cc b/src/dev/arm/smmu_v3_cmdexec.cc
index 8660846fd..494c86798 100644
--- a/src/dev/arm/smmu_v3_cmdexec.cc
+++ b/src/dev/arm/smmu_v3_cmdexec.cc
@@ -75,6 +75,8 @@ SMMUCommandExecProcess::main(Yield &yield)
}
busy = false;
+ // No more commands to process, signal the SMMU as drained
+ smmu.signalDrainDone();
doSleep(yield);
}
diff --git a/src/dev/arm/smmu_v3_slaveifc.cc b/src/dev/arm/smmu_v3_slaveifc.cc
index 48b114115..0a53ed0ba 100644
--- a/src/dev/arm/smmu_v3_slaveifc.cc
+++ b/src/dev/arm/smmu_v3_slaveifc.cc
@@ -253,6 +253,16 @@ SMMUv3SlaveInterface::scheduleDeviceRetry()
}
}
+DrainState
+SMMUv3SlaveInterface::drain()
+{
+ // Wait until all SMMU translations are completed
+ if (xlateSlotsRemaining < params()->xlate_slots) {
+ return DrainState::Draining;
+ }
+ return DrainState::Drained;
+}
+
SMMUv3SlaveInterface*
SMMUv3SlaveInterfaceParams::create()
{
diff --git a/src/dev/arm/smmu_v3_slaveifc.hh b/src/dev/arm/smmu_v3_slaveifc.hh
index a782ff9b7..3302d829b 100644
--- a/src/dev/arm/smmu_v3_slaveifc.hh
+++ b/src/dev/arm/smmu_v3_slaveifc.hh
@@ -56,6 +56,9 @@ class SMMUSlavePort;
class SMMUv3SlaveInterface : public MemObject
{
+ protected:
+ friend class SMMUTranslationProcess;
+
public:
SMMUv3 *smmu;
SMMUTLB* microTLB;
@@ -124,6 +127,14 @@ class SMMUv3SlaveInterface : public MemObject
delete mainTLB;
}
+ const SMMUv3SlaveInterfaceParams *
+ params() const
+ {
+ return static_cast<const SMMUv3SlaveInterfaceParams *>(_params);
+ }
+
+ DrainState drain() override;
+
void setSMMU(SMMUv3 *_smmu) { smmu = _smmu; }
void sendRange();
};
diff --git a/src/dev/arm/smmu_v3_transl.cc b/src/dev/arm/smmu_v3_transl.cc
index 6e0dacb88..f1e1fb11f 100644
--- a/src/dev/arm/smmu_v3_transl.cc
+++ b/src/dev/arm/smmu_v3_transl.cc
@@ -94,6 +94,11 @@ SMMUTranslationProcess::~SMMUTranslationProcess()
{
// Increase number of pending translation slots on the slave interface
ifc.xlateSlotsRemaining++;
+ // If no more SMMU translations are pending (all slots available),
+ // signal SMMU Slave Interface as drained
+ if (ifc.xlateSlotsRemaining == ifc.params()->xlate_slots) {
+ ifc.signalDrainDone();
+ }
}
void