2 * Copyright (c) 2000-2005 The Regents of The University of Michigan
3 * Copyright (c) 2008 The Hewlett-Packard Development Company
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Authors: Nathan Binkert
42 #include "base/cprintf.hh"
43 #include "base/misc.hh"
44 #include "base/types.hh"
45 #include "sim/async.hh"
46 #include "sim/core.hh"
47 #include "sim/init.hh"
51 /// Stats signal handler.
53 dumpStatsHandler(int sigtype
)
56 async_statdump
= true;
60 dumprstStatsHandler(int sigtype
)
63 async_statdump
= true;
64 async_statreset
= true;
67 /// Exit signal handler.
69 exitNowHandler(int sigtype
)
75 /// Abort signal handler.
77 abortHandler(int sigtype
)
79 ccprintf(cerr
, "Program aborted at cycle %d\n", curTick());
83 * M5 can do several special things when various signals are sent.
89 // Floating point exceptions may happen on misspeculated paths, so
91 signal(SIGFPE
, SIG_IGN
);
93 // We use SIGTRAP sometimes for debugging
94 signal(SIGTRAP
, SIG_IGN
);
96 // Dump intermediate stats
97 signal(SIGUSR1
, dumpStatsHandler
);
99 // Dump intermediate stats and reset them
100 signal(SIGUSR2
, dumprstStatsHandler
);
102 // Exit cleanly on Interrupt (Ctrl-C)
103 signal(SIGINT
, exitNowHandler
);
105 // Print out cycle number on abort
106 signal(SIGABRT
, abortHandler
);
109 // The python library is totally messed up with respect to constness,
110 // so make a simple macro to make life a little easier
111 #define PyCC(x) (const_cast<char *>(x))
113 EmbeddedPython
*EmbeddedPython::importer
= NULL
;
114 PyObject
*EmbeddedPython::importerModule
= NULL
;
115 EmbeddedPython::EmbeddedPython(const char *filename
, const char *abspath
,
116 const char *modpath
, const char *code
, int zlen
, int len
)
117 : filename(filename
), abspath(abspath
), modpath(modpath
), code(code
),
120 // if we've added the importer keep track of it because we need it
122 if (string(modpath
) == string("importer"))
125 getList().push_back(this);
128 list
<EmbeddedPython
*> &
129 EmbeddedPython::getList()
131 static list
<EmbeddedPython
*> the_list
;
136 * Uncompress and unmarshal the code object stored in the
140 EmbeddedPython::getCode() const
142 Bytef marshalled
[len
];
144 int ret
= uncompress(marshalled
, &unzlen
, (const Bytef
*)code
, zlen
);
146 panic("Could not uncompress code: %s\n", zError(ret
));
147 assert(unzlen
== (uLongf
)len
);
149 return PyMarshal_ReadObjectFromString((char *)marshalled
, len
);
153 EmbeddedPython::addModule() const
155 PyObject
*code
= getCode();
156 PyObject
*result
= PyObject_CallMethod(importerModule
, PyCC("add_module"),
157 PyCC("sssO"), filename
, abspath
, modpath
, code
);
168 * Load and initialize all of the python parts of M5, including Swig
169 * and the embedded module importer.
172 EmbeddedPython::initAll()
174 // Load the importer module
175 PyObject
*code
= importer
->getCode();
176 importerModule
= PyImport_ExecCodeModule(PyCC("importer"), code
);
177 if (!importerModule
) {
182 // Load the rest of the embedded python files into the embedded
184 list
<EmbeddedPython
*>::iterator i
= getList().begin();
185 list
<EmbeddedPython
*>::iterator end
= getList().end();
186 for (; i
!= end
; ++i
)
187 if (!(*i
)->addModule())
193 EmbeddedSwig::EmbeddedSwig(void (*init_func
)())
194 : initFunc(init_func
)
196 getList().push_back(this);
199 list
<EmbeddedSwig
*> &
200 EmbeddedSwig::getList()
202 static list
<EmbeddedSwig
*> the_list
;
207 EmbeddedSwig::initAll()
209 // initialize SWIG modules. initSwig() is autogenerated and calls
210 // all of the individual swig initialization functions.
211 list
<EmbeddedSwig
*>::iterator i
= getList().begin();
212 list
<EmbeddedSwig
*>::iterator end
= getList().end();
213 for (; i
!= end
; ++i
)
220 EmbeddedSwig::initAll();
221 return EmbeddedPython::initAll();
225 * Make the commands array weak so that they can be overridden (used
226 * by unit tests to specify a different python main function.
228 const char * __attribute__((weak
)) m5MainCommands
[] = {
231 0 // sentinel is required
235 * Start up the M5 simulator. This mostly vectors into the python
239 m5Main(int argc
, char **argv
)
241 PySys_SetArgv(argc
, argv
);
243 // We have to set things up in the special __main__ module
244 PyObject
*module
= PyImport_AddModule(PyCC("__main__"));
246 panic("Could not import __main__");
247 PyObject
*dict
= PyModule_GetDict(module
);
249 // import the main m5 module
251 const char **command
= m5MainCommands
;
253 // evaluate each command in the m5MainCommands array (basically a
254 // bunch of python statements.
256 result
= PyRun_String(*command
, Py_file_input
, dict
, dict
);
273 PyImport_ImportModule(PyCC("m5"));