summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system/DMASequencer.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/system/DMASequencer.hh')
-rw-r--r--src/mem/ruby/system/DMASequencer.hh75
1 files changed, 73 insertions, 2 deletions
diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh
index 13d79182d..a24db2d34 100644
--- a/src/mem/ruby/system/DMASequencer.hh
+++ b/src/mem/ruby/system/DMASequencer.hh
@@ -33,10 +33,16 @@
#include <memory>
#include "mem/protocol/DMASequencerRequestType.hh"
+#include "mem/protocol/RequestStatus.hh"
#include "mem/ruby/common/DataBlock.hh"
-#include "mem/ruby/system/RubyPort.hh"
+#include "mem/ruby/network/MessageBuffer.hh"
+#include "mem/ruby/system/System.hh"
+#include "mem/mem_object.hh"
+#include "mem/tport.hh"
#include "params/DMASequencer.hh"
+class AbstractController;
+
struct DMARequest
{
uint64_t start_paddr;
@@ -48,12 +54,45 @@ struct DMARequest
PacketPtr pkt;
};
-class DMASequencer : public RubyPort
+class DMASequencer : public MemObject
{
public:
typedef DMASequencerParams Params;
DMASequencer(const Params *);
void init();
+
+ public:
+ class MemSlavePort : public QueuedSlavePort
+ {
+ private:
+ SlavePacketQueue queue;
+ bool access_phys_mem;
+
+ public:
+ MemSlavePort(const std::string &_name, DMASequencer *_port,
+ bool _access_phys_mem, PortID id);
+ void hitCallback(PacketPtr pkt);
+ void evictionCallback(const Address& 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);
+
/* external interface */
RequestStatus makeRequest(PacketPtr pkt);
bool busy() { return m_is_busy;}
@@ -61,6 +100,12 @@ class DMASequencer : public RubyPort
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; }
+ unsigned int drain(DrainManager *dm);
+
/* SLICC callback */
void dataCallback(const DataBlock & dblk);
void ackCallback();
@@ -69,8 +114,34 @@ class DMASequencer : public RubyPort
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(DrainManager *dm);
private:
+ uint32_t m_version;
+ AbstractController* m_controller;
+ MessageBuffer* m_mandatory_q_ptr;
+ bool m_usingRubyTester;
+
+ MemSlavePort slave_port;
+
+ DrainManager *drainManager;
+ System* system;
+
+ bool retry;
+ bool access_phys_mem;
+
bool m_is_busy;
uint64_t m_data_block_mask;
DMARequest active_request;