ruby: make DMASequencer inherit from RubyPort
authorMichael LeBeane <Michael.Lebeane@amd.com>
Mon, 15 Feb 2016 01:28:48 +0000 (20:28 -0500)
committerMichael LeBeane <Michael.Lebeane@amd.com>
Mon, 15 Feb 2016 01:28:48 +0000 (20:28 -0500)
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.

src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/DMASequencer.hh
src/mem/ruby/system/Sequencer.py

index 2b65d675a651748b8ee4cca141d82be992711aac..fc2433a6c8e0eac08431dae05a767097f39748c0 100644 (file)
 
 #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
index 34f9be34c8f64e1b65bec4334aeef56a02fe8fee..9cf187c8323e59fa194da87d505a74f3ac4390d0 100644 (file)
 #include <memory>
 #include <ostream>
 
-#include "mem/mem_object.hh"
 #include "mem/protocol/DMASequencerRequestType.hh"
-#include "mem/protocol/RequestStatus.hh"
 #include "mem/ruby/common/DataBlock.hh"
-#include "mem/ruby/network/MessageBuffer.hh"
-#include "mem/ruby/system/RubySystem.hh"
-#include "mem/simple_mem.hh"
-#include "mem/tport.hh"
+#include "mem/ruby/system/RubyPort.hh"
 #include "params/DMASequencer.hh"
 
-class AbstractController;
-
 struct DMARequest
 {
     uint64_t start_paddr;
@@ -55,47 +48,12 @@ struct DMARequest
     PacketPtr pkt;
 };
 
-class DMASequencer : public MemObject
+class DMASequencer : public RubyPort
 {
   public:
     typedef DMASequencerParams Params;
     DMASequencer(const Params *);
     void init() override;
-    RubySystem *m_ruby_system;
-
-  public:
-    class MemSlavePort : public QueuedSlavePort
-    {
-      private:
-        RespPacketQueue queue;
-        RubySystem* m_ruby_system;
-        bool access_backing_store;
-
-      public:
-        MemSlavePort(const std::string &_name, DMASequencer *_port,
-                     PortID id, RubySystem *_ruby_system,
-                     bool _access_backing_store);
-        void hitCallback(PacketPtr pkt);
-        void evictionCallback(Addr address);
-
-      protected:
-        bool recvTimingReq(PacketPtr pkt);
-
-        Tick recvAtomic(PacketPtr pkt)
-        { panic("DMASequencer::MemSlavePort::recvAtomic() not implemented!\n"); }
-
-        void recvFunctional(PacketPtr pkt)
-        { panic("DMASequencer::MemSlavePort::recvFunctional() not implemented!\n"); }
-
-        AddrRangeList getAddrRanges() const
-        { AddrRangeList ranges; return ranges; }
-
-      private:
-        bool isPhysMemAddress(Addr addr) const;
-    };
-
-    BaseSlavePort &getSlavePort(const std::string &if_name,
-                                PortID idx = InvalidPortID) override;
 
     /* external interface */
     RequestStatus makeRequest(PacketPtr pkt);
@@ -104,12 +62,6 @@ class DMASequencer : public MemObject
     bool isDeadlockEventScheduled() const { return false; }
     void descheduleDeadlockEvent() {}
 
-    // Called by the controller to give the sequencer a pointer.
-    // A pointer to the controller is needed for atomic support.
-    void setController(AbstractController* _cntrl) { m_controller = _cntrl; }
-    uint32_t getId() { return m_version; }
-    DrainState drain() override;
-
     /* SLICC callback */
     void dataCallback(const DataBlock & dblk);
     void ackCallback();
@@ -118,31 +70,7 @@ class DMASequencer : public MemObject
 
   private:
     void issueNext();
-    void ruby_hit_callback(PacketPtr pkt);
-    void testDrainComplete();
-
-    /**
-     * Called by the PIO port when receiving a timing response.
-     *
-     * @param pkt Response packet
-     * @param master_port_id Port id of the PIO port
-     *
-     * @return Whether successfully sent
-     */
-    bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
-    unsigned int getChildDrainCount();
-
-  private:
-    uint32_t m_version;
-    AbstractController* m_controller;
-    MessageBuffer* m_mandatory_q_ptr;
-    bool m_usingRubyTester;
-
-    MemSlavePort slave_port;
-
-    System* system;
 
-    bool retry;
     bool m_is_busy;
     uint64_t m_data_block_mask;
     DMARequest active_request;
index d6ee0aa2fd47be60594d11806d8e4441b5919bf6..5b6a673da4572492f78f17f3586252889a525649 100644 (file)
@@ -78,12 +78,6 @@ class RubySequencer(RubyPort):
    # 99 is the dummy default value
    coreid = Param.Int(99, "CorePair core id")
 
-class DMASequencer(MemObject):
+class DMASequencer(RubyPort):
    type = 'DMASequencer'
    cxx_header = "mem/ruby/system/DMASequencer.hh"
-
-   version = Param.Int(0, "")
-   slave = SlavePort("Device slave port")
-   using_ruby_tester = Param.Bool(False, "")
-   ruby_system = Param.RubySystem(Parent.any, "")
-   system = Param.System(Parent.any, "system object")