gem5.cc revision 12334
111618SCurtis.Dunham@arm.com// Copyright (c) 2015-2016 ARM Limited 210779SCurtis.Dunham@arm.com// All rights reserved. 310779SCurtis.Dunham@arm.com// 410779SCurtis.Dunham@arm.com// The license below extends only to copyright in the software and shall 510779SCurtis.Dunham@arm.com// not be construed as granting a license to any other intellectual 610779SCurtis.Dunham@arm.com// property including but not limited to intellectual property relating 710779SCurtis.Dunham@arm.com// to a hardware implementation of the functionality of the software 810779SCurtis.Dunham@arm.com// licensed hereunder. You may use the software subject to the license 910779SCurtis.Dunham@arm.com// terms below provided that you ensure that this notice is replicated 1010779SCurtis.Dunham@arm.com// unmodified and in its entirety in all distributions of the software, 1110779SCurtis.Dunham@arm.com// modified or unmodified, in source code or in binary form. 1210779SCurtis.Dunham@arm.com// 1310779SCurtis.Dunham@arm.com// Redistribution and use in source and binary forms, with or without 1410779SCurtis.Dunham@arm.com// modification, are permitted provided that the following conditions are 1510779SCurtis.Dunham@arm.com// met: redistributions of source code must retain the above copyright 1610779SCurtis.Dunham@arm.com// notice, this list of conditions and the following disclaimer; 1710779SCurtis.Dunham@arm.com// redistributions in binary form must reproduce the above copyright 1810779SCurtis.Dunham@arm.com// notice, this list of conditions and the following disclaimer in the 1910779SCurtis.Dunham@arm.com// documentation and/or other materials provided with the distribution; 2010779SCurtis.Dunham@arm.com// neither the name of the copyright holders nor the names of its 2110779SCurtis.Dunham@arm.com// contributors may be used to endorse or promote products derived from 2210779SCurtis.Dunham@arm.com// this software without specific prior written permission. 2310779SCurtis.Dunham@arm.com// 2410779SCurtis.Dunham@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2510779SCurtis.Dunham@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2610779SCurtis.Dunham@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2710779SCurtis.Dunham@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2810779SCurtis.Dunham@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2910779SCurtis.Dunham@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3010779SCurtis.Dunham@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3110779SCurtis.Dunham@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3210779SCurtis.Dunham@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3310779SCurtis.Dunham@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3410779SCurtis.Dunham@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3510779SCurtis.Dunham@arm.com 3610779SCurtis.Dunham@arm.com// Copyright 2009-2014 Sandia Coporation. Under the terms 3710779SCurtis.Dunham@arm.com// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 3810779SCurtis.Dunham@arm.com// Government retains certain rights in this software. 3910779SCurtis.Dunham@arm.com// 4010779SCurtis.Dunham@arm.com// Copyright (c) 2009-2014, Sandia Corporation 4110779SCurtis.Dunham@arm.com// All rights reserved. 4210779SCurtis.Dunham@arm.com// 4310779SCurtis.Dunham@arm.com// For license information, see the LICENSE file in the current directory. 4410779SCurtis.Dunham@arm.com 4511617SCurtis.Dunham@arm.com#include <core/sst_config.h> 4610779SCurtis.Dunham@arm.com#include <Python.h> // Before serialization to prevent spurious warnings 4710779SCurtis.Dunham@arm.com 4810779SCurtis.Dunham@arm.com#include "gem5.hh" 4910779SCurtis.Dunham@arm.com 5010779SCurtis.Dunham@arm.com// System headers 5110779SCurtis.Dunham@arm.com#include <boost/tokenizer.hpp> 5210779SCurtis.Dunham@arm.com#include <string> 5310779SCurtis.Dunham@arm.com 5410779SCurtis.Dunham@arm.com// gem5 Headers 5510779SCurtis.Dunham@arm.com#include <sim/core.hh> 5610779SCurtis.Dunham@arm.com#include <sim/init.hh> 5710779SCurtis.Dunham@arm.com#include <sim/init_signals.hh> 5810779SCurtis.Dunham@arm.com#include <sim/system.hh> 5910779SCurtis.Dunham@arm.com#include <sim/sim_object.hh> 6012334Sgabeblack@google.com#include <base/logging.hh> 6110779SCurtis.Dunham@arm.com#include <base/debug.hh> 6210779SCurtis.Dunham@arm.com 6310779SCurtis.Dunham@arm.com#ifdef fatal // gem5 sets this 6410779SCurtis.Dunham@arm.com#undef fatal 6510779SCurtis.Dunham@arm.com#endif 6610779SCurtis.Dunham@arm.com 6710779SCurtis.Dunham@arm.com// More SST Headers 6811618SCurtis.Dunham@arm.com#include <core/timeConverter.h> 6910779SCurtis.Dunham@arm.com 7010779SCurtis.Dunham@arm.comusing namespace SST; 7110779SCurtis.Dunham@arm.comusing namespace SST::gem5; 7210779SCurtis.Dunham@arm.com 7310779SCurtis.Dunham@arm.comgem5Component::gem5Component(ComponentId_t id, Params ¶ms) : 7410779SCurtis.Dunham@arm.com SST::Component(id) 7510779SCurtis.Dunham@arm.com{ 7610779SCurtis.Dunham@arm.com dbg.init("@t:gem5:@p():@l " + getName() + ": ", 0, 0, 7711618SCurtis.Dunham@arm.com (Output::output_location_t)params.find<int>("comp_debug", 0)); 7810779SCurtis.Dunham@arm.com info.init("gem5:" + getName() + ": ", 0, 0, Output::STDOUT); 7910779SCurtis.Dunham@arm.com 8010779SCurtis.Dunham@arm.com TimeConverter *clock = registerClock( 8111618SCurtis.Dunham@arm.com params.find<std::string>("frequency", "1GHz"), 8210779SCurtis.Dunham@arm.com new Clock::Handler<gem5Component>(this, &gem5Component::clockTick)); 8310779SCurtis.Dunham@arm.com 8410779SCurtis.Dunham@arm.com // This sets how many gem5 cycles we'll need to simulate per clock tick 8510779SCurtis.Dunham@arm.com sim_cycles = clock->getFactor(); 8610779SCurtis.Dunham@arm.com 8710779SCurtis.Dunham@arm.com // Disable gem5's inform() messages. 8810779SCurtis.Dunham@arm.com want_info = false; 8910779SCurtis.Dunham@arm.com 9011618SCurtis.Dunham@arm.com std::string cmd = params.find<std::string>("cmd", ""); 9110779SCurtis.Dunham@arm.com if (cmd.empty()) { 9211315SCurtis.Dunham@arm.com dbg.fatal(CALL_INFO, -1, "Component %s must have a 'cmd' parameter.\n", 9310779SCurtis.Dunham@arm.com getName().c_str()); 9410779SCurtis.Dunham@arm.com } 9510779SCurtis.Dunham@arm.com 9610779SCurtis.Dunham@arm.com std::vector<char*> args; 9710779SCurtis.Dunham@arm.com args.push_back(const_cast<char*>("sst.x")); // TODO: Compute this somehow? 9810779SCurtis.Dunham@arm.com splitCommandArgs(cmd, args); 9910779SCurtis.Dunham@arm.com args.push_back(const_cast<char*>("--initialize-only")); 10010779SCurtis.Dunham@arm.com dbg.output(CALL_INFO, "Command string: [sst.x %s --initialize-only]\n", 10110779SCurtis.Dunham@arm.com cmd.c_str()); 10210779SCurtis.Dunham@arm.com for (size_t i = 0; i < args.size(); ++i) { 10310779SCurtis.Dunham@arm.com dbg.output(CALL_INFO, " Arg [%02zu] = %s\n", i, args[i]); 10410779SCurtis.Dunham@arm.com } 10510779SCurtis.Dunham@arm.com 10610779SCurtis.Dunham@arm.com std::vector<char*> flags; 10711618SCurtis.Dunham@arm.com std::string gem5DbgFlags = params.find<std::string>("gem5DebugFlags", ""); 10810779SCurtis.Dunham@arm.com splitCommandArgs(gem5DbgFlags, flags); 10910779SCurtis.Dunham@arm.com for (auto flag : flags) { 11010779SCurtis.Dunham@arm.com dbg.output(CALL_INFO, " Setting Debug Flag [%s]\n", flag); 11110779SCurtis.Dunham@arm.com setDebugFlag(flag); 11210779SCurtis.Dunham@arm.com } 11310779SCurtis.Dunham@arm.com 11410779SCurtis.Dunham@arm.com ExternalMaster::registerHandler("sst", this); // these are idempotent 11510779SCurtis.Dunham@arm.com ExternalSlave ::registerHandler("sst", this); 11610779SCurtis.Dunham@arm.com 11710779SCurtis.Dunham@arm.com // Initialize m5 special signal handling. 11810779SCurtis.Dunham@arm.com initSignals(); 11910779SCurtis.Dunham@arm.com 12010779SCurtis.Dunham@arm.com initPython(args.size(), &args[0]); 12110779SCurtis.Dunham@arm.com 12210779SCurtis.Dunham@arm.com // tell the simulator not to end without us 12310779SCurtis.Dunham@arm.com registerAsPrimaryComponent(); 12410779SCurtis.Dunham@arm.com primaryComponentDoNotEndSim(); 12510779SCurtis.Dunham@arm.com 12610779SCurtis.Dunham@arm.com clocks_processed = 0; 12710779SCurtis.Dunham@arm.com} 12810779SCurtis.Dunham@arm.com 12910779SCurtis.Dunham@arm.comgem5Component::~gem5Component(void) 13010779SCurtis.Dunham@arm.com{ 13110779SCurtis.Dunham@arm.com Py_Finalize(); 13210779SCurtis.Dunham@arm.com} 13310779SCurtis.Dunham@arm.com 13410779SCurtis.Dunham@arm.comvoid 13510779SCurtis.Dunham@arm.comgem5Component::init(unsigned phase) 13610779SCurtis.Dunham@arm.com{ 13710779SCurtis.Dunham@arm.com for (auto m : masters) { 13810779SCurtis.Dunham@arm.com m->init(phase); 13910779SCurtis.Dunham@arm.com } 14010779SCurtis.Dunham@arm.com for (auto s : slaves) { 14110779SCurtis.Dunham@arm.com s->init(phase); 14210779SCurtis.Dunham@arm.com } 14310779SCurtis.Dunham@arm.com} 14410779SCurtis.Dunham@arm.com 14510779SCurtis.Dunham@arm.comvoid 14610779SCurtis.Dunham@arm.comgem5Component::setup(void) 14710779SCurtis.Dunham@arm.com{ 14810779SCurtis.Dunham@arm.com // Switch connectors from initData to regular Sends 14910779SCurtis.Dunham@arm.com for (auto m : masters) { 15010779SCurtis.Dunham@arm.com m->setup(); 15110779SCurtis.Dunham@arm.com } 15210779SCurtis.Dunham@arm.com for (auto s : slaves) { 15310779SCurtis.Dunham@arm.com s->setup(); 15410779SCurtis.Dunham@arm.com } 15510779SCurtis.Dunham@arm.com} 15610779SCurtis.Dunham@arm.com 15710779SCurtis.Dunham@arm.comvoid 15810779SCurtis.Dunham@arm.comgem5Component::finish(void) 15910779SCurtis.Dunham@arm.com{ 16010779SCurtis.Dunham@arm.com for (auto m : masters) { 16110779SCurtis.Dunham@arm.com m->finish(); 16210779SCurtis.Dunham@arm.com } 16311618SCurtis.Dunham@arm.com info.output("Complete. Clocks Processed: %" PRIu64"\n", clocks_processed); 16410779SCurtis.Dunham@arm.com} 16510779SCurtis.Dunham@arm.com 16610779SCurtis.Dunham@arm.combool 16710779SCurtis.Dunham@arm.comgem5Component::clockTick(Cycle_t cycle) 16810779SCurtis.Dunham@arm.com{ 16910779SCurtis.Dunham@arm.com dbg.output(CALL_INFO, "Cycle %lu\n", cycle); 17010779SCurtis.Dunham@arm.com 17110779SCurtis.Dunham@arm.com for (auto m : masters) { 17210779SCurtis.Dunham@arm.com m->clock(); 17310779SCurtis.Dunham@arm.com } 17410779SCurtis.Dunham@arm.com 17510779SCurtis.Dunham@arm.com GlobalSimLoopExitEvent *event = simulate(sim_cycles); 17610779SCurtis.Dunham@arm.com ++clocks_processed; 17710779SCurtis.Dunham@arm.com if (event != simulate_limit_event) { 17810779SCurtis.Dunham@arm.com info.output("exiting: curTick()=%lu cause=`%s` code=%d\n", 17910779SCurtis.Dunham@arm.com curTick(), event->getCause().c_str(), event->getCode()); 18010779SCurtis.Dunham@arm.com primaryComponentOKToEndSim(); 18110779SCurtis.Dunham@arm.com return true; 18210779SCurtis.Dunham@arm.com } 18310779SCurtis.Dunham@arm.com 18410779SCurtis.Dunham@arm.com return false; 18510779SCurtis.Dunham@arm.com} 18610779SCurtis.Dunham@arm.com 18710779SCurtis.Dunham@arm.com 18810779SCurtis.Dunham@arm.comvoid 18910779SCurtis.Dunham@arm.comgem5Component::splitCommandArgs(std::string &cmd, 19010779SCurtis.Dunham@arm.com std::vector<char *> &args) 19110779SCurtis.Dunham@arm.com{ 19210779SCurtis.Dunham@arm.com std::string sep1("\\"); 19310779SCurtis.Dunham@arm.com std::string sep2(" "); 19410779SCurtis.Dunham@arm.com std::string sep3("\"\'"); 19510779SCurtis.Dunham@arm.com 19610779SCurtis.Dunham@arm.com boost::escaped_list_separator<char> els(sep1, sep2, sep3); 19710779SCurtis.Dunham@arm.com boost::tokenizer<boost::escaped_list_separator<char>> tok(cmd, els); 19810779SCurtis.Dunham@arm.com 19910779SCurtis.Dunham@arm.com for (auto beg : tok) { 20010779SCurtis.Dunham@arm.com args.push_back(strdup(beg.c_str())); 20110779SCurtis.Dunham@arm.com } 20210779SCurtis.Dunham@arm.com} 20310779SCurtis.Dunham@arm.com 20410779SCurtis.Dunham@arm.com 20510779SCurtis.Dunham@arm.comvoid 20610779SCurtis.Dunham@arm.comgem5Component::initPython(int argc, char *argv[]) 20710779SCurtis.Dunham@arm.com{ 20810779SCurtis.Dunham@arm.com const char * m5MainCommands[] = { 20910779SCurtis.Dunham@arm.com "import m5", 21010779SCurtis.Dunham@arm.com "m5.main()", 21110779SCurtis.Dunham@arm.com 0 // sentinel is required 21210779SCurtis.Dunham@arm.com }; 21310779SCurtis.Dunham@arm.com 21410779SCurtis.Dunham@arm.com PyObject *mainModule,*mainDict; 21510779SCurtis.Dunham@arm.com 21610779SCurtis.Dunham@arm.com Py_SetProgramName(argv[0]); // optional but recommended 21710779SCurtis.Dunham@arm.com 21810779SCurtis.Dunham@arm.com Py_Initialize(); 21910779SCurtis.Dunham@arm.com 22010779SCurtis.Dunham@arm.com int ret = initM5Python(); 22110779SCurtis.Dunham@arm.com if (ret != 0) { 22211315SCurtis.Dunham@arm.com dbg.fatal(CALL_INFO, -1, "Python failed to initialize. Code: %d\n", 22311315SCurtis.Dunham@arm.com ret); 22410779SCurtis.Dunham@arm.com } 22510779SCurtis.Dunham@arm.com 22610779SCurtis.Dunham@arm.com PySys_SetArgv(argc, argv); 22710779SCurtis.Dunham@arm.com 22810779SCurtis.Dunham@arm.com mainModule = PyImport_AddModule("__main__"); 22910779SCurtis.Dunham@arm.com assert(mainModule); 23010779SCurtis.Dunham@arm.com 23110779SCurtis.Dunham@arm.com mainDict = PyModule_GetDict(mainModule); 23210779SCurtis.Dunham@arm.com assert(mainDict); 23310779SCurtis.Dunham@arm.com 23410779SCurtis.Dunham@arm.com PyObject *result; 23510779SCurtis.Dunham@arm.com const char **command = m5MainCommands; 23610779SCurtis.Dunham@arm.com 23710779SCurtis.Dunham@arm.com // evaluate each command in the m5MainCommands array (basically a 23810779SCurtis.Dunham@arm.com // bunch of python statements. 23910779SCurtis.Dunham@arm.com while (*command) { 24010779SCurtis.Dunham@arm.com result = PyRun_String(*command, Py_file_input, mainDict, mainDict); 24110779SCurtis.Dunham@arm.com if (!result) { 24210779SCurtis.Dunham@arm.com PyErr_Print(); 24310779SCurtis.Dunham@arm.com break; 24410779SCurtis.Dunham@arm.com } 24510779SCurtis.Dunham@arm.com Py_DECREF(result); 24610779SCurtis.Dunham@arm.com 24710779SCurtis.Dunham@arm.com command++; 24810779SCurtis.Dunham@arm.com } 24910779SCurtis.Dunham@arm.com} 25010779SCurtis.Dunham@arm.com 25110779SCurtis.Dunham@arm.comExternalMaster::Port* 25210779SCurtis.Dunham@arm.comgem5Component::getExternalPort(const std::string &name, 25310779SCurtis.Dunham@arm.com ExternalMaster &owner, const std::string &port_data) 25410779SCurtis.Dunham@arm.com{ 25510779SCurtis.Dunham@arm.com std::string s(name); // bridges non-& result and &-arg 25610779SCurtis.Dunham@arm.com auto master = new ExtMaster(this, info, owner, s); 25710779SCurtis.Dunham@arm.com masters.push_back(master); 25810779SCurtis.Dunham@arm.com return master; 25910779SCurtis.Dunham@arm.com} 26010779SCurtis.Dunham@arm.com 26110779SCurtis.Dunham@arm.comExternalSlave::Port* 26210779SCurtis.Dunham@arm.comgem5Component::getExternalPort(const std::string &name, 26310779SCurtis.Dunham@arm.com ExternalSlave &owner, const std::string &port_data) 26410779SCurtis.Dunham@arm.com{ 26510779SCurtis.Dunham@arm.com std::string s(name); // bridges non-& result and &-arg 26610779SCurtis.Dunham@arm.com auto slave = new ExtSlave(this, info, owner, s); 26710779SCurtis.Dunham@arm.com slaves.push_back(slave); 26810779SCurtis.Dunham@arm.com return slave; 26910779SCurtis.Dunham@arm.com} 270