diff options
Diffstat (limited to 'src/sim')
-rw-r--r-- | src/sim/SConscript | 3 | ||||
-rw-r--r-- | src/sim/init.cc | 202 | ||||
-rw-r--r-- | src/sim/init.hh | 54 | ||||
-rw-r--r-- | src/sim/main.cc | 124 |
4 files changed, 274 insertions, 109 deletions
diff --git a/src/sim/SConscript b/src/sim/SConscript index c9e4415f5..3e6adb85a 100644 --- a/src/sim/SConscript +++ b/src/sim/SConscript @@ -40,7 +40,8 @@ Source('core.cc') Source('debug.cc') Source('eventq.cc') Source('faults.cc') -Source('main.cc') +Source('init.cc') +BinSource('main.cc') Source('root.cc') Source('serialize.cc') Source('sim_events.cc') diff --git a/src/sim/init.cc b/src/sim/init.cc new file mode 100644 index 000000000..804389dae --- /dev/null +++ b/src/sim/init.cc @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2000-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#include <Python.h> +#include <marshal.h> +#include <signal.h> + +#include <iostream> +#include <string> +#include <zlib.h> + +#include "base/cprintf.hh" +#include "base/misc.hh" +#include "sim/async.hh" +#include "sim/core.hh" +#include "sim/host.hh" +#include "sim/init.hh" + +using namespace std; + +/// Stats signal handler. +void +dumpStatsHandler(int sigtype) +{ + async_event = true; + async_statdump = true; +} + +void +dumprstStatsHandler(int sigtype) +{ + async_event = true; + async_statdump = true; + async_statreset = true; +} + +/// Exit signal handler. +void +exitNowHandler(int sigtype) +{ + async_event = true; + async_exit = true; +} + +/// Abort signal handler. +void +abortHandler(int sigtype) +{ + ccprintf(cerr, "Program aborted at cycle %d\n", curTick); +} + +/* + * M5 can do several special things when various signals are sent. + * None are mandatory. + */ +void +initSignals() +{ + // Floating point exceptions may happen on misspeculated paths, so + // ignore them + signal(SIGFPE, SIG_IGN); + + // We use SIGTRAP sometimes for debugging + signal(SIGTRAP, SIG_IGN); + + // Dump intermediate stats + signal(SIGUSR1, dumpStatsHandler); + + // Dump intermediate stats and reset them + signal(SIGUSR2, dumprstStatsHandler); + + // Exit cleanly on Interrupt (Ctrl-C) + signal(SIGINT, exitNowHandler); + + // Print out cycle number on abort + signal(SIGABRT, abortHandler); +} + +/* + * Uncompress and unmarshal the code object stored in the + * EmbeddedPyModule + */ +PyObject * +getCode(const EmbeddedPyModule *pymod) +{ + assert(pymod->zlen == pymod->code_end - pymod->code); + Bytef *marshalled = new Bytef[pymod->mlen]; + uLongf unzlen = pymod->mlen; + int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code, + pymod->zlen); + if (ret != Z_OK) + panic("Could not uncompress code: %s\n", zError(ret)); + assert(unzlen == pymod->mlen); + + return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen); +} + +// The python library is totally messed up with respect to constness, +// so make a simple macro to make life a little easier +#define PyCC(x) (const_cast<char *>(x)) + +/* + * Load and initialize all of the python parts of M5, including Swig + * and the embedded module importer. + */ +int +initM5Python() +{ + extern void initSwig(); + + // initialize SWIG modules. initSwig() is autogenerated and calls + // all of the individual swig initialization functions. + initSwig(); + + // Load the importer module + PyObject *code = getCode(&embeddedPyImporter); + PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code); + if (!module) { + PyErr_Print(); + return 1; + } + + // Load the rest of the embedded python files into the embedded + // python importer + const EmbeddedPyModule *pymod = &embeddedPyModules[0]; + while (pymod->filename) { + PyObject *code = getCode(pymod); + PyObject *result = PyObject_CallMethod(module, PyCC("add_module"), + PyCC("ssO"), pymod->filename, pymod->modpath, code); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + ++pymod; + } + + return 0; +} + +/* + * Start up the M5 simulator. This mostly vectors into the python + * main function. + */ +int +m5Main(int argc, char **argv) +{ + PySys_SetArgv(argc, argv); + + // We have to set things up in the special __main__ module + PyObject *module = PyImport_AddModule(PyCC("__main__")); + if (module == NULL) + panic("Could not import __main__"); + PyObject *dict = PyModule_GetDict(module); + + // import the main m5 module + PyObject *result; + result = PyRun_String("import m5", Py_file_input, dict, dict); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + + // Start m5 + result = PyRun_String("m5.main()", Py_file_input, dict, dict); + if (!result) { + PyErr_Print(); + return 1; + } + Py_DECREF(result); + + return 0; +} diff --git a/src/sim/init.hh b/src/sim/init.hh new file mode 100644 index 000000000..b0f29bf30 --- /dev/null +++ b/src/sim/init.hh @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Nathan Binkert + */ + +#ifndef __SIM_INIT_HH__ +#define __SIM_INIT_HH__ + +/* + * Data structure describing an embedded python file. + */ +struct EmbeddedPyModule +{ + const char *filename; + const char *modpath; + const char *code; + const char *code_end; + int zlen; + int mlen; +}; + +extern const EmbeddedPyModule embeddedPyImporter; +extern const EmbeddedPyModule embeddedPyModules[]; + +void initSignals(); +int initM5Python(); +int m5Main(int argc, char **argv); + +#endif // __SIM_INIT_HH__ diff --git a/src/sim/main.cc b/src/sim/main.cc index baca556a0..d674e0cff 100644 --- a/src/sim/main.cc +++ b/src/sim/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,125 +29,33 @@ */ #include <Python.h> -#include <signal.h> -#include <iostream> -#include <string> - -#include "base/cprintf.hh" -#include "base/misc.hh" -#include "config/pythonhome.hh" -#include "python/swig/init.hh" -#include "sim/async.hh" -#include "sim/host.hh" -#include "sim/core.hh" - -using namespace std; - -/// Stats signal handler. -void -dumpStatsHandler(int sigtype) -{ - async_event = true; - async_statdump = true; -} - -void -dumprstStatsHandler(int sigtype) -{ - async_event = true; - async_statdump = true; - async_statreset = true; -} - -/// Exit signal handler. -void -exitNowHandler(int sigtype) -{ - async_event = true; - async_exit = true; -} - -/// Abort signal handler. -void -abortHandler(int sigtype) -{ - ccprintf(cerr, "Program aborted at cycle %d\n", curTick); -} - -int -python_main() -{ - PyObject *module; - PyObject *dict; - PyObject *result; - - module = PyImport_AddModule(const_cast<char*>("__main__")); - if (module == NULL) - fatal("Could not import __main__"); - - dict = PyModule_GetDict(module); - - result = PyRun_String("import m5.main", Py_file_input, dict, dict); - if (!result) { - PyErr_Print(); - return 1; - } - Py_DECREF(result); - - result = PyRun_String("m5.main.main()", Py_file_input, dict, dict); - if (!result) { - PyErr_Print(); - return 1; - } - Py_DECREF(result); - - if (Py_FlushLine()) - PyErr_Clear(); - - return 0; -} +#include "sim/init.hh" +// main() is now pretty stripped down and just sets up python and then +// calls initM5Python which loads the various embedded python modules +// into the python environment and then starts things running by +// calling m5Main. int main(int argc, char **argv) { - signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths - signal(SIGTRAP, SIG_IGN); - signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats - signal(SIGUSR2, dumprstStatsHandler); // dump and reset stats - signal(SIGINT, exitNowHandler); // dump final stats and exit - signal(SIGABRT, abortHandler); - - Py_SetProgramName(argv[0]); - - // default path to m5 python code is the currently executing - // file... Python ZipImporter will find embedded zip archive. - // The M5_ARCHIVE environment variable can be used to override this. - char *m5_archive = getenv("M5_ARCHIVE"); - string pythonpath = m5_archive ? m5_archive : argv[0]; + int ret; - char *oldpath = getenv("PYTHONPATH"); - if (oldpath != NULL) { - pythonpath += ":"; - pythonpath += oldpath; - } - - if (setenv("PYTHONPATH", pythonpath.c_str(), true) == -1) - fatal("setenv: %s\n", strerror(errno)); + // Initialize m5 special signal handling. + initSignals(); - const char *python_home = getenv("PYTHONHOME"); - if (!python_home) - python_home = PYTHONHOME; - Py_SetPythonHome(const_cast<char*>(python_home)); + Py_SetProgramName(argv[0]); // initialize embedded Python interpreter Py_Initialize(); - PySys_SetArgv(argc, argv); - // initialize SWIG modules - init_swig(); + // Initialize the embedded m5 python library + ret = initM5Python(); - int ret = python_main(); + if (ret == 0) { + // start m5 + ret = m5Main(argc, argv); + } // clean up Python intepreter. Py_Finalize(); |