ruby: replace global g_system_ptr with per-object pointers

This is another step in the process of removing global variables
from Ruby to enable multiple RubySystem instances in a single simulation.

With possibly multiple RubySystem objects, we can no longer use a global
variable to find "the" RubySystem object.  Instead, each Ruby component
has to carry a pointer to the RubySystem object to which it belongs.
diff --git a/src/mem/ruby/common/Global.cc b/src/mem/ruby/common/Global.cc
index 407e373..c82a9c7 100644
--- a/src/mem/ruby/common/Global.cc
+++ b/src/mem/ruby/common/Global.cc
@@ -30,5 +30,4 @@
 
 using namespace std;
 
-RubySystem* g_system_ptr = 0;
 vector<map<uint32_t, AbstractController *> > g_abs_controls;
diff --git a/src/mem/ruby/common/Global.hh b/src/mem/ruby/common/Global.hh
index e6f943a..2b07ffb 100644
--- a/src/mem/ruby/common/Global.hh
+++ b/src/mem/ruby/common/Global.hh
@@ -35,9 +35,6 @@
 #include "base/str.hh"
 #include "base/types.hh"
 
-class RubySystem;
-extern RubySystem* g_system_ptr;
-
 class AbstractController;
 extern std::vector<std::map<uint32_t, AbstractController *> > g_abs_controls;
 
diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc
index 7353c51..0555f9b 100644
--- a/src/mem/ruby/network/MessageBuffer.cc
+++ b/src/mem/ruby/network/MessageBuffer.cc
@@ -41,7 +41,7 @@
 
 MessageBuffer::MessageBuffer(const string &name)
     : m_time_last_time_size_checked(0), m_time_last_time_enqueue(0),
-    m_time_last_time_pop(0), m_last_arrival_time(0)
+      m_time_last_time_pop(0), m_last_arrival_time(0)
 {
     m_msg_counter = 0;
     m_consumer = NULL;
diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc
index f0cd6bd..2164d76 100644
--- a/src/mem/ruby/network/simple/Throttle.cc
+++ b/src/mem/ruby/network/simple/Throttle.cc
@@ -128,7 +128,7 @@
             DPRINTF(RubyNetwork, "throttle: %d my bw %d bw spent "
                     "enqueueing net msg %d time: %lld.\n",
                     m_node, getLinkBandwidth(), m_units_remaining[vnet],
-                    g_system_ptr->curCycle());
+                    m_ruby_system->curCycle());
 
             // Move the message
             in->dequeue();
diff --git a/src/mem/ruby/profiler/AddressProfiler.cc b/src/mem/ruby/profiler/AddressProfiler.cc
index 0d5d135..a2e41ee 100644
--- a/src/mem/ruby/profiler/AddressProfiler.cc
+++ b/src/mem/ruby/profiler/AddressProfiler.cc
@@ -32,7 +32,6 @@
 #include "mem/protocol/RubyRequest.hh"
 #include "mem/ruby/profiler/AddressProfiler.hh"
 #include "mem/ruby/profiler/Profiler.hh"
-#include "mem/ruby/system/System.hh"
 
 using namespace std;
 typedef AddressProfiler::AddressMap AddressMap;
@@ -64,7 +63,7 @@
 
 void
 printSorted(ostream& out, int num_of_sequencers, const AddressMap &record_map,
-            string description)
+            string description, Profiler *profiler)
 {
     const int records_printed = 100;
 
@@ -82,7 +81,7 @@
 
     out << "Total_entries_" << description << ": " << record_map.size()
         << endl;
-    if (g_system_ptr->getProfiler()->getAllInstructions())
+    if (profiler->getAllInstructions())
         out << "Total_Instructions_" << description << ": " << misses << endl;
     else
         out << "Total_data_misses_" << description << ": " << misses << endl;
@@ -143,7 +142,8 @@
         << endl;
 }
 
