113372Sgabeblack@google.com/* 213372Sgabeblack@google.com * Copyright (c) 2014 ARM Limited 313372Sgabeblack@google.com * All rights reserved 413372Sgabeblack@google.com * 513372Sgabeblack@google.com * The license below extends only to copyright in the software and shall 613372Sgabeblack@google.com * not be construed as granting a license to any other intellectual 713372Sgabeblack@google.com * property including but not limited to intellectual property relating 813372Sgabeblack@google.com * to a hardware implementation of the functionality of the software 913372Sgabeblack@google.com * licensed hereunder. You may use the software subject to the license 1013372Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated 1113372Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software, 1213372Sgabeblack@google.com * modified or unmodified, in source code or in binary form. 1313372Sgabeblack@google.com * 1413372Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 1513372Sgabeblack@google.com * modification, are permitted provided that the following conditions are 1613372Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 1713372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 1813372Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1913372Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 2013372Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 2113372Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 2213372Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 2313372Sgabeblack@google.com * this software without specific prior written permission. 2413372Sgabeblack@google.com * 2513372Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2613372Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2713372Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2813372Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2913372Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3013372Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3113372Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3213372Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3313372Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3413372Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3513372Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3613372Sgabeblack@google.com * 3713372Sgabeblack@google.com * Authors: Andrew Bardsley 3813372Sgabeblack@google.com * Abdul Mutaal Ahmad 3913372Sgabeblack@google.com */ 4013372Sgabeblack@google.com 4113372Sgabeblack@google.com/** 4213372Sgabeblack@google.com * @file 4313372Sgabeblack@google.com * 4413372Sgabeblack@google.com * Example top level file for SystemC integration with C++-only 4513372Sgabeblack@google.com * instantiation. 4613372Sgabeblack@google.com * 4713372Sgabeblack@google.com * Build with something like: 4813372Sgabeblack@google.com * 4913372Sgabeblack@google.com * scons --without-python build/ARM/libgem5_opt.so 5013372Sgabeblack@google.com * 5113372Sgabeblack@google.com * g++ -std=c++0x -Ibuild/ARM -Isrc -DTRACING_ON \ 5213372Sgabeblack@google.com * -o gem5cxx.opt -Lbuild/ARM -lgem5_opt \ 5313372Sgabeblack@google.com * src/sim/sc_main_cxx.cc src/sim/cxx_stats.cc \ 5413372Sgabeblack@google.com * src/sim/sc_module.cc src/sim/sc_logger.cc 5513372Sgabeblack@google.com */ 5613372Sgabeblack@google.com 5713372Sgabeblack@google.com#include <cstdlib> 5813372Sgabeblack@google.com#include <iostream> 5913372Sgabeblack@google.com#include <sstream> 6013372Sgabeblack@google.com#include <systemc> 6113372Sgabeblack@google.com 6213372Sgabeblack@google.com#include "base/statistics.hh" 6313372Sgabeblack@google.com#include "base/str.hh" 6413372Sgabeblack@google.com#include "base/trace.hh" 6513372Sgabeblack@google.com#include "cpu/base.hh" 6613372Sgabeblack@google.com#include "sc_logger.hh" 6713372Sgabeblack@google.com#include "sc_module.hh" 6813372Sgabeblack@google.com#include "sim/cxx_config_ini.hh" 6913372Sgabeblack@google.com#include "sim/cxx_manager.hh" 7013372Sgabeblack@google.com#include "sim/init_signals.hh" 7113372Sgabeblack@google.com#include "sim/serialize.hh" 7213372Sgabeblack@google.com#include "sim/simulate.hh" 7313372Sgabeblack@google.com#include "sim/stat_control.hh" 7413372Sgabeblack@google.com#include "sim/system.hh" 7513372Sgabeblack@google.com#include "stats.hh" 7613372Sgabeblack@google.com 7713372Sgabeblack@google.com// Defining global string variable decalred in stats.hh 7813372Sgabeblack@google.comstd::string filename; 7913372Sgabeblack@google.com 8013372Sgabeblack@google.comvoid 8113372Sgabeblack@google.comusage(const std::string &prog_name) 8213372Sgabeblack@google.com{ 8313372Sgabeblack@google.com std::cerr << "Usage: " << prog_name << ( 8413372Sgabeblack@google.com " <config_file.ini> [ <option> ]\n\n" 8513372Sgabeblack@google.com "OPTIONS:\n" 8613372Sgabeblack@google.com " -p <object> <param> <value> -- set a parameter\n" 8713372Sgabeblack@google.com " -v <object> <param> <values> -- set a vector parameter from" 8813372Sgabeblack@google.com " a comma\n" 8913372Sgabeblack@google.com " separated values string\n" 9013372Sgabeblack@google.com " -d <flag> -- set a debug flag (-<flag>\n" 9113372Sgabeblack@google.com " clear a flag)\n" 9213372Sgabeblack@google.com " -s <dir> <ticks> -- save checkpoint to dir after" 9313372Sgabeblack@google.com " the given\n" 9413372Sgabeblack@google.com " number of ticks\n" 9513372Sgabeblack@google.com " -r <dir> -- restore checkpoint to dir\n" 9613372Sgabeblack@google.com " -c <from> <to> <ticks> -- switch from cpu 'from' to cpu" 9713372Sgabeblack@google.com " 'to' after\n" 9813372Sgabeblack@google.com " the given number of ticks\n" 9913372Sgabeblack@google.com " -n <#cpus> the number of cpus to switch\n" 10013372Sgabeblack@google.com " (appended to 'to' and 'from'" 10113372Sgabeblack@google.com " cpus above)\n" 10213372Sgabeblack@google.com "\n" 10313372Sgabeblack@google.com ); 10413372Sgabeblack@google.com 10513372Sgabeblack@google.com std::exit(EXIT_FAILURE); 10613372Sgabeblack@google.com} 10713372Sgabeblack@google.com 10813372Sgabeblack@google.comclass SimControl : public Gem5SystemC::Module 10913372Sgabeblack@google.com{ 11013372Sgabeblack@google.com protected: 11113372Sgabeblack@google.com int argc; 11213372Sgabeblack@google.com char **argv; 11313372Sgabeblack@google.com CxxConfigManager *config_manager; 11413372Sgabeblack@google.com Gem5SystemC::Logger logger; 11513372Sgabeblack@google.com 11613372Sgabeblack@google.com bool checkpoint_restore; 11713372Sgabeblack@google.com bool checkpoint_save; 11813372Sgabeblack@google.com bool switch_cpus; 11913372Sgabeblack@google.com std::string checkpoint_dir; 12013372Sgabeblack@google.com std::string from_cpu; 12113372Sgabeblack@google.com std::string to_cpu; 12213372Sgabeblack@google.com Tick pre_run_time; 12313372Sgabeblack@google.com Tick pre_switch_time; 12413372Sgabeblack@google.com unsigned num_switch_cpus; 12513372Sgabeblack@google.com 12613372Sgabeblack@google.com public: 12713372Sgabeblack@google.com SC_HAS_PROCESS(SimControl); 12813372Sgabeblack@google.com 12913372Sgabeblack@google.com SimControl(sc_core::sc_module_name name, int argc_, char **argv_); 13013372Sgabeblack@google.com 13113372Sgabeblack@google.com void run(); 13213372Sgabeblack@google.com private: 13313372Sgabeblack@google.com /** 13413372Sgabeblack@google.com * Switch a single CPU 13513372Sgabeblack@google.com * 13613372Sgabeblack@google.com * If numTotalCpus is greater than 1, the CPU index will be appended to 13713372Sgabeblack@google.com * the object name when searching config manager for the CPU name 13813372Sgabeblack@google.com * 13913372Sgabeblack@google.com * @param The CPU number to switch 14013372Sgabeblack@google.com * @param The total number of CPUs in the system 14113372Sgabeblack@google.com */ 14213372Sgabeblack@google.com void switchCpu(unsigned cpuNum, unsigned numTotalCpus); 14313372Sgabeblack@google.com 14413372Sgabeblack@google.com}; 14513372Sgabeblack@google.com 14613372Sgabeblack@google.comSimControl::SimControl(sc_core::sc_module_name name, 14713372Sgabeblack@google.com int argc_, char **argv_) : 14813372Sgabeblack@google.com Gem5SystemC::Module(name), 14913372Sgabeblack@google.com argc(argc_), 15013372Sgabeblack@google.com argv(argv_) 15113372Sgabeblack@google.com{ 15213372Sgabeblack@google.com SC_THREAD(run); 15313372Sgabeblack@google.com 15413372Sgabeblack@google.com std::string prog_name(argv[0]); 15513372Sgabeblack@google.com unsigned int arg_ptr = 1; 15613372Sgabeblack@google.com 15713372Sgabeblack@google.com if (argc == 1) 15813372Sgabeblack@google.com usage(prog_name); 15913372Sgabeblack@google.com 16013372Sgabeblack@google.com cxxConfigInit(); 16113372Sgabeblack@google.com 16213372Sgabeblack@google.com /* Pass DPRINTF messages to SystemC */ 16313372Sgabeblack@google.com Trace::setDebugLogger(&logger); 16413372Sgabeblack@google.com 16513372Sgabeblack@google.com /* @todo need this as an option */ 16613372Sgabeblack@google.com Gem5SystemC::setTickFrequency(); 16713372Sgabeblack@google.com 16813372Sgabeblack@google.com /* Make a SystemC-synchronising event queue and install it as the 16913372Sgabeblack@google.com * sole top level gem5 EventQueue */ 17013372Sgabeblack@google.com Gem5SystemC::Module::setupEventQueues(*this); 17113372Sgabeblack@google.com 17213372Sgabeblack@google.com if (sc_core::sc_get_time_resolution() != 17313372Sgabeblack@google.com sc_core::sc_time(1, sc_core::SC_PS)) 17413372Sgabeblack@google.com { 17513372Sgabeblack@google.com fatal("Time resolution must be set to 1 ps for gem5 to work"); 17613372Sgabeblack@google.com } 17713372Sgabeblack@google.com 17813372Sgabeblack@google.com /* Enable keyboard interrupt, async I/O etc. */ 17913372Sgabeblack@google.com initSignals(); 18013372Sgabeblack@google.com 18113372Sgabeblack@google.com /* Enable stats */ 18213372Sgabeblack@google.com Stats::initSimStats(); 18313372Sgabeblack@google.com Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump); 18413372Sgabeblack@google.com 18513372Sgabeblack@google.com Trace::enable(); 18613372Sgabeblack@google.com setDebugFlag("Terminal"); 18713372Sgabeblack@google.com 18813372Sgabeblack@google.com checkpoint_restore = false; 18913372Sgabeblack@google.com checkpoint_save = false; 19013372Sgabeblack@google.com switch_cpus = false; 19113372Sgabeblack@google.com checkpoint_dir = ""; 19213372Sgabeblack@google.com from_cpu = ""; 19313372Sgabeblack@google.com to_cpu = ""; 19413372Sgabeblack@google.com pre_run_time = 1000000; 19513372Sgabeblack@google.com pre_switch_time = 1000000; 19613372Sgabeblack@google.com num_switch_cpus = 1; 19713372Sgabeblack@google.com 19813372Sgabeblack@google.com const std::string config_file(argv[arg_ptr]); 19913372Sgabeblack@google.com 20013372Sgabeblack@google.com CxxConfigFileBase *conf = new CxxIniFile(); 20113372Sgabeblack@google.com 20213372Sgabeblack@google.com if (!conf->load(config_file.c_str())) 20313372Sgabeblack@google.com fatal("Can't open config file: %s", config_file); 20413372Sgabeblack@google.com 20513372Sgabeblack@google.com arg_ptr++; 20613372Sgabeblack@google.com 20713372Sgabeblack@google.com config_manager = new CxxConfigManager(*conf); 20813372Sgabeblack@google.com 20913372Sgabeblack@google.com try { 21013372Sgabeblack@google.com while (arg_ptr < argc) { 21113372Sgabeblack@google.com std::string option(argv[arg_ptr]); 21213372Sgabeblack@google.com arg_ptr++; 21313372Sgabeblack@google.com unsigned num_args = argc - arg_ptr; 21413372Sgabeblack@google.com 21513372Sgabeblack@google.com if (option == "-p") { 21613372Sgabeblack@google.com if (num_args < 3) 21713372Sgabeblack@google.com usage(prog_name); 21813372Sgabeblack@google.com config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1], 21913372Sgabeblack@google.com argv[arg_ptr + 2]); 22013372Sgabeblack@google.com arg_ptr += 3; 22113372Sgabeblack@google.com } else if (option == "-v") { 22213372Sgabeblack@google.com std::vector<std::string> values; 22313372Sgabeblack@google.com 22413372Sgabeblack@google.com if (num_args < 3) 22513372Sgabeblack@google.com usage(prog_name); 22613372Sgabeblack@google.com tokenize(values, argv[2], ','); 22713372Sgabeblack@google.com config_manager->setParamVector(argv[arg_ptr], 22813372Sgabeblack@google.com argv[arg_ptr], values); 22913372Sgabeblack@google.com arg_ptr += 3; 23013372Sgabeblack@google.com } else if (option == "-d") { 23113372Sgabeblack@google.com if (num_args < 1) 23213372Sgabeblack@google.com usage(prog_name); 23313372Sgabeblack@google.com if (argv[arg_ptr][0] == '-') 23413372Sgabeblack@google.com clearDebugFlag(argv[arg_ptr] + 1); 23513372Sgabeblack@google.com else 23613372Sgabeblack@google.com setDebugFlag(argv[arg_ptr]); 23713372Sgabeblack@google.com arg_ptr++; 23813372Sgabeblack@google.com } else if (option == "-r") { 23913372Sgabeblack@google.com if (num_args < 1) 24013372Sgabeblack@google.com usage(prog_name); 24113372Sgabeblack@google.com checkpoint_dir = argv[arg_ptr]; 24213372Sgabeblack@google.com checkpoint_restore = true; 24313372Sgabeblack@google.com arg_ptr++; 24413372Sgabeblack@google.com } else if (option == "-s") { 24513372Sgabeblack@google.com if (num_args < 2) 24613372Sgabeblack@google.com usage(prog_name); 24713372Sgabeblack@google.com checkpoint_dir = argv[arg_ptr]; 24813372Sgabeblack@google.com std::istringstream(argv[arg_ptr + 1]) >> pre_run_time; 24913372Sgabeblack@google.com checkpoint_save = true; 25013372Sgabeblack@google.com arg_ptr += 2; 25113372Sgabeblack@google.com } else if (option == "-c") { 25213372Sgabeblack@google.com if (num_args < 3) 25313372Sgabeblack@google.com usage(prog_name); 25413372Sgabeblack@google.com switch_cpus = true; 25513372Sgabeblack@google.com from_cpu = argv[arg_ptr]; 25613372Sgabeblack@google.com to_cpu = argv[arg_ptr + 1]; 25713372Sgabeblack@google.com std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time; 25813372Sgabeblack@google.com arg_ptr += 3; 25913372Sgabeblack@google.com } else if (option == "-n") { 26013372Sgabeblack@google.com if (num_args < 1) 26113372Sgabeblack@google.com usage(prog_name); 26213372Sgabeblack@google.com std::istringstream(argv[arg_ptr]) >> num_switch_cpus; 26313372Sgabeblack@google.com arg_ptr++; 26413372Sgabeblack@google.com } else { 26513372Sgabeblack@google.com usage(prog_name); 26613372Sgabeblack@google.com } 26713372Sgabeblack@google.com } 26813372Sgabeblack@google.com } catch (CxxConfigManager::Exception &e) { 26913372Sgabeblack@google.com fatal("Config problem in sim object %s: %s", e.name, e.message); 27013372Sgabeblack@google.com } 27113372Sgabeblack@google.com 27213372Sgabeblack@google.com if (checkpoint_save && checkpoint_restore) { 27313372Sgabeblack@google.com fatal("Don't try to save and restore a checkpoint in the same" 27413372Sgabeblack@google.com "run"); 27513372Sgabeblack@google.com } 27613372Sgabeblack@google.com 27713372Sgabeblack@google.com CxxConfig::statsEnable(); 27813372Sgabeblack@google.com getEventQueue(0)->dump(); 27913372Sgabeblack@google.com 28013372Sgabeblack@google.com try { 28113372Sgabeblack@google.com config_manager->instantiate(); 28213372Sgabeblack@google.com } catch (CxxConfigManager::Exception &e) { 28313372Sgabeblack@google.com fatal("Config problem in sim object %s: %s", e.name, e.message); 28413372Sgabeblack@google.com } 28513372Sgabeblack@google.com} 28613372Sgabeblack@google.com 28713372Sgabeblack@google.comvoid SimControl::run() 28813372Sgabeblack@google.com{ 28913372Sgabeblack@google.com EventQueue *eventq = getEventQueue(0); 29013372Sgabeblack@google.com GlobalSimLoopExitEvent *exit_event = NULL; 29113372Sgabeblack@google.com 29213372Sgabeblack@google.com /* There *must* be no scheduled events yet */ 29313372Sgabeblack@google.com fatal_if(!eventq->empty(), "There must be no posted events" 29413372Sgabeblack@google.com " before SimControl::run"); 29513372Sgabeblack@google.com 29613372Sgabeblack@google.com try { 29713372Sgabeblack@google.com if (checkpoint_restore) { 29813372Sgabeblack@google.com std::cerr << "Restoring checkpoint\n"; 29913372Sgabeblack@google.com 30013372Sgabeblack@google.com CheckpointIn *checkpoint = new CheckpointIn(checkpoint_dir, 30113372Sgabeblack@google.com config_manager->getSimObjectResolver()); 30213372Sgabeblack@google.com 30313372Sgabeblack@google.com /* Catch SystemC up with gem5 after checkpoint restore. 30413372Sgabeblack@google.com * Note that gem5 leading SystemC is always a violation of the 30513372Sgabeblack@google.com * required relationship between the two, hence this careful 30613372Sgabeblack@google.com * catchup */ 30713372Sgabeblack@google.com 30813372Sgabeblack@google.com DrainManager::instance().preCheckpointRestore(); 30913372Sgabeblack@google.com Serializable::unserializeGlobals(*checkpoint); 31013372Sgabeblack@google.com 31113372Sgabeblack@google.com Tick systemc_time = sc_core::sc_time_stamp().value(); 31213372Sgabeblack@google.com if (curTick() > systemc_time) { 31313372Sgabeblack@google.com Tick wait_period = curTick() - systemc_time; 31413372Sgabeblack@google.com 31513372Sgabeblack@google.com std::cerr << "Waiting for " << wait_period << "ps for" 31613372Sgabeblack@google.com " SystemC to catch up to gem5\n"; 31713372Sgabeblack@google.com wait(sc_core::sc_time::from_value(wait_period)); 31813372Sgabeblack@google.com } 31913372Sgabeblack@google.com 32013372Sgabeblack@google.com config_manager->loadState(*checkpoint); 32113372Sgabeblack@google.com config_manager->startup(); 32213372Sgabeblack@google.com config_manager->drainResume(); 32313372Sgabeblack@google.com 32413372Sgabeblack@google.com std::cerr << "Restored from Checkpoint\n"; 32513372Sgabeblack@google.com } else { 32613372Sgabeblack@google.com config_manager->initState(); 32713372Sgabeblack@google.com config_manager->startup(); 32813372Sgabeblack@google.com } 32913372Sgabeblack@google.com } catch (CxxConfigManager::Exception &e) { 33013372Sgabeblack@google.com fatal("Config problem in sim object %s: %s", e.name, e.message); 33113372Sgabeblack@google.com } 33213372Sgabeblack@google.com 33313372Sgabeblack@google.com fatal_if(eventq->empty(), "No events to process after system startup"); 33413372Sgabeblack@google.com 33513372Sgabeblack@google.com if (checkpoint_save) { 33613372Sgabeblack@google.com exit_event = simulate(pre_run_time); 33713372Sgabeblack@google.com 33813372Sgabeblack@google.com unsigned int drain_count = 1; 33913372Sgabeblack@google.com do { 34013372Sgabeblack@google.com drain_count = config_manager->drain(); 34113372Sgabeblack@google.com 34213372Sgabeblack@google.com std::cerr << "Draining " << drain_count << '\n'; 34313372Sgabeblack@google.com 34413372Sgabeblack@google.com if (drain_count > 0) { 34513372Sgabeblack@google.com exit_event = simulate(); 34613372Sgabeblack@google.com } 34713372Sgabeblack@google.com } while (drain_count > 0); 34813372Sgabeblack@google.com 34913372Sgabeblack@google.com std::cerr << "Simulation stop at tick " << curTick() 35013372Sgabeblack@google.com << ", cause: " << exit_event->getCause() << '\n'; 35113372Sgabeblack@google.com 35213372Sgabeblack@google.com std::cerr << "Checkpointing\n"; 35313372Sgabeblack@google.com 35413372Sgabeblack@google.com /* FIXME, this should really be serialising just for 35513372Sgabeblack@google.com * config_manager rather than using serializeAll's ugly 35613372Sgabeblack@google.com * SimObject static object list */ 35713372Sgabeblack@google.com Serializable::serializeAll(checkpoint_dir); 35813372Sgabeblack@google.com 35913372Sgabeblack@google.com std::cerr << "Completed checkpoint\n"; 36013372Sgabeblack@google.com 36113372Sgabeblack@google.com config_manager->drainResume(); 36213372Sgabeblack@google.com } 36313372Sgabeblack@google.com 36413372Sgabeblack@google.com if (switch_cpus) { 36513372Sgabeblack@google.com exit_event = simulate(pre_switch_time); 36613372Sgabeblack@google.com 36713372Sgabeblack@google.com unsigned int drain_count = 1; 36813372Sgabeblack@google.com do { 36913372Sgabeblack@google.com drain_count = config_manager->drain(); 37013372Sgabeblack@google.com 37113372Sgabeblack@google.com std::cerr << "Draining " << drain_count << '\n'; 37213372Sgabeblack@google.com 37313372Sgabeblack@google.com if (drain_count > 0) { 37413372Sgabeblack@google.com exit_event = simulate(); 37513372Sgabeblack@google.com } 37613372Sgabeblack@google.com } while (drain_count > 0); 37713372Sgabeblack@google.com 37813372Sgabeblack@google.com for (unsigned cpu_num = 0; cpu_num < num_switch_cpus; ++cpu_num) { 37913372Sgabeblack@google.com switchCpu(cpu_num, num_switch_cpus); 38013372Sgabeblack@google.com } 38113372Sgabeblack@google.com 38213372Sgabeblack@google.com config_manager->drainResume(); 38313372Sgabeblack@google.com 38413372Sgabeblack@google.com } 38513372Sgabeblack@google.com 38613372Sgabeblack@google.com exit_event = simulate(); 38713372Sgabeblack@google.com 38813372Sgabeblack@google.com std::cerr << "Exit at tick " << curTick() 38913372Sgabeblack@google.com << ", cause: " << exit_event->getCause() << '\n'; 39013372Sgabeblack@google.com 39113372Sgabeblack@google.com getEventQueue(0)->dump(); 39213372Sgabeblack@google.com 39313372Sgabeblack@google.com#if TRY_CLEAN_DELETE 39413372Sgabeblack@google.com config_manager->deleteObjects(); 39513372Sgabeblack@google.com#endif 39613372Sgabeblack@google.com} 39713372Sgabeblack@google.com 39813372Sgabeblack@google.comint 39913372Sgabeblack@google.comsc_main(int argc, char **argv) 40013372Sgabeblack@google.com{ 40113372Sgabeblack@google.com SimControl sim_control("gem5", argc, argv); 40213372Sgabeblack@google.com 40313372Sgabeblack@google.com filename = "m5out/stats-systemc.txt"; 40413372Sgabeblack@google.com 40513372Sgabeblack@google.com sc_core::sc_start(); 40613372Sgabeblack@google.com 40713372Sgabeblack@google.com CxxConfig::statsDump(); 40813372Sgabeblack@google.com 40913372Sgabeblack@google.com return EXIT_SUCCESS; 41013372Sgabeblack@google.com} 41113372Sgabeblack@google.com 41213372Sgabeblack@google.comvoid 41313372Sgabeblack@google.comSimControl::switchCpu(unsigned cpuNum, unsigned numTotalCpus) { 41413372Sgabeblack@google.com assert(cpuNum < numTotalCpus); 41513372Sgabeblack@google.com std::ostringstream from_cpu_name; 41613372Sgabeblack@google.com std::ostringstream to_cpu_name; 41713372Sgabeblack@google.com 41813372Sgabeblack@google.com from_cpu_name << from_cpu; 41913372Sgabeblack@google.com to_cpu_name << to_cpu; 42013372Sgabeblack@google.com 42113372Sgabeblack@google.com if (numTotalCpus > 1) { 42213372Sgabeblack@google.com from_cpu_name << cpuNum; 42313372Sgabeblack@google.com to_cpu_name << cpuNum; 42413372Sgabeblack@google.com } 42513372Sgabeblack@google.com 42613372Sgabeblack@google.com std::cerr << "Switching CPU "<< cpuNum << "(from='" << from_cpu_name.str() 42713372Sgabeblack@google.com <<"' to '"<< to_cpu_name.str() << "')\n"; 42813372Sgabeblack@google.com 42913372Sgabeblack@google.com /* Assume the system is called system */ 43013372Sgabeblack@google.com System &system = config_manager->getObject<System>("system"); 43113372Sgabeblack@google.com BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu_name.str()); 43213372Sgabeblack@google.com BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu_name.str()); 43313372Sgabeblack@google.com 43413372Sgabeblack@google.com old_cpu.switchOut(); 43513372Sgabeblack@google.com 43613372Sgabeblack@google.com // I'm not sure if this can be called before old_cpu.switchOut(). If so, 43713372Sgabeblack@google.com // it is best to just move this call before the switchCpu loop in run() 43813372Sgabeblack@google.com // where it previously was 43913372Sgabeblack@google.com if (cpuNum == 0) 44013372Sgabeblack@google.com system.setMemoryMode(Enums::timing); 44113372Sgabeblack@google.com 44213372Sgabeblack@google.com new_cpu.takeOverFrom(&old_cpu); 44313372Sgabeblack@google.com 44413372Sgabeblack@google.com 44513372Sgabeblack@google.com std::cerr << "Switched CPU"<<cpuNum<<"\n"; 44613372Sgabeblack@google.com} 447