ruby: rename System.{hh,cc} to RubySystem.{hh,cc}
authorDavid Hashe <david.hashe@amd.com>
Wed, 16 Sep 2015 16:03:03 +0000 (12:03 -0400)
committerDavid Hashe <david.hashe@amd.com>
Wed, 16 Sep 2015 16:03:03 +0000 (12:03 -0400)
The eventual aim of this change is to pass RubySystem pointers through to
objects generated from the SLICC protocol code.

Because some of these objects need to dereference their RubySystem pointers,
they need access to the System.hh header file.

In src/mem/ruby/SConscript, the MakeInclude function creates single-line header
files in the build directory that do nothing except include the corresponding
header file from the source tree.

However, SLICC also generates a list of header files from its symbol table, and
writes it to mem/protocol/Types.hh in the build directory. This code assumes
that the header file name is the same as the class name.

The end result of this is the many of the generated slicc files try to include
RubySystem.hh, when the file they really need is System.hh. The path of least
resistence is just to rename System.hh to RubySystem.hh.

--HG--
rename : src/mem/ruby/system/System.cc => src/mem/ruby/system/RubySystem.cc
rename : src/mem/ruby/system/System.hh => src/mem/ruby/system/RubySystem.hh

39 files changed:
src/mem/ruby/common/Address.cc
src/mem/ruby/common/DataBlock.cc
src/mem/ruby/filters/BlockBloomFilter.cc
src/mem/ruby/filters/BulkBloomFilter.cc
src/mem/ruby/filters/LSB_CountingBloomFilter.cc
src/mem/ruby/filters/MultiGrainBloomFilter.cc
src/mem/ruby/filters/NonCountingBloomFilter.cc
src/mem/ruby/network/MessageBuffer.cc
src/mem/ruby/network/Network.cc
src/mem/ruby/network/garnet/fixed-pipeline/GarnetNetwork_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.cc
src/mem/ruby/network/garnet/flexible-pipeline/GarnetNetwork.cc
src/mem/ruby/network/simple/SimpleNetwork.cc
src/mem/ruby/network/simple/Throttle.cc
src/mem/ruby/network/simple/Throttle.hh
src/mem/ruby/slicc_interface/AbstractController.cc
src/mem/ruby/structures/BankedArray.cc
src/mem/ruby/structures/BankedArray.hh
src/mem/ruby/structures/CacheMemory.cc
src/mem/ruby/structures/DirectoryMemory.cc
src/mem/ruby/structures/Prefetcher.cc
src/mem/ruby/structures/Prefetcher.hh
src/mem/ruby/structures/RubyMemoryControl.cc
src/mem/ruby/structures/RubyMemoryControl.hh
src/mem/ruby/structures/TimerTable.cc
src/mem/ruby/structures/WireBuffer.cc
src/mem/ruby/system/CacheRecorder.cc
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/DMASequencer.hh
src/mem/ruby/system/RubyPort.hh
src/mem/ruby/system/RubySystem.cc [new file with mode: 0644]
src/mem/ruby/system/RubySystem.hh [new file with mode: 0644]
src/mem/ruby/system/RubySystem.py
src/mem/ruby/system/SConscript
src/mem/ruby/system/Sequencer.cc
src/mem/ruby/system/System.cc [deleted file]
src/mem/ruby/system/System.hh [deleted file]
src/mem/slicc/symbols/StateMachine.py
src/mem/slicc/symbols/Type.py

index 8d8800501d2ec85a5cc22a44206e0a385aebeb42..d9fadf12876ced31e53578861d942bb4aeb6c576 100644 (file)
@@ -27,7 +27,8 @@
  */
 
 #include "mem/ruby/common/Address.hh"
-#include "mem/ruby/system/System.hh"
+
+#include "mem/ruby/system/RubySystem.hh"
 
 Addr
 bitSelect(Addr addr, unsigned int small, unsigned int big)
index 2a292444aebb3adb8cd0c4198d1b22caad4f2eb5..fb2e956e01bb2dfac62b1e0a23efbc8d1b48da2d 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 #include "mem/ruby/common/DataBlock.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 DataBlock::DataBlock(const DataBlock &cp)
 {
index c902f9f38d4bed1bdb82a89d046efdac57a28f7f..94e748d6e9b6a402fa895e0f37e651fb89c2d4a8 100644 (file)
@@ -29,7 +29,7 @@
 #include "base/intmath.hh"
 #include "base/str.hh"
 #include "mem/ruby/filters/BlockBloomFilter.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 953add21989656c6368f9166ed90e10100c9f9e5..c656776a4a636d7674600476ccaa6fa6bc39a2fe 100644 (file)
@@ -31,7 +31,7 @@
 #include "base/intmath.hh"
 #include "base/str.hh"
 #include "mem/ruby/filters/BulkBloomFilter.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 265e58625a895c1dbf7172cd829a1f4b67bb0d20..1c2d4fea6eccf4fa9a8b0f551f215629e27ac020 100644 (file)
@@ -29,7 +29,7 @@
 #include "base/intmath.hh"
 #include "base/str.hh"
 #include "mem/ruby/filters/LSB_CountingBloomFilter.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 33d80f0c41c591ca3f0c772aeb5b220ac7d9d8d2..52aae0b55ba16cbaff13e768a42eae816a04a99b 100644 (file)
@@ -29,7 +29,7 @@
 #include "base/intmath.hh"
 #include "base/str.hh"
 #include "mem/ruby/filters/MultiGrainBloomFilter.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 14bb3a2450d8a9ba7d5b1cb97d67f8ab5d2fd6ec..a8d00c8d7a13842c77252c9f7cccb4f84bb7771b 100644 (file)
@@ -29,7 +29,7 @@
 #include "base/intmath.hh"
 #include "base/str.hh"
 #include "mem/ruby/filters/NonCountingBloomFilter.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index a72d8509e0d308b86d5dbc91e54d1e648cabc571..b07bdbdca729cfb65c229de445e933ebc97dbca6 100644 (file)
@@ -34,7 +34,7 @@
 #include "base/stl_helpers.hh"
 #include "debug/RubyQueue.hh"
 #include "mem/ruby/network/MessageBuffer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 using m5::stl_helpers::operator<<;
index 5d0ff980c026323d1f63c40d7380e113743bcc79..d35b909d927380c50889c687764ee7d45a685525 100644 (file)
@@ -29,7 +29,7 @@
 #include "base/misc.hh"
 #include "mem/ruby/network/BasicLink.hh"
 #include "mem/ruby/network/Network.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 uint32_t Network::m_virtual_networks;
 uint32_t Network::m_control_msg_size;
index 196ebb089f72b0693311005d69aa742e7b11e8bc..4d5846f55b147719d14b11f21bbf947345c8af05 100644 (file)
@@ -39,7 +39,7 @@
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
 #include "mem/ruby/network/garnet/fixed-pipeline/Router_d.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 using m5::stl_helpers::deletePointers;
index d0a422f1f8a889237d2d4b5cda547505c6848ff8..39cfc00b547930eef9bfd9efc0874db9bf606b4b 100644 (file)
@@ -29,7 +29,8 @@
  */
 
 #include "mem/ruby/network/garnet/fixed-pipeline/OutVcState_d.hh"
-#include "mem/ruby/system/System.hh"
+
+#include "mem/ruby/system/RubySystem.hh"
 
 OutVcState_d::OutVcState_d(int id, GarnetNetwork_d *network_ptr)
     : m_time(0)
index 87418b6b1c6231ea211385e4fd9fb0de676190a3..83cbe8d516e8f7e6d94c9d9ccaa4b448cfd20258 100644 (file)
@@ -39,7 +39,7 @@
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
 #include "mem/ruby/network/garnet/flexible-pipeline/Router.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 using m5::stl_helpers::deletePointers;
index eb3bec256d69e30a0dcd8615a888d283ecce5bde..c10d1cce86c7629ec641fa6ecd18be72396bc782 100644 (file)
@@ -38,7 +38,7 @@
 #include "mem/ruby/network/simple/Switch.hh"
 #include "mem/ruby/network/simple/Throttle.hh"
 #include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 using m5::stl_helpers::deletePointers;
index c97531e585210ae58c212279e00cde0632f42eac..01d1f6fbe407436b7cba0ff5e595a800fbd1a6eb 100644 (file)
@@ -36,7 +36,7 @@
 #include "mem/ruby/network/MessageBuffer.hh"
 #include "mem/ruby/network/Network.hh"
 #include "mem/ruby/slicc_interface/Message.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 405593bb129d70a86313176faffa67f885a03bcf..bf70c3075d6ad49811ec48ff572475ab4501f13d 100644 (file)
@@ -44,7 +44,7 @@
 
 #include "mem/ruby/common/Consumer.hh"
 #include "mem/ruby/network/Network.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 class MessageBuffer;
 class Switch;
index 9ed8b08d061bcf5f4169056c63ecfa1ab6618318..5bd38195a5e9f4bc07f63cccfef50394c7d017b1 100644 (file)
@@ -30,8 +30,8 @@
 
 #include "debug/RubyQueue.hh"
 #include "mem/protocol/MemoryMsg.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
 #include "sim/system.hh"
 
 AbstractController::AbstractController(const Params *p)
index b25962df6a13379f5b26d1187ac197e130001998..550693ca2184fa3d5e24511484cccff4e26857a1 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "base/intmath.hh"
 #include "mem/ruby/structures/BankedArray.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 BankedArray::BankedArray(unsigned int banks, Cycles accessLatency,
                          unsigned int startIndexBit, RubySystem *rs)