-AddressProfiler::AddressProfiler(int num_of_sequencers)
+AddressProfiler::AddressProfiler(int num_of_sequencers, Profiler *profiler)
+    : m_profiler(profiler)
 {
     m_num_of_sequencers = num_of_sequencers;
     clearStats();
@@ -183,20 +183,20 @@
         out << "---------------" << endl;
         out << endl;
         printSorted(out, m_num_of_sequencers, m_dataAccessTrace,
-                    "block_address");
+                    "block_address", m_profiler);
 
         out << endl;
         out << "Hot MacroData Blocks" << endl;
         out << "--------------------" << endl;
         out << endl;
         printSorted(out, m_num_of_sequencers, m_macroBlockAccessTrace,
-                    "macroblock_address");
+                    "macroblock_address", m_profiler);
 
         out << "Hot Instructions" << endl;
         out << "----------------" << endl;
         out << endl;
         printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
-                    "pc_address");
+                    "pc_address", m_profiler);
     }
 
     if (m_all_instructions) {
@@ -205,7 +205,7 @@
         out << "-------------------------" << endl;
         out << endl;
         printSorted(out, m_num_of_sequencers, m_programCounterAccessTrace,
-                    "pc_address");
+                    "pc_address", m_profiler);
         out << endl;
     }
 
@@ -222,7 +222,7 @@
         out << endl;
 
         printSorted(out, m_num_of_sequencers, m_retryProfileMap,
-                    "block_address");
+                    "block_address", m_profiler);
         out << endl;
     }
 }
diff --git a/src/mem/ruby/profiler/AddressProfiler.hh b/src/mem/ruby/profiler/AddressProfiler.hh
index 9bf1d51..ff9b39e 100644
--- a/src/mem/ruby/profiler/AddressProfiler.hh
+++ b/src/mem/ruby/profiler/AddressProfiler.hh
@@ -35,9 +35,9 @@
 #include "mem/protocol/AccessType.hh"
 #include "mem/protocol/RubyRequest.hh"
 #include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Global.hh"
 #include "mem/ruby/common/Histogram.hh"
 #include "mem/ruby/profiler/AccessTraceForAddress.hh"
+#include "mem/ruby/profiler/Profiler.hh"
 
 class Set;
 
@@ -47,7 +47,7 @@
     typedef m5::hash_map<Address, AccessTraceForAddress> AddressMap;
 
   public:
-    AddressProfiler(int num_of_sequencers);
+    AddressProfiler(int num_of_sequencers, Profiler *profiler);
     ~AddressProfiler();
 
     void printStats(std::ostream& out) const;
@@ -87,6 +87,8 @@
     Histogram m_getx_sharing_histogram;
     Histogram m_gets_sharing_histogram;
 
+    Profiler *m_profiler;
+
     //added by SS
     bool m_hot_lines;
     bool m_all_instructions;
@@ -100,7 +102,7 @@
 
 void printSorted(std::ostream& out, int num_of_sequencers,
                  const AddressProfiler::AddressMap &record_map,
-                 std::string description);
+                 std::string description, Profiler *profiler);
 
 inline std::ostream&
 operator<<(std::ostream& out, const AddressProfiler& obj)
diff --git a/src/mem/ruby/profiler/Profiler.cc b/src/mem/ruby/profiler/Profiler.cc
index f078ef2..070db68 100644
--- a/src/mem/ruby/profiler/Profiler.cc
+++ b/src/mem/ruby/profiler/Profiler.cc
@@ -56,7 +56,6 @@
 #include "mem/ruby/profiler/AddressProfiler.hh"
 #include "mem/ruby/profiler/Profiler.hh"
 #include "mem/ruby/system/Sequencer.hh"
-#include "mem/ruby/system/System.hh"
 
 using namespace std;
 using m5::stl_helpers::operator<<;
@@ -66,12 +65,12 @@
     m_hot_lines = p->hot_lines;
     m_all_instructions = p->all_instructions;
 
-    m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
+    m_address_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
     m_address_profiler_ptr->setHotLines(m_hot_lines);
     m_address_profiler_ptr->setAllInstructions(m_all_instructions);
 
     if (m_all_instructions) {
-        m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers);
+        m_inst_profiler_ptr = new AddressProfiler(p->num_of_sequencers, this);
         m_inst_profiler_ptr->setHotLines(m_hot_lines);
         m_inst_profiler_ptr->setAllInstructions(m_all_instructions);
     }
