init.cc revision 5522
16145Snate@binkert.org/*
26145Snate@binkert.org * Copyright (c) 2000-2005 The Regents of The University of Michigan
36145Snate@binkert.org * Copyright (c) 2008 The Hewlett-Packard Development Company
46145Snate@binkert.org * All rights reserved.
56145Snate@binkert.org *
66145Snate@binkert.org * Redistribution and use in source and binary forms, with or without
76145Snate@binkert.org * modification, are permitted provided that the following conditions are
86145Snate@binkert.org * met: redistributions of source code must retain the above copyright
96145Snate@binkert.org * notice, this list of conditions and the following disclaimer;
106145Snate@binkert.org * redistributions in binary form must reproduce the above copyright
116145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the
126145Snate@binkert.org * documentation and/or other materials provided with the distribution;
136145Snate@binkert.org * neither the name of the copyright holders nor the names of its
146145Snate@binkert.org * contributors may be used to endorse or promote products derived from
156145Snate@binkert.org * this software without specific prior written permission.
166145Snate@binkert.org *
176145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
186145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
196145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
206145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
216145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
226145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
236145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
246145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
256145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
266145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
276145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
286145Snate@binkert.org *
296145Snate@binkert.org * Authors: Nathan Binkert
306145Snate@binkert.org */
316145Snate@binkert.org
326145Snate@binkert.org#include <Python.h>
336145Snate@binkert.org#include <marshal.h>
346145Snate@binkert.org#include <signal.h>
356145Snate@binkert.org
366145Snate@binkert.org#include <iostream>
376145Snate@binkert.org#include <string>
386145Snate@binkert.org#include <zlib.h>
396145Snate@binkert.org
406145Snate@binkert.org#include "base/cprintf.hh"
416145Snate@binkert.org#include "base/misc.hh"
426145Snate@binkert.org#include "sim/async.hh"
436145Snate@binkert.org#include "sim/core.hh"
446145Snate@binkert.org#include "sim/host.hh"
456145Snate@binkert.org#include "sim/init.hh"
466145Snate@binkert.org
476145Snate@binkert.orgusing namespace std;
486145Snate@binkert.org
496145Snate@binkert.org/// Stats signal handler.
506145Snate@binkert.orgvoid
516145Snate@binkert.orgdumpStatsHandler(int sigtype)
526145Snate@binkert.org{
536145Snate@binkert.org    async_event = true;
546145Snate@binkert.org    async_statdump = true;
556145Snate@binkert.org}
566145Snate@binkert.org
576145Snate@binkert.orgvoid
586145Snate@binkert.orgdumprstStatsHandler(int sigtype)
596145Snate@binkert.org{
606145Snate@binkert.org    async_event = true;
616145Snate@binkert.org    async_statdump = true;
626145Snate@binkert.org    async_statreset = true;
636145Snate@binkert.org}
646145Snate@binkert.org
656145Snate@binkert.org/// Exit signal handler.
666145Snate@binkert.orgvoid
676145Snate@binkert.orgexitNowHandler(int sigtype)
686145Snate@binkert.org{
696145Snate@binkert.org    async_event = true;
706145Snate@binkert.org    async_exit = true;
716145Snate@binkert.org}
726145Snate@binkert.org
736145Snate@binkert.org/// Abort signal handler.
746145Snate@binkert.orgvoid
756145Snate@binkert.orgabortHandler(int sigtype)
766145Snate@binkert.org{
776145Snate@binkert.org    ccprintf(cerr, "Program aborted at cycle %d\n", curTick);
786145Snate@binkert.org}
796145Snate@binkert.org
806145Snate@binkert.org/*
816145Snate@binkert.org * M5 can do several special things when various signals are sent.
826145Snate@binkert.org * None are mandatory.
836145Snate@binkert.org */
846145Snate@binkert.orgvoid
856145Snate@binkert.orginitSignals()
866145Snate@binkert.org{
876145Snate@binkert.org    // Floating point exceptions may happen on misspeculated paths, so
886145Snate@binkert.org    // ignore them
896145Snate@binkert.org    signal(SIGFPE, SIG_IGN);
906145Snate@binkert.org
916145Snate@binkert.org    // We use SIGTRAP sometimes for debugging
926145Snate@binkert.org    signal(SIGTRAP, SIG_IGN);
936145Snate@binkert.org
946145Snate@binkert.org    // Dump intermediate stats
956145Snate@binkert.org    signal(SIGUSR1, dumpStatsHandler);
966145Snate@binkert.org
976145Snate@binkert.org    // Dump intermediate stats and reset them
986145Snate@binkert.org    signal(SIGUSR2, dumprstStatsHandler);
996145Snate@binkert.org
1006145Snate@binkert.org    // Exit cleanly on Interrupt (Ctrl-C)
1016145Snate@binkert.org    signal(SIGINT, exitNowHandler);
1026145Snate@binkert.org
1036145Snate@binkert.org    // Print out cycle number on abort
1046145Snate@binkert.org    signal(SIGABRT, abortHandler);
1056145Snate@binkert.org}
1066145Snate@binkert.org
1076145Snate@binkert.org/*
1086145Snate@binkert.org * Uncompress and unmarshal the code object stored in the
1096145Snate@binkert.org * EmbeddedPyModule
1106145Snate@binkert.org */
1116145Snate@binkert.orgPyObject *
1126145Snate@binkert.orggetCode(const EmbeddedPyModule *pymod)
1136145Snate@binkert.org{
1146145Snate@binkert.org    assert(pymod->zlen == pymod->code_end - pymod->code);
1156145Snate@binkert.org    Bytef *marshalled = new Bytef[pymod->mlen];
1166145Snate@binkert.org    uLongf unzlen = pymod->mlen;
1176145Snate@binkert.org    int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code,
1186145Snate@binkert.org        pymod->zlen);
1196145Snate@binkert.org    if (ret != Z_OK)
1206145Snate@binkert.org        panic("Could not uncompress code: %s\n", zError(ret));
1216145Snate@binkert.org    assert(unzlen == pymod->mlen);
1226145Snate@binkert.org
1236145Snate@binkert.org    return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen);
1246145Snate@binkert.org}
1256145Snate@binkert.org
1266145Snate@binkert.org// The python library is totally messed up with respect to constness,
1276145Snate@binkert.org// so make a simple macro to make life a little easier
1286145Snate@binkert.org#define PyCC(x) (const_cast<char *>(x))
1296145Snate@binkert.org
1306145Snate@binkert.org/*
1316145Snate@binkert.org * Load and initialize all of the python parts of M5, including Swig
1326145Snate@binkert.org * and the embedded module importer.
1336145Snate@binkert.org */
1346145Snate@binkert.orgint
1356145Snate@binkert.orginitM5Python()
1366145Snate@binkert.org{
1376145Snate@binkert.org    extern void initSwig();
1386145Snate@binkert.org
1396145Snate@binkert.org    // initialize SWIG modules.  initSwig() is autogenerated and calls
1406145Snate@binkert.org    // all of the individual swig initialization functions.
1416145Snate@binkert.org    initSwig();
1426145Snate@binkert.org
1436145Snate@binkert.org    // Load the importer module
1446145Snate@binkert.org    PyObject *code = getCode(&embeddedPyImporter);
1456145Snate@binkert.org    PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code);
1466145Snate@binkert.org    if (!module) {
1476145Snate@binkert.org        PyErr_Print();
1486145Snate@binkert.org        return 1;
1496145Snate@binkert.org    }
1506145Snate@binkert.org
1516145Snate@binkert.org    // Load the rest of the embedded python files into the embedded
1526145Snate@binkert.org    // python importer
1536145Snate@binkert.org    const EmbeddedPyModule *pymod = &embeddedPyModules[0];
1546145Snate@binkert.org    while (pymod->filename) {
1556145Snate@binkert.org        PyObject *code = getCode(pymod);
1566145Snate@binkert.org        PyObject *result = PyObject_CallMethod(module, PyCC("add_module"),
1576145Snate@binkert.org            PyCC("ssO"), pymod->filename, pymod->modpath, code);
1586145Snate@binkert.org        if (!result) {
1596145Snate@binkert.org            PyErr_Print();
1606145Snate@binkert.org            return 1;
1616145Snate@binkert.org        }
1626145Snate@binkert.org        Py_DECREF(result);
1636145Snate@binkert.org        ++pymod;
1646145Snate@binkert.org    }
1656145Snate@binkert.org
1666145Snate@binkert.org    return 0;
1676145Snate@binkert.org}
1686145Snate@binkert.org
1696145Snate@binkert.org/*
1706145Snate@binkert.org * Start up the M5 simulator.  This mostly vectors into the python
1716145Snate@binkert.org * main function.
1726145Snate@binkert.org */
1736145Snate@binkert.orgint
1746145Snate@binkert.orgm5Main(int argc, char **argv)
1756145Snate@binkert.org{
1766145Snate@binkert.org    PySys_SetArgv(argc, argv);
1776145Snate@binkert.org
1786145Snate@binkert.org    // We have to set things up in the special __main__ module
1796145Snate@binkert.org    PyObject *module = PyImport_AddModule(PyCC("__main__"));
1806145Snate@binkert.org    if (module == NULL)
1816145Snate@binkert.org        panic("Could not import __main__");
1826145Snate@binkert.org    PyObject *dict = PyModule_GetDict(module);
1836145Snate@binkert.org
1846145Snate@binkert.org    // import the main m5 module
1856145Snate@binkert.org    PyObject *result;
1866145Snate@binkert.org    result = PyRun_String("import m5", Py_file_input, dict, dict);
1876145Snate@binkert.org    if (!result) {
1886145Snate@binkert.org        PyErr_Print();
1896145Snate@binkert.org        return 1;
1906145Snate@binkert.org    }
1916145Snate@binkert.org    Py_DECREF(result);
1926145Snate@binkert.org
1936145Snate@binkert.org    // Start m5
1946145Snate@binkert.org    result = PyRun_String("m5.main()", Py_file_input, dict, dict);
1956145Snate@binkert.org    if (!result) {
1966145Snate@binkert.org        PyErr_Print();
1976145Snate@binkert.org        return 1;
1986145Snate@binkert.org    }
1996145Snate@binkert.org    Py_DECREF(result);
2006145Snate@binkert.org
2016145Snate@binkert.org    return 0;
2026145Snate@binkert.org}
2036145Snate@binkert.org