index 179676f1928b1066b8614bd0a377ec27461af44c..e2359afc99d8603c8248e8d408d81a1985586b44 100644 (file)
@@ -35,7 +35,7 @@
 #include <vector>
 
 #include "mem/ruby/common/TypeDefines.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "sim/core.hh"
 
 class BankedArray
index 931f58a8ef686b111f1d829c5b43920c169026b4..a269d4f5bc00db6922b6e0d50e427ad94930d926 100644 (file)
@@ -34,7 +34,7 @@
 #include "debug/RubyStats.hh"
 #include "mem/protocol/AccessPermission.hh"
 #include "mem/ruby/structures/CacheMemory.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 82388a8954f6f27c28a46b2c011c7c686c08a94b..267c07174b040ae0d14f61bdedfb44b67f52da61 100644 (file)
@@ -31,7 +31,7 @@
 #include "debug/RubyStats.hh"
 #include "mem/ruby/slicc_interface/RubySlicc_Util.hh"
 #include "mem/ruby/structures/DirectoryMemory.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index fbf027bef99c025efa66fc967b54ca6234c2ea4c..d12665ae9f391155d22e418cd95e2509caf511bc 100644 (file)
@@ -29,7 +29,7 @@
 #include "debug/RubyPrefetcher.hh"
 #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
 #include "mem/ruby/structures/Prefetcher.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 Prefetcher*
 PrefetcherParams::create()
index d5c3d4b58740ceaf74cb4f8b70ea3aa3d43ac01b..9c3c06851fe6a3eaeb3dab6e56f921c1e0364d6c 100644 (file)
@@ -38,7 +38,7 @@
 #include "mem/ruby/network/MessageBuffer.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
 #include "mem/ruby/slicc_interface/RubyRequest.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "params/Prefetcher.hh"
 #include "sim/sim_object.hh"
 #include "sim/system.hh"
index 413850627d8023b764065e4a8264fe6c3b11a957..452606451c5597fd1f3c763b1e95bf3bc3e7bc2f 100644 (file)
 #include "mem/ruby/slicc_interface/Message.hh"
 #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh"
 #include "mem/ruby/structures/RubyMemoryControl.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
index 376ce4d75b42b9c6821c62ff01d9cc68a2ebdc14..f5f31458bc6d9af24864b0ad4cac0bb0de06edee 100644 (file)
@@ -39,7 +39,7 @@
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/profiler/MemCntrlProfiler.hh"
 #include "mem/ruby/structures/MemoryNode.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "params/RubyMemoryControl.hh"
 
 // This constant is part of the definition of tFAW; see
index 7d0dd3c01fd9bb27ced8a957b7a644ce844ce2df..17dac6fc0c9fc0d7f5aebaf6497f28389d42e819 100644 (file)
@@ -27,7 +27,8 @@
  */
 
 #include "mem/ruby/structures/TimerTable.hh"
-#include "mem/ruby/system/System.hh"
+
+#include "mem/ruby/system/RubySystem.hh"
 
 TimerTable::TimerTable()
     : m_next_time(0)
index 0375d944624d71e4cbd6f1e5bc1570a19c56b0e5..e2f11364316556545727731abae0a5f57930db60 100644 (file)
@@ -35,7 +35,7 @@
 #include "base/cprintf.hh"
 #include "base/stl_helpers.hh"
 #include "mem/ruby/structures/WireBuffer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 
@@ -121,7 +121,8 @@ WireBuffer::recycle()
     push_heap(m_message_queue.begin(), m_message_queue.end(),
         greater<MsgPtr>());
     m_consumer_ptr->
-        scheduleEventAbsolute(m_ruby_system->curCycle() + Cycles(1));
+        scheduleEventAbsolute(m_ruby_system->clockPeriod()
+                              * (m_ruby_system->curCycle() + Cycles(1)));
 }
 
 bool
index 339cf1b4f748bc76c6b142365b7e676da7341dbf..78d6939fc500f8329fdd51473aac49dd6bf6366d 100644 (file)
@@ -29,8 +29,8 @@
 
 #include "debug/RubyCacheTrace.hh"
 #include "mem/ruby/system/CacheRecorder.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
 
 using namespace std;
 
index e263fefdb1820c51a7d79db41d27aa4739c4ebbb..85b476cfdcb8de73f7be3a9d1f52175ead8cccc5 100644 (file)
@@ -34,7 +34,7 @@
 #include "debug/RubyStats.hh"
 #include "mem/protocol/SequencerMsg.hh"
 #include "mem/ruby/system/DMASequencer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "sim/system.hh"
 
 DMASequencer::DMASequencer(const Params *p)
index 1539c3999988a168da8ad92f60843b210098ad16..f9d1b630e4fd4f94fe8b4d200d431725910eed3f 100644 (file)
@@ -37,7 +37,7 @@
 #include "mem/protocol/RequestStatus.hh"
 #include "mem/ruby/common/DataBlock.hh"
 #include "mem/ruby/network/MessageBuffer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "mem/simple_mem.hh"
 #include "mem/tport.hh"
 #include "params/DMASequencer.hh"
index f2841e56108ac623a68fcf53bcc12fb74e4a3f72..cbcc678d39ef641190acf024a6350e7f9e2a8c98 100644 (file)
@@ -47,7 +47,7 @@
 
 #include "mem/protocol/RequestStatus.hh"
 #include "mem/ruby/network/MessageBuffer.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "mem/mem_object.hh"
 #include "mem/tport.hh"
 #include "params/RubyPort.hh"