diff --git a/src/mem/ruby/profiler/Profiler.hh b/src/mem/ruby/profiler/Profiler.hh
index 07d1411..5b1c9fe 100644
--- a/src/mem/ruby/profiler/Profiler.hh
+++ b/src/mem/ruby/profiler/Profiler.hh
@@ -66,7 +66,7 @@
 class Profiler
 {
   public:
-    Profiler(const RubySystemParams *);
+    Profiler(const RubySystemParams *params);
     ~Profiler();
 
     void wakeup();
diff --git a/src/mem/ruby/structures/BankedArray.cc b/src/mem/ruby/structures/BankedArray.cc
index 0207f96..dbde2ab 100644
--- a/src/mem/ruby/structures/BankedArray.cc
+++ b/src/mem/ruby/structures/BankedArray.cc
@@ -34,7 +34,8 @@
 #include "mem/ruby/system/System.hh"
 
 BankedArray::BankedArray(unsigned int banks, Cycles accessLatency,
-                         unsigned int startIndexBit)
+                         unsigned int startIndexBit, RubySystem *rs)
+    : m_ruby_system(rs)
 {
     this->banks = banks;
     this->accessLatency = accessLatency;
@@ -70,7 +71,7 @@
     busyBanks[bank].idx = idx;
     busyBanks[bank].startAccess = curTick();
     busyBanks[bank].endAccess = curTick() +
-        (accessLatency-1) * g_system_ptr->clockPeriod();
+        (accessLatency-1) * m_ruby_system->clockPeriod();
 
     return true;
 }
diff --git a/src/mem/ruby/structures/BankedArray.hh b/src/mem/ruby/structures/BankedArray.hh
index ed9269e..5cc3eee 100644
--- a/src/mem/ruby/structures/BankedArray.hh
+++ b/src/mem/ruby/structures/BankedArray.hh
@@ -35,6 +35,7 @@
 #include <vector>
 
 #include "mem/ruby/common/TypeDefines.hh"
+#include "mem/ruby/system/System.hh"
 #include "sim/core.hh"
 
 class BankedArray
@@ -44,6 +45,7 @@
     Cycles accessLatency;
     unsigned int bankBits;
     unsigned int startIndexBit;
+    RubySystem *m_ruby_system;
 
     class AccessRecord
     {
@@ -62,7 +64,7 @@
 
   public:
     BankedArray(unsigned int banks, Cycles accessLatency,
-                unsigned int startIndexBit);
+                unsigned int startIndexBit, RubySystem *rs);
 
     // Note: We try the access based on the cache index, not the address
     // This is so we don't get aliasing on blocks being replaced
diff --git a/src/mem/ruby/structures/Cache.py b/src/mem/ruby/structures/Cache.py
index c6e165e..3acec32 100644
--- a/src/mem/ruby/structures/Cache.py
+++ b/src/mem/ruby/structures/Cache.py
@@ -28,6 +28,7 @@
 #          Brad Beckmann
 
 from m5.params import *
+from m5.proxy import *
 from m5.SimObject import SimObject
 
 class RubyCache(SimObject):
@@ -46,3 +47,4 @@
     dataAccessLatency = Param.Cycles(1, "cycles for a data array access")
     tagAccessLatency = Param.Cycles(1, "cycles for a tag array access")
     resourceStalls = Param.Bool(False, "stall if there is a resource failure")
+    ruby_system = Param.RubySystem(Parent.any, "")
diff --git a/src/mem/ruby/structures/CacheMemory.cc b/src/mem/ruby/structures/CacheMemory.cc
index 9c17508..0576c4b 100644
--- a/src/mem/ruby/structures/CacheMemory.cc
+++ b/src/mem/ruby/structures/CacheMemory.cc
@@ -53,8 +53,10 @@
 
 CacheMemory::CacheMemory(const Params *p)
     : SimObject(p),
