changeset 77787650cbbc in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=77787650cbbc
description:
        ruby: provide a backing store
        Ruby's functional accesses are not guaranteed to succeed as of now.  
While
        this is not a problem for the protocols that are currently in the 
mainline
        repo, it seems that coherence protocols for gpus rely on a backing 
store to
        supply the correct data.  The aim of this patch is to make this backing 
store
        configurable i.e. it comes into play only when a particular option:
        --access-backing-store is invoked.

        The backing store has been there since M5 and GEMS were integrated.  
The only
        difference is that earlier the system used to maintain the backing 
store and
        ruby's copy was write-only.  Sometime last year, we moved to data being
        supplied supplied by ruby in SE mode simulations.  And now we have 
patches on
        the reviewboard, which remove ruby's copy of memory altogether and rely
        completely on the system's memory to supply data.  This patch adds back 
a
        SimpleMemory member to RubySystem.  This member is used only if the 
option:
        access-backing-store is set to true.  By default, the memory would not 
be
        accessed.

diffstat:

 configs/ruby/Ruby.py              |   8 ++++++++
 src/mem/ruby/system/RubyPort.cc   |  35 ++++++++++++++---------------------
 src/mem/ruby/system/RubyPort.hh   |   7 ++-----
 src/mem/ruby/system/RubySystem.py |   2 ++
 src/mem/ruby/system/Sequencer.py  |   3 +--
 src/mem/ruby/system/System.cc     |   1 +
 src/mem/ruby/system/System.hh     |   3 +++
 7 files changed, 31 insertions(+), 28 deletions(-)

diffs (243 lines):

diff -r fff17530cef6 -r 77787650cbbc configs/ruby/Ruby.py
--- a/configs/ruby/Ruby.py      Thu Nov 06 05:42:21 2014 -0600
+++ b/configs/ruby/Ruby.py      Thu Nov 06 05:42:21 2014 -0600
@@ -56,6 +56,9 @@
                       default='2GHz',
                       help="Clock for blocks running at Ruby system's speed")
 
+    parser.add_option("--access-backing-store", action="store_true", 
default=False,
+                      help="Should ruby maintain a second copy of memory")
+
     # Options related to cache structure
     parser.add_option("--ports", action="store", type="int", default=4,
                       help="used of transitions per cycle which is a proxy \
@@ -229,3 +232,8 @@
     ruby._cpu_ports = cpu_sequencers
     ruby.num_of_sequencers = len(cpu_sequencers)
     ruby.random_seed    = options.random_seed
+
+    # Create a backing copy of physical memory in case required
+    if options.access_backing_store:
+        ruby.phys_mem = SimpleMemory(range=AddrRange(options.mem_size),
+                                     in_addr_map=False)
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc   Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/RubyPort.cc   Thu Nov 06 05:42:21 2014 -0600
@@ -46,6 +46,7 @@
 #include "mem/protocol/AccessPermission.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/ruby/system/RubyPort.hh"
+#include "mem/simple_mem.hh"
 #include "sim/full_system.hh"
 #include "sim/system.hh"
 
@@ -57,16 +58,15 @@
       pioSlavePort(csprintf("%s.pio-slave-port", name()), this),
       memMasterPort(csprintf("%s.mem-master-port", name()), this),
       memSlavePort(csprintf("%s-mem-slave-port", name()), this,
-          p->ruby_system, p->access_phys_mem, -1),
-      gotAddrRanges(p->port_master_connection_count), drainManager(NULL),
-      access_phys_mem(p->access_phys_mem)
+          p->ruby_system, p->access_backing_store, -1),
+      gotAddrRanges(p->port_master_connection_count), drainManager(NULL)
 {
     assert(m_version != -1);
 
     // create the slave ports based on the number of connected ports
     for (size_t i = 0; i < p->port_slave_connection_count; ++i) {
         slave_ports.push_back(new MemSlavePort(csprintf("%s.slave%d", name(),
-            i), this, p->ruby_system, access_phys_mem, i));
+            i), this, p->ruby_system, p->access_backing_store, i));
     }
 
     // create the master ports based on the number of connected ports
@@ -155,9 +155,10 @@
 }
 
 RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port,
-                         RubySystem *_system, bool _access_phys_mem, PortID id)
+                                     RubySystem *_system,
+                                     bool _access_backing_store, PortID id)
     : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
-      ruby_system(_system), access_phys_mem(_access_phys_mem)
+      ruby_system(_system), access_backing_store(_access_backing_store)
 {
     DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name);
 }
@@ -281,11 +282,11 @@
 RubyPort::MemSlavePort::recvFunctional(PacketPtr pkt)
 {
     DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr());
-    RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
 
     // Check for pio requests and directly send them to the dedicated
     // pio port.
     if (!isPhysMemAddress(pkt->getAddr())) {
+        RubyPort *ruby_port M5_VAR_USED = static_cast<RubyPort *>(&owner);
         assert(ruby_port->memMasterPort.isConnected());
         DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr());
         panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n");
@@ -314,23 +315,19 @@
               pkt->isWrite() ? "write" : "read", pkt->getAddr());
     }
 
