diff options
Diffstat (limited to 'src/mem/ruby/system/DMASequencer.hh')
-rw-r--r-- | src/mem/ruby/system/DMASequencer.hh | 75 |
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; |