-    dataArray(p->dataArrayBanks, p->dataAccessLatency, p->start_index_bit),
-    tagArray(p->tagArrayBanks, p->tagAccessLatency, p->start_index_bit)
+    dataArray(p->dataArrayBanks, p->dataAccessLatency,
+              p->start_index_bit, p->ruby_system),
+    tagArray(p->tagArrayBanks, p->tagAccessLatency,
+             p->start_index_bit, p->ruby_system)
 {
     m_cache_size = p->size;
     m_latency = p->latency;
diff --git a/src/mem/ruby/structures/RubyMemoryControl.cc b/src/mem/ruby/structures/RubyMemoryControl.cc
index 6e40d41..6cd9bdf 100644
--- a/src/mem/ruby/structures/RubyMemoryControl.cc
+++ b/src/mem/ruby/structures/RubyMemoryControl.cc
@@ -310,12 +310,6 @@
     physical_address_t addr = memRef->m_addr;
     int bank = getBank(addr);
 
-    DPRINTF(RubyMemory,
-            "New memory request%7d: %#08x %c arrived at %10d bank = %3x sched %c\n",
-            m_msg_counter, addr, memRef->m_is_mem_read ? 'R':'W',
-            memRef->m_time * g_system_ptr->clockPeriod(),
-            bank, m_event.scheduled() ? 'Y':'N');
-
     m_profiler_ptr->profileMemReq(bank);
     m_input_queue.push_back(memRef);
 
diff --git a/src/mem/ruby/structures/WireBuffer.cc b/src/mem/ruby/structures/WireBuffer.cc
index 3308dbe..0375d94 100644
--- a/src/mem/ruby/structures/WireBuffer.cc
+++ b/src/mem/ruby/structures/WireBuffer.cc
@@ -34,7 +34,6 @@
 
 #include "base/cprintf.hh"
 #include "base/stl_helpers.hh"
-#include "mem/ruby/common/Global.hh"
 #include "mem/ruby/structures/WireBuffer.hh"
 #include "mem/ruby/system/System.hh"
 
@@ -58,6 +57,7 @@
     : SimObject(p)
 {
     m_msg_counter = 0;
+    m_ruby_system = p->ruby_system;
 }
 
 void
@@ -73,7 +73,7 @@
 WireBuffer::enqueue(MsgPtr message, Cycles latency)
 {
     m_msg_counter++;
-    Cycles current_time = g_system_ptr->curCycle();
+    Cycles current_time = m_ruby_system->curCycle();
     Cycles arrival_time = current_time + latency;
     assert(arrival_time > current_time);
 
@@ -82,7 +82,7 @@
     m_message_queue.push_back(message);
     if (m_consumer_ptr != NULL) {
         m_consumer_ptr->
-            scheduleEventAbsolute(g_system_ptr->clockPeriod() * arrival_time);
+            scheduleEventAbsolute(m_ruby_system->clockPeriod() * arrival_time);
     } else {
         panic("No Consumer for WireBuffer! %s\n", *this);
     }
@@ -116,12 +116,12 @@
     MsgPtr node = m_message_queue.front();
     pop_heap(m_message_queue.begin(), m_message_queue.end(), greater<MsgPtr>());
 
-    node->setLastEnqueueTime(g_system_ptr->curCycle() + Cycles(1));
+    node->setLastEnqueueTime(m_ruby_system->curCycle() + Cycles(1));
     m_message_queue.back() = node;
     push_heap(m_message_queue.begin(), m_message_queue.end(),
         greater<MsgPtr>());
     m_consumer_ptr->
-        scheduleEventAbsolute(g_system_ptr->curCycle() + Cycles(1));
+        scheduleEventAbsolute(m_ruby_system->curCycle() + Cycles(1));
 }
 
 bool
@@ -129,7 +129,7 @@
 {
     return ((!m_message_queue.empty()) &&
             (m_message_queue.front()->getLastEnqueueTime() <=
-                    g_system_ptr->curCycle()));
+                    m_ruby_system->curCycle()));
 }
 
 void
diff --git a/src/mem/ruby/structures/WireBuffer.hh b/src/mem/ruby/structures/WireBuffer.hh
index a724f13..4282f52 100644
--- a/src/mem/ruby/structures/WireBuffer.hh
+++ b/src/mem/ruby/structures/WireBuffer.hh
@@ -94,6 +94,8 @@
     // queues where memory requests live
     std::vector<MsgPtr> m_message_queue;
 
+    RubySystem * m_ruby_system;
+
 };
 
 std::ostream& operator<<(std::ostream& out, const WireBuffer& obj);
