RubySystem.cc revision 6145
1
2/*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
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.
16 *
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.
28 */
29
30/*
31 * System.C
32 *
33 * Description: See System.h
34 *
35 * $Id$
36 *
37 */
38
39
40#include "System.hh"
41#include "Profiler.hh"
42#include "Network.hh"
43#include "Tester.hh"
44#include "SyntheticDriver.hh"
45#include "DeterministicDriver.hh"
46#include "OpalInterface.hh"
47#include "Chip.hh"
48//#include "Tracer.hh"
49#include "Protocol.hh"
50//#include "XactIsolationChecker.hh"  // gem5:Arka for decomissioning of log_tm
51//#include "XactCommitArbiter.hh"
52//#include "XactVisualizer.hh"
53#include "M5Driver.hh"
54
55System::System()
56{
57  DEBUG_MSG(SYSTEM_COMP, MedPrio,"initializing");
58
59  m_driver_ptr = NULL;
60  m_profiler_ptr = new Profiler;
61
62  // NETWORK INITIALIZATION
63  // create the network by calling a function that calls new
64  m_network_ptr = Network::createNetwork(RubyConfig::numberOfChips());
65
66  DEBUG_MSG(SYSTEM_COMP, MedPrio,"Constructed network");
67
68  // CHIP INITIALIZATION
69  m_chip_vector.setSize(RubyConfig::numberOfChips());// create the vector of pointers to processors
70  for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip
71    // create the chip
72    m_chip_vector[i] = new Chip(i, m_network_ptr);
73    DEBUG_MSG(SYSTEM_COMP, MedPrio,"Constructed a chip");
74  }
75
76  // These must be after the chips are constructed
77
78#if 0
79  if (!g_SIMICS) {
80    if (g_SYNTHETIC_DRIVER && !g_DETERMINISTIC_DRIVER) {
81      m_driver_ptr = new SyntheticDriver(this);
82    } else if (!g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) {
83      m_driver_ptr = new DeterministicDriver(this);
84    } else if (g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) {
85      ERROR_MSG("SYNTHETIC and DETERMINISTIC DRIVERS are exclusive and cannot be both enabled");
86    } else {
87      // normally make tester object, otherwise make an opal interface object.
88      if (!OpalInterface::isOpalLoaded()) {
89        m_driver_ptr = new Tester(this);
90      } else {
91        m_driver_ptr = new OpalInterface(this);
92      }
93    }
94  } else {
95    // detect if opal is loaded or not
96    if (OpalInterface::isOpalLoaded()) {
97      m_driver_ptr = new OpalInterface(this);
98    } else {
99      assert(0);
100      /* Need to allocate a driver here */
101      // m_driver_ptr = new SimicsDriver(this);
102    }
103  }
104#endif
105
106    if (g_SYNTHETIC_DRIVER && !g_DETERMINISTIC_DRIVER) {
107      cerr << "Creating Synthetic Driver" << endl;
108      m_driver_ptr = new SyntheticDriver(this);
109    } else if (!g_SYNTHETIC_DRIVER && g_DETERMINISTIC_DRIVER) {
110      cerr << "Creating Deterministic Driver" << endl;
111      m_driver_ptr = new DeterministicDriver(this);
112    } else {
113      cerr << "Creating M5 Driver" << endl;
114      m_driver_ptr = new M5Driver(this);
115    }
116 /*  gem5:Binkert for decomissiong of tracer
117     m_tracer_ptr = new Tracer;
118 */
119
120 /*  gem5:Arka for decomissiong of log_tm
121  if (XACT_MEMORY) {
122    m_xact_isolation_checker = new XactIsolationChecker;
123    m_xact_commit_arbiter    = new XactCommitArbiter;
124    m_xact_visualizer        = new XactVisualizer;
125  }
126*/
127  DEBUG_MSG(SYSTEM_COMP, MedPrio,"finished initializing");
128  DEBUG_NEWLINE(SYSTEM_COMP, MedPrio);
129
130}
131
132System::~System()
133{
134  for (int i = 0; i < m_chip_vector.size(); i++) {
135    delete m_chip_vector[i];
136  }
137  delete m_driver_ptr;
138  delete m_network_ptr;
139  delete m_profiler_ptr;
140 /*  gem5:Binkert for decomissiong of tracer
141     delete m_tracer_ptr;
142 */
143}
144
145void System::printConfig(ostream& out) const
146{
147  out << "\n================ Begin System Configuration Print ================\n\n";
148  RubyConfig::printConfiguration(out);
149  out << endl;
150  getChip(0)->printConfig(out);
151  m_network_ptr->printConfig(out);
152  m_driver_ptr->printConfig(out);
153  m_profiler_ptr->printConfig(out);
154  out << "\n================ End System Configuration Print ================\n\n";
155}
156
157void System::printStats(ostream& out)
158{
159  const time_t T = time(NULL);
160  tm *localTime = localtime(&T);
161  char buf[100];
162  strftime(buf, 100, "%b/%d/%Y %H:%M:%S", localTime);
163
164  out << "Real time: " << buf << endl;
165
166  m_profiler_ptr->printStats(out);
167  for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip
168    for(int p=0; p<RubyConfig::numberOfProcsPerChip(); p++) {
169      m_chip_vector[i]->m_L1Cache_mandatoryQueue_vec[p]->printStats(out);
170    }
171  }
172  m_network_ptr->printStats(out);
173  m_driver_ptr->printStats(out);
174  Chip::printStats(out);
175}
176
177void System::clearStats() const
178{
179  m_profiler_ptr->clearStats();
180  m_network_ptr->clearStats();
181  m_driver_ptr->clearStats();
182  Chip::clearStats();
183  for(int i=0; i<RubyConfig::numberOfChips(); i++) { // for each chip
184    for(int p=0; p<RubyConfig::numberOfProcsPerChip(); p++) {
185      m_chip_vector[i]->m_L1Cache_mandatoryQueue_vec[p]->clearStats();
186    }
187  }
188}
189
190void System::recordCacheContents(CacheRecorder& tr) const
191{
192  for (int i = 0; i < m_chip_vector.size(); i++) {
193    for (int m_version = 0; m_version < RubyConfig::numberOfProcsPerChip(); m_version++) {
194      if (Protocol::m_TwoLevelCache) {
195        m_chip_vector[i]->m_L1Cache_L1IcacheMemory_vec[m_version]->setAsInstructionCache(true);
196        m_chip_vector[i]->m_L1Cache_L1DcacheMemory_vec[m_version]->setAsInstructionCache(false);
197      } else {
198        m_chip_vector[i]->m_L1Cache_cacheMemory_vec[m_version]->setAsInstructionCache(false);
199      }
200    }
201    m_chip_vector[i]->recordCacheContents(tr);
202  }
203}
204
205void System::opalLoadNotify()
206{
207  if (OpalInterface::isOpalLoaded()) {
208    // change the driver pointer to point to an opal driver
209    delete m_driver_ptr;
210    m_driver_ptr  = new OpalInterface(this);
211  }
212}
213
214#ifdef CHECK_COHERENCE
215// This code will check for cases if the given cache block is exclusive in
216// one node and shared in another-- a coherence violation
217//
218// To use, the SLICC specification must call sequencer.checkCoherence(address)
219// when the controller changes to a state with new permissions.  Do this
220// in setState.  The SLICC spec must also define methods "isBlockShared"
221// and "isBlockExclusive" that are specific to that protocol
222//
223void System::checkGlobalCoherenceInvariant(const Address& addr  )  {
224
225  NodeID exclusive = -1;
226  bool sharedDetected = false;
227  NodeID lastShared = -1;
228
229  for (int i = 0; i < m_chip_vector.size(); i++) {
230
231    if (m_chip_vector[i]->isBlockExclusive(addr)) {
232      if (exclusive != -1) {
233        // coherence violation
234        WARN_EXPR(exclusive);
235        WARN_EXPR(m_chip_vector[i]->getID());
236        WARN_EXPR(addr);
237        WARN_EXPR(g_eventQueue_ptr->getTime());
238        ERROR_MSG("Coherence Violation Detected -- 2 exclusive chips");
239      }
240      else if (sharedDetected) {
241        WARN_EXPR(lastShared);
242        WARN_EXPR(m_chip_vector[i]->getID());
243        WARN_EXPR(addr);
244        WARN_EXPR(g_eventQueue_ptr->getTime());
245        ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
246      }
247      else {
248        exclusive = m_chip_vector[i]->getID();
249      }
250    }
251    else if (m_chip_vector[i]->isBlockShared(addr)) {
252      sharedDetected = true;
253      lastShared = m_chip_vector[i]->getID();
254
255      if (exclusive != -1) {
256        WARN_EXPR(lastShared);
257        WARN_EXPR(exclusive);
258        WARN_EXPR(addr);
259        WARN_EXPR(g_eventQueue_ptr->getTime());
260        ERROR_MSG("Coherence Violation Detected -- exclusive chip with >=1 shared");
261      }
262    }
263  }
264}
265#endif
266
267
268
269
270