diff --git a/src/mem/ruby/system/RubySystem.cc b/src/mem/ruby/system/RubySystem.cc
new file mode 100644 (file)
index 0000000..4547751
--- /dev/null
@@ -0,0 +1,567 @@
+/*
+ * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "mem/ruby/system/RubySystem.hh"
+
+#include <fcntl.h>
+#include <zlib.h>
+
+#include <cstdio>
+#include <list>
+
+#include "base/intmath.hh"
+#include "base/statistics.hh"
+#include "debug/RubyCacheTrace.hh"
+#include "debug/RubySystem.hh"
+#include "mem/ruby/common/Address.hh"
+#include "mem/ruby/network/Network.hh"
+#include "mem/simple_mem.hh"
+#include "sim/eventq.hh"
+#include "sim/simulate.hh"
+
+using namespace std;
+
+bool RubySystem::m_randomization;
+uint32_t RubySystem::m_block_size_bytes;
+uint32_t RubySystem::m_block_size_bits;
+uint32_t RubySystem::m_memory_size_bits;
+bool RubySystem::m_warmup_enabled = false;
+// To look forward to allowing multiple RubySystem instances, track the number
+// of RubySystems that need to be warmed up on checkpoint restore.
+unsigned RubySystem::m_systems_to_warmup = 0;
+bool RubySystem::m_cooldown_enabled = false;
+
+RubySystem::RubySystem(const Params *p)
+    : ClockedObject(p), m_access_backing_store(p->access_backing_store),
+      m_cache_recorder(NULL)
+{
+    m_randomization = p->randomization;
+
+    m_block_size_bytes = p->block_size_bytes;
+    assert(isPowerOf2(m_block_size_bytes));
+    m_block_size_bits = floorLog2(m_block_size_bytes);
+    m_memory_size_bits = p->memory_size_bits;
+
+    // Resize to the size of different machine types
+    m_abstract_controls.resize(MachineType_NUM);
+
+    // Collate the statistics before they are printed.
+    Stats::registerDumpCallback(new RubyStatsCallback(this));
+    // Create the profiler
+    m_profiler = new Profiler(p, this);
+    m_phys_mem = p->phys_mem;
+}
+
+void
+RubySystem::registerNetwork(Network* network_ptr)
+{
+    m_network = network_ptr;
+}
+
+void
+RubySystem::registerAbstractController(AbstractController* cntrl)
+{
+    m_abs_cntrl_vec.push_back(cntrl);
+
+    MachineID id = cntrl->getMachineID();
+    m_abstract_controls[id.getType()][id.getNum()] = cntrl;
+}
+
+RubySystem::~RubySystem()
+{
+    delete m_network;
+    delete m_profiler;
+}
+
+void
+RubySystem::makeCacheRecorder(uint8_t *uncompressed_trace,
+                              uint64_t cache_trace_size,
+                              uint64_t block_size_bytes)
+{
+    vector<Sequencer*> sequencer_map;
+    Sequencer* sequencer_ptr = NULL;
+
+    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
+        sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer());
+        if (sequencer_ptr == NULL) {
+            sequencer_ptr = sequencer_map[cntrl];
+        }
+    }
+
+    assert(sequencer_ptr != NULL);
+
+    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
+        if (sequencer_map[cntrl] == NULL) {
+            sequencer_map[cntrl] = sequencer_ptr;
+        }
+    }
+
+    // Remove the old CacheRecorder if it's still hanging about.
+    if (m_cache_recorder != NULL) {
+        delete m_cache_recorder;
+    }
+
+    // Create the CacheRecorder and record the cache trace
+    m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size,
+                                         sequencer_map, block_size_bytes);
+}
+
+void
+RubySystem::memWriteback()
+{
+    m_cooldown_enabled = true;
+
+    // Make the trace so we know what to write back.
+    DPRINTF(RubyCacheTrace, "Recording Cache Trace\n");
+    makeCacheRecorder(NULL, 0, getBlockSizeBytes());
+    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
+        m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder);
+    }
+    DPRINTF(RubyCacheTrace, "Cache Trace Complete\n");
+
+    // save the current tick value
+    Tick curtick_original = curTick();
+    DPRINTF(RubyCacheTrace, "Recording current tick %ld\n", curtick_original);
+
+    // Deschedule all prior events on the event queue, but record the tick they
+    // were scheduled at so they can be restored correctly later.
+    list<pair<Event*, Tick> > original_events;
+    while (!eventq->empty()) {
+        Event *curr_head = eventq->getHead();
+        if (curr_head->isAutoDelete()) {
+            DPRINTF(RubyCacheTrace, "Event %s auto-deletes when descheduled,"
+                    " not recording\n", curr_head->name());
+        } else {
+            original_events.push_back(make_pair(curr_head, curr_head->when()));
+        }
+        eventq->deschedule(curr_head);
+    }
+
+    // Schedule an event to start cache cooldown
+    DPRINTF(RubyCacheTrace, "Starting cache flush\n");
+    enqueueRubyEvent(curTick());
+    simulate();
+    DPRINTF(RubyCacheTrace, "Cache flush complete\n");
+
+    // Deschedule any events left on the event queue.
+    while (!eventq->empty()) {
+        eventq->deschedule(eventq->getHead());
+    }
+
+    // Restore curTick
+    setCurTick(curtick_original);
+
+    // Restore all events that were originally on the event queue.  This is
+    // done after setting curTick back to its original value so that events do
+    // not seem to be scheduled in the past.
+    while (!original_events.empty()) {
+        pair<Event*, Tick> event = original_events.back();
+        eventq->schedule(event.first, event.second);
+        original_events.pop_back();
+    }
+
+    // No longer flushing back to memory.
+    m_cooldown_enabled = false;
+
+    // There are several issues with continuing simulation after calling
+    // memWriteback() at the moment, that stem from taking events off the
+    // queue, simulating again, and then putting them back on, whilst
+    // pretending that no time has passed.  One is that some events will have
+    // been deleted, so can't be put back.  Another is that any object
+    // recording the tick something happens may end up storing a tick in the
+    // future.  A simple warning here alerts the user that things may not work
+    // as expected.
+    warn_once("Ruby memory writeback is experimental.  Continuing simulation "
+              "afterwards may not always work as intended.");
+
+    // Keep the cache recorder around so that we can dump the trace if a
+    // checkpoint is immediately taken.
+}
+
+void
+RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename,
+                                 uint64_t uncompressed_trace_size)
+{
+    // Create the checkpoint file for the memory
+    string thefile = CheckpointIn::dir() + "/" + filename.c_str();
+
+    int fd = creat(thefile.c_str(), 0664);
+    if (fd < 0) {
+        perror("creat");
+        fatal("Can't open memory trace file '%s'\n", filename);
+    }
+
+    gzFile compressedMemory = gzdopen(fd, "wb");
+    if (compressedMemory == NULL)
+        fatal("Insufficient memory to allocate compression state for %s\n",
+              filename);
+
+    if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) !=
+        uncompressed_trace_size) {
+        fatal("Write failed on memory trace file '%s'\n", filename);
+    }
+
+    if (gzclose(compressedMemory)) {
+        fatal("Close failed on memory trace file '%s'\n", filename);
+    }
+    delete[] raw_data;
+}
+
+void
+RubySystem::serialize(CheckpointOut &cp) const
+{
+    // Store the cache-block size, so we are able to restore on systems with a
+    // different cache-block size. CacheRecorder depends on the correct
+    // cache-block size upon unserializing.
+    uint64_t block_size_bytes = getBlockSizeBytes();
+    SERIALIZE_SCALAR(block_size_bytes);
+
+    // Check that there's a valid trace to use.  If not, then memory won't be
+    // up-to-date and the simulation will probably fail when restoring from the
+    // checkpoint.
+    if (m_cache_recorder == NULL) {
+        fatal("Call memWriteback() before serialize() to create ruby trace");
+    }
+
+    // Aggregate the trace entries together into a single array
+    uint8_t *raw_data = new uint8_t[4096];
+    uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data,
+                                                                 4096);
+    string cache_trace_file = name() + ".cache.gz";
+    writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size);
+
+    SERIALIZE_SCALAR(cache_trace_file);
+    SERIALIZE_SCALAR(cache_trace_size);
+}
+
+void
+RubySystem::drainResume()
+{
+    // Delete the cache recorder if it was created in memWriteback()
+    // to checkpoint the current cache state.
+    if (m_cache_recorder) {
+        delete m_cache_recorder;
+        m_cache_recorder = NULL;
+    }
+}
+
+void
+RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data,
+                                uint64_t &uncompressed_trace_size)
+{
+    // Read the trace file
+    gzFile compressedTrace;
+
+    // trace file
+    int fd = open(filename.c_str(), O_RDONLY);
+    if (fd < 0) {
+        perror("open");
+        fatal("Unable to open trace file %s", filename);
+    }
+
+    compressedTrace = gzdopen(fd, "rb");
+    if (compressedTrace == NULL) {
+        fatal("Insufficient memory to allocate compression state for %s\n",
+              filename);
+    }
+
+    raw_data = new uint8_t[uncompressed_trace_size];
+    if (gzread(compressedTrace, raw_data, uncompressed_trace_size) <
+            uncompressed_trace_size) {
+        fatal("Unable to read complete trace from file %s\n", filename);
+    }
+
+    if (gzclose(compressedTrace)) {
+        fatal("Failed to close cache trace file '%s'\n", filename);
+    }
+}
+
+void
+RubySystem::unserialize(CheckpointIn &cp)
+{
+    uint8_t *uncompressed_trace = NULL;
+
+    // This value should be set to the checkpoint-system's block-size.
+    // Optional, as checkpoints without it can be run if the
+    // checkpoint-system's block-size == current block-size.
+    uint64_t block_size_bytes = getBlockSizeBytes();
+    UNSERIALIZE_OPT_SCALAR(block_size_bytes);
+
+    string cache_trace_file;
+    uint64_t cache_trace_size = 0;
+
+    UNSERIALIZE_SCALAR(cache_trace_file);
+    UNSERIALIZE_SCALAR(cache_trace_size);
+    cache_trace_file = cp.cptDir + "/" + cache_trace_file;
+
+    readCompressedTrace(cache_trace_file, uncompressed_trace,
+                        cache_trace_size);
+    m_warmup_enabled = true;
+    m_systems_to_warmup++;
+
+    // Create the cache recorder that will hang around until startup.
+    makeCacheRecorder(uncompressed_trace, cache_trace_size, block_size_bytes);
+}
+
+void
+RubySystem::startup()
+{
+
+    // Ruby restores state from a checkpoint by resetting the clock to 0 and
+    // playing the requests that can possibly re-generate the cache state.
+    // The clock value is set to the actual checkpointed value once all the
+    // requests have been executed.
+    //
+    // This way of restoring state is pretty finicky. For example, if a
+    // Ruby component reads time before the state has been restored, it would
+    // cache this value and hence its clock would not be reset to 0, when
+    // Ruby resets the global clock. This can potentially result in a
+    // deadlock.
+    //
+    // The solution is that no Ruby component should read time before the
+    // simulation starts. And then one also needs to hope that the time
+    // Ruby finishes restoring the state is less than the time when the
+    // state was checkpointed.
+
+    if (m_warmup_enabled) {
+        DPRINTF(RubyCacheTrace, "Starting ruby cache warmup\n");
+        // save the current tick value
+        Tick curtick_original = curTick();
+        // save the event queue head
+        Event* eventq_head = eventq->replaceHead(NULL);
+        // set curTick to 0 and reset Ruby System's clock
+        setCurTick(0);
+        resetClock();
+
+        // Schedule an event to start cache warmup
+        enqueueRubyEvent(curTick());
+        simulate();
+
+        delete m_cache_recorder;
+        m_cache_recorder = NULL;
+        m_systems_to_warmup--;
+        if (m_systems_to_warmup == 0) {
+            m_warmup_enabled = false;
+        }
+
+        // Restore eventq head
+        eventq_head = eventq->replaceHead(eventq_head);
+        // Restore curTick and Ruby System's clock
+        setCurTick(curtick_original);
+        resetClock();
+    }
+
+    resetStats();
+}
+
+void
+RubySystem::RubyEvent::process()
+{
+    if (RubySystem::getWarmupEnabled()) {
+        m_ruby_system->m_cache_recorder->enqueueNextFetchRequest();
+    } else if (RubySystem::getCooldownEnabled()) {
+        m_ruby_system->m_cache_recorder->enqueueNextFlushRequest();
+    }
+}
+
+void
+RubySystem::resetStats()
+{
+    m_start_cycle = curCycle();
+}
+
+bool
+RubySystem::functionalRead(PacketPtr pkt)
+{
+    Addr address(pkt->getAddr());
+    Addr line_address = makeLineAddress(address);
+
+    AccessPermission access_perm = AccessPermission_NotPresent;
+    int num_controllers = m_abs_cntrl_vec.size();
+
+    DPRINTF(RubySystem, "Functional Read request for %s\n", address);
+
+    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 (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++;
+        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++;
+    }
+    assert(num_rw <= 1);
+
+    // This if case is meant to capture what happens in a Broadcast/Snoop
+    // protocol where the block does not exist in the cache hierarchy. You
+    // only want to read from the Backing_Store memory if there is no copy in
+    // the cache hierarchy, otherwise you want to try to read the RO or RW
+    // copies existing in the cache hierarchy (covered by the else statement).
+    // The reason is because the Backing_Store memory could easily be stale, if
+    // there are copies floating around the cache hierarchy, so you want to read
+    // it only if it's not in the cache hierarchy at all.
+    if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
+        DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n");
+        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) {
+                m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
+                return true;
+            }
+        }
+    } 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
+        // to read any valid readable copy of the block.
+        DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n",
+                num_busy, num_ro, num_rw);
+        // 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 (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) {
+                m_abs_cntrl_vec[i]->functionalRead(line_address, 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)
+{
+    Addr addr(pkt->getAddr());
+    Addr line_addr = makeLineAddress(addr);
+    AccessPermission access_perm = AccessPermission_NotPresent;
+    int num_controllers = m_abs_cntrl_vec.size();
+
+    DPRINTF(RubySystem, "Functional Write request for %s\n", addr);
+
+    uint32_t M5_VAR_USED num_functional_writes = 0;
+
+    for (unsigned int i = 0; i < num_controllers;++i) {
+        num_functional_writes +=
+            m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt);
+
+        access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
+        if (access_perm != AccessPermission_Invalid &&
+            access_perm != AccessPermission_NotPresent) {
+            num_functional_writes +=
+                m_abs_cntrl_vec[i]->functionalWrite(line_addr, pkt);
+        }
+    }
+
+    num_functional_writes += m_network->functionalWrite(pkt);
+    DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);
+
+    return true;
+}
+
+#ifdef CHECK_COHERENCE
+// This code will check for cases if the given cache block is exclusive in
+// one node and shared in another-- a coherence violation
+//
+// To use, the SLICC specification must call sequencer.checkCoherence(address)
+// when the controller changes to a state with new permissions.  Do this
+// in setState.  The SLICC spec must also define methods "isBlockShared"
+// and "isBlockExclusive" that are specific to that protocol
+//
+void
+RubySystem::checkGlobalCoherenceInvariant(const Address& addr)
+{
+#if 0
+    NodeID exclusive = -1;
+    bool sharedDetected = false;
+    NodeID lastShared = -1;
+
+    for (int i = 0; i < m_chip_vector.size(); i++) {
+        if (m_chip_vector[i]->isBlockExclusive(addr)) {
+            if (exclusive != -1) {
+                // coherence violation
+                WARN_EXPR(exclusive);
+                WARN_EXPR(m_chip_vector[i]->getID());
+                WARN_EXPR(addr);
+                WARN_EXPR(getTime());
+                ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
+            } else if (sharedDetected) {
+                WARN_EXPR(lastShared);
+                WARN_EXPR(m_chip_vector[i]->getID());
+                WARN_EXPR(addr);
+                WARN_EXPR(getTime());
+                ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
+            } else {
+                exclusive = m_chip_vector[i]->getID();
+            }
+        } else if (m_chip_vector[i]->isBlockShared(addr)) {
+            sharedDetected = true;
+            lastShared = m_chip_vector[i]->getID();
+
+            if (exclusive != -1) {
+                WARN_EXPR(lastShared);
+                WARN_EXPR(exclusive);
+                WARN_EXPR(addr);
+                WARN_EXPR(getTime());
+                ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
+            }
+        }
+    }
+#endif
+}
+#endif
+
+RubySystem *
+RubySystemParams::create()
+{
+    return new RubySystem(this);
+}
diff --git a/src/mem/ruby/system/RubySystem.hh b/src/mem/ruby/system/RubySystem.hh
new file mode 100644 (file)
index 0000000..7026f67
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Contains all of the various parts of the system we are simulating.
+ * Performs allocation, deallocation, and setup of all the major
+ * components of the system
+ */
+
+#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__
+#define __MEM_RUBY_SYSTEM_SYSTEM_HH__
+
+#include "base/callback.hh"
+#include "base/output.hh"
+#include "mem/packet.hh"
+#include "mem/ruby/profiler/Profiler.hh"
+#include "mem/ruby/slicc_interface/AbstractController.hh"
+#include "mem/ruby/system/CacheRecorder.hh"
+#include "params/RubySystem.hh"
+#include "sim/clocked_object.hh"
+
+class Network;
+class AbstractController;
+
+class RubySystem : public ClockedObject
+{
+  public:
+    class RubyEvent : public Event
+    {
+      public:
+        RubyEvent(RubySystem* _ruby_system)
+        {
+            m_ruby_system = _ruby_system;
+        }
+      private:
+        void process();
+
+        RubySystem* m_ruby_system;
+    };
+
+    friend class RubyEvent;
+
+    typedef RubySystemParams Params;
+    RubySystem(const Params *p);
+    ~RubySystem();
+
+    // config accessors
+    static int getRandomization() { return m_randomization; }
+    static uint32_t getBlockSizeBytes() { return m_block_size_bytes; }
+    static uint32_t getBlockSizeBits() { return m_block_size_bits; }
+    static uint32_t getMemorySizeBits() { return m_memory_size_bits; }
+    static bool getWarmupEnabled() { return m_warmup_enabled; }
+    static bool getCooldownEnabled() { return m_cooldown_enabled; }
+
+    SimpleMemory *getPhysMem() { return m_phys_mem; }
+    Cycles getStartCycle() { return m_start_cycle; }
+    const bool getAccessBackingStore() { return m_access_backing_store; }
+
+    // Public Methods
+    Profiler*
+    getProfiler()
+    {
+        assert(m_profiler != NULL);
+        return m_profiler;
+    }
+
+    void regStats() { m_profiler->regStats(name()); }
+    void collateStats() { m_profiler->collateStats(); }
+    void resetStats();
+
+    void memWriteback();
+    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
+    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
+    void drainResume() M5_ATTR_OVERRIDE;
+    void process();
+    void startup();
+    bool functionalRead(Packet *ptr);
+    bool functionalWrite(Packet *ptr);
+
+    void registerNetwork(Network*);
+    void registerAbstractController(AbstractController*);
+
+    bool eventQueueEmpty() { return eventq->empty(); }
+    void enqueueRubyEvent(Tick tick)
+    {
+        RubyEvent* e = new RubyEvent(this);
+        schedule(e, tick);
+    }
+
+  private:
+    // Private copy constructor and assignment operator
+    RubySystem(const RubySystem& obj);
+    RubySystem& operator=(const RubySystem& obj);
+
+    void makeCacheRecorder(uint8_t *uncompressed_trace,
+                           uint64_t cache_trace_size,
+                           uint64_t block_size_bytes);
+
+    static void readCompressedTrace(std::string filename,
+                                    uint8_t *&raw_data,
+                                    uint64_t &uncompressed_trace_size);
+    static void writeCompressedTrace(uint8_t *raw_data, std::string file,
+                                     uint64_t uncompressed_trace_size);
+
+  private:
+    // configuration parameters
+    static bool m_randomization;
+    static uint32_t m_block_size_bytes;
+    static uint32_t m_block_size_bits;
+    static uint32_t m_memory_size_bits;
+
+    static bool m_warmup_enabled;
+    static unsigned m_systems_to_warmup;
+    static bool m_cooldown_enabled;
+    SimpleMemory *m_phys_mem;
+    const bool m_access_backing_store;
+
+    Network* m_network;
+    std::vector<AbstractController *> m_abs_cntrl_vec;
+    Cycles m_start_cycle;
+
+  public:
+    Profiler* m_profiler;
+    CacheRecorder* m_cache_recorder;
+    std::vector<std::map<uint32_t, AbstractController *> > m_abstract_controls;
+};
+
+class RubyStatsCallback : public Callback
+{
+  private:
+    RubySystem *m_ruby_system;
+
+  public:
+    virtual ~RubyStatsCallback() {}
+    RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {}
+    void process() { m_ruby_system->collateStats(); }
+};
+
+#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
index c10f8117fd66ffa45b38f45a021a58e96af64c0f..5b13f2ea6d2baa659cb22ba93a7896b6292ec48f 100644 (file)
@@ -33,7 +33,7 @@ from SimpleMemory import *
 
 class RubySystem(ClockedObject):
     type = 'RubySystem'
