summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/DMASequencer.cc
diff options
context:
space:
mode:
authorMichael LeBeane <Michael.Lebeane@amd.com>2016-02-14 20:28:48 -0500
committerMichael LeBeane <Michael.Lebeane@amd.com>2016-02-14 20:28:48 -0500
commitb181cea3645929d11b21a29ac8c3e3ed3079e91b (patch)
treeeb0025357f0e3847c9633e4bf1b193f2937b3a5b /src/mem/ruby/system/DMASequencer.cc
parent2ae4cce3934873908afacc81b65d4093731a3e93 (diff)
downloadgem5-b181cea3645929d11b21a29ac8c3e3ed3079e91b.tar.xz
ruby: make DMASequencer inherit from RubyPort
This patch essentially rolls back 10518:30e3715c9405 to make RubyPort the parent class of DMASequencer. It removes redundant code and restores some features which were lost when directly inheriting from MemObject. For example, DMASequencer can now communicate to other devices using PIO, which is useful for memmory-mapped communication between multiple DMADevices.
Diffstat (limited to 'src/mem/ruby/system/DMASequencer.cc')
-rw-r--r--src/mem/ruby/system/DMASequencer.cc174
1 files changed, 3 insertions, 171 deletions
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc
index 2b65d675a..fc2433a6c 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -28,192 +28,24 @@
#include <memory>
-#include "debug/Config.hh"
-#include "debug/Drain.hh"
#include "debug/RubyDma.hh"
#include "debug/RubyStats.hh"
#include "mem/protocol/SequencerMsg.hh"
+#include "mem/protocol/SequencerRequestType.hh"
#include "mem/ruby/system/DMASequencer.hh"
#include "mem/ruby/system/RubySystem.hh"
-#include "sim/system.hh"
DMASequencer::DMASequencer(const Params *p)
- : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version),
- m_controller(NULL), m_mandatory_q_ptr(NULL),
- m_usingRubyTester(p->using_ruby_tester),
- slave_port(csprintf("%s.slave", name()), this, 0, p->ruby_system,
- p->ruby_system->getAccessBackingStore()),
- system(p->system), retry(false)
+ : RubyPort(p)
{
- assert(m_version != -1);
}
void
DMASequencer::init()
{
- MemObject::init();
- assert(m_controller != NULL);
- m_mandatory_q_ptr = m_controller->getMandatoryQueue();
+ RubyPort::init();
m_is_busy = false;
m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
-
- slave_port.sendRangeChange();
-}
-
-BaseSlavePort &
-DMASequencer::getSlavePort(const std::string &if_name, PortID idx)
-{
- // used by the CPUs to connect the caches to the interconnect, and
- // for the x86 case also the interrupt master
- if (if_name != "slave") {
- // pass it along to our super class
- return MemObject::getSlavePort(if_name, idx);
- } else {
- return slave_port;
- }
-}
-
-DMASequencer::MemSlavePort::MemSlavePort(const std::string &_name,
- DMASequencer *_port, PortID id, RubySystem* _ruby_system,
- bool _access_backing_store)
- : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
- m_ruby_system(_ruby_system), access_backing_store(_access_backing_store)
-{
- DPRINTF(RubyDma, "Created slave memport on ruby sequencer %s\n", _name);
-}
-
-bool
-DMASequencer::MemSlavePort::recvTimingReq(PacketPtr pkt)
-{
- DPRINTF(RubyDma, "Timing request for address %#x on port %d\n",
- pkt->getAddr(), id);
- DMASequencer *seq = static_cast<DMASequencer *>(&owner);
-
- if (pkt->cacheResponding())
- panic("DMASequencer should never see a request with the "
- "cacheResponding flag set\n");
-
- assert(isPhysMemAddress(pkt->getAddr()));
- assert(getOffset(pkt->getAddr()) + pkt->getSize() <=
- RubySystem::getBlockSizeBytes());
-
- // Submit the ruby request
- RequestStatus requestStatus = seq->makeRequest(pkt);
-
- // If the request successfully issued then we should return true.
- // Otherwise, we need to tell the port to retry at a later point
- // and return false.
- if (requestStatus == RequestStatus_Issued) {
- DPRINTF(RubyDma, "Request %s 0x%x issued\n", pkt->cmdString(),
- pkt->getAddr());
- return true;
- }
-
- // Unless one is using the ruby tester, record the stalled M5 port for
- // later retry when the sequencer becomes free.
- if (!seq->m_usingRubyTester) {
- seq->retry = true;
- }
-
- DPRINTF(RubyDma, "Request for address %#x did not issued because %s\n",
- pkt->getAddr(), RequestStatus_to_string(requestStatus));
-
- return false;
-}
-
-void
-DMASequencer::ruby_hit_callback(PacketPtr pkt)
-{
- DPRINTF(RubyDma, "Hit callback for %s 0x%x\n", pkt->cmdString(),
- pkt->getAddr());
-
- // The packet was destined for memory and has not yet been turned
- // into a response
- assert(system->isMemAddr(pkt->getAddr()));
- assert(pkt->isRequest());
- slave_port.hitCallback(pkt);
-
- // If we had to stall the slave ports, wake it up because
- // the sequencer likely has free resources now.
- if (retry) {
- retry = false;
- DPRINTF(RubyDma,"Sequencer may now be free. SendRetry to port %s\n",
- slave_port.name());
- slave_port.sendRetryReq();
- }
-
- testDrainComplete();
-}
-
-void
-DMASequencer::testDrainComplete()
-{
- //If we weren't able to drain before, we might be able to now.
- if (drainState() == DrainState::Draining) {
- unsigned int drainCount = outstandingCount();
- DPRINTF(Drain, "Drain count: %u\n", drainCount);
- if (drainCount == 0) {
- DPRINTF(Drain, "DMASequencer done draining, signaling drain done\n");
- signalDrainDone();
- }
- }
-}
-
-DrainState
-DMASequencer::drain()
-{
- if (isDeadlockEventScheduled()) {
- descheduleDeadlockEvent();
- }
-
- // If the DMASequencer is not empty, then it needs to clear all outstanding
- // requests before it should call signalDrainDone()
- DPRINTF(Config, "outstanding count %d\n", outstandingCount());
-
- // Set status
- if (outstandingCount() > 0) {
- DPRINTF(Drain, "DMASequencer not drained\n");
- return DrainState::Draining;
- } else {
- return DrainState::Drained;
- }
-}
-
-void
-DMASequencer::MemSlavePort::hitCallback(PacketPtr pkt)
-{
- bool needsResponse = pkt->needsResponse();
- assert(!pkt->isLLSC());
- assert(!pkt->isFlush());
-
- DPRINTF(RubyDma, "Hit callback needs response %d\n", needsResponse);
-
- // turn packet around to go back to requester if response expected
-
- if (access_backing_store) {
- m_ruby_system->getPhysMem()->access(pkt);
- } else if (needsResponse) {
- pkt->makeResponse();
- }
-
- if (needsResponse) {
- DPRINTF(RubyDma, "Sending packet back over port\n");
- // send next cycle
- DMASequencer *seq = static_cast<DMASequencer *>(&owner);
- RubySystem *rs = seq->m_ruby_system;
- schedTimingResp(pkt, curTick() + rs->clockPeriod());
- } else {
- delete pkt;
- }
-
- DPRINTF(RubyDma, "Hit callback done!\n");
-}
-
-bool
-DMASequencer::MemSlavePort::isPhysMemAddress(Addr addr) const
-{
- DMASequencer *seq = static_cast<DMASequencer *>(&owner);
- return seq->system->isMemAddr(addr);
}
RequestStatus