1// Copyright (c) 2015 ARM Limited 2// All rights reserved. 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 36// Copyright 2009-2014 Sandia Coporation. Under the terms 37// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 38// Government retains certain rights in this software. 39// 40// Copyright (c) 2009-2014, Sandia Corporation 41// All rights reserved. 42// 43// For license information, see the LICENSE file in the current directory. 44 45#include <sst_config.h> 46#include <Python.h> // Before serialization to prevent spurious warnings 47#include <sst/core/serialization.h> 48 49#include "gem5.hh" 50 51// System headers 52#include <boost/tokenizer.hpp> 53#include <string> 54 55// gem5 Headers 56#include <sim/core.hh> 57#include <sim/init.hh> 58#include <sim/init_signals.hh> 59#include <sim/system.hh> 60#include <sim/sim_object.hh> 61#include <base/misc.hh> 62#include <base/debug.hh> 63 64#ifdef fatal // gem5 sets this 65#undef fatal 66#endif 67 68// More SST Headers 69#include <sst/core/params.h> 70#include <sst/core/link.h> 71#include <sst/core/timeConverter.h>
| 1// Copyright (c) 2015 ARM Limited 2// All rights reserved. 3// 4// The license below extends only to copyright in the software and shall 5// not be construed as granting a license to any other intellectual 6// property including but not limited to intellectual property relating 7// to a hardware implementation of the functionality of the software 8// licensed hereunder. You may use the software subject to the license 9// terms below provided that you ensure that this notice is replicated 10// unmodified and in its entirety in all distributions of the software, 11// modified or unmodified, in source code or in binary form. 12// 13// Redistribution and use in source and binary forms, with or without 14// modification, are permitted provided that the following conditions are 15// met: redistributions of source code must retain the above copyright 16// notice, this list of conditions and the following disclaimer; 17// redistributions in binary form must reproduce the above copyright 18// notice, this list of conditions and the following disclaimer in the 19// documentation and/or other materials provided with the distribution; 20// neither the name of the copyright holders nor the names of its 21// contributors may be used to endorse or promote products derived from 22// this software without specific prior written permission. 23// 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 36// Copyright 2009-2014 Sandia Coporation. Under the terms 37// of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. 38// Government retains certain rights in this software. 39// 40// Copyright (c) 2009-2014, Sandia Corporation 41// All rights reserved. 42// 43// For license information, see the LICENSE file in the current directory. 44 45#include <sst_config.h> 46#include <Python.h> // Before serialization to prevent spurious warnings 47#include <sst/core/serialization.h> 48 49#include "gem5.hh" 50 51// System headers 52#include <boost/tokenizer.hpp> 53#include <string> 54 55// gem5 Headers 56#include <sim/core.hh> 57#include <sim/init.hh> 58#include <sim/init_signals.hh> 59#include <sim/system.hh> 60#include <sim/sim_object.hh> 61#include <base/misc.hh> 62#include <base/debug.hh> 63 64#ifdef fatal // gem5 sets this 65#undef fatal 66#endif 67 68// More SST Headers 69#include <sst/core/params.h> 70#include <sst/core/link.h> 71#include <sst/core/timeConverter.h>
|
72#include <sst/core/debug.h>
| |
73 74using namespace SST; 75using namespace SST::gem5; 76 77gem5Component::gem5Component(ComponentId_t id, Params ¶ms) : 78 SST::Component(id) 79{ 80 dbg.init("@t:gem5:@p():@l " + getName() + ": ", 0, 0, 81 (Output::output_location_t)params.find_integer("comp_debug", 0)); 82 info.init("gem5:" + getName() + ": ", 0, 0, Output::STDOUT); 83 84 TimeConverter *clock = registerClock( 85 params.find_string("frequency", "1GHz"), 86 new Clock::Handler<gem5Component>(this, &gem5Component::clockTick)); 87 88 // This sets how many gem5 cycles we'll need to simulate per clock tick 89 sim_cycles = clock->getFactor(); 90 91 // Disable gem5's inform() messages. 92 want_info = false; 93 94 std::string cmd = params.find_string("cmd", ""); 95 if (cmd.empty()) {
| 72 73using namespace SST; 74using namespace SST::gem5; 75 76gem5Component::gem5Component(ComponentId_t id, Params ¶ms) : 77 SST::Component(id) 78{ 79 dbg.init("@t:gem5:@p():@l " + getName() + ": ", 0, 0, 80 (Output::output_location_t)params.find_integer("comp_debug", 0)); 81 info.init("gem5:" + getName() + ": ", 0, 0, Output::STDOUT); 82 83 TimeConverter *clock = registerClock( 84 params.find_string("frequency", "1GHz"), 85 new Clock::Handler<gem5Component>(this, &gem5Component::clockTick)); 86 87 // This sets how many gem5 cycles we'll need to simulate per clock tick 88 sim_cycles = clock->getFactor(); 89 90 // Disable gem5's inform() messages. 91 want_info = false; 92 93 std::string cmd = params.find_string("cmd", ""); 94 if (cmd.empty()) {
|
96 _abort(gem5Component, "Component %s must have a 'cmd' parameter.\n",
| 95 dbg.fatal(CALL_INFO, -1, "Component %s must have a 'cmd' parameter.\n",
|
97 getName().c_str()); 98 } 99 100 std::vector<char*> args; 101 args.push_back(const_cast<char*>("sst.x")); // TODO: Compute this somehow? 102 splitCommandArgs(cmd, args); 103 args.push_back(const_cast<char*>("--initialize-only")); 104 dbg.output(CALL_INFO, "Command string: [sst.x %s --initialize-only]\n", 105 cmd.c_str()); 106 for (size_t i = 0; i < args.size(); ++i) { 107 dbg.output(CALL_INFO, " Arg [%02zu] = %s\n", i, args[i]); 108 } 109 110 std::vector<char*> flags; 111 std::string gem5DbgFlags = params.find_string("gem5DebugFlags", ""); 112 splitCommandArgs(gem5DbgFlags, flags); 113 for (auto flag : flags) { 114 dbg.output(CALL_INFO, " Setting Debug Flag [%s]\n", flag); 115 setDebugFlag(flag); 116 } 117 118 ExternalMaster::registerHandler("sst", this); // these are idempotent 119 ExternalSlave ::registerHandler("sst", this); 120 121 // Initialize m5 special signal handling. 122 initSignals(); 123 124 initPython(args.size(), &args[0]); 125 126 // tell the simulator not to end without us 127 registerAsPrimaryComponent(); 128 primaryComponentDoNotEndSim(); 129 130 clocks_processed = 0; 131} 132 133gem5Component::~gem5Component(void) 134{ 135 Py_Finalize(); 136} 137 138void 139gem5Component::init(unsigned phase) 140{ 141 for (auto m : masters) { 142 m->init(phase); 143 } 144 for (auto s : slaves) { 145 s->init(phase); 146 } 147} 148 149void 150gem5Component::setup(void) 151{ 152 // Switch connectors from initData to regular Sends 153 for (auto m : masters) { 154 m->setup(); 155 } 156 for (auto s : slaves) { 157 s->setup(); 158 } 159} 160 161void 162gem5Component::finish(void) 163{ 164 for (auto m : masters) { 165 m->finish(); 166 } 167 info.output("Complete. Clocks Processed: %"PRIu64"\n", clocks_processed); 168} 169 170bool 171gem5Component::clockTick(Cycle_t cycle) 172{ 173 dbg.output(CALL_INFO, "Cycle %lu\n", cycle); 174 175 for (auto m : masters) { 176 m->clock(); 177 } 178 179 GlobalSimLoopExitEvent *event = simulate(sim_cycles); 180 ++clocks_processed; 181 if (event != simulate_limit_event) { 182 info.output("exiting: curTick()=%lu cause=`%s` code=%d\n", 183 curTick(), event->getCause().c_str(), event->getCode()); 184 primaryComponentOKToEndSim(); 185 return true; 186 } 187 188 return false; 189} 190 191 192void 193gem5Component::splitCommandArgs(std::string &cmd, 194 std::vector<char *> &args) 195{ 196 std::string sep1("\\"); 197 std::string sep2(" "); 198 std::string sep3("\"\'"); 199 200 boost::escaped_list_separator<char> els(sep1, sep2, sep3); 201 boost::tokenizer<boost::escaped_list_separator<char>> tok(cmd, els); 202 203 for (auto beg : tok) { 204 args.push_back(strdup(beg.c_str())); 205 } 206} 207 208 209void 210gem5Component::initPython(int argc, char *argv[]) 211{ 212 const char * m5MainCommands[] = { 213 "import m5", 214 "m5.main()", 215 0 // sentinel is required 216 }; 217 218 PyObject *mainModule,*mainDict; 219 220 Py_SetProgramName(argv[0]); // optional but recommended 221 222 Py_Initialize(); 223 224 int ret = initM5Python(); 225 if (ret != 0) {
| 96 getName().c_str()); 97 } 98 99 std::vector<char*> args; 100 args.push_back(const_cast<char*>("sst.x")); // TODO: Compute this somehow? 101 splitCommandArgs(cmd, args); 102 args.push_back(const_cast<char*>("--initialize-only")); 103 dbg.output(CALL_INFO, "Command string: [sst.x %s --initialize-only]\n", 104 cmd.c_str()); 105 for (size_t i = 0; i < args.size(); ++i) { 106 dbg.output(CALL_INFO, " Arg [%02zu] = %s\n", i, args[i]); 107 } 108 109 std::vector<char*> flags; 110 std::string gem5DbgFlags = params.find_string("gem5DebugFlags", ""); 111 splitCommandArgs(gem5DbgFlags, flags); 112 for (auto flag : flags) { 113 dbg.output(CALL_INFO, " Setting Debug Flag [%s]\n", flag); 114 setDebugFlag(flag); 115 } 116 117 ExternalMaster::registerHandler("sst", this); // these are idempotent 118 ExternalSlave ::registerHandler("sst", this); 119 120 // Initialize m5 special signal handling. 121 initSignals(); 122 123 initPython(args.size(), &args[0]); 124 125 // tell the simulator not to end without us 126 registerAsPrimaryComponent(); 127 primaryComponentDoNotEndSim(); 128 129 clocks_processed = 0; 130} 131 132gem5Component::~gem5Component(void) 133{ 134 Py_Finalize(); 135} 136 137void 138gem5Component::init(unsigned phase) 139{ 140 for (auto m : masters) { 141 m->init(phase); 142 } 143 for (auto s : slaves) { 144 s->init(phase); 145 } 146} 147 148void 149gem5Component::setup(void) 150{ 151 // Switch connectors from initData to regular Sends 152 for (auto m : masters) { 153 m->setup(); 154 } 155 for (auto s : slaves) { 156 s->setup(); 157 } 158} 159 160void 161gem5Component::finish(void) 162{ 163 for (auto m : masters) { 164 m->finish(); 165 } 166 info.output("Complete. Clocks Processed: %"PRIu64"\n", clocks_processed); 167} 168 169bool 170gem5Component::clockTick(Cycle_t cycle) 171{ 172 dbg.output(CALL_INFO, "Cycle %lu\n", cycle); 173 174 for (auto m : masters) { 175 m->clock(); 176 } 177 178 GlobalSimLoopExitEvent *event = simulate(sim_cycles); 179 ++clocks_processed; 180 if (event != simulate_limit_event) { 181 info.output("exiting: curTick()=%lu cause=`%s` code=%d\n", 182 curTick(), event->getCause().c_str(), event->getCode()); 183 primaryComponentOKToEndSim(); 184 return true; 185 } 186 187 return false; 188} 189 190 191void 192gem5Component::splitCommandArgs(std::string &cmd, 193 std::vector<char *> &args) 194{ 195 std::string sep1("\\"); 196 std::string sep2(" "); 197 std::string sep3("\"\'"); 198 199 boost::escaped_list_separator<char> els(sep1, sep2, sep3); 200 boost::tokenizer<boost::escaped_list_separator<char>> tok(cmd, els); 201 202 for (auto beg : tok) { 203 args.push_back(strdup(beg.c_str())); 204 } 205} 206 207 208void 209gem5Component::initPython(int argc, char *argv[]) 210{ 211 const char * m5MainCommands[] = { 212 "import m5", 213 "m5.main()", 214 0 // sentinel is required 215 }; 216 217 PyObject *mainModule,*mainDict; 218 219 Py_SetProgramName(argv[0]); // optional but recommended 220 221 Py_Initialize(); 222 223 int ret = initM5Python(); 224 if (ret != 0) {
|
226 _abort(gem5Component, "Python failed to initialize. Code: %d\n", ret);
| 225 dbg.fatal(CALL_INFO, -1, "Python failed to initialize. Code: %d\n", 226 ret);
|
227 } 228 229 PySys_SetArgv(argc, argv); 230 231 mainModule = PyImport_AddModule("__main__"); 232 assert(mainModule); 233 234 mainDict = PyModule_GetDict(mainModule); 235 assert(mainDict); 236 237 PyObject *result; 238 const char **command = m5MainCommands; 239 240 // evaluate each command in the m5MainCommands array (basically a 241 // bunch of python statements. 242 while (*command) { 243 result = PyRun_String(*command, Py_file_input, mainDict, mainDict); 244 if (!result) { 245 PyErr_Print(); 246 break; 247 } 248 Py_DECREF(result); 249 250 command++; 251 } 252} 253 254ExternalMaster::Port* 255gem5Component::getExternalPort(const std::string &name, 256 ExternalMaster &owner, const std::string &port_data) 257{ 258 std::string s(name); // bridges non-& result and &-arg 259 auto master = new ExtMaster(this, info, owner, s); 260 masters.push_back(master); 261 return master; 262} 263 264ExternalSlave::Port* 265gem5Component::getExternalPort(const std::string &name, 266 ExternalSlave &owner, const std::string &port_data) 267{ 268 std::string s(name); // bridges non-& result and &-arg 269 auto slave = new ExtSlave(this, info, owner, s); 270 slaves.push_back(slave); 271 return slave; 272}
| 227 } 228 229 PySys_SetArgv(argc, argv); 230 231 mainModule = PyImport_AddModule("__main__"); 232 assert(mainModule); 233 234 mainDict = PyModule_GetDict(mainModule); 235 assert(mainDict); 236 237 PyObject *result; 238 const char **command = m5MainCommands; 239 240 // evaluate each command in the m5MainCommands array (basically a 241 // bunch of python statements. 242 while (*command) { 243 result = PyRun_String(*command, Py_file_input, mainDict, mainDict); 244 if (!result) { 245 PyErr_Print(); 246 break; 247 } 248 Py_DECREF(result); 249 250 command++; 251 } 252} 253 254ExternalMaster::Port* 255gem5Component::getExternalPort(const std::string &name, 256 ExternalMaster &owner, const std::string &port_data) 257{ 258 std::string s(name); // bridges non-& result and &-arg 259 auto master = new ExtMaster(this, info, owner, s); 260 masters.push_back(master); 261 return master; 262} 263 264ExternalSlave::Port* 265gem5Component::getExternalPort(const std::string &name, 266 ExternalSlave &owner, const std::string &port_data) 267{ 268 std::string s(name); // bridges non-& result and &-arg 269 auto slave = new ExtSlave(this, info, owner, s); 270 slaves.push_back(slave); 271 return slave; 272}
|