diff --git a/src/mem/ruby/structures/WireBuffer.py b/src/mem/ruby/structures/WireBuffer.py
index 441947a..9a55390 100644
--- a/src/mem/ruby/structures/WireBuffer.py
+++ b/src/mem/ruby/structures/WireBuffer.py
@@ -27,9 +27,11 @@
 # Author: Lisa Hsu
 
 from m5.params import *
+from m5.proxy import *
 from m5.SimObject import SimObject
 
 class RubyWireBuffer(SimObject):
     type = 'RubyWireBuffer'
     cxx_class = 'WireBuffer'
     cxx_header = "mem/ruby/structures/WireBuffer.hh"
+    ruby_system = Param.RubySystem(Parent.any, "")
diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc
index 646601a..7f12fda 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -38,8 +38,9 @@
 #include "sim/system.hh"
 
 DMASequencer::DMASequencer(const Params *p)
-    : MemObject(p), m_version(p->version), m_controller(NULL),
-      m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
+    : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version),
+      m_controller(NULL), m_mandatory_q_ptr(NULL),
+      m_usingRubyTester(p->using_ruby_tester),
       slave_port(csprintf("%s.slave", name()), this, 0, p->ruby_system,
                  p->ruby_system->getAccessBackingStore()),
       system(p->system), retry(false)
@@ -77,7 +78,7 @@
     DMASequencer *_port, PortID id, RubySystem* _ruby_system,
     bool _access_backing_store)
     : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
-      ruby_system(_ruby_system), access_backing_store(_access_backing_store)
+      m_ruby_system(_ruby_system), access_backing_store(_access_backing_store)
 {
     DPRINTF(RubyDma, "Created slave memport on ruby sequencer %s\n", _name);
 }
@@ -190,7 +191,7 @@
     // turn packet around to go back to requester if response expected
 
     if (access_backing_store) {
-        ruby_system->getPhysMem()->access(pkt);
+        m_ruby_system->getPhysMem()->access(pkt);
     } else if (needsResponse) {
         pkt->makeResponse();
     }
@@ -198,7 +199,9 @@
     if (needsResponse) {
         DPRINTF(RubyDma, "Sending packet back over port\n");
         // send next cycle
-        schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+        DMASequencer *seq = static_cast<DMASequencer *>(&owner);
+        RubySystem *rs = seq->m_ruby_system;
+        schedTimingResp(pkt, curTick() + rs->clockPeriod());
     } else {
         delete pkt;
     }
diff --git a/src/mem/ruby/system/DMASequencer.hh b/src/mem/ruby/system/DMASequencer.hh
index ee5a4b6..ee7d578e 100644
--- a/src/mem/ruby/system/DMASequencer.hh
+++ b/src/mem/ruby/system/DMASequencer.hh
@@ -32,12 +32,12 @@
 #include <memory>
 #include <ostream>
 
+#include "mem/mem_object.hh"
 #include "mem/protocol/DMASequencerRequestType.hh"
 #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/mem_object.hh"
 #include "mem/simple_mem.hh"
 #include "mem/tport.hh"
 #include "params/DMASequencer.hh"
@@ -61,13 +61,14 @@
     typedef DMASequencerParams Params;
     DMASequencer(const Params *);
     void init();
+    RubySystem *m_ruby_system;
 
   public:
     class MemSlavePort : public QueuedSlavePort
     {
       private:
         RespPacketQueue queue;
-        RubySystem* ruby_system;
+        RubySystem* m_ruby_system;
         bool access_backing_store;
 
       public:
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index 94f0c09..2974d07 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -51,14 +51,14 @@
 #include "sim/system.hh"
 
 RubyPort::RubyPort(const Params *p)
-    : MemObject(p), m_version(p->version), m_controller(NULL),
-      m_mandatory_q_ptr(NULL), m_usingRubyTester(p->using_ruby_tester),
-      system(p->system),
+    : MemObject(p), m_ruby_system(p->ruby_system), m_version(p->version),
+      m_controller(NULL), m_mandatory_q_ptr(NULL),
+      m_usingRubyTester(p->using_ruby_tester), system(p->system),
       pioMasterPort(csprintf("%s.pio-master-port", name()), this),
       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->ruby_system->getAccessBackingStore(), -1),
