summaryrefslogtreecommitdiff
path: root/src/mem/ruby/system
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/ruby/system')
-rw-r--r--src/mem/ruby/system/MemoryControl.cc14
-rw-r--r--src/mem/ruby/system/MemoryControl.hh10
-rw-r--r--src/mem/ruby/system/RubyMemoryControl.cc88
-rw-r--r--src/mem/ruby/system/RubyMemoryControl.hh2
-rw-r--r--src/mem/ruby/system/System.cc110
5 files changed, 146 insertions, 78 deletions
diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc
index c5ddb0c44..e58b36f63 100644
--- a/src/mem/ruby/system/MemoryControl.cc
+++ b/src/mem/ruby/system/MemoryControl.cc
@@ -27,18 +27,10 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "base/cast.hh"
-#include "base/cprintf.hh"
#include "debug/RubyStats.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Global.hh"
-#include "mem/ruby/network/Network.hh"
-#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/slicc_interface/NetworkMessage.hh"
#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
#include "mem/ruby/system/MemoryControl.hh"
-#include "mem/ruby/system/RubyMemoryControl.hh"
#include "mem/ruby/system/System.hh"
using namespace std;
@@ -55,9 +47,3 @@ MemoryControl::recordRequestType(MemoryControlRequestType request) {
DPRINTF(RubyStats, "Recorded request: %s\n",
MemoryControlRequestType_to_string(request));
}
-
-RubyMemoryControl *
-RubyMemoryControlParams::create()
-{
- return new RubyMemoryControl(this);
-}
diff --git a/src/mem/ruby/system/MemoryControl.hh b/src/mem/ruby/system/MemoryControl.hh
index 7bdc14cfc..8d15b8dec 100644
--- a/src/mem/ruby/system/MemoryControl.hh
+++ b/src/mem/ruby/system/MemoryControl.hh
@@ -35,19 +35,14 @@
#include <string>
#include "mem/protocol/MemoryControlRequestType.hh"
-#include "mem/protocol/MemoryMsg.hh"
#include "mem/ruby/common/Consumer.hh"
-#include "mem/ruby/profiler/MemCntrlProfiler.hh"
#include "mem/ruby/slicc_interface/Message.hh"
#include "mem/ruby/system/MemoryNode.hh"
-#include "mem/ruby/system/System.hh"
#include "params/MemoryControl.hh"
#include "sim/clocked_object.hh"
//////////////////////////////////////////////////////////////////////////////
-class Consumer;
-
class MemoryControl : public ClockedObject, public Consumer
{
public:
@@ -97,6 +92,11 @@ class MemoryControl : public ClockedObject, public Consumer
virtual void recordRequestType(MemoryControlRequestType requestType);
+ virtual bool functionalReadBuffers(Packet *pkt)
+ { fatal("Functional read access not implemented!");}
+ virtual uint32_t functionalWriteBuffers(Packet *pkt)
+ { fatal("Functional read access not implemented!");}
+
protected:
class MemCntrlEvent : public Event
{
diff --git a/src/mem/ruby/system/RubyMemoryControl.cc b/src/mem/ruby/system/RubyMemoryControl.cc
index cfdaaaef7..c0e91c28b 100644
--- a/src/mem/ruby/system/RubyMemoryControl.cc
+++ b/src/mem/ruby/system/RubyMemoryControl.cc
@@ -708,3 +708,91 @@ RubyMemoryControl::wakeup()
}
}
+/**
+ * This function reads the different buffers that exist in the Ruby Memory
+ * Controller, and figures out if any of the buffers hold a message that
+ * contains the data for the address provided in the packet. True is returned
+ * if any of the messages was read, otherwise false is returned.
+ *
+ * I think we should move these buffers to being message buffers, instead of
+ * being lists.
+ */
+bool
+RubyMemoryControl::functionalReadBuffers(Packet *pkt)
+{
+ for (std::list<MemoryNode>::iterator it = m_input_queue.begin();
+ it != m_input_queue.end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalRead(pkt)) {
+ return true;
+ }
+ }
+
+ for (std::list<MemoryNode>::iterator it = m_response_queue.begin();
+ it != m_response_queue.end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalRead(pkt)) {
+ return true;
+ }
+ }
+
+ for (uint32_t bank = 0; bank < m_total_banks; ++bank) {
+ for (std::list<MemoryNode>::iterator it = m_bankQueues[bank].begin();
+ it != m_bankQueues[bank].end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalRead(pkt)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+/**
+ * This function reads the different buffers that exist in the Ruby Memory
+ * Controller, and figures out if any of the buffers hold a message that
+ * needs to functionally written with the data in the packet.
+ *
+ * The number of messages written is returned at the end. This is required
+ * for debugging purposes.
+ */
+uint32_t
+RubyMemoryControl::functionalWriteBuffers(Packet *pkt)
+{
+ uint32_t num_functional_writes = 0;
+
+ for (std::list<MemoryNode>::iterator it = m_input_queue.begin();
+ it != m_input_queue.end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalWrite(pkt)) {
+ num_functional_writes++;
+ }
+ }
+
+ for (std::list<MemoryNode>::iterator it = m_response_queue.begin();
+ it != m_response_queue.end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalWrite(pkt)) {
+ num_functional_writes++;
+ }
+ }
+
+ for (uint32_t bank = 0; bank < m_total_banks; ++bank) {
+ for (std::list<MemoryNode>::iterator it = m_bankQueues[bank].begin();
+ it != m_bankQueues[bank].end(); ++it) {
+ Message* msg_ptr = (*it).m_msgptr.get();
+ if (msg_ptr->functionalWrite(pkt)) {
+ num_functional_writes++;
+ }
+ }
+ }
+
+ return num_functional_writes;
+}
+
+RubyMemoryControl *
+RubyMemoryControlParams::create()
+{
+ return new RubyMemoryControl(this);
+}
diff --git a/src/mem/ruby/system/RubyMemoryControl.hh b/src/mem/ruby/system/RubyMemoryControl.hh
index 98636e408..1f3a8acf5 100644
--- a/src/mem/ruby/system/RubyMemoryControl.hh
+++ b/src/mem/ruby/system/RubyMemoryControl.hh
@@ -96,6 +96,8 @@ class RubyMemoryControl : public MemoryControl
int getRanksPerDimm() { return m_ranks_per_dimm; };
int getDimmsPerChannel() { return m_dimms_per_channel; }
+ bool functionalReadBuffers(Packet *pkt);
+ uint32_t functionalWriteBuffers(Packet *pkt);
private:
void enqueueToDirectory(MemoryNode req, int latency);
diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc
index b41f2d727..5ee22e9f5 100644
--- a/src/mem/ruby/system/System.cc
+++ b/src/mem/ruby/system/System.cc
@@ -417,7 +417,7 @@ RubySystem::functionalRead(PacketPtr pkt)
// In this loop we count the number of controllers that have the given
// address in read only, read write and busy states.
- for (int i = 0; i < num_controllers; ++i) {
+ for (unsigned int i = 0; i < num_controllers; ++i) {
access_perm = m_abs_cntrl_vec[i]-> getAccessPermission(line_address);
if (access_perm == AccessPermission_Read_Only)
num_ro++;
@@ -452,7 +452,7 @@ RubySystem::functionalRead(PacketPtr pkt)
if (num_invalid == (num_controllers - 1) &&
num_backing_store == 1) {
DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n");
- for (int i = 0; i < num_controllers; ++i) {
+ for (unsigned int i = 0; i < num_controllers; ++i) {
access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address);
if (access_perm == AccessPermission_Backing_Store) {
DataBlock& block = m_abs_cntrl_vec[i]->
@@ -466,7 +466,7 @@ RubySystem::functionalRead(PacketPtr pkt)
return true;
}
}
- } else {
+ } else if (num_ro > 0 || num_rw == 1) {
// In Broadcast/Snoop protocols, this covers if you know the block
// exists somewhere in the caching hierarchy, then you want to read any
// valid RO or RW block. In directory protocols, same thing, you want
@@ -476,7 +476,7 @@ RubySystem::functionalRead(PacketPtr pkt)
// In this loop, we try to figure which controller has a read only or
// a read write copy of the given address. Any valid copy would suffice
// for a functional read.
- for (int i = 0;i < num_controllers;++i) {
+ for (unsigned int i = 0;i < num_controllers;++i) {
access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address);
if (access_perm == AccessPermission_Read_Only ||
access_perm == AccessPermission_Read_Write) {
@@ -492,9 +492,34 @@ RubySystem::functionalRead(PacketPtr pkt)
}
}
}
+
+ // Since we are here, this means that none of the controllers hold this
+ // address in a stable/base state. The function searches through all the
+ // buffers that exist in different cache, directory and memory
+ // controllers, and in the network components and reads the data portion
+ // of the first message that holds address specified in the packet.
+ for (unsigned int i = 0; i < num_controllers;++i) {
+ if (m_abs_cntrl_vec[i]->functionalReadBuffers(pkt)) {
+ return true;
+ }
+ }
+
+ for (unsigned int i = 0; i < m_memory_controller_vec.size(); ++i) {
+ if (m_memory_controller_vec[i]->functionalReadBuffers(pkt)) {
+ return true;
+ }
+ }
+
+ if (m_network_ptr->functionalRead(pkt)) {
+ return true;
+ }
return false;
}
+// The function searches through all the buffers that exist in different
+// cache, directory and memory controllers, and in the network components
+// and writes the data portion of those that hold the address specified
+// in the packet.
bool
RubySystem::functionalWrite(PacketPtr pkt)
{
@@ -505,69 +530,36 @@ RubySystem::functionalWrite(PacketPtr pkt)
DPRINTF(RubySystem, "Functional Write request for %s\n",addr);
- unsigned int num_ro = 0;
- unsigned int num_rw = 0;
- unsigned int num_busy = 0;
- unsigned int num_backing_store = 0;
- unsigned int num_invalid = 0;
-
- // In this loop we count the number of controllers that have the given
- // address in read only, read write and busy states.
- for (int i = 0;i < num_controllers;++i) {
- access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
- if (access_perm == AccessPermission_Read_Only)
- num_ro++;
- else if (access_perm == AccessPermission_Read_Write)
- num_rw++;
- else if (access_perm == AccessPermission_Busy)
- num_busy++;
- else if (access_perm == AccessPermission_Backing_Store)
- // See RubySlicc_Exports.sm for details, but Backing_Store is meant
- // to represent blocks in memory *for Broadcast/Snooping protocols*,
- // where memory has no idea whether it has an exclusive copy of data
- // or not.
- num_backing_store++;
- else if (access_perm == AccessPermission_Invalid ||
- access_perm == AccessPermission_NotPresent)
- num_invalid++;
- }
-
- // If the number of read write copies is more than 1, then there is bug in
- // coherence protocol. Otherwise, if all copies are in stable states, i.e.
- // num_busy == 0, we update all the copies. If there is at least one copy
- // in busy state, then we check if there is read write copy. If yes, then
- // also we let the access go through. Or, if there is no copy in the cache
- // hierarchy at all, we still want to do the write to the memory
- // (Backing_Store) instead of failing.
-
- DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n",
- num_busy, num_ro, num_rw);
- assert(num_rw <= 1);
-
uint8_t *data = pkt->getPtr<uint8_t>(true);
unsigned int size_in_bytes = pkt->getSize();
unsigned startByte = addr.getAddress() - line_addr.getAddress();
- if ((num_busy == 0 && num_ro > 0) || num_rw == 1 ||
- (num_invalid == (num_controllers - 1) && num_backing_store == 1)) {
- for (int i = 0; i < num_controllers;++i) {
- access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
- if (access_perm == AccessPermission_Read_Only ||
- access_perm == AccessPermission_Read_Write||
- access_perm == AccessPermission_Maybe_Stale ||
- access_perm == AccessPermission_Backing_Store) {
+ for (unsigned int i = 0; i < num_controllers;++i) {
+ m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt);
- DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr);
- DPRINTF(RubySystem, "%s\n",block);
- for (unsigned i = 0; i < size_in_bytes; ++i) {
- block.setByte(i + startByte, data[i]);
- }
- DPRINTF(RubySystem, "%s\n",block);
+ access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
+ if (access_perm != AccessPermission_Invalid &&
+ access_perm != AccessPermission_NotPresent) {
+
+ DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr);
+ DPRINTF(RubySystem, "%s\n",block);
+ for (unsigned i = 0; i < size_in_bytes; ++i) {
+ block.setByte(i + startByte, data[i]);
}
+ DPRINTF(RubySystem, "%s\n",block);
}
- return true;
}
- return false;
+
+ uint32_t M5_VAR_USED num_functional_writes = 0;
+ for (unsigned int i = 0; i < m_memory_controller_vec.size() ;++i) {
+ num_functional_writes +=
+ m_memory_controller_vec[i]->functionalWriteBuffers(pkt);
+ }
+
+ num_functional_writes += m_network_ptr->functionalWrite(pkt);
+ DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);
+
+ return true;
}
#ifdef CHECK_COHERENCE