main.cc revision 10538
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" 7110458Sandreas.hansson@arm.com#include "sim/simulate.hh" 7210458Sandreas.hansson@arm.com#include "sim/stat_control.hh" 7310458Sandreas.hansson@arm.com#include "sim/system.hh" 7410458Sandreas.hansson@arm.com#include "stats.hh" 7510458Sandreas.hansson@arm.com 7610458Sandreas.hansson@arm.comvoid 7710458Sandreas.hansson@arm.comusage(const std::string &prog_name) 7810458Sandreas.hansson@arm.com{ 7910458Sandreas.hansson@arm.com std::cerr << "Usage: " << prog_name << ( 8010458Sandreas.hansson@arm.com " <config-file.ini> [ <option> ]\n\n" 8110458Sandreas.hansson@arm.com "OPTIONS:\n" 8210458Sandreas.hansson@arm.com " -p <object> <param> <value> -- set a parameter\n" 8310458Sandreas.hansson@arm.com " -v <object> <param> <values> -- set a vector parameter from" 8410458Sandreas.hansson@arm.com " a comma\n" 8510458Sandreas.hansson@arm.com " separated values string\n" 8610458Sandreas.hansson@arm.com " -d <flag> -- set a debug flag (-<flag>\n" 8710458Sandreas.hansson@arm.com " clear a flag)\n" 8810458Sandreas.hansson@arm.com " -s <dir> <ticks> -- save checkpoint to dir after" 8910458Sandreas.hansson@arm.com " the given\n" 9010458Sandreas.hansson@arm.com " number of ticks\n" 9110538SAndrew.Bardsley@arm.com " -r <dir> -- restore checkpoint from dir\n" 9210458Sandreas.hansson@arm.com " -c <from> <to> <ticks> -- switch from cpu 'from' to cpu" 9310458Sandreas.hansson@arm.com " 'to' after\n" 9410458Sandreas.hansson@arm.com " the given number of ticks\n" 9510458Sandreas.hansson@arm.com "\n" 9610458Sandreas.hansson@arm.com ); 9710458Sandreas.hansson@arm.com 9810458Sandreas.hansson@arm.com std::exit(EXIT_FAILURE); 9910458Sandreas.hansson@arm.com} 10010458Sandreas.hansson@arm.com 10110458Sandreas.hansson@arm.comint 10210458Sandreas.hansson@arm.commain(int argc, char **argv) 10310458Sandreas.hansson@arm.com{ 10410458Sandreas.hansson@arm.com std::string prog_name(argv[0]); 10510458Sandreas.hansson@arm.com unsigned int arg_ptr = 1; 10610458Sandreas.hansson@arm.com 10710458Sandreas.hansson@arm.com if (argc == 1) 10810458Sandreas.hansson@arm.com usage(prog_name); 10910458Sandreas.hansson@arm.com 11010458Sandreas.hansson@arm.com cxxConfigInit(); 11110458Sandreas.hansson@arm.com 11210458Sandreas.hansson@arm.com initSignals(); 11310458Sandreas.hansson@arm.com 11410458Sandreas.hansson@arm.com setClockFrequency(1000000000000); 11510458Sandreas.hansson@arm.com curEventQueue(getEventQueue(0)); 11610458Sandreas.hansson@arm.com 11710458Sandreas.hansson@arm.com Stats::initSimStats(); 11810458Sandreas.hansson@arm.com Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump); 11910458Sandreas.hansson@arm.com 12010458Sandreas.hansson@arm.com Trace::enabled = true; 12110458Sandreas.hansson@arm.com setDebugFlag("Terminal"); 12210458Sandreas.hansson@arm.com // setDebugFlag("CxxConfig"); 12310458Sandreas.hansson@arm.com 12410458Sandreas.hansson@arm.com const std::string config_file(argv[arg_ptr]); 12510458Sandreas.hansson@arm.com 12610458Sandreas.hansson@arm.com CxxConfigFileBase *conf = new CxxIniFile(); 12710458Sandreas.hansson@arm.com 12810458Sandreas.hansson@arm.com if (!conf->load(config_file.c_str())) { 12910458Sandreas.hansson@arm.com std::cerr << "Can't open config file: " << config_file << '\n'; 13010458Sandreas.hansson@arm.com return EXIT_FAILURE; 13110458Sandreas.hansson@arm.com } 13210458Sandreas.hansson@arm.com arg_ptr++; 13310458Sandreas.hansson@arm.com 13410458Sandreas.hansson@arm.com CxxConfigManager *config_manager = new CxxConfigManager(*conf); 13510458Sandreas.hansson@arm.com 13610458Sandreas.hansson@arm.com bool checkpoint_restore = false; 13710458Sandreas.hansson@arm.com bool checkpoint_save = false; 13810458Sandreas.hansson@arm.com bool switch_cpus = false; 13910458Sandreas.hansson@arm.com std::string checkpoint_dir = ""; 14010458Sandreas.hansson@arm.com std::string from_cpu = ""; 14110458Sandreas.hansson@arm.com std::string to_cpu = ""; 14210458Sandreas.hansson@arm.com Tick pre_run_time = 1000000; 14310458Sandreas.hansson@arm.com Tick pre_switch_time = 1000000; 14410458Sandreas.hansson@arm.com 14510458Sandreas.hansson@arm.com try { 14610458Sandreas.hansson@arm.com while (arg_ptr < argc) { 14710458Sandreas.hansson@arm.com std::string option(argv[arg_ptr]); 14810458Sandreas.hansson@arm.com arg_ptr++; 14910458Sandreas.hansson@arm.com unsigned num_args = argc - arg_ptr; 15010458Sandreas.hansson@arm.com 15110458Sandreas.hansson@arm.com if (option == "-p") { 15210458Sandreas.hansson@arm.com if (num_args < 3) 15310458Sandreas.hansson@arm.com usage(prog_name); 15410458Sandreas.hansson@arm.com config_manager->setParam(argv[arg_ptr], argv[arg_ptr + 1], 15510458Sandreas.hansson@arm.com argv[arg_ptr + 2]); 15610458Sandreas.hansson@arm.com arg_ptr += 3; 15710458Sandreas.hansson@arm.com } else if (option == "-v") { 15810458Sandreas.hansson@arm.com std::vector<std::string> values; 15910458Sandreas.hansson@arm.com 16010458Sandreas.hansson@arm.com if (num_args < 3) 16110458Sandreas.hansson@arm.com usage(prog_name); 16210458Sandreas.hansson@arm.com tokenize(values, argv[arg_ptr + 2], ','); 16310458Sandreas.hansson@arm.com config_manager->setParamVector(argv[arg_ptr], 16410458Sandreas.hansson@arm.com argv[arg_ptr + 1], values); 16510458Sandreas.hansson@arm.com arg_ptr += 3; 16610458Sandreas.hansson@arm.com } else if (option == "-d") { 16710458Sandreas.hansson@arm.com if (num_args < 1) 16810458Sandreas.hansson@arm.com usage(prog_name); 16910458Sandreas.hansson@arm.com if (argv[arg_ptr][0] == '-') 17010458Sandreas.hansson@arm.com clearDebugFlag(argv[arg_ptr] + 1); 17110458Sandreas.hansson@arm.com else 17210458Sandreas.hansson@arm.com setDebugFlag(argv[arg_ptr]); 17310458Sandreas.hansson@arm.com arg_ptr++; 17410458Sandreas.hansson@arm.com } else if (option == "-r") { 17510458Sandreas.hansson@arm.com if (num_args < 1) 17610458Sandreas.hansson@arm.com usage(prog_name); 17710458Sandreas.hansson@arm.com checkpoint_dir = argv[arg_ptr]; 17810458Sandreas.hansson@arm.com checkpoint_restore = true; 17910458Sandreas.hansson@arm.com arg_ptr++; 18010458Sandreas.hansson@arm.com } else if (option == "-s") { 18110458Sandreas.hansson@arm.com if (num_args < 2) 18210458Sandreas.hansson@arm.com usage(prog_name); 18310458Sandreas.hansson@arm.com checkpoint_dir = argv[arg_ptr]; 18410458Sandreas.hansson@arm.com std::istringstream(argv[arg_ptr + 1]) >> pre_run_time; 18510458Sandreas.hansson@arm.com checkpoint_save = true; 18610458Sandreas.hansson@arm.com arg_ptr += 2; 18710458Sandreas.hansson@arm.com } else if (option == "-c") { 18810458Sandreas.hansson@arm.com if (num_args < 3) 18910458Sandreas.hansson@arm.com usage(prog_name); 19010458Sandreas.hansson@arm.com switch_cpus = true; 19110458Sandreas.hansson@arm.com from_cpu = argv[arg_ptr]; 19210458Sandreas.hansson@arm.com to_cpu = argv[arg_ptr + 1]; 19310458Sandreas.hansson@arm.com std::istringstream(argv[arg_ptr + 2]) >> pre_switch_time; 19410458Sandreas.hansson@arm.com arg_ptr += 3; 19510458Sandreas.hansson@arm.com } else { 19610458Sandreas.hansson@arm.com usage(prog_name); 19710458Sandreas.hansson@arm.com } 19810458Sandreas.hansson@arm.com } 19910458Sandreas.hansson@arm.com } catch (CxxConfigManager::Exception &e) { 20010458Sandreas.hansson@arm.com std::cerr << e.name << ": " << e.message << "\n"; 20110458Sandreas.hansson@arm.com return EXIT_FAILURE; 20210458Sandreas.hansson@arm.com } 20310458Sandreas.hansson@arm.com 20410458Sandreas.hansson@arm.com if (checkpoint_save && checkpoint_restore) { 20510458Sandreas.hansson@arm.com std::cerr << "Don't try and save and restore a checkpoint in the" 20610458Sandreas.hansson@arm.com " same run\n"; 20710458Sandreas.hansson@arm.com return EXIT_FAILURE; 20810458Sandreas.hansson@arm.com } 20910458Sandreas.hansson@arm.com 21010458Sandreas.hansson@arm.com CxxConfig::statsEnable(); 21110458Sandreas.hansson@arm.com getEventQueue(0)->dump(); 21210458Sandreas.hansson@arm.com 21310458Sandreas.hansson@arm.com try { 21410458Sandreas.hansson@arm.com config_manager->instantiate(); 21510458Sandreas.hansson@arm.com if (!checkpoint_restore) { 21610458Sandreas.hansson@arm.com config_manager->initState(); 21710458Sandreas.hansson@arm.com config_manager->startup(); 21810458Sandreas.hansson@arm.com } 21910458Sandreas.hansson@arm.com } catch (CxxConfigManager::Exception &e) { 22010458Sandreas.hansson@arm.com std::cerr << "Config problem in sim object " << e.name 22110458Sandreas.hansson@arm.com << ": " << e.message << "\n"; 22210458Sandreas.hansson@arm.com 22310458Sandreas.hansson@arm.com return EXIT_FAILURE; 22410458Sandreas.hansson@arm.com } 22510458Sandreas.hansson@arm.com 22610458Sandreas.hansson@arm.com GlobalSimLoopExitEvent *exit_event = NULL; 22710458Sandreas.hansson@arm.com 22810458Sandreas.hansson@arm.com if (checkpoint_save) { 22910458Sandreas.hansson@arm.com exit_event = simulate(pre_run_time); 23010458Sandreas.hansson@arm.com 23110458Sandreas.hansson@arm.com DrainManager drain_manager; 23210458Sandreas.hansson@arm.com unsigned int drain_count = 1; 23310458Sandreas.hansson@arm.com do { 23410458Sandreas.hansson@arm.com drain_count = config_manager->drain(&drain_manager); 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 drain_manager.setCount(drain_count); 24010458Sandreas.hansson@arm.com exit_event = simulate(); 24110458Sandreas.hansson@arm.com } 24210458Sandreas.hansson@arm.com } while (drain_count > 0); 24310458Sandreas.hansson@arm.com 24410458Sandreas.hansson@arm.com std::cerr << "Simulation stop at tick " << curTick() 24510458Sandreas.hansson@arm.com << ", cause: " << exit_event->getCause() << '\n'; 24610458Sandreas.hansson@arm.com 24710458Sandreas.hansson@arm.com std::cerr << "Checkpointing\n"; 24810458Sandreas.hansson@arm.com 24910458Sandreas.hansson@arm.com /* FIXME, this should really be serialising just for 25010458Sandreas.hansson@arm.com * config_manager rather than using serializeAll's ugly 25110458Sandreas.hansson@arm.com * SimObject static object list */ 25210458Sandreas.hansson@arm.com Serializable::serializeAll(checkpoint_dir); 25310458Sandreas.hansson@arm.com 25410458Sandreas.hansson@arm.com std::cerr << "Completed checkpoint\n"; 25510458Sandreas.hansson@arm.com 25610458Sandreas.hansson@arm.com config_manager->drainResume(); 25710458Sandreas.hansson@arm.com } 25810458Sandreas.hansson@arm.com 25910458Sandreas.hansson@arm.com if (checkpoint_restore) { 26010458Sandreas.hansson@arm.com std::cerr << "Restoring checkpoint\n"; 26110458Sandreas.hansson@arm.com 26210458Sandreas.hansson@arm.com Checkpoint *checkpoint = new Checkpoint(checkpoint_dir, 26310458Sandreas.hansson@arm.com config_manager->getSimObjectResolver()); 26410458Sandreas.hansson@arm.com 26510458Sandreas.hansson@arm.com Serializable::unserializeGlobals(checkpoint); 26610458Sandreas.hansson@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 DrainManager drain_manager; 28510458Sandreas.hansson@arm.com unsigned int drain_count = 1; 28610458Sandreas.hansson@arm.com do { 28710458Sandreas.hansson@arm.com drain_count = config_manager->drain(&drain_manager); 28810458Sandreas.hansson@arm.com 28910458Sandreas.hansson@arm.com std::cerr << "Draining " << drain_count << '\n'; 29010458Sandreas.hansson@arm.com 29110458Sandreas.hansson@arm.com if (drain_count > 0) { 29210458Sandreas.hansson@arm.com drain_manager.setCount(drain_count); 29310458Sandreas.hansson@arm.com exit_event = simulate(); 29410458Sandreas.hansson@arm.com } 29510458Sandreas.hansson@arm.com } while (drain_count > 0); 29610458Sandreas.hansson@arm.com 29710458Sandreas.hansson@arm.com old_cpu.switchOut(); 29810458Sandreas.hansson@arm.com system.setMemoryMode(Enums::timing); 29910458Sandreas.hansson@arm.com new_cpu.takeOverFrom(&old_cpu); 30010458Sandreas.hansson@arm.com config_manager->drainResume(); 30110458Sandreas.hansson@arm.com 30210458Sandreas.hansson@arm.com std::cerr << "Switched CPU\n"; 30310458Sandreas.hansson@arm.com } 30410458Sandreas.hansson@arm.com 30510458Sandreas.hansson@arm.com exit_event = simulate(); 30610458Sandreas.hansson@arm.com 30710458Sandreas.hansson@arm.com std::cerr << "Exit at tick " << curTick() 30810458Sandreas.hansson@arm.com << ", cause: " << exit_event->getCause() << '\n'; 30910458Sandreas.hansson@arm.com 31010458Sandreas.hansson@arm.com getEventQueue(0)->dump(); 31110458Sandreas.hansson@arm.com 31210458Sandreas.hansson@arm.com#if TRY_CLEAN_DELETE 31310458Sandreas.hansson@arm.com config_manager->deleteObjects(); 31410458Sandreas.hansson@arm.com#endif 31510458Sandreas.hansson@arm.com 31610458Sandreas.hansson@arm.com delete config_manager; 31710458Sandreas.hansson@arm.com 31810458Sandreas.hansson@arm.com return EXIT_SUCCESS; 31910458Sandreas.hansson@arm.com} 320