+                   p->ruby_system->getAccessBackingStore(), -1),
       gotAddrRanges(p->port_master_connection_count)
 {
     assert(m_version != -1);
@@ -66,8 +66,7 @@
     // 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,
-            p->ruby_system->getAccessBackingStore(), i));
+            i), this, p->ruby_system->getAccessBackingStore(), i));
     }
 
     // create the master ports based on the number of connected ports
@@ -158,10 +157,9 @@
 }
 
 RubyPort::MemSlavePort::MemSlavePort(const std::string &_name, RubyPort *_port,
-                                     RubySystem *_system,
                                      bool _access_backing_store, PortID id)
     : QueuedSlavePort(_name, _port, queue, id), queue(*_port, *this),
-      ruby_system(_system), access_backing_store(_access_backing_store)
+      access_backing_store(_access_backing_store)
 {
     DPRINTF(RubyPort, "Created slave memport on ruby sequencer %s\n", _name);
 }
@@ -169,12 +167,12 @@
 bool
 RubyPort::PioMasterPort::recvTimingResp(PacketPtr pkt)
 {
-    RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+    RubyPort *rp = static_cast<RubyPort *>(&owner);
     DPRINTF(RubyPort, "Response for address: 0x%#x\n", pkt->getAddr());
 
     // send next cycle
-    ruby_port->pioSlavePort.schedTimingResp(
-            pkt, curTick() + g_system_ptr->clockPeriod());
+    rp->pioSlavePort.schedTimingResp(
+            pkt, curTick() + rp->m_ruby_system->clockPeriod());
     return true;
 }
 
@@ -196,7 +194,8 @@
             pkt->getAddr(), port->name());
 
     // attempt to send the response in the next cycle
-    port->schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+    RubyPort *rp = static_cast<RubyPort *>(&owner);
+    port->schedTimingResp(pkt, curTick() + rp->m_ruby_system->clockPeriod());
 
     return true;
 }
@@ -244,8 +243,9 @@
         pkt->pushSenderState(new SenderState(this));
 
         // send next cycle
+        RubySystem *rs = ruby_port->m_ruby_system;
         ruby_port->memMasterPort.schedTimingReq(pkt,
-            curTick() + g_system_ptr->clockPeriod());
+            curTick() + rs->clockPeriod());
         return true;
     }
 
@@ -269,7 +269,7 @@
     }
 
     //
