3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * Description: See RubySystem.h
41 #include "Profiler.hh"
44 #include "SyntheticDriver.hh"
45 #include "DeterministicDriver.hh"
47 //#include "Tracer.hh"
48 #include "Protocol.hh"
49 //#include "XactIsolationChecker.hh" // gem5:Arka for decomissioning of log_tm
50 //#include "XactCommitArbiter.hh"
51 //#include "XactVisualizer.hh"
52 #include "M5Driver.hh"
54 RubySystem::RubySystem()
56 DEBUG_MSG(SYSTEM_COMP
, MedPrio
,"initializing");
59 m_profiler_ptr
= new Profiler
;
61 // NETWORK INITIALIZATION
62 // create the network by calling a function that calls new
63 m_network_ptr
= Network::createNetwork(RubyConfig::numberOfChips());
65 DEBUG_MSG(SYSTEM_COMP
, MedPrio
,"Constructed network");
67 // CHIP INITIALIZATION
68 m_chip_vector
.setSize(RubyConfig::numberOfChips());// create the vector of pointers to processors
69 for(int i
=0; i
<RubyConfig::numberOfChips(); i
++) { // for each chip
71 m_chip_vector
[i
] = new Chip(i
, m_network_ptr
);
72 DEBUG_MSG(SYSTEM_COMP
, MedPrio
,"Constructed a chip");
75 // These must be after the chips are constructed
79 if (g_SYNTHETIC_DRIVER
&& !g_DETERMINISTIC_DRIVER
) {
80 m_driver_ptr
= new SyntheticDriver(this);
81 } else if (!g_SYNTHETIC_DRIVER
&& g_DETERMINISTIC_DRIVER
) {
82 m_driver_ptr
= new DeterministicDriver(this);
83 } else if (g_SYNTHETIC_DRIVER
&& g_DETERMINISTIC_DRIVER
) {
84 ERROR_MSG("SYNTHETIC and DETERMINISTIC DRIVERS are exclusive and cannot be both enabled");
86 // normally make tester object, otherwise make an opal interface object.
87 if (!OpalInterface::isOpalLoaded()) {
88 m_driver_ptr
= new Tester(this);
90 m_driver_ptr
= new OpalInterface(this);
94 // detect if opal is loaded or not
95 if (OpalInterface::isOpalLoaded()) {
96 m_driver_ptr
= new OpalInterface(this);
99 /* Need to allocate a driver here */
100 // m_driver_ptr = new SimicsDriver(this);
105 if (g_SYNTHETIC_DRIVER
&& !g_DETERMINISTIC_DRIVER
) {
106 cerr
<< "Creating Synthetic Driver" << endl
;
107 m_driver_ptr
= new SyntheticDriver(this);
108 } else if (!g_SYNTHETIC_DRIVER
&& g_DETERMINISTIC_DRIVER
) {
109 cerr
<< "Creating Deterministic Driver" << endl
;
110 m_driver_ptr
= new DeterministicDriver(this);
112 cerr
<< "Creating M5 Driver" << endl
;
113 m_driver_ptr
= new M5Driver(this);
115 /* gem5:Binkert for decomissiong of tracer
116 m_tracer_ptr = new Tracer;
119 /* gem5:Arka for decomissiong of log_tm
121 m_xact_isolation_checker = new XactIsolationChecker;
122 m_xact_commit_arbiter = new XactCommitArbiter;
123 m_xact_visualizer = new XactVisualizer;
126 DEBUG_MSG(SYSTEM_COMP
, MedPrio
,"finished initializing");
127 DEBUG_NEWLINE(SYSTEM_COMP
, MedPrio
);
131 RubySystem::~RubySystem()
133 for (int i
= 0; i
< m_chip_vector
.size(); i
++) {
134 delete m_chip_vector
[i
];
137 delete m_network_ptr
;
138 delete m_profiler_ptr
;
139 /* gem5:Binkert for decomissiong of tracer
144 void RubySystem::printConfig(ostream
& out
) const
146 out
<< "\n================ Begin RubySystem Configuration Print ================\n\n";
147 RubyConfig::printConfiguration(out
);
149 getChip(0)->printConfig(out
);
150 m_network_ptr
->printConfig(out
);
151 m_driver_ptr
->printConfig(out
);
152 m_profiler_ptr
->printConfig(out
);
153 out
<< "\n================ End RubySystem Configuration Print ================\n\n";
156 void RubySystem::printStats(ostream
& out
)
158 const time_t T
= time(NULL
);
159 tm
*localTime
= localtime(&T
);
161 strftime(buf
, 100, "%b/%d/%Y %H:%M:%S", localTime
);
163 out
<< "Real time: " << buf
<< endl
;
165 m_profiler_ptr
->printStats(out
);
166 for(int i
=0; i
<RubyConfig::numberOfChips(); i
++) { // for each chip
167 for(int p
=0; p
<RubyConfig::numberOfProcsPerChip(); p
++) {
168 m_chip_vector
[i
]->m_L1Cache_mandatoryQueue_vec
[p
]->printStats(out
);
171 m_network_ptr
->printStats(out
);
172 m_driver_ptr
->printStats(out
);
173 Chip::printStats(out
);
176 void RubySystem::clearStats() const
178 m_profiler_ptr
->clearStats();
179 m_network_ptr
->clearStats();
180 m_driver_ptr
->clearStats();
182 for(int i
=0; i
<RubyConfig::numberOfChips(); i
++) { // for each chip
183 for(int p
=0; p
<RubyConfig::numberOfProcsPerChip(); p
++) {
184 m_chip_vector
[i
]->m_L1Cache_mandatoryQueue_vec
[p
]->clearStats();
189 void RubySystem::recordCacheContents(CacheRecorder
& tr
) const
191 for (int i
= 0; i
< m_chip_vector
.size(); i
++) {
192 for (int m_version
= 0; m_version
< RubyConfig::numberOfProcsPerChip(); m_version
++) {
193 if (Protocol::m_TwoLevelCache
) {
194 m_chip_vector
[i
]->m_L1Cache_L1IcacheMemory_vec
[m_version
]->setAsInstructionCache(true);
195 m_chip_vector
[i
]->m_L1Cache_L1DcacheMemory_vec
[m_version
]->setAsInstructionCache(false);
197 m_chip_vector
[i
]->m_L1Cache_cacheMemory_vec
[m_version
]->setAsInstructionCache(false);
200 m_chip_vector
[i
]->recordCacheContents(tr
);
204 #ifdef CHECK_COHERENCE
205 // This code will check for cases if the given cache block is exclusive in
206 // one node and shared in another-- a coherence violation
208 // To use, the SLICC specification must call sequencer.checkCoherence(address)
209 // when the controller changes to a state with new permissions. Do this
210 // in setState. The SLICC spec must also define methods "isBlockShared"
211 // and "isBlockExclusive" that are specific to that protocol
213 void RubySystem::checkGlobalCoherenceInvariant(const Address
& addr
) {
215 NodeID exclusive
= -1;
216 bool sharedDetected
= false;
217 NodeID lastShared
= -1;
219 for (int i
= 0; i
< m_chip_vector
.size(); i
++) {
221 if (m_chip_vector
[i
]->isBlockExclusive(addr
)) {
222 if (exclusive
!= -1) {
223 // coherence violation
224 WARN_EXPR(exclusive
);
225 WARN_EXPR(m_chip_vector
[i
]->getID());
227 WARN_EXPR(g_eventQueue_ptr
->getTime());
228 ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
230 else if (sharedDetected
) {
231 WARN_EXPR(lastShared
);
232 WARN_EXPR(m_chip_vector
[i
]->getID());
234 WARN_EXPR(g_eventQueue_ptr
->getTime());
235 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
238 exclusive
= m_chip_vector
[i
]->getID();
241 else if (m_chip_vector
[i
]->isBlockShared(addr
)) {
242 sharedDetected
= true;
243 lastShared
= m_chip_vector
[i
]->getID();
245 if (exclusive
!= -1) {
246 WARN_EXPR(lastShared
);
247 WARN_EXPR(exclusive
);
249 WARN_EXPR(g_eventQueue_ptr
->getTime());
250 ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");