init.cc revision 5522
15522Snate@binkert.org/* 25522Snate@binkert.org * Copyright (c) 2000-2005 The Regents of The University of Michigan 35522Snate@binkert.org * Copyright (c) 2008 The Hewlett-Packard Development Company 45522Snate@binkert.org * All rights reserved. 55522Snate@binkert.org * 65522Snate@binkert.org * Redistribution and use in source and binary forms, with or without 75522Snate@binkert.org * modification, are permitted provided that the following conditions are 85522Snate@binkert.org * met: redistributions of source code must retain the above copyright 95522Snate@binkert.org * notice, this list of conditions and the following disclaimer; 105522Snate@binkert.org * redistributions in binary form must reproduce the above copyright 115522Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 125522Snate@binkert.org * documentation and/or other materials provided with the distribution; 135522Snate@binkert.org * neither the name of the copyright holders nor the names of its 145522Snate@binkert.org * contributors may be used to endorse or promote products derived from 155522Snate@binkert.org * this software without specific prior written permission. 165522Snate@binkert.org * 175522Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 185522Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 195522Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 205522Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 215522Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 225522Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 235522Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 245522Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 255522Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 265522Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 275522Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 285522Snate@binkert.org * 295522Snate@binkert.org * Authors: Nathan Binkert 305522Snate@binkert.org */ 315522Snate@binkert.org 325522Snate@binkert.org#include <Python.h> 335522Snate@binkert.org#include <marshal.h> 345522Snate@binkert.org#include <signal.h> 355522Snate@binkert.org 365522Snate@binkert.org#include <iostream> 375522Snate@binkert.org#include <string> 385522Snate@binkert.org#include <zlib.h> 395522Snate@binkert.org 405522Snate@binkert.org#include "base/cprintf.hh" 415522Snate@binkert.org#include "base/misc.hh" 425522Snate@binkert.org#include "sim/async.hh" 435522Snate@binkert.org#include "sim/core.hh" 445522Snate@binkert.org#include "sim/host.hh" 455522Snate@binkert.org#include "sim/init.hh" 465522Snate@binkert.org 475522Snate@binkert.orgusing namespace std; 485522Snate@binkert.org 495522Snate@binkert.org/// Stats signal handler. 505522Snate@binkert.orgvoid 515522Snate@binkert.orgdumpStatsHandler(int sigtype) 525522Snate@binkert.org{ 535522Snate@binkert.org async_event = true; 545522Snate@binkert.org async_statdump = true; 555522Snate@binkert.org} 565522Snate@binkert.org 575522Snate@binkert.orgvoid 585522Snate@binkert.orgdumprstStatsHandler(int sigtype) 595522Snate@binkert.org{ 605522Snate@binkert.org async_event = true; 615522Snate@binkert.org async_statdump = true; 625522Snate@binkert.org async_statreset = true; 635522Snate@binkert.org} 645522Snate@binkert.org 655522Snate@binkert.org/// Exit signal handler. 665522Snate@binkert.orgvoid 675522Snate@binkert.orgexitNowHandler(int sigtype) 685522Snate@binkert.org{ 695522Snate@binkert.org async_event = true; 705522Snate@binkert.org async_exit = true; 715522Snate@binkert.org} 725522Snate@binkert.org 735522Snate@binkert.org/// Abort signal handler. 745522Snate@binkert.orgvoid 755522Snate@binkert.orgabortHandler(int sigtype) 765522Snate@binkert.org{ 775522Snate@binkert.org ccprintf(cerr, "Program aborted at cycle %d\n", curTick); 785522Snate@binkert.org} 795522Snate@binkert.org 805522Snate@binkert.org/* 815522Snate@binkert.org * M5 can do several special things when various signals are sent. 825522Snate@binkert.org * None are mandatory. 835522Snate@binkert.org */ 845522Snate@binkert.orgvoid 855522Snate@binkert.orginitSignals() 865522Snate@binkert.org{ 875522Snate@binkert.org // Floating point exceptions may happen on misspeculated paths, so 885522Snate@binkert.org // ignore them 895522Snate@binkert.org signal(SIGFPE, SIG_IGN); 905522Snate@binkert.org 915522Snate@binkert.org // We use SIGTRAP sometimes for debugging 925522Snate@binkert.org signal(SIGTRAP, SIG_IGN); 935522Snate@binkert.org 945522Snate@binkert.org // Dump intermediate stats 955522Snate@binkert.org signal(SIGUSR1, dumpStatsHandler); 965522Snate@binkert.org 975522Snate@binkert.org // Dump intermediate stats and reset them 985522Snate@binkert.org signal(SIGUSR2, dumprstStatsHandler); 995522Snate@binkert.org 1005522Snate@binkert.org // Exit cleanly on Interrupt (Ctrl-C) 1015522Snate@binkert.org signal(SIGINT, exitNowHandler); 1025522Snate@binkert.org 1035522Snate@binkert.org // Print out cycle number on abort 1045522Snate@binkert.org signal(SIGABRT, abortHandler); 1055522Snate@binkert.org} 1065522Snate@binkert.org 1075522Snate@binkert.org/* 1085522Snate@binkert.org * Uncompress and unmarshal the code object stored in the 1095522Snate@binkert.org * EmbeddedPyModule 1105522Snate@binkert.org */ 1115522Snate@binkert.orgPyObject * 1125522Snate@binkert.orggetCode(const EmbeddedPyModule *pymod) 1135522Snate@binkert.org{ 1145522Snate@binkert.org assert(pymod->zlen == pymod->code_end - pymod->code); 1155522Snate@binkert.org Bytef *marshalled = new Bytef[pymod->mlen]; 1165522Snate@binkert.org uLongf unzlen = pymod->mlen; 1175522Snate@binkert.org int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code, 1185522Snate@binkert.org pymod->zlen); 1195522Snate@binkert.org if (ret != Z_OK) 1205522Snate@binkert.org panic("Could not uncompress code: %s\n", zError(ret)); 1215522Snate@binkert.org assert(unzlen == pymod->mlen); 1225522Snate@binkert.org 1235522Snate@binkert.org return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen); 1245522Snate@binkert.org} 1255522Snate@binkert.org 1265522Snate@binkert.org// The python library is totally messed up with respect to constness, 1275522Snate@binkert.org// so make a simple macro to make life a little easier 1285522Snate@binkert.org#define PyCC(x) (const_cast<char *>(x)) 1295522Snate@binkert.org 1305522Snate@binkert.org/* 1315522Snate@binkert.org * Load and initialize all of the python parts of M5, including Swig 1325522Snate@binkert.org * and the embedded module importer. 1335522Snate@binkert.org */ 1345522Snate@binkert.orgint 1355522Snate@binkert.orginitM5Python() 1365522Snate@binkert.org{ 1375522Snate@binkert.org extern void initSwig(); 1385522Snate@binkert.org 1395522Snate@binkert.org // initialize SWIG modules. initSwig() is autogenerated and calls 1405522Snate@binkert.org // all of the individual swig initialization functions. 1415522Snate@binkert.org initSwig(); 1425522Snate@binkert.org 1435522Snate@binkert.org // Load the importer module 1445522Snate@binkert.org PyObject *code = getCode(&embeddedPyImporter); 1455522Snate@binkert.org PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code); 1465522Snate@binkert.org if (!module) { 1475522Snate@binkert.org PyErr_Print(); 1485522Snate@binkert.org return 1; 1495522Snate@binkert.org } 1505522Snate@binkert.org 1515522Snate@binkert.org // Load the rest of the embedded python files into the embedded 1525522Snate@binkert.org // python importer 1535522Snate@binkert.org const EmbeddedPyModule *pymod = &embeddedPyModules[0]; 1545522Snate@binkert.org while (pymod->filename) { 1555522Snate@binkert.org PyObject *code = getCode(pymod); 1565522Snate@binkert.org PyObject *result = PyObject_CallMethod(module, PyCC("add_module"), 1575522Snate@binkert.org PyCC("ssO"), pymod->filename, pymod->modpath, code); 1585522Snate@binkert.org if (!result) { 1595522Snate@binkert.org PyErr_Print(); 1605522Snate@binkert.org return 1; 1615522Snate@binkert.org } 1625522Snate@binkert.org Py_DECREF(result); 1635522Snate@binkert.org ++pymod; 1645522Snate@binkert.org } 1655522Snate@binkert.org 1665522Snate@binkert.org return 0; 1675522Snate@binkert.org} 1685522Snate@binkert.org 1695522Snate@binkert.org/* 1705522Snate@binkert.org * Start up the M5 simulator. This mostly vectors into the python 1715522Snate@binkert.org * main function. 1725522Snate@binkert.org */ 1735522Snate@binkert.orgint 1745522Snate@binkert.orgm5Main(int argc, char **argv) 1755522Snate@binkert.org{ 1765522Snate@binkert.org PySys_SetArgv(argc, argv); 1775522Snate@binkert.org 1785522Snate@binkert.org // We have to set things up in the special __main__ module 1795522Snate@binkert.org PyObject *module = PyImport_AddModule(PyCC("__main__")); 1805522Snate@binkert.org if (module == NULL) 1815522Snate@binkert.org panic("Could not import __main__"); 1825522Snate@binkert.org PyObject *dict = PyModule_GetDict(module); 1835522Snate@binkert.org 1845522Snate@binkert.org // import the main m5 module 1855522Snate@binkert.org PyObject *result; 1865522Snate@binkert.org result = PyRun_String("import m5", Py_file_input, dict, dict); 1875522Snate@binkert.org if (!result) { 1885522Snate@binkert.org PyErr_Print(); 1895522Snate@binkert.org return 1; 1905522Snate@binkert.org } 1915522Snate@binkert.org Py_DECREF(result); 1925522Snate@binkert.org 1935522Snate@binkert.org // Start m5 1945522Snate@binkert.org result = PyRun_String("m5.main()", Py_file_input, dict, dict); 1955522Snate@binkert.org if (!result) { 1965522Snate@binkert.org PyErr_Print(); 1975522Snate@binkert.org return 1; 1985522Snate@binkert.org } 1995522Snate@binkert.org Py_DECREF(result); 2005522Snate@binkert.org 2015522Snate@binkert.org return 0; 2025522Snate@binkert.org} 203