-    cxx_header = "mem/ruby/system/System.hh"
+    cxx_header = "mem/ruby/system/RubySystem.hh"
     randomization = Param.Bool(False,
         "insert random delays on message enqueue times");
     block_size_bytes = Param.UInt32(64,
index 55fe11d39f6d8aa6251b3867e6a8ec89cbd6aa92..8c507736244187d1eddf8c9e03a636f9433e3720 100644 (file)
@@ -33,12 +33,12 @@ Import('*')
 if env['PROTOCOL'] == 'None':
     Return()
 
-SimObject('Sequencer.py')
 SimObject('RubySystem.py')
+SimObject('Sequencer.py')
 
 Source('CacheRecorder.cc')
 Source('DMASequencer.cc')
 Source('RubyPort.cc')
 Source('RubyPortProxy.cc')
+Source('RubySystem.cc')
 Source('Sequencer.cc')
-Source('System.cc')
index 740db7d8ded9ad84d1ac7638ab7d28bde9729d65..8e41204b72ec735fa51ac8c269c4298490b11deb 100644 (file)
@@ -38,8 +38,8 @@
 #include "mem/protocol/RubyAccessMode.hh"
 #include "mem/ruby/profiler/Profiler.hh"
 #include "mem/ruby/slicc_interface/RubyRequest.hh"
+#include "mem/ruby/system/RubySystem.hh"
 #include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
 #include "mem/packet.hh"
 #include "sim/system.hh"
 
diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc
deleted file mode 100644 (file)
index 490a1f0..0000000
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (c) 1999-2011 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <fcntl.h>
-#include <zlib.h>
-
-#include <cstdio>
-#include <list>
-
-#include "base/intmath.hh"
-#include "base/statistics.hh"
-#include "debug/RubyCacheTrace.hh"
-#include "debug/RubySystem.hh"
-#include "mem/ruby/common/Address.hh"
-#include "mem/ruby/network/Network.hh"
-#include "mem/ruby/system/System.hh"
-#include "mem/simple_mem.hh"
-#include "sim/eventq.hh"
-#include "sim/simulate.hh"
-
-using namespace std;
-
-bool RubySystem::m_randomization;
-uint32_t RubySystem::m_block_size_bytes;
-uint32_t RubySystem::m_block_size_bits;
-uint32_t RubySystem::m_memory_size_bits;
-bool RubySystem::m_warmup_enabled = false;
-// To look forward to allowing multiple RubySystem instances, track the number
-// of RubySystems that need to be warmed up on checkpoint restore.
-unsigned RubySystem::m_systems_to_warmup = 0;
-bool RubySystem::m_cooldown_enabled = false;
-
-RubySystem::RubySystem(const Params *p)
-    : ClockedObject(p), m_access_backing_store(p->access_backing_store),
-      m_cache_recorder(NULL)
-{
-    m_randomization = p->randomization;
-
-    m_block_size_bytes = p->block_size_bytes;
-    assert(isPowerOf2(m_block_size_bytes));
-    m_block_size_bits = floorLog2(m_block_size_bytes);
-    m_memory_size_bits = p->memory_size_bits;
-
-    // Resize to the size of different machine types
-    m_abstract_controls.resize(MachineType_NUM);
-
-    // Collate the statistics before they are printed.
-    Stats::registerDumpCallback(new RubyStatsCallback(this));
-    // Create the profiler
-    m_profiler = new Profiler(p, this);
-    m_phys_mem = p->phys_mem;
-}
-
-void
-RubySystem::registerNetwork(Network* network_ptr)
-{
-    m_network = network_ptr;
-}
-
-void
-RubySystem::registerAbstractController(AbstractController* cntrl)
-{
-    m_abs_cntrl_vec.push_back(cntrl);
-
-    MachineID id = cntrl->getMachineID();
-    m_abstract_controls[id.getType()][id.getNum()] = cntrl;
-}
-
-RubySystem::~RubySystem()
-{
-    delete m_network;
-    delete m_profiler;
-}
-
-void
-RubySystem::makeCacheRecorder(uint8_t *uncompressed_trace,
-                              uint64_t cache_trace_size,
-                              uint64_t block_size_bytes)
-{
-    vector<Sequencer*> sequencer_map;
-    Sequencer* sequencer_ptr = NULL;
-
-    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
-        sequencer_map.push_back(m_abs_cntrl_vec[cntrl]->getSequencer());
-        if (sequencer_ptr == NULL) {
-            sequencer_ptr = sequencer_map[cntrl];
-        }
-    }
-
-    assert(sequencer_ptr != NULL);
-
-    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
-        if (sequencer_map[cntrl] == NULL) {
-            sequencer_map[cntrl] = sequencer_ptr;
-        }
-    }
-
-    // Remove the old CacheRecorder if it's still hanging about.
-    if (m_cache_recorder != NULL) {
-        delete m_cache_recorder;
-    }
-
-    // Create the CacheRecorder and record the cache trace
-    m_cache_recorder = new CacheRecorder(uncompressed_trace, cache_trace_size,
-                                         sequencer_map, block_size_bytes);
-}
-
-void
-RubySystem::memWriteback()
-{
-    m_cooldown_enabled = true;
-
-    // Make the trace so we know what to write back.
-    DPRINTF(RubyCacheTrace, "Recording Cache Trace\n");
-    makeCacheRecorder(NULL, 0, getBlockSizeBytes());
-    for (int cntrl = 0; cntrl < m_abs_cntrl_vec.size(); cntrl++) {
-        m_abs_cntrl_vec[cntrl]->recordCacheTrace(cntrl, m_cache_recorder);
-    }
-    DPRINTF(RubyCacheTrace, "Cache Trace Complete\n");
-
-    // save the current tick value
-    Tick curtick_original = curTick();
-    DPRINTF(RubyCacheTrace, "Recording current tick %ld\n", curtick_original);
-
-    // Deschedule all prior events on the event queue, but record the tick they
-    // were scheduled at so they can be restored correctly later.
-    list<pair<Event*, Tick> > original_events;
-    while (!eventq->empty()) {
-        Event *curr_head = eventq->getHead();
-        if (curr_head->isAutoDelete()) {
-            DPRINTF(RubyCacheTrace, "Event %s auto-deletes when descheduled,"
-                    " not recording\n", curr_head->name());
-        } else {
-            original_events.push_back(make_pair(curr_head, curr_head->when()));
-        }
-        eventq->deschedule(curr_head);
-    }
-
-    // Schedule an event to start cache cooldown
-    DPRINTF(RubyCacheTrace, "Starting cache flush\n");
-    enqueueRubyEvent(curTick());
-    simulate();
-    DPRINTF(RubyCacheTrace, "Cache flush complete\n");
-
-    // Deschedule any events left on the event queue.
-    while (!eventq->empty()) {
-        eventq->deschedule(eventq->getHead());
-    }
-
-    // Restore curTick
-    setCurTick(curtick_original);
-
-    // Restore all events that were originally on the event queue.  This is
-    // done after setting curTick back to its original value so that events do
-    // not seem to be scheduled in the past.
-    while (!original_events.empty()) {
-        pair<Event*, Tick> event = original_events.back();
-        eventq->schedule(event.first, event.second);
-        original_events.pop_back();
-    }
-
-    // No longer flushing back to memory.
-    m_cooldown_enabled = false;
-
-    // There are several issues with continuing simulation after calling
-    // memWriteback() at the moment, that stem from taking events off the
-    // queue, simulating again, and then putting them back on, whilst
-    // pretending that no time has passed.  One is that some events will have
-    // been deleted, so can't be put back.  Another is that any object
-    // recording the tick something happens may end up storing a tick in the
-    // future.  A simple warning here alerts the user that things may not work
-    // as expected.
-    warn_once("Ruby memory writeback is experimental.  Continuing simulation "
-              "afterwards may not always work as intended.");
-
-    // Keep the cache recorder around so that we can dump the trace if a
-    // checkpoint is immediately taken.
-}
-
-void
-RubySystem::writeCompressedTrace(uint8_t *raw_data, string filename,
-                                 uint64_t uncompressed_trace_size)
-{
-    // Create the checkpoint file for the memory
-    string thefile = CheckpointIn::dir() + "/" + filename.c_str();
-
-    int fd = creat(thefile.c_str(), 0664);
-    if (fd < 0) {
-        perror("creat");
-        fatal("Can't open memory trace file '%s'\n", filename);
-    }
-
-    gzFile compressedMemory = gzdopen(fd, "wb");
-    if (compressedMemory == NULL)
-        fatal("Insufficient memory to allocate compression state for %s\n",
-              filename);
-
-    if (gzwrite(compressedMemory, raw_data, uncompressed_trace_size) !=
-        uncompressed_trace_size) {
-        fatal("Write failed on memory trace file '%s'\n", filename);
-    }
-
-    if (gzclose(compressedMemory)) {
-        fatal("Close failed on memory trace file '%s'\n", filename);
-    }
-    delete[] raw_data;
-}
-
-void
-RubySystem::serialize(CheckpointOut &cp) const
-{
-    // Store the cache-block size, so we are able to restore on systems with a
-    // different cache-block size. CacheRecorder depends on the correct
-    // cache-block size upon unserializing.
-    uint64_t block_size_bytes = getBlockSizeBytes();
-    SERIALIZE_SCALAR(block_size_bytes);
-
-    // Check that there's a valid trace to use.  If not, then memory won't be
-    // up-to-date and the simulation will probably fail when restoring from the
-    // checkpoint.
-    if (m_cache_recorder == NULL) {
-        fatal("Call memWriteback() before serialize() to create ruby trace");
-    }
-
-    // Aggregate the trace entries together into a single array
-    uint8_t *raw_data = new uint8_t[4096];
-    uint64_t cache_trace_size = m_cache_recorder->aggregateRecords(&raw_data,
-                                                                 4096);
-    string cache_trace_file = name() + ".cache.gz";
-    writeCompressedTrace(raw_data, cache_trace_file, cache_trace_size);
-
-    SERIALIZE_SCALAR(cache_trace_file);
-    SERIALIZE_SCALAR(cache_trace_size);
-}
-
-void
-RubySystem::drainResume()
-{
-    // Delete the cache recorder if it was created in memWriteback()
-    // to checkpoint the current cache state.
-    if (m_cache_recorder) {
-        delete m_cache_recorder;
-        m_cache_recorder = NULL;
-    }
-}
-
-void
-RubySystem::readCompressedTrace(string filename, uint8_t *&raw_data,
-                                uint64_t &uncompressed_trace_size)
-{
-    // Read the trace file
-    gzFile compressedTrace;
-
-    // trace file
-    int fd = open(filename.c_str(), O_RDONLY);
-    if (fd < 0) {
-        perror("open");
-        fatal("Unable to open trace file %s", filename);
-    }
-
-    compressedTrace = gzdopen(fd, "rb");
-    if (compressedTrace == NULL) {
-        fatal("Insufficient memory to allocate compression state for %s\n",
-              filename);
-    }
-
-    raw_data = new uint8_t[uncompressed_trace_size];
-    if (gzread(compressedTrace, raw_data, uncompressed_trace_size) <
-            uncompressed_trace_size) {
-        fatal("Unable to read complete trace from file %s\n", filename);
-    }
-
-    if (gzclose(compressedTrace)) {
-        fatal("Failed to close cache trace file '%s'\n", filename);
-    }
-}
-
-void
-RubySystem::unserialize(CheckpointIn &cp)
-{
-    uint8_t *uncompressed_trace = NULL;
-
-    // This value should be set to the checkpoint-system's block-size.
-    // Optional, as checkpoints without it can be run if the
-    // checkpoint-system's block-size == current block-size.
-    uint64_t block_size_bytes = getBlockSizeBytes();
-    UNSERIALIZE_OPT_SCALAR(block_size_bytes);
-
-    string cache_trace_file;
-    uint64_t cache_trace_size = 0;
-
-    UNSERIALIZE_SCALAR(cache_trace_file);
-    UNSERIALIZE_SCALAR(cache_trace_size);
-    cache_trace_file = cp.cptDir + "/" + cache_trace_file;
-
-    readCompressedTrace(cache_trace_file, uncompressed_trace,
-                        cache_trace_size);
-    m_warmup_enabled = true;
-    m_systems_to_warmup++;
-
-    // Create the cache recorder that will hang around until startup.
-    makeCacheRecorder(uncompressed_trace, cache_trace_size, block_size_bytes);
-}
-
-void
-RubySystem::startup()
-{
-
-    // Ruby restores state from a checkpoint by resetting the clock to 0 and
-    // playing the requests that can possibly re-generate the cache state.
-    // The clock value is set to the actual checkpointed value once all the
-    // requests have been executed.
-    //
-    // This way of restoring state is pretty finicky. For example, if a
-    // Ruby component reads time before the state has been restored, it would
-    // cache this value and hence its clock would not be reset to 0, when
-    // Ruby resets the global clock. This can potentially result in a
-    // deadlock.
-    //
-    // The solution is that no Ruby component should read time before the
-    // simulation starts. And then one also needs to hope that the time
-    // Ruby finishes restoring the state is less than the time when the
-    // state was checkpointed.
-
-    if (m_warmup_enabled) {
-        DPRINTF(RubyCacheTrace, "Starting ruby cache warmup\n");
-        // save the current tick value
-        Tick curtick_original = curTick();
-        // save the event queue head
-        Event* eventq_head = eventq->replaceHead(NULL);
-        // set curTick to 0 and reset Ruby System's clock
-        setCurTick(0);
-        resetClock();
-
-        // Schedule an event to start cache warmup
-        enqueueRubyEvent(curTick());
-        simulate();
-
-        delete m_cache_recorder;
-        m_cache_recorder = NULL;
-        m_systems_to_warmup--;
-        if (m_systems_to_warmup == 0) {
-            m_warmup_enabled = false;
-        }
-
-        // Restore eventq head
-        eventq_head = eventq->replaceHead(eventq_head);
-        // Restore curTick and Ruby System's clock
-        setCurTick(curtick_original);
-        resetClock();
-    }
-
-    resetStats();
-}
-
-void
-RubySystem::RubyEvent::process()
-{
-    if (RubySystem::getWarmupEnabled()) {
-        m_ruby_system->m_cache_recorder->enqueueNextFetchRequest();
-    } else if (RubySystem::getCooldownEnabled()) {
-        m_ruby_system->m_cache_recorder->enqueueNextFlushRequest();
-    }
-}
-
-void
-RubySystem::resetStats()
-{
-    m_start_cycle = curCycle();
-}
-
-bool
-RubySystem::functionalRead(PacketPtr pkt)
-{
-    Addr address(pkt->getAddr());
-    Addr line_address = makeLineAddress(address);
-
-    AccessPermission access_perm = AccessPermission_NotPresent;
-    int num_controllers = m_abs_cntrl_vec.size();
-
-    DPRINTF(RubySystem, "Functional Read request for %s\n", address);
-
-    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 (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++;
-        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++;
-    }
-    assert(num_rw <= 1);
-
-    // This if case is meant to capture what happens in a Broadcast/Snoop
-    // protocol where the block does not exist in the cache hierarchy. You
-    // only want to read from the Backing_Store memory if there is no copy in
-    // the cache hierarchy, otherwise you want to try to read the RO or RW
-    // copies existing in the cache hierarchy (covered by the else statement).
-    // The reason is because the Backing_Store memory could easily be stale, if
-    // there are copies floating around the cache hierarchy, so you want to read
-    // it only if it's not in the cache hierarchy at all.
-    if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
-        DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n");
-        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) {
-                m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
-                return true;
-            }
-        }
-    } 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
-        // to read any valid readable copy of the block.
-        DPRINTF(RubySystem, "num_busy = %d, num_ro = %d, num_rw = %d\n",
-                num_busy, num_ro, num_rw);
-        // 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 (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) {
-                m_abs_cntrl_vec[i]->functionalRead(line_address, 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)
-{
-    Addr addr(pkt->getAddr());
-    Addr line_addr = makeLineAddress(addr);
-    AccessPermission access_perm = AccessPermission_NotPresent;
-    int num_controllers = m_abs_cntrl_vec.size();
-
-    DPRINTF(RubySystem, "Functional Write request for %s\n", addr);
-
-    uint32_t M5_VAR_USED num_functional_writes = 0;
-
-    for (unsigned int i = 0; i < num_controllers;++i) {
-        num_functional_writes +=
-            m_abs_cntrl_vec[i]->functionalWriteBuffers(pkt);
-
-        access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
-        if (access_perm != AccessPermission_Invalid &&
-            access_perm != AccessPermission_NotPresent) {
-            num_functional_writes +=
-                m_abs_cntrl_vec[i]->functionalWrite(line_addr, pkt);
-        }
-    }
-
-    num_functional_writes += m_network->functionalWrite(pkt);
-    DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);
-
-    return true;
-}
-
-#ifdef CHECK_COHERENCE
-// This code will check for cases if the given cache block is exclusive in
-// one node and shared in another-- a coherence violation
-//
-// To use, the SLICC specification must call sequencer.checkCoherence(address)
-// when the controller changes to a state with new permissions.  Do this
-// in setState.  The SLICC spec must also define methods "isBlockShared"
-// and "isBlockExclusive" that are specific to that protocol
-//
-void
-RubySystem::checkGlobalCoherenceInvariant(const Address& addr)
-{
-#if 0
-    NodeID exclusive = -1;
-    bool sharedDetected = false;
-    NodeID lastShared = -1;
-
-    for (int i = 0; i < m_chip_vector.size(); i++) {
-        if (m_chip_vector[i]->isBlockExclusive(addr)) {
-            if (exclusive != -1) {
-                // coherence violation
-                WARN_EXPR(exclusive);
-                WARN_EXPR(m_chip_vector[i]->getID());
-                WARN_EXPR(addr);
-                WARN_EXPR(getTime());
-                ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
-            } else if (sharedDetected) {
-                WARN_EXPR(lastShared);
-                WARN_EXPR(m_chip_vector[i]->getID());
-                WARN_EXPR(addr);
-                WARN_EXPR(getTime());
-                ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
-            } else {
-                exclusive = m_chip_vector[i]->getID();
-            }
-        } else if (m_chip_vector[i]->isBlockShared(addr)) {
-            sharedDetected = true;
-            lastShared = m_chip_vector[i]->getID();
-
-            if (exclusive != -1) {
-                WARN_EXPR(lastShared);
-                WARN_EXPR(exclusive);
-                WARN_EXPR(addr);
-                WARN_EXPR(getTime());
-                ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
-            }
-        }
-    }
-#endif
-}
-#endif
-
-RubySystem *
-RubySystemParams::create()
-{
-    return new RubySystem(this);
-}
diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh
deleted file mode 100644 (file)
index c797326..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met: redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer;
- * redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution;
- * neither the name of the copyright holders nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Contains all of the various parts of the system we are simulating.
- * Performs allocation, deallocation, and setup of all the major
- * components of the system
- */
-
-#ifndef __MEM_RUBY_SYSTEM_SYSTEM_HH__
-#define __MEM_RUBY_SYSTEM_SYSTEM_HH__
-
-#include "base/callback.hh"
-#include "base/output.hh"
-#include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/slicc_interface/AbstractController.hh"
-#include "mem/ruby/system/CacheRecorder.hh"
-#include "mem/packet.hh"
-#include "params/RubySystem.hh"
-#include "sim/clocked_object.hh"
-
-class Network;
-class AbstractController;
-
-class RubySystem : public ClockedObject
-{
-  public:
-    class RubyEvent : public Event
-    {
-      public:
-        RubyEvent(RubySystem* _ruby_system)
-        {
-            m_ruby_system = _ruby_system;
-        }
-      private:
-        void process();
-
-        RubySystem* m_ruby_system;
-    };
-
-    friend class RubyEvent;
-
-    typedef RubySystemParams Params;
-    RubySystem(const Params *p);
-    ~RubySystem();
-
-    // config accessors
-    static int getRandomization() { return m_randomization; }
-    static uint32_t getBlockSizeBytes() { return m_block_size_bytes; }
-    static uint32_t getBlockSizeBits() { return m_block_size_bits; }
-    static uint32_t getMemorySizeBits() { return m_memory_size_bits; }
-    static bool getWarmupEnabled() { return m_warmup_enabled; }
-    static bool getCooldownEnabled() { return m_cooldown_enabled; }
-
-    SimpleMemory *getPhysMem() { return m_phys_mem; }
-    Cycles getStartCycle() { return m_start_cycle; }
-    const bool getAccessBackingStore() { return m_access_backing_store; }
-
-    // Public Methods
-    Profiler*
-    getProfiler()
-    {
-        assert(m_profiler != NULL);
-        return m_profiler;
-    }
-
-    void regStats() { m_profiler->regStats(name()); }
-    void collateStats() { m_profiler->collateStats(); }
-    void resetStats();
-
-    void memWriteback();
-    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
-    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
-    void drainResume() M5_ATTR_OVERRIDE;
-    void process();
-    void startup();
-    bool functionalRead(Packet *ptr);
-    bool functionalWrite(Packet *ptr);
-
-    void registerNetwork(Network*);
-    void registerAbstractController(AbstractController*);
-
-    bool eventQueueEmpty() { return eventq->empty(); }
-    void enqueueRubyEvent(Tick tick)
-    {
-        RubyEvent* e = new RubyEvent(this);
-        schedule(e, tick);
-    }
-
-  private:
-    // Private copy constructor and assignment operator
-    RubySystem(const RubySystem& obj);
-    RubySystem& operator=(const RubySystem& obj);
-
-    void makeCacheRecorder(uint8_t *uncompressed_trace,
-                           uint64_t cache_trace_size,
-                           uint64_t block_size_bytes);
-
-    static void readCompressedTrace(std::string filename,
-                                    uint8_t *&raw_data,
-                                    uint64_t &uncompressed_trace_size);
-    static void writeCompressedTrace(uint8_t *raw_data, std::string file,
-                                     uint64_t uncompressed_trace_size);
-
-  private:
-    // configuration parameters
-    static bool m_randomization;
-    static uint32_t m_block_size_bytes;
-    static uint32_t m_block_size_bits;
-    static uint32_t m_memory_size_bits;
-
-    static bool m_warmup_enabled;
-    static unsigned m_systems_to_warmup;
-    static bool m_cooldown_enabled;
-    SimpleMemory *m_phys_mem;
-    const bool m_access_backing_store;
-
-    Network* m_network;
-    std::vector<AbstractController *> m_abs_cntrl_vec;
-    Cycles m_start_cycle;
-
-  public:
-    Profiler* m_profiler;
-    CacheRecorder* m_cache_recorder;
-    std::vector<std::map<uint32_t, AbstractController *> > m_abstract_controls;
-};
-
-class RubyStatsCallback : public Callback
-{
-  private:
-    RubySystem *m_ruby_system;
-
-  public:
-    virtual ~RubyStatsCallback() {}
-    RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {}
-    void process() { m_ruby_system->collateStats(); }
-};
-
-#endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
index b5d9c2afe4f616559cb0e77a0537f86a0bda9f4e..42a81c0960ffe4aea98d85ee89f9dd05f397cba6 100644 (file)
@@ -464,7 +464,7 @@ void unset_tbe(${{self.TBEType.c_ident}}*& m_tbe_ptr);
 #include "mem/protocol/${ident}_Event.hh"
 #include "mem/protocol/${ident}_State.hh"
 #include "mem/protocol/Types.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 ''')
         for include_path in includes:
@@ -1029,7 +1029,7 @@ $c_ident::functionalWriteBuffers(PacketPtr& pkt)
 
         code('''
 #include "mem/protocol/Types.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 ''')
 
@@ -1137,7 +1137,7 @@ ${ident}_Controller::wakeup()
 #include "mem/protocol/${ident}_Event.hh"
 #include "mem/protocol/${ident}_State.hh"
 #include "mem/protocol/Types.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 #define HASH_FUN(state, event)  ((int(state)*${ident}_Event_NUM)+int(event))
 
index 08fe94ef8358c63ca7bc06c3fd94f0b1533def3e..2dc35784a50bbbe36fbd6d38e8ffacc682518cbd 100644 (file)
@@ -397,7 +397,7 @@ operator<<(std::ostream& out, const ${{self.c_ident}}& obj)
 #include <memory>
 
 #include "mem/protocol/${{self.c_ident}}.hh"
-#include "mem/ruby/system/System.hh"
+#include "mem/ruby/system/RubySystem.hh"
 
 using namespace std;
 ''')