init.cc revision 6227:a17798f2a52c
12SN/A/*
21762SN/A * Copyright (c) 2000-2005 The Regents of The University of Michigan
32SN/A * Copyright (c) 2008 The Hewlett-Packard Development Company
42SN/A * All rights reserved.
52SN/A *
62SN/A * Redistribution and use in source and binary forms, with or without
72SN/A * modification, are permitted provided that the following conditions are
82SN/A * met: redistributions of source code must retain the above copyright
92SN/A * notice, this list of conditions and the following disclaimer;
102SN/A * redistributions in binary form must reproduce the above copyright
112SN/A * notice, this list of conditions and the following disclaimer in the
122SN/A * documentation and/or other materials provided with the distribution;
132SN/A * neither the name of the copyright holders nor the names of its
142SN/A * contributors may be used to endorse or promote products derived from
152SN/A * this software without specific prior written permission.
162SN/A *
172SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272665SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665SN/A *
292SN/A * Authors: Nathan Binkert
302SN/A */
312SN/A
322SN/A#include <Python.h>
336214Snate@binkert.org#include <marshal.h>
342SN/A#include <signal.h>
352SN/A
362SN/A#include <iostream>
376214Snate@binkert.org#include <string>
386214Snate@binkert.org#include <zlib.h>
392SN/A
402SN/A#include "base/cprintf.hh"
412SN/A#include "base/misc.hh"
429180Sandreas.hansson@arm.com#include "base/types.hh"
439180Sandreas.hansson@arm.com#include "sim/async.hh"
442SN/A#include "sim/core.hh"
455543SN/A#include "sim/init.hh"
462SN/A
475543SN/Ausing namespace std;
482SN/A
492SN/A/// Stats signal handler.
502SN/Avoid
512SN/AdumpStatsHandler(int sigtype)
522SN/A{
532SN/A    async_event = true;
542SN/A    async_statdump = true;
552SN/A}
569158Sandreas.hansson@arm.com
572SN/Avoid
589158Sandreas.hansson@arm.comdumprstStatsHandler(int sigtype)
592SN/A{
609158Sandreas.hansson@arm.com    async_event = true;
612667SN/A    async_statdump = true;
622130SN/A    async_statreset = true;
639180Sandreas.hansson@arm.com}
649180Sandreas.hansson@arm.com
659180Sandreas.hansson@arm.com/// Exit signal handler.
669180Sandreas.hansson@arm.comvoid
679180Sandreas.hansson@arm.comexitNowHandler(int sigtype)
689180Sandreas.hansson@arm.com{
699180Sandreas.hansson@arm.com    async_event = true;
709180Sandreas.hansson@arm.com    async_exit = true;
719180Sandreas.hansson@arm.com}
729180Sandreas.hansson@arm.com
739180Sandreas.hansson@arm.com/// Abort signal handler.
749180Sandreas.hansson@arm.comvoid
759180Sandreas.hansson@arm.comabortHandler(int sigtype)
769180Sandreas.hansson@arm.com{
779180Sandreas.hansson@arm.com    ccprintf(cerr, "Program aborted at cycle %d\n", curTick);
789180Sandreas.hansson@arm.com}
799180Sandreas.hansson@arm.com
809180Sandreas.hansson@arm.com/*
819180Sandreas.hansson@arm.com * M5 can do several special things when various signals are sent.
829180Sandreas.hansson@arm.com * None are mandatory.
839180Sandreas.hansson@arm.com */
849180Sandreas.hansson@arm.comvoid
859180Sandreas.hansson@arm.cominitSignals()
869180Sandreas.hansson@arm.com{
879180Sandreas.hansson@arm.com    // Floating point exceptions may happen on misspeculated paths, so
889180Sandreas.hansson@arm.com    // ignore them
899180Sandreas.hansson@arm.com    signal(SIGFPE, SIG_IGN);
909180Sandreas.hansson@arm.com
919180Sandreas.hansson@arm.com    // We use SIGTRAP sometimes for debugging
929184Sandreas.hansson@arm.com    signal(SIGTRAP, SIG_IGN);
939184Sandreas.hansson@arm.com
949184Sandreas.hansson@arm.com    // Dump intermediate stats
959180Sandreas.hansson@arm.com    signal(SIGUSR1, dumpStatsHandler);
969180Sandreas.hansson@arm.com
979180Sandreas.hansson@arm.com    // Dump intermediate stats and reset them
989180Sandreas.hansson@arm.com    signal(SIGUSR2, dumprstStatsHandler);
999180Sandreas.hansson@arm.com
1009180Sandreas.hansson@arm.com    // Exit cleanly on Interrupt (Ctrl-C)
1019180Sandreas.hansson@arm.com    signal(SIGINT, exitNowHandler);
1029180Sandreas.hansson@arm.com
1039180Sandreas.hansson@arm.com    // Print out cycle number on abort
1049180Sandreas.hansson@arm.com    signal(SIGABRT, abortHandler);
1059180Sandreas.hansson@arm.com}
1069180Sandreas.hansson@arm.com
1079180Sandreas.hansson@arm.com/*
1089180Sandreas.hansson@arm.com * Uncompress and unmarshal the code object stored in the
1099180Sandreas.hansson@arm.com * EmbeddedPyModule
1109180Sandreas.hansson@arm.com */
1119180Sandreas.hansson@arm.comPyObject *
1129180Sandreas.hansson@arm.comgetCode(const EmbeddedPyModule *pymod)
1139180Sandreas.hansson@arm.com{
1149180Sandreas.hansson@arm.com    assert(pymod->zlen == pymod->code_end - pymod->code);
1159180Sandreas.hansson@arm.com    Bytef *marshalled = new Bytef[pymod->mlen];
1169180Sandreas.hansson@arm.com    uLongf unzlen = pymod->mlen;
1179180Sandreas.hansson@arm.com    int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code,
1189180Sandreas.hansson@arm.com        pymod->zlen);
1199180Sandreas.hansson@arm.com    if (ret != Z_OK)
1209180Sandreas.hansson@arm.com        panic("Could not uncompress code: %s\n", zError(ret));
1212130SN/A    assert(unzlen == (uLongf)pymod->mlen);
1222130SN/A
1232130SN/A    return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen);
1242130SN/A}
1252130SN/A
1262130SN/A// The python library is totally messed up with respect to constness,
1272130SN/A// so make a simple macro to make life a little easier
1287720Sgblack@eecs.umich.edu#define PyCC(x) (const_cast<char *>(x))
1297720Sgblack@eecs.umich.edu
1307720Sgblack@eecs.umich.edu/*
1317720Sgblack@eecs.umich.edu * Load and initialize all of the python parts of M5, including Swig
1327720Sgblack@eecs.umich.edu * and the embedded module importer.
1337720Sgblack@eecs.umich.edu */
1347720Sgblack@eecs.umich.eduint
1357720Sgblack@eecs.umich.eduinitM5Python()
1367720Sgblack@eecs.umich.edu{
1377720Sgblack@eecs.umich.edu    extern void initSwig();
1387720Sgblack@eecs.umich.edu
1397720Sgblack@eecs.umich.edu    // initialize SWIG modules.  initSwig() is autogenerated and calls
1407720Sgblack@eecs.umich.edu    // all of the individual swig initialization functions.
1417720Sgblack@eecs.umich.edu    initSwig();
1427720Sgblack@eecs.umich.edu
1437720Sgblack@eecs.umich.edu    // Load the importer module
1447720Sgblack@eecs.umich.edu    PyObject *code = getCode(&embeddedPyImporter);
1457720Sgblack@eecs.umich.edu    PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code);
1467720Sgblack@eecs.umich.edu    if (!module) {
1477720Sgblack@eecs.umich.edu        PyErr_Print();
1487720Sgblack@eecs.umich.edu        return 1;
1497720Sgblack@eecs.umich.edu    }
1502438SN/A
1512438SN/A    // Load the rest of the embedded python files into the embedded
1526221Snate@binkert.org    // python importer
1536221Snate@binkert.org    const EmbeddedPyModule *pymod = &embeddedPyModules[0];
1546221Snate@binkert.org    while (pymod->filename) {
1556221Snate@binkert.org        PyObject *code = getCode(pymod);
1566221Snate@binkert.org        PyObject *result = PyObject_CallMethod(module, PyCC("add_module"),
1576221Snate@binkert.org            PyCC("ssO"), pymod->filename, pymod->modpath, code);
1589031Sandreas.hansson@arm.com        if (!result) {
1599031Sandreas.hansson@arm.com            PyErr_Print();
1609031Sandreas.hansson@arm.com            return 1;
1619031Sandreas.hansson@arm.com        }
1629031Sandreas.hansson@arm.com        Py_DECREF(result);
1639031Sandreas.hansson@arm.com        ++pymod;
1647678Sgblack@eecs.umich.edu    }
1657678Sgblack@eecs.umich.edu
1667678Sgblack@eecs.umich.edu    return 0;
1677678Sgblack@eecs.umich.edu}
1686214Snate@binkert.org
169/*
170 * Start up the M5 simulator.  This mostly vectors into the python
171 * main function.
172 */
173int
174m5Main(int argc, char **argv)
175{
176    PySys_SetArgv(argc, argv);
177
178    // We have to set things up in the special __main__ module
179    PyObject *module = PyImport_AddModule(PyCC("__main__"));
180    if (module == NULL)
181        panic("Could not import __main__");
182    PyObject *dict = PyModule_GetDict(module);
183
184    // import the main m5 module
185    PyObject *result;
186    result = PyRun_String("import m5", Py_file_input, dict, dict);
187    if (!result) {
188        PyErr_Print();
189        return 1;
190    }
191    Py_DECREF(result);
192
193    // Start m5
194    result = PyRun_String("m5.main()", Py_file_input, dict, dict);
195    if (!result) {
196        PyErr_Print();
197        return 1;
198    }
199    Py_DECREF(result);
200
201    return 0;
202}
203
204PyMODINIT_FUNC
205initm5(void)
206{
207    initM5Python();
208    PyImport_ImportModule(PyCC("m5"));
209}
210