summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/SConscript3
-rw-r--r--src/sim/init.cc202
-rw-r--r--src/sim/init.hh54
-rw-r--r--src/sim/main.cc124
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();