-    // Unless one is using the ruby tester, record the stalled M5 port for 
+    // Unless one is using the ruby tester, record the stalled M5 port for
     // later retry when the sequencer becomes free.
     //
     if (!ruby_port->m_usingRubyTester) {
@@ -287,11 +287,13 @@
 {
     DPRINTF(RubyPort, "Functional access for address: %#x\n", pkt->getAddr());
 
+    RubyPort *rp M5_VAR_USED = static_cast<RubyPort *>(&owner);
+    RubySystem *rs = rp->m_ruby_system;
+
     // 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());
+        assert(rp->memMasterPort.isConnected());
         DPRINTF(RubyPort, "Pio Request for address: 0x%#x\n", pkt->getAddr());
         panic("RubyPort::PioMasterPort::recvFunctional() not implemented!\n");
     }
@@ -305,16 +307,16 @@
         // The following command performs the real functional access.
         // This line should be removed once Ruby supplies the official version
         // of data.
-        ruby_system->getPhysMem()->functionalAccess(pkt);
+        rs->getPhysMem()->functionalAccess(pkt);
     } else {
         bool accessSucceeded = false;
         bool needsResponse = pkt->needsResponse();
 
         // Do the functional access on ruby memory
         if (pkt->isRead()) {
-            accessSucceeded = ruby_system->functionalRead(pkt);
+            accessSucceeded = rs->functionalRead(pkt);
         } else if (pkt->isWrite()) {
-            accessSucceeded = ruby_system->functionalWrite(pkt);
+            accessSucceeded = rs->functionalWrite(pkt);
         } else {
             panic("Unsupported functional command %s\n", pkt->cmdString());
         }
@@ -456,8 +458,10 @@
 
     DPRINTF(RubyPort, "Hit callback needs response %d\n", needsResponse);
 
+    RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+    RubySystem *rs = ruby_port->m_ruby_system;
     if (accessPhysMem) {
-        ruby_system->getPhysMem()->access(pkt);
+        rs->getPhysMem()->access(pkt);
     } else if (needsResponse) {
         pkt->makeResponse();
     }
@@ -466,7 +470,7 @@
     if (needsResponse) {
         DPRINTF(RubyPort, "Sending packet back over port\n");
         // send next cycle
-        schedTimingResp(pkt, curTick() + g_system_ptr->clockPeriod());
+        schedTimingResp(pkt, curTick() + rs->clockPeriod());
     } else {
         delete pkt;
     }
diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh
index 1fbaeba..07fca59 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -75,12 +75,11 @@
     {
       private:
         RespPacketQueue queue;
-        RubySystem* ruby_system;
         bool access_backing_store;
 
       public:
         MemSlavePort(const std::string &_name, RubyPort *_port,
-               RubySystem*_system, bool _access_backing_store, PortID id);
+                     bool _access_backing_store, PortID id);
         void hitCallback(PacketPtr pkt);
         void evictionCallback(const Address& address);
 
@@ -179,6 +178,7 @@
      */
     bool recvTimingResp(PacketPtr pkt, PortID master_port_id);
 
+    RubySystem *m_ruby_system;
     uint32_t m_version;
     AbstractController* m_controller;
     MessageBuffer* m_mandatory_q_ptr;
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
index a5e26b8..f64e24f 100644
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -160,7 +160,7 @@
 #if 0
     int total_demand = 0;
     out << "Sequencer Stats Version " << m_version << endl;
-    out << "Current time = " << g_system_ptr->getTime() << endl;
+    out << "Current time = " << m_ruby_system->getTime() << endl;
     out << "---------------" << endl;
     out << "outstanding requests" << endl;
 
@@ -557,14 +557,15 @@
 
     delete srequest;
 
+    RubySystem *rs = m_ruby_system;
     if (RubySystem::getWarmupEnabled()) {
         assert(pkt->req);
         delete pkt->req;
         delete pkt;
-        g_system_ptr->m_cache_recorder->enqueueNextFetchRequest();
+        rs->m_cache_recorder->enqueueNextFetchRequest();
     } else if (RubySystem::getCooldownEnabled()) {
         delete pkt;
-        g_system_ptr->m_cache_recorder->enqueueNextFlushRequest();
+        rs->m_cache_recorder->enqueueNextFlushRequest();
     } else {
         ruby_hit_callback(pkt);
     }
@@ -737,7 +738,7 @@
 Sequencer::checkCoherence(const Address& addr)
 {
 #ifdef CHECK_COHERENCE
-    g_system_ptr->checkGlobalCoherenceInvariant(addr);
+    m_ruby_system->checkGlobalCoherenceInvariant(addr);
 #endif
 }
 
diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py
index aac0542..e545000 100644
--- a/src/mem/ruby/system/Sequencer.py
+++ b/src/mem/ruby/system/Sequencer.py
@@ -45,7 +45,7 @@
     mem_slave_port = SlavePort("Ruby memory port")
 
     using_ruby_tester = Param.Bool(False, "")
-    ruby_system = Param.RubySystem("")
+    ruby_system = Param.RubySystem(Parent.any, "")
     system = Param.System(Parent.any, "system object")
     support_data_reqs = Param.Bool(True, "data cache requests supported")
     support_inst_reqs = Param.Bool(True, "inst cache requests supported")
@@ -53,7 +53,7 @@
 class RubyPortProxy(RubyPort):
     type = 'RubyPortProxy'
     cxx_header = "mem/ruby/system/RubyPortProxy.hh"
-    
+
 class RubySequencer(RubyPort):
     type = 'RubySequencer'
     cxx_class = 'Sequencer'
diff --git a/src/mem/ruby/system/System.cc b/src/mem/ruby/system/System.cc
index 1cdc387..128d160 100644
--- a/src/mem/ruby/system/System.cc
+++ b/src/mem/ruby/system/System.cc
@@ -58,9 +58,6 @@
 RubySystem::RubySystem(const Params *p)
     : ClockedObject(p), m_access_backing_store(p->access_backing_store)
 {
-    if (g_system_ptr != NULL)
-        fatal("Only one RubySystem object currently allowed.\n");
-
     m_random_seed = p->random_seed;
     srandom(m_random_seed);
     m_randomization = p->randomization;
@@ -70,9 +67,6 @@
     m_block_size_bits = floorLog2(m_block_size_bytes);
     m_memory_size_bits = p->memory_size_bits;
 
-    // Setup the global variables used in Ruby
-    g_system_ptr = this;
-
     // Resize to the size of different machine types
     g_abs_controls.resize(MachineType_NUM);
 
@@ -329,9 +323,9 @@
 RubySystem::RubyEvent::process()
 {
     if (RubySystem::getWarmupEnabled()) {
-        ruby_system->m_cache_recorder->enqueueNextFetchRequest();
+        m_ruby_system->m_cache_recorder->enqueueNextFetchRequest();
     } else if (RubySystem::getCooldownEnabled()) {
-        ruby_system->m_cache_recorder->enqueueNextFlushRequest();
+        m_ruby_system->m_cache_recorder->enqueueNextFlushRequest();
     }
 }
 
diff --git a/src/mem/ruby/system/System.hh b/src/mem/ruby/system/System.hh
index 0030b50..57a1b7c 100644
--- a/src/mem/ruby/system/System.hh
+++ b/src/mem/ruby/system/System.hh
@@ -54,12 +54,12 @@
       public:
         RubyEvent(RubySystem* _ruby_system)
         {
-            ruby_system = _ruby_system;
+            m_ruby_system = _ruby_system;
         }
       private:
         void process();
 
-        RubySystem* ruby_system;
+        RubySystem* m_ruby_system;
     };
 
     friend class RubyEvent;
@@ -128,6 +128,7 @@
     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;
@@ -146,12 +147,12 @@
 class RubyStatsCallback : public Callback
 {
   private:
-    RubySystem *ruby_system;
+    RubySystem *m_ruby_system;
 
   public:
     virtual ~RubyStatsCallback() {}
-    RubyStatsCallback(RubySystem *system) : ruby_system(system) {}
-    void process() { ruby_system->collateStats(); }
+    RubyStatsCallback(RubySystem *system) : m_ruby_system(system) {}
+    void process() { m_ruby_system->collateStats(); }
 };
 
 #endif // __MEM_RUBY_SYSTEM_SYSTEM_HH__
diff --git a/src/mem/slicc/symbols/StateMachine.py b/src/mem/slicc/symbols/StateMachine.py
index c5ad751..24b429b 100644
--- a/src/mem/slicc/symbols/StateMachine.py
+++ b/src/mem/slicc/symbols/StateMachine.py
@@ -735,7 +735,7 @@
              event < ${ident}_Event_NUM; ++event) {
             Stats::Vector *t = new Stats::Vector();
             t->init(m_num_controllers);
-            t->name(g_system_ptr->name() + ".${c_ident}." +
+            t->name(params()->ruby_system->name() + ".${c_ident}." +
                 ${ident}_Event_to_string(event));
             t->flags(Stats::pdf | Stats::total | Stats::oneline |
                      Stats::nozero);
@@ -753,7 +753,7 @@
 
                 Stats::Vector *t = new Stats::Vector();
                 t->init(m_num_controllers);
-                t->name(g_system_ptr->name() + ".${c_ident}." +
+                t->name(params()->ruby_system->name() + ".${c_ident}." +
                         ${ident}_State_to_string(state) +
                         "." + ${ident}_Event_to_string(event));
 
diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py
index fecc637..eb1dead 100644
--- a/src/mem/slicc/symbols/Type.py
+++ b/src/mem/slicc/symbols/Type.py
@@ -418,8 +418,6 @@
         for dm in self.data_members.values():
             code('out << "${{dm.ident}} = " << m_${{dm.ident}} << " ";''')
 
-        if self.isMessage:
-            code('out << "Time = " << g_system_ptr->clockPeriod() * getTime() << " ";')
         code.dedent()
 
         # Trailer