110458Sandreas.hansson@arm.com/* 210458Sandreas.hansson@arm.com * Copyright (c) 2014 ARM Limited 310458Sandreas.hansson@arm.com * All rights reserved 410458Sandreas.hansson@arm.com * 510458Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall 610458Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual 710458Sandreas.hansson@arm.com * property including but not limited to intellectual property relating 810458Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software 910458Sandreas.hansson@arm.com * licensed hereunder. You may use the software subject to the license 1010458Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated 1110458Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software, 1210458Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form. 1310458Sandreas.hansson@arm.com * 1410458Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 1510458Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 1610458Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 1710458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 1810458Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1910458Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 2010458Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 2110458Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 2210458Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 2310458Sandreas.hansson@arm.com * this software without specific prior written permission. 2410458Sandreas.hansson@arm.com * 2510458Sandreas.hansson@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610458Sandreas.hansson@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710458Sandreas.hansson@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810458Sandreas.hansson@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910458Sandreas.hansson@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010458Sandreas.hansson@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110458Sandreas.hansson@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210458Sandreas.hansson@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310458Sandreas.hansson@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410458Sandreas.hansson@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510458Sandreas.hansson@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610458Sandreas.hansson@arm.com * 3710458Sandreas.hansson@arm.com * Authors: Andrew Bardsley 3810458Sandreas.hansson@arm.com */ 3910458Sandreas.hansson@arm.com 4010458Sandreas.hansson@arm.com/** 4110458Sandreas.hansson@arm.com * @file 4210458Sandreas.hansson@arm.com * 4310458Sandreas.hansson@arm.com * C++-only configuration and instantiation support. This allows a 4410458Sandreas.hansson@arm.com * config to be read back from a .ini and instantiated without 4510458Sandreas.hansson@arm.com * Python. Useful if you want to embed gem5 within a larger system 4610458Sandreas.hansson@arm.com * without carrying the integration cost of the fully-featured 4710458Sandreas.hansson@arm.com * configuration system. 4810458Sandreas.hansson@arm.com * 4910458Sandreas.hansson@arm.com * This file contains a demonstration main using CxxConfigManager. 5010458Sandreas.hansson@arm.com * Build with something like: 5110458Sandreas.hansson@arm.com * 5210458Sandreas.hansson@arm.com * scons --without-python build/ARM/libgem5_opt.so 5310458Sandreas.hansson@arm.com * 5410458Sandreas.hansson@arm.com * g++ -DTRACING_ON -std=c++0x -Ibuild/ARM src/sim/cxx_main.cc \ 5510458Sandreas.hansson@arm.com * -o gem5cxx.opt -Lbuild/ARM -lgem5_opt 5610458Sandreas.hansson@arm.com */ 5710458Sandreas.hansson@arm.com 5810458Sandreas.hansson@arm.com#include <cstdlib> 5910458Sandreas.hansson@arm.com#include <iostream> 6010458Sandreas.hansson@arm.com#include <sstream> 6110458Sandreas.hansson@arm.com 6210458Sandreas.hansson@arm.com#include "base/inifile.hh" 6310458Sandreas.hansson@arm.com#include "base/statistics.hh" 6410458Sandreas.hansson@arm.com#include "base/str.hh" 6510458Sandreas.hansson@arm.com#include "base/trace.hh" 6610458Sandreas.hansson@arm.com#include "cpu/base.hh" 6710458Sandreas.hansson@arm.com#include "sim/cxx_config_ini.hh" 6810458Sandreas.hansson@arm.com#include "sim/cxx_manager.hh" 6910458Sandreas.hansson@arm.com#include "sim/init_signals.hh" 7010458Sandreas.hansson@arm.com#include "sim/serialize.hh" 7112000Sprosenfeld@micron.com#include "sim/sim_events.hh" 7210458Sandreas.hansson@arm.com#include "sim/simulate.hh" 7310458Sandreas.hansson@arm.com#include "sim/stat_control.hh" 7410458Sandreas.hansson@arm.com#include "sim/system.hh" 7510458Sandreas.hansson@arm.com#include "stats.hh" 7610458Sandreas.hansson@arm.com 7710458Sandreas.hansson@arm.comvoid 7810458Sandreas.hansson@arm.comusage(const std::string &prog_name) 7910458Sandreas.hansson@arm.com{ 8010458Sandreas.hansson@arm.com std::cerr << "Usage: " << prog_name << ( 8110458Sandreas.hansson@arm.com " <config-file.ini> [ <option> ]\n\n" 8210458Sandreas.hansson@arm.com "OPTIONS:\n" 8310458Sandreas.hansson@arm.com " -p <object> <param> <value> -- set a parameter\n" 8410458Sandreas.hansson@arm.com " -v <object> <param> <values> -- set a vector parameter from" 8510458Sandreas.hansson@arm.com " a comma\n" 8610458Sandreas.hansson@arm.com " separated values string\n" 8710458Sandreas.hansson@arm.com " -d <flag> -- set a debug flag (-<flag>\n" 8810458Sandreas.hansson@arm.com " clear a flag)\n" 8910458Sandreas.hansson@arm.com " -s <dir> <ticks> -- save checkpoint to dir after" 9010458Sandreas.hansson@arm.com " the given\n" 9110458Sandreas.hansson@arm.com " number of ticks\n" 9210538SAndrew.Bardsley@arm.com " -r <dir> -- restore checkpoint from dir\n" 9310458Sandreas.hansson@arm.com " -c <from> <to> <ticks> -- switch from cpu 'from' to cpu" 9410458Sandreas.hansson@arm.com " 'to' after\n" 9510458Sandreas.hansson@arm.com " the given number of ticks\n" 9610458Sandreas.hansson@arm.com "\n" 9710458Sandreas.hansson@arm.com ); 9810458Sandreas.hansson@arm.com 9910458Sandreas.hansson@arm.com std::exit(EXIT_FAILURE); 10010458Sandreas.hansson@arm.com} 10110458Sandreas.hansson@arm.com 10210458Sandreas.hansson@arm.comint 10310458Sandreas.hansson@arm.commain(int argc, char **argv) 10410458Sandreas.hansson@arm.com{ 10510458Sandreas.hansson@arm.com std::string prog_name(argv[0]); 10610458Sandreas.hansson@arm.com unsigned int arg_ptr = 1; 10710458Sandreas.hansson@arm.com 10810458Sandreas.hansson@arm.com if (argc == 1) 10910458Sandreas.hansson@arm.com usage(prog_name); 11010458Sandreas.hansson@arm.com 11110458Sandreas.hansson@arm.com cxxConfigInit(); 11210458Sandreas.hansson@arm.com 11310458Sandreas.hansson@arm.com initSignals(); 11410458Sandreas.hansson@arm.com 11510458Sandreas.hansson@arm.com setClockFrequency(1000000000000); 11610458Sandreas.hansson@arm.com curEventQueue(getEventQueue(0)); 11710458Sandreas.hansson@arm.com 11810458Sandreas.hansson@arm.com Stats::initSimStats(); 11910458Sandreas.hansson@arm.com Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump); 12010458Sandreas.hansson@arm.com 12111153SCurtis.Dunham@arm.com Trace::enable(); 12210458Sandreas.hansson@arm.com setDebugFlag("Terminal"); 12310458Sandreas.hansson@arm.com // setDebugFlag("CxxConfig"); 12410458Sandreas.hansson@arm.com 12510458Sandreas.hansson@arm.com const std::string config_file(argv[arg_ptr]); 12610458Sandreas.hansson@arm.com 12710458Sandreas.hansson@arm.com CxxConfigFileBase *conf = new CxxIniFile(); 12810458Sandreas.hansson@arm.com 12910458Sandreas.hansson@arm.com if (!conf->load(config_file.c_str())) { 13010458Sandreas.hansson@arm.com std::cerr << "Can't open config file: " << config_file << '\n'; 13110458Sandreas.hansson@arm.com return EXIT_FAILURE; 13210458Sandreas.hansson@arm.com } 13310458Sandreas.hansson@arm.com arg_ptr++; 13410458Sandreas.hansson@arm.com 13510458Sandreas.hansson@arm.com CxxConfigManager *config_manager = new CxxConfigManager(*conf); 13610458Sandreas.hansson@arm.com 13710458Sandreas.hansson@arm.com bool checkpoint_restore = false; 13810458Sandreas.hansson@arm.com bool checkpoint_save = false; 13910458Sandreas.hansson@arm.com bool switch_cpus = false; 14010458Sandreas.hansson@arm.com std::string checkpoint_dir = ""; 14110458Sandreas.hansson@arm.com std::string from_cpu = ""; 14210458Sandreas.hansson@arm.com std::string to_cpu = ""; 14310458Sandreas.hansson@arm.com Tick pre_run_time = 1000000; 14410458Sandreas.hansson@arm.com Tick pre_switch_time = 1000000; 14510458Sandreas.hansson@arm.com 14610458Sandreas.hansson@arm.com try { 14710458Sandreas.hansson@arm.com while (arg_ptr < argc) { 14810458Sandreas.hansson@arm.com std::string option(argv[arg_ptr]); 14910458Sandreas.hansson@arm.com arg_ptr++; 15010458Sandreas.hansson@arm.com unsigned num_args = argc - arg_ptr; 15110458Sandreas.hansson@arm.com 15210458Sandreas.hansson@arm.com if (option == "-p") { 15310458Sandreas.hansson@arm.com if (num_args < 3) 15410458Sandreas.hansson@arm.com usage(prog_name); 15510458Sandreas.hansson@arm.com config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1], 15610458Sandreas.hansson@arm.com argv[arg_ptr + 2]); 15710458Sandreas.hansson@arm.com arg_ptr += 3; 15810458Sandreas.hansson@arm.com } else if (option == "-v") { 15910458Sandreas.hansson@arm.com std::vector<std::string> values; 16010458Sandreas.hansson@arm.com 16110458Sandreas.hansson@arm.com if (num_args < 3) 16210458Sandreas.hansson@arm.com usage(prog_name); 16310458Sandreas.hansson@arm.com tokenize(values, argv[arg_ptr + 2], ','); 16410458Sandreas.hansson@arm.com config_manager->setParamVector(argv[arg_ptr], 16510458Sandreas.hansson@arm.com argv[arg_ptr + 1], values); 16610458Sandreas.hansson@arm.com arg_ptr += 3; 16710458Sandreas.hansson@arm.com } else if (option == "-d") { 16810458Sandreas.hansson@arm.com if (num_args < 1) 16910458Sandreas.hansson@arm.com usage(prog_name); 17010458Sandreas.hansson@arm.com if (argv[arg_ptr][0] == '-') 17110458Sandreas.hansson@arm.com clearDebugFlag(argv[arg_ptr] + 1); 17210458Sandreas.hansson@arm.com else 17310458Sandreas.hansson@arm.com setDebugFlag(argv[arg_ptr]); 17410458Sandreas.hansson@arm.com arg_ptr++; 17510458Sandreas.hansson@arm.com } else if (option == "-r") { 17610458Sandreas.hansson@arm.com if (num_args < 1) 17710458Sandreas.hansson@arm.com usage(prog_name); 17810458Sandreas.hansson@arm.com checkpoint_dir = argv[arg_ptr]; 17910458Sandreas.hansson@arm.com checkpoint_restore = true; 18010458Sandreas.hansson@arm.com arg_ptr++; 18110458Sandreas.hansson@arm.com } else if (option == "-s") { 18210458Sandreas.hansson@arm.com if (num_args < 2) 18310458Sandreas.hansson@arm.com usage(prog_name); 18410458Sandreas.hansson@arm.com checkpoint_dir = argv[arg_ptr]; 18510458Sandreas.hansson@arm.com std::istringstream(argv[arg_ptr + 1]) >> pre_run_time; 18610458Sandreas.hansson@arm.com checkpoint_save = true; 18710458Sandreas.hansson@arm.com arg_ptr += 2; 18810458Sandreas.hansson@arm.com } else if (option == "-c") { 18910458Sandreas.hansson@arm.com if (num_args < 3) 19010458Sandreas.hansson@arm.com usage(prog_name); 19110458Sandreas.hansson@arm.com switch_cpus = true; 19210458Sandreas.hansson@arm.com from_cpu = argv[arg_ptr]; 19310458Sandreas.hansson@arm.com to_cpu = argv[arg_ptr + 1]; 19410458Sandreas.hansson@arm.com std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time; 19510458Sandreas.hansson@arm.com arg_ptr += 3; 19610458Sandreas.hansson@arm.com } else { 19710458Sandreas.hansson@arm.com usage(prog_name); 19810458Sandreas.hansson@arm.com } 19910458Sandreas.hansson@arm.com } 20010458Sandreas.hansson@arm.com } catch (CxxConfigManager::Exception &e) { 20110458Sandreas.hansson@arm.com std::cerr << e.name << ": " << e.message << "\n"; 20210458Sandreas.hansson@arm.com return EXIT_FAILURE; 20310458Sandreas.hansson@arm.com } 20410458Sandreas.hansson@arm.com 20510458Sandreas.hansson@arm.com if (checkpoint_save && checkpoint_restore) { 20610458Sandreas.hansson@arm.com std::cerr << "Don't try and save and restore a checkpoint in the" 20710458Sandreas.hansson@arm.com " same run\n"; 20810458Sandreas.hansson@arm.com return EXIT_FAILURE; 20910458Sandreas.hansson@arm.com } 21010458Sandreas.hansson@arm.com 21110458Sandreas.hansson@arm.com CxxConfig::statsEnable(); 21210458Sandreas.hansson@arm.com getEventQueue(0)->dump(); 21310458Sandreas.hansson@arm.com 21410458Sandreas.hansson@arm.com try { 21510458Sandreas.hansson@arm.com config_manager->instantiate(); 21610458Sandreas.hansson@arm.com if (!checkpoint_restore) { 21710458Sandreas.hansson@arm.com config_manager->initState(); 21810458Sandreas.hansson@arm.com config_manager->startup(); 21910458Sandreas.hansson@arm.com } 22010458Sandreas.hansson@arm.com } catch (CxxConfigManager::Exception &e) { 22110458Sandreas.hansson@arm.com std::cerr << "Config problem in sim object " << e.name 22210458Sandreas.hansson@arm.com << ": " << e.message << "\n"; 22310458Sandreas.hansson@arm.com 22410458Sandreas.hansson@arm.com return EXIT_FAILURE; 22510458Sandreas.hansson@arm.com } 22610458Sandreas.hansson@arm.com 22710458Sandreas.hansson@arm.com GlobalSimLoopExitEvent *exit_event = NULL; 22810458Sandreas.hansson@arm.com 22910458Sandreas.hansson@arm.com if (checkpoint_save) { 23010458Sandreas.hansson@arm.com exit_event = simulate(pre_run_time); 23110458Sandreas.hansson@arm.com 23210458Sandreas.hansson@arm.com unsigned int drain_count = 1; 23310458Sandreas.hansson@arm.com do { 23411227SAndrew.Bardsley@arm.com drain_count = config_manager->drain(); 23510458Sandreas.hansson@arm.com 23610458Sandreas.hansson@arm.com std::cerr << "Draining " << drain_count << '\n'; 23710458Sandreas.hansson@arm.com 23810458Sandreas.hansson@arm.com if (drain_count > 0) { 23910458Sandreas.hansson@arm.com exit_event = simulate(); 24010458Sandreas.hansson@arm.com } 24110458Sandreas.hansson@arm.com } while (drain_count > 0); 24210458Sandreas.hansson@arm.com 24310458Sandreas.hansson@arm.com std::cerr << "Simulation stop at tick " << curTick() 24410458Sandreas.hansson@arm.com << ", cause: " << exit_event->getCause() << '\n'; 24510458Sandreas.hansson@arm.com 24610458Sandreas.hansson@arm.com std::cerr << "Checkpointing\n"; 24710458Sandreas.hansson@arm.com 24810458Sandreas.hansson@arm.com /* FIXME, this should really be serialising just for 24910458Sandreas.hansson@arm.com * config_manager rather than using serializeAll's ugly 25010458Sandreas.hansson@arm.com * SimObject static object list */ 25110458Sandreas.hansson@arm.com Serializable::serializeAll(checkpoint_dir); 25210458Sandreas.hansson@arm.com 25310458Sandreas.hansson@arm.com std::cerr << "Completed checkpoint\n"; 25410458Sandreas.hansson@arm.com 25510458Sandreas.hansson@arm.com config_manager->drainResume(); 25610458Sandreas.hansson@arm.com } 25710458Sandreas.hansson@arm.com 25810458Sandreas.hansson@arm.com if (checkpoint_restore) { 25910458Sandreas.hansson@arm.com std::cerr << "Restoring checkpoint\n"; 26010458Sandreas.hansson@arm.com 26111227SAndrew.Bardsley@arm.com CheckpointIn *checkpoint = new CheckpointIn(checkpoint_dir, 26210458Sandreas.hansson@arm.com config_manager->getSimObjectResolver()); 26310458Sandreas.hansson@arm.com 26411227SAndrew.Bardsley@arm.com DrainManager::instance().preCheckpointRestore(); 26511227SAndrew.Bardsley@arm.com Serializable::unserializeGlobals(*checkpoint); 26611227SAndrew.Bardsley@arm.com config_manager->loadState(*checkpoint); 26710538SAndrew.Bardsley@arm.com config_manager->startup(); 26810458Sandreas.hansson@arm.com 26910458Sandreas.hansson@arm.com config_manager->drainResume(); 27010458Sandreas.hansson@arm.com 27110458Sandreas.hansson@arm.com std::cerr << "Restored from checkpoint\n"; 27210458Sandreas.hansson@arm.com } 27310458Sandreas.hansson@arm.com 27410458Sandreas.hansson@arm.com if (switch_cpus) { 27510458Sandreas.hansson@arm.com exit_event = simulate(pre_switch_time); 27610458Sandreas.hansson@arm.com 27710458Sandreas.hansson@arm.com std::cerr << "Switching CPU\n"; 27810458Sandreas.hansson@arm.com 27910458Sandreas.hansson@arm.com /* Assume the system is called system */ 28010458Sandreas.hansson@arm.com System &system = config_manager->getObject<System>("system"); 28110458Sandreas.hansson@arm.com BaseCPU &old_cpu = config_manager->getObject<BaseCPU>(from_cpu); 28210458Sandreas.hansson@arm.com BaseCPU &new_cpu = config_manager->getObject<BaseCPU>(to_cpu); 28310458Sandreas.hansson@arm.com 28410458Sandreas.hansson@arm.com unsigned int drain_count = 1; 28510458Sandreas.hansson@arm.com do { 28611227SAndrew.Bardsley@arm.com drain_count = config_manager->drain(); 28710458Sandreas.hansson@arm.com 28810458Sandreas.hansson@arm.com std::cerr << "Draining " << drain_count << '\n'; 28910458Sandreas.hansson@arm.com 29010458Sandreas.hansson@arm.com if (drain_count > 0) { 29110458Sandreas.hansson@arm.com exit_event = simulate(); 29210458Sandreas.hansson@arm.com } 29310458Sandreas.hansson@arm.com } while (drain_count > 0); 29410458Sandreas.hansson@arm.com 29510458Sandreas.hansson@arm.com old_cpu.switchOut(); 29610458Sandreas.hansson@arm.com system.setMemoryMode(Enums::timing); 29710458Sandreas.hansson@arm.com new_cpu.takeOverFrom(&old_cpu); 29810458Sandreas.hansson@arm.com config_manager->drainResume(); 29910458Sandreas.hansson@arm.com 30010458Sandreas.hansson@arm.com std::cerr << "Switched CPU\n"; 30110458Sandreas.hansson@arm.com } 30210458Sandreas.hansson@arm.com 30310458Sandreas.hansson@arm.com exit_event = simulate(); 30410458Sandreas.hansson@arm.com 30510458Sandreas.hansson@arm.com std::cerr << "Exit at tick " << curTick() 30610458Sandreas.hansson@arm.com << ", cause: " << exit_event->getCause() << '\n'; 30710458Sandreas.hansson@arm.com 30810458Sandreas.hansson@arm.com getEventQueue(0)->dump(); 30910458Sandreas.hansson@arm.com 31010458Sandreas.hansson@arm.com#if TRY_CLEAN_DELETE 31110458Sandreas.hansson@arm.com config_manager->deleteObjects(); 31210458Sandreas.hansson@arm.com#endif 31310458Sandreas.hansson@arm.com 31410458Sandreas.hansson@arm.com delete config_manager; 31510458Sandreas.hansson@arm.com 31610458Sandreas.hansson@arm.com return EXIT_SUCCESS; 31710458Sandreas.hansson@arm.com} 318