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