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