-    if (access_phys_mem) {
+    if (access_backing_store) {
         // The attached physmem contains the official version of data.
         // The following command performs the real functional access.
         // This line should be removed once Ruby supplies the official version
         // of data.
-        ruby_port->system->getPhysMem().functionalAccess(pkt);
+        ruby_system->getPhysMem()->functionalAccess(pkt);
     }
 
     // turn packet around to go back to requester if response expected
     if (needsResponse) {
         pkt->setFunctionalResponseStatus(accessSucceeded);
+    }
 
-        // @todo There should not be a reverse call since the response is
-        // communicated through the packet pointer
-        // DPRINTF(RubyPort, "Sending packet back over port\n");
-        // sendFunctional(pkt);
-    }
     DPRINTF(RubyPort, "Functional access %s!\n",
             accessSucceeded ? "successful":"failed");
 }
@@ -459,11 +456,9 @@
 {
     bool needsResponse = pkt->needsResponse();
 
-    //
     // Unless specified at configuraiton, all responses except failed SC 
     // and Flush operations access M5 physical memory.
-    //
-    bool accessPhysMem = access_phys_mem;
+    bool accessPhysMem = access_backing_store;
 
     if (pkt->isLLSC()) {
         if (pkt->isWrite()) {
@@ -488,9 +483,7 @@
         }
     }
 
-    //
     // Flush requests don't access physical memory
-    //
     if (pkt->isFlush()) {
         accessPhysMem = false;
     }
@@ -498,8 +491,7 @@
     DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
 
     if (accessPhysMem) {
-        RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
-        ruby_port->system->getPhysMem().access(pkt);
+        ruby_system->getPhysMem()->functionalAccess(pkt);
     } else if (needsResponse) {
         pkt->makeResponse();
     }
@@ -512,6 +504,7 @@
     } else {
         delete pkt;
     }
+
     DPRINTF(RubyPort, "Hit callback done!\n");
 }
 
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/RubyPort.hh
--- a/src/mem/ruby/system/RubyPort.hh   Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/RubyPort.hh   Thu Nov 06 05:42:21 2014 -0600
@@ -73,14 +73,13 @@
     class MemSlavePort : public QueuedSlavePort
     {
       private:
-
         SlavePacketQueue queue;
         RubySystem* ruby_system;
-        bool access_phys_mem;
+        bool access_backing_store;
 
       public:
         MemSlavePort(const std::string &_name, RubyPort *_port,
-               RubySystem*_system, bool _access_phys_mem, PortID id);
+               RubySystem*_system, bool _access_backing_store, PortID id);
         void hitCallback(PacketPtr pkt);
         void evictionCallback(const Address& address);
 
@@ -212,8 +211,6 @@
     // that should be called when the Sequencer becomes available after a 
stall.
     //
     std::vector<MemSlavePort *> retryList;
-
-    bool access_phys_mem;
 };
 
 #endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/RubySystem.py
--- a/src/mem/ruby/system/RubySystem.py Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/RubySystem.py Thu Nov 06 05:42:21 2014 -0600
@@ -29,6 +29,7 @@
 
 from m5.params import *
 from ClockedObject import ClockedObject
+from SimpleMemory import *
 
 class RubySystem(ClockedObject):
     type = 'RubySystem'
@@ -45,3 +46,4 @@
     hot_lines = Param.Bool(False, "")
     all_instructions = Param.Bool(False, "")
     num_of_sequencers = Param.Int("")
+    phys_mem = Param.SimpleMemory(NULL, "")
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/Sequencer.py
--- a/src/mem/ruby/system/Sequencer.py  Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/Sequencer.py  Thu Nov 06 05:42:21 2014 -0600
@@ -45,7 +45,7 @@
     mem_slave_port = SlavePort("Ruby memory port")
 
     using_ruby_tester = Param.Bool(False, "")
-    access_phys_mem = Param.Bool(False,
+    access_backing_store = Param.Bool(False,
         "should the rubyport atomically update phys_mem")
     ruby_system = Param.RubySystem("")
     system = Param.System(Parent.any, "system object")
@@ -55,7 +55,6 @@
 class RubyPortProxy(RubyPort):
     type = 'RubyPortProxy'
     cxx_header = "mem/ruby/system/RubyPortProxy.hh"
-    access_phys_mem = False
     
 class RubySequencer(RubyPort):
     type = 'RubySequencer'
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/System.cc
--- a/src/mem/ruby/system/System.cc     Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/System.cc     Thu Nov 06 05:42:21 2014 -0600
@@ -77,6 +77,7 @@
     Stats::registerDumpCallback(new RubyStatsCallback(this));
     // Create the profiler
     m_profiler = new Profiler(p);
+    m_phys_mem = p->phys_mem;
 }
 
 void
diff -r fff17530cef6 -r 77787650cbbc src/mem/ruby/system/System.hh
--- a/src/mem/ruby/system/System.hh     Thu Nov 06 05:42:21 2014 -0600
+++ b/src/mem/ruby/system/System.hh     Thu Nov 06 05:42:21 2014 -0600
@@ -75,6 +75,8 @@
     static uint32_t getBlockSizeBits() { return m_block_size_bits; }
     static uint32_t getMemorySizeBits() { return m_memory_size_bits; }
 
+    SimpleMemory *getPhysMem() { return m_phys_mem; }
+
     // Public Methods
     Profiler*
     getProfiler()
@@ -122,6 +124,7 @@
     static uint32_t m_block_size_bytes;
     static uint32_t m_block_size_bits;
     static uint32_t m_memory_size_bits;
+    SimpleMemory *m_phys_mem;
 
     Network* m_network;
     std::vector<AbstractController *> m_abs_cntrl_vec;
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to