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 */ 3913372Sgabeblack@google.com 4013372Sgabeblack@google.com#include <cstdlib> 4113372Sgabeblack@google.com#include <iostream> 4213372Sgabeblack@google.com#include <list> 4313372Sgabeblack@google.com 4413372Sgabeblack@google.com#include "base/statistics.hh" 4513372Sgabeblack@google.com#include "sc_gem5_control.hh" 4613372Sgabeblack@google.com#include "sc_logger.hh" 4713372Sgabeblack@google.com#include "sc_module.hh" 4813372Sgabeblack@google.com#include "sim/cxx_config_ini.hh" 4913372Sgabeblack@google.com#include "sim/cxx_manager.hh" 5013372Sgabeblack@google.com#include "sim/debug.hh" 5113372Sgabeblack@google.com#include "sim/init_signals.hh" 5213372Sgabeblack@google.com#include "sim/stat_control.hh" 5313372Sgabeblack@google.com#include "stats.hh" 5413372Sgabeblack@google.com 5513372Sgabeblack@google.comnamespace Gem5SystemC 5613372Sgabeblack@google.com{ 5713372Sgabeblack@google.com 5813372Sgabeblack@google.com/** This is the private side of Gem5Control */ 5913372Sgabeblack@google.comclass Gem5TopLevelModule : public Gem5SystemC::Module 6013372Sgabeblack@google.com{ 6113372Sgabeblack@google.com friend class Gem5Control; 6213372Sgabeblack@google.com 6313372Sgabeblack@google.com protected: 6413372Sgabeblack@google.com CxxConfigFileBase *config_file; 6513372Sgabeblack@google.com CxxConfigManager *root_manager; 6613372Sgabeblack@google.com Gem5SystemC::Logger logger; 6713372Sgabeblack@google.com 6813372Sgabeblack@google.com /** Things to do at end_of_elaborate */ 6913372Sgabeblack@google.com std::list<void (*)()> endOfElaborationFuncs; 7013372Sgabeblack@google.com 7113372Sgabeblack@google.com public: 7213372Sgabeblack@google.com SC_HAS_PROCESS(Gem5TopLevelModule); 7313372Sgabeblack@google.com 7413372Sgabeblack@google.com Gem5TopLevelModule(sc_core::sc_module_name name, 7513372Sgabeblack@google.com const std::string &config_filename); 7613372Sgabeblack@google.com ~Gem5TopLevelModule(); 7713372Sgabeblack@google.com 7813372Sgabeblack@google.com /** gem5 simulate. @todo for more interesting simulation control, 7913372Sgabeblack@google.com * this needs to be more complicated */ 8013372Sgabeblack@google.com void run(); 8113372Sgabeblack@google.com 8213372Sgabeblack@google.com /* Register an action to happen at the end of elaboration */ 8313372Sgabeblack@google.com void registerEndOfElaboration(void (*func)()) 8413372Sgabeblack@google.com { 8513372Sgabeblack@google.com endOfElaborationFuncs.push_back(func); 8613372Sgabeblack@google.com } 8713372Sgabeblack@google.com 8813372Sgabeblack@google.com /** SystemC startup */ 8913372Sgabeblack@google.com void end_of_elaboration(); 9013372Sgabeblack@google.com}; 9113372Sgabeblack@google.com 9213372Sgabeblack@google.comGem5System::Gem5System(CxxConfigManager *manager_, 9313372Sgabeblack@google.com const std::string &system_name, const std::string &instance_name) : 9413372Sgabeblack@google.com manager(manager_), 9513372Sgabeblack@google.com systemName(system_name), 9613372Sgabeblack@google.com instanceName(instance_name) 9713372Sgabeblack@google.com{ 9813372Sgabeblack@google.com manager->addRenaming(CxxConfigManager::Renaming( 9913372Sgabeblack@google.com system_name, instance_name)); 10013372Sgabeblack@google.com} 10113372Sgabeblack@google.com 10213372Sgabeblack@google.comGem5System::~Gem5System() 10313372Sgabeblack@google.com{ 10413372Sgabeblack@google.com delete manager; 10513372Sgabeblack@google.com} 10613372Sgabeblack@google.com 10713372Sgabeblack@google.comvoid 10813372Sgabeblack@google.comGem5System::setParam(const std::string &object, 10913372Sgabeblack@google.com const std::string ¶m_name, const std::string ¶m_value) 11013372Sgabeblack@google.com{ 11113372Sgabeblack@google.com manager->setParam(systemName + (object != "" ? "." + object : ""), 11213372Sgabeblack@google.com param_name, param_value); 11313372Sgabeblack@google.com} 11413372Sgabeblack@google.com 11513372Sgabeblack@google.comvoid 11613372Sgabeblack@google.comGem5System::setParamVector(const std::string &object, 11713372Sgabeblack@google.com const std::string ¶m_name, 11813372Sgabeblack@google.com const std::vector<std::string> ¶m_values) 11913372Sgabeblack@google.com{ 12013372Sgabeblack@google.com manager->setParamVector(systemName + 12113372Sgabeblack@google.com (object != "" ? "." + object : ""), param_name, param_values); 12213372Sgabeblack@google.com} 12313372Sgabeblack@google.com 12413372Sgabeblack@google.comvoid 12513372Sgabeblack@google.comGem5System::instantiate() 12613372Sgabeblack@google.com{ 12713372Sgabeblack@google.com try { 12813372Sgabeblack@google.com /* Make a new System */ 12913372Sgabeblack@google.com SimObject *obj = manager->findObject(systemName, true); 13013372Sgabeblack@google.com 13113372Sgabeblack@google.com /* Add the System's objects to the list of managed 13213372Sgabeblack@google.com * objects for initialisation */ 13313372Sgabeblack@google.com manager->findTraversalOrder(systemName); 13413372Sgabeblack@google.com 13513372Sgabeblack@google.com /* Bound ports *must* be internal to System */ 13613372Sgabeblack@google.com for (auto i = manager->objectsInOrder.begin(); 13713372Sgabeblack@google.com i != manager->objectsInOrder.end(); 13813372Sgabeblack@google.com ++ i) 13913372Sgabeblack@google.com { 14013372Sgabeblack@google.com manager->bindObjectPorts(*i); 14113372Sgabeblack@google.com } 14213372Sgabeblack@google.com 14313372Sgabeblack@google.com /* gem5 startup sequence */ 14413372Sgabeblack@google.com manager->instantiate(false); 14513372Sgabeblack@google.com manager->initState(); 14613372Sgabeblack@google.com manager->startup(); 14713372Sgabeblack@google.com } catch (CxxConfigManager::Exception &e) { 14813372Sgabeblack@google.com fatal("Config problem in Gem5System: %s: %s", 14913372Sgabeblack@google.com e.name, e.message); 15013372Sgabeblack@google.com } 15113372Sgabeblack@google.com} 15213372Sgabeblack@google.com 15313372Sgabeblack@google.comGem5Control::Gem5Control(const std::string &config_filename) 15413372Sgabeblack@google.com{ 15513372Sgabeblack@google.com module = new Gem5TopLevelModule("gem5", config_filename); 15613372Sgabeblack@google.com} 15713372Sgabeblack@google.com 15813372Sgabeblack@google.comGem5Control::~Gem5Control() 15913372Sgabeblack@google.com{ } 16013372Sgabeblack@google.com 16113372Sgabeblack@google.comvoid 16213372Sgabeblack@google.comGem5Control::registerEndOfElaboration(void (*func)()) 16313372Sgabeblack@google.com{ 16413372Sgabeblack@google.com module->registerEndOfElaboration(func); 16513372Sgabeblack@google.com} 16613372Sgabeblack@google.com 16713372Sgabeblack@google.comvoid 16813372Sgabeblack@google.comGem5Control::setDebugFlag(const char *flag) 16913372Sgabeblack@google.com{ 17013372Sgabeblack@google.com ::setDebugFlag(flag); 17113372Sgabeblack@google.com} 17213372Sgabeblack@google.com 17313372Sgabeblack@google.comvoid 17413372Sgabeblack@google.comGem5Control::clearDebugFlag(const char *flag) 17513372Sgabeblack@google.com{ 17613372Sgabeblack@google.com ::clearDebugFlag(flag); 17713372Sgabeblack@google.com} 17813372Sgabeblack@google.com 17913372Sgabeblack@google.comvoid 18013372Sgabeblack@google.comGem5Control::setRemoteGDBPort(unsigned int port) 18113372Sgabeblack@google.com{ 18213372Sgabeblack@google.com ::setRemoteGDBPort(port); 18313372Sgabeblack@google.com} 18413372Sgabeblack@google.com 18513372Sgabeblack@google.comGem5System * 18613372Sgabeblack@google.comGem5Control::makeSystem(const std::string &system_name, 18713372Sgabeblack@google.com const std::string &instance_name) 18813372Sgabeblack@google.com{ 18913372Sgabeblack@google.com Gem5System *ret = new Gem5System( 19013372Sgabeblack@google.com new CxxConfigManager(*(module->config_file)), 19113372Sgabeblack@google.com system_name, instance_name); 19213372Sgabeblack@google.com 19313372Sgabeblack@google.com return ret; 19413372Sgabeblack@google.com} 19513372Sgabeblack@google.com 19613372Sgabeblack@google.comconst std::string & 19713372Sgabeblack@google.comGem5Control::getVersion() const 19813372Sgabeblack@google.com{ 19913372Sgabeblack@google.com return version; 20013372Sgabeblack@google.com} 20113372Sgabeblack@google.com 20213372Sgabeblack@google.comvoid 20313372Sgabeblack@google.comGem5Control::setVersion(const std::string &new_version) 20413372Sgabeblack@google.com{ 20513372Sgabeblack@google.com if (version != "") 20613372Sgabeblack@google.com fatal("Gem5Control::setVersion called for a second time"); 20713372Sgabeblack@google.com 20813372Sgabeblack@google.com version = new_version; 20913372Sgabeblack@google.com} 21013372Sgabeblack@google.com 21113372Sgabeblack@google.comGem5TopLevelModule::Gem5TopLevelModule(sc_core::sc_module_name name, 21213372Sgabeblack@google.com const std::string &config_filename) : 21313372Sgabeblack@google.com Gem5SystemC::Module(name), 21413372Sgabeblack@google.com config_file(NULL), 21513372Sgabeblack@google.com root_manager(NULL) 21613372Sgabeblack@google.com{ 21713372Sgabeblack@google.com SC_THREAD(run); 21813372Sgabeblack@google.com 21913372Sgabeblack@google.com cxxConfigInit(); 22013372Sgabeblack@google.com 22113372Sgabeblack@google.com /* Pass DPRINTF messages to SystemC */ 22213372Sgabeblack@google.com Trace::setDebugLogger(&logger); 22313372Sgabeblack@google.com 22413372Sgabeblack@google.com /* @todo need this as an option */ 22513372Sgabeblack@google.com Gem5SystemC::setTickFrequency(); 22613372Sgabeblack@google.com 22713372Sgabeblack@google.com /* Make a SystemC-synchronising event queue and install it as the 22813372Sgabeblack@google.com * sole top level gem5 EventQueue */ 22913372Sgabeblack@google.com Gem5SystemC::Module::setupEventQueues(*this); 23013372Sgabeblack@google.com 23113372Sgabeblack@google.com if (sc_core::sc_get_time_resolution() != 23213372Sgabeblack@google.com sc_core::sc_time(1, sc_core::SC_PS)) 23313372Sgabeblack@google.com { 23413372Sgabeblack@google.com fatal("Time resolution must be set to 1 ps for gem5 to work"); 23513372Sgabeblack@google.com } 23613372Sgabeblack@google.com 23713372Sgabeblack@google.com /* Enable keyboard interrupt, async I/O etc. */ 23813372Sgabeblack@google.com initSignals(); 23913372Sgabeblack@google.com 24013372Sgabeblack@google.com /* Enable stats */ 24113372Sgabeblack@google.com Stats::initSimStats(); 24213372Sgabeblack@google.com Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump); 24313372Sgabeblack@google.com 24413372Sgabeblack@google.com Trace::enable(); 24513372Sgabeblack@google.com 24613372Sgabeblack@google.com config_file = new CxxIniFile(); 24713372Sgabeblack@google.com 24813372Sgabeblack@google.com if (!config_file->load(config_filename)) { 24913372Sgabeblack@google.com fatal("Gem5TopLevelModule: Can't open config file: %s", 25013372Sgabeblack@google.com config_filename); 25113372Sgabeblack@google.com } 25213372Sgabeblack@google.com 25313372Sgabeblack@google.com root_manager = new CxxConfigManager(*config_file); 25413372Sgabeblack@google.com 25513372Sgabeblack@google.com CxxConfig::statsEnable(); 25613372Sgabeblack@google.com 25713372Sgabeblack@google.com /* Make the root object */ 25813372Sgabeblack@google.com try { 25913372Sgabeblack@google.com SimObject *root = root_manager->findObject("root", false); 26013372Sgabeblack@google.com 26113372Sgabeblack@google.com /* Make sure we don't traverse into root's children */ 26213372Sgabeblack@google.com root_manager->objectsInOrder.push_back(root); 26313372Sgabeblack@google.com 26413372Sgabeblack@google.com root_manager->instantiate(false); 26513372Sgabeblack@google.com root_manager->initState(); 26613372Sgabeblack@google.com root_manager->startup(); 26713372Sgabeblack@google.com } catch (CxxConfigManager::Exception &e) { 26813372Sgabeblack@google.com fatal("Config problem in Gem5TopLevelModule: %s: %s", 26913372Sgabeblack@google.com e.name, e.message); 27013372Sgabeblack@google.com } 27113372Sgabeblack@google.com} 27213372Sgabeblack@google.com 27313372Sgabeblack@google.comGem5TopLevelModule::~Gem5TopLevelModule() 27413372Sgabeblack@google.com{ 27513372Sgabeblack@google.com delete config_file; 27613372Sgabeblack@google.com delete root_manager; 27713372Sgabeblack@google.com} 27813372Sgabeblack@google.com 27913372Sgabeblack@google.comvoid 28013372Sgabeblack@google.comGem5TopLevelModule::run() 28113372Sgabeblack@google.com{ 28213372Sgabeblack@google.com GlobalSimLoopExitEvent *exit_event = NULL; 28313372Sgabeblack@google.com 28413372Sgabeblack@google.com exit_event = simulate(); 28513372Sgabeblack@google.com 28613372Sgabeblack@google.com std::cerr << "Exit at tick " << curTick() 28713372Sgabeblack@google.com << ", cause: " << exit_event->getCause() << '\n'; 28813372Sgabeblack@google.com 28913372Sgabeblack@google.com getEventQueue(0)->dump(); 29013372Sgabeblack@google.com} 29113372Sgabeblack@google.com 29213372Sgabeblack@google.comvoid 29313372Sgabeblack@google.comGem5TopLevelModule::end_of_elaboration() 29413372Sgabeblack@google.com{ 29513372Sgabeblack@google.com for (auto i = endOfElaborationFuncs.begin(); 29613372Sgabeblack@google.com i != endOfElaborationFuncs.end(); ++i) 29713372Sgabeblack@google.com { 29813372Sgabeblack@google.com (*i)(); 29913372Sgabeblack@google.com } 30013372Sgabeblack@google.com} 30113372Sgabeblack@google.com 30213372Sgabeblack@google.com} 30313372Sgabeblack@google.com 30413372Sgabeblack@google.comGem5SystemC::Gem5Control * 30513372Sgabeblack@google.commakeGem5Control(const std::string &config_filename) 30613372Sgabeblack@google.com{ 30713372Sgabeblack@google.com return new Gem5SystemC::Gem5Control(config_filename); 30813372Sgabeblack@google.com} 30913372Sgabeblack@google.com 310