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
}
busy = false;
+ // No more commands to process, signal the SMMU as drained
+ smmu.signalDrainDone();
doSleep(yield);
}
}
}
+DrainState
+SMMUv3SlaveInterface::drain()
+{
+ // Wait until all SMMU translations are completed
+ if (xlateSlotsRemaining < params()->xlate_slots) {
+ return DrainState::Draining;
+ }
+ return DrainState::Drained;
+}
+
SMMUv3SlaveInterface*
SMMUv3SlaveInterfaceParams::create()
{
class SMMUv3SlaveInterface : public MemObject
{
+ protected:
+ friend class SMMUTranslationProcess;
+
public:
SMMUv3 *smmu;
SMMUTLB* microTLB;
delete mainTLB;
}
+ const SMMUv3SlaveInterfaceParams *
+ params() const
+ {
+ return static_cast<const SMMUv3SlaveInterfaceParams *>(_params);
+ }
+
+ DrainState drain() override;
+
void setSMMU(SMMUv3 *_smmu) { smmu = _smmu; }
void sendRange();
};
{
// 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