diff options
Diffstat (limited to 'src/mem/ruby/slicc_interface')
-rw-r--r-- | src/mem/ruby/slicc_interface/AbstractController.hh | 10 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/Message.hh | 12 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/NetworkMessage.hh | 1 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/RubyRequest.cc | 37 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/RubyRequest.hh | 3 | ||||
-rw-r--r-- | src/mem/ruby/slicc_interface/RubySlicc_Util.hh | 57 |
6 files changed, 119 insertions, 1 deletions
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 70b9968c7..c5cb46f1e 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -32,6 +32,7 @@ #include <iostream> #include <string> +#include "mem/packet.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Consumer.hh" @@ -68,6 +69,15 @@ class AbstractController : public SimObject, public Consumer virtual void clearStats() = 0; virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0; virtual Sequencer* getSequencer() const = 0; + + //! These functions are used by ruby system to read/write the message + //! queues that exist with in the controller. + //! The boolean return value indicates if the read was performed + //! successfully. + virtual bool functionalReadBuffers(PacketPtr&) = 0; + //! The return value indicates the number of messages written with the + //! data from the packet. + virtual uint32_t functionalWriteBuffers(PacketPtr&) = 0; }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh index 48156a99a..7b94a01e2 100644 --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -61,6 +61,18 @@ class Message : public RefCounted virtual void setIncomingLink(int) {} virtual void setVnet(int) {} + /** + * The two functions below are used for reading / writing the message + * functionally. The methods return true if the address in the packet + * matches the address / address range in the message. Each message + * class that can be potentially searched for the address needs to + * implement these methods. + */ + virtual bool functionalRead(Packet *pkt) = 0; + //{ fatal("Read functional access not implemented!"); } + virtual bool functionalWrite(Packet *pkt) = 0; + //{ fatal("Write functional access not implemented!"); } + void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; } const int& getDelayedCycles() const {return m_DelayedCycles;} int& getDelayedCycles() {return m_DelayedCycles;} diff --git a/src/mem/ruby/slicc_interface/NetworkMessage.hh b/src/mem/ruby/slicc_interface/NetworkMessage.hh index a8f9c625b..d2bcb1241 100644 --- a/src/mem/ruby/slicc_interface/NetworkMessage.hh +++ b/src/mem/ruby/slicc_interface/NetworkMessage.hh @@ -33,7 +33,6 @@ #include "base/refcnt.hh" #include "mem/protocol/MessageSizeType.hh" -#include "mem/ruby/common/Global.hh" #include "mem/ruby/common/NetDest.hh" #include "mem/ruby/slicc_interface/Message.hh" diff --git a/src/mem/ruby/slicc_interface/RubyRequest.cc b/src/mem/ruby/slicc_interface/RubyRequest.cc index 2aae61d7b..7ff2b75d8 100644 --- a/src/mem/ruby/slicc_interface/RubyRequest.cc +++ b/src/mem/ruby/slicc_interface/RubyRequest.cc @@ -18,3 +18,40 @@ RubyRequest::print(ostream& out) const // out << "Time = " << getTime() << " "; out << "]"; } + +bool +RubyRequest::functionalRead(Packet *pkt) +{ + // This needs a little explanation. Initially I thought that this + // message should be read. But the way the memtester works for now, + // we should not be reading this message as memtester updates the + // functional memory only after a write has actually taken place. + return false; +} + +bool +RubyRequest::functionalWrite(Packet *pkt) +{ + // This needs a little explanation. I am not sure if this message + // should be written. Essentially the question is how are writes + // ordered. I am assuming that if a functional write is issued after + // a timing write to the same address, then the functional write + // has to overwrite the data for the timing request, even if the + // timing request has still not been ordered globally. + + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + if (pktLineAddr == m_LineAddress) { + uint8_t *pktData = pkt->getPtr<uint8_t>(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - m_LineAddress.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + data[i + startByte] = pktData[i]; + } + + return true; + } + return false; +} diff --git a/src/mem/ruby/slicc_interface/RubyRequest.hh b/src/mem/ruby/slicc_interface/RubyRequest.hh index 870ad1d0e..a4dadc7a7 100644 --- a/src/mem/ruby/slicc_interface/RubyRequest.hh +++ b/src/mem/ruby/slicc_interface/RubyRequest.hh @@ -126,6 +126,9 @@ class RubyRequest : public Message } void print(std::ostream& out) const; + + bool functionalRead(Packet *pkt); + bool functionalWrite(Packet *pkt); }; inline std::ostream& diff --git a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh index 06372c9fc..06c540db5 100644 --- a/src/mem/ruby/slicc_interface/RubySlicc_Util.hh +++ b/src/mem/ruby/slicc_interface/RubySlicc_Util.hh @@ -35,6 +35,7 @@ #include <cassert> +#include "debug/RubySlicc.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/common/Global.hh" #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" @@ -129,4 +130,60 @@ mod(int val, int mod) return val % mod; } +/** + * This function accepts an address, a data block and a packet. If the address + * range for the data block contains the address which the packet needs to + * read, then the data from the data block is written to the packet. True is + * returned if the data block was read, otherwise false is returned. + */ +inline bool +testAndRead(Address addr, DataBlock& blk, Packet *pkt) +{ + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + Address lineAddr = addr; + lineAddr.makeLineAddress(); + + if (pktLineAddr == lineAddr) { + uint8_t *data = pkt->getPtr<uint8_t>(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - lineAddr.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + data[i] = blk.getByte(i + startByte); + } + return true; + } + return false; +} + +/** + * This function accepts an address, a data block and a packet. If the address + * range for the data block contains the address which the packet needs to + * write, then the data from the packet is written to the data block. True is + * returned if the data block was written, otherwise false is returned. + */ +inline bool +testAndWrite(Address addr, DataBlock& blk, Packet *pkt) +{ + Address pktLineAddr(pkt->getAddr()); + pktLineAddr.makeLineAddress(); + + Address lineAddr = addr; + lineAddr.makeLineAddress(); + + if (pktLineAddr == lineAddr) { + uint8_t *data = pkt->getPtr<uint8_t>(true); + unsigned int size_in_bytes = pkt->getSize(); + unsigned startByte = pkt->getAddr() - lineAddr.getAddress(); + + for (unsigned i = 0; i < size_in_bytes; ++i) { + blk.setByte(i + startByte, data[i]); + } + return true; + } + return false; +} + #endif // __MEM_RUBY_SLICC_INTERFACE_RUBYSLICCUTIL_HH__ |