main.cc revision 1703
112027Sjungma@eit.uni-kl.de/* 212027Sjungma@eit.uni-kl.de * Copyright (c) 2000-2004 The Regents of The University of Michigan 312027Sjungma@eit.uni-kl.de * All rights reserved. 412027Sjungma@eit.uni-kl.de * 512027Sjungma@eit.uni-kl.de * Redistribution and use in source and binary forms, with or without 612027Sjungma@eit.uni-kl.de * modification, are permitted provided that the following conditions are 712027Sjungma@eit.uni-kl.de * met: redistributions of source code must retain the above copyright 812027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer; 912027Sjungma@eit.uni-kl.de * redistributions in binary form must reproduce the above copyright 1012027Sjungma@eit.uni-kl.de * notice, this list of conditions and the following disclaimer in the 1112027Sjungma@eit.uni-kl.de * documentation and/or other materials provided with the distribution; 1212027Sjungma@eit.uni-kl.de * neither the name of the copyright holders nor the names of its 1312027Sjungma@eit.uni-kl.de * contributors may be used to endorse or promote products derived from 1412027Sjungma@eit.uni-kl.de * this software without specific prior written permission. 1512027Sjungma@eit.uni-kl.de * 1612027Sjungma@eit.uni-kl.de * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712027Sjungma@eit.uni-kl.de * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812027Sjungma@eit.uni-kl.de * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912027Sjungma@eit.uni-kl.de * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012027Sjungma@eit.uni-kl.de * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112027Sjungma@eit.uni-kl.de * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212027Sjungma@eit.uni-kl.de * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312027Sjungma@eit.uni-kl.de * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412027Sjungma@eit.uni-kl.de * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512027Sjungma@eit.uni-kl.de * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612027Sjungma@eit.uni-kl.de * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712027Sjungma@eit.uni-kl.de */ 2812027Sjungma@eit.uni-kl.de 2912027Sjungma@eit.uni-kl.de/// 3012027Sjungma@eit.uni-kl.de/// @file sim/main.cc 3112027Sjungma@eit.uni-kl.de/// 3212027Sjungma@eit.uni-kl.de#include <sys/types.h> 3312027Sjungma@eit.uni-kl.de#include <sys/stat.h> 3412027Sjungma@eit.uni-kl.de#include <errno.h> 3512027Sjungma@eit.uni-kl.de#include <libgen.h> 3612027Sjungma@eit.uni-kl.de#include <stdlib.h> 3712027Sjungma@eit.uni-kl.de#include <signal.h> 3812027Sjungma@eit.uni-kl.de 3912027Sjungma@eit.uni-kl.de#include <list> 4012027Sjungma@eit.uni-kl.de#include <string> 4112027Sjungma@eit.uni-kl.de#include <vector> 4212027Sjungma@eit.uni-kl.de 4312027Sjungma@eit.uni-kl.de#include "base/copyright.hh" 4412027Sjungma@eit.uni-kl.de#include "base/embedfile.hh" 4512027Sjungma@eit.uni-kl.de#include "base/inifile.hh" 4612027Sjungma@eit.uni-kl.de#include "base/misc.hh" 4712027Sjungma@eit.uni-kl.de#include "base/output.hh" 4812027Sjungma@eit.uni-kl.de#include "base/pollevent.hh" 4912027Sjungma@eit.uni-kl.de#include "base/statistics.hh" 5012027Sjungma@eit.uni-kl.de#include "base/str.hh" 5112027Sjungma@eit.uni-kl.de#include "base/time.hh" 5212027Sjungma@eit.uni-kl.de#include "cpu/base_cpu.hh" 5312027Sjungma@eit.uni-kl.de#include "cpu/full_cpu/smt.hh" 5412027Sjungma@eit.uni-kl.de#include "python/pyconfig.hh" 5512027Sjungma@eit.uni-kl.de#include "sim/async.hh" 5612027Sjungma@eit.uni-kl.de#include "sim/builder.hh" 5712027Sjungma@eit.uni-kl.de#include "sim/configfile.hh" 5812027Sjungma@eit.uni-kl.de#include "sim/host.hh" 5912027Sjungma@eit.uni-kl.de#include "sim/sim_events.hh" 6012027Sjungma@eit.uni-kl.de#include "sim/sim_exit.hh" 6112027Sjungma@eit.uni-kl.de#include "sim/sim_object.hh" 6212027Sjungma@eit.uni-kl.de#include "sim/stat_control.hh" 6312027Sjungma@eit.uni-kl.de#include "sim/stats.hh" 6412027Sjungma@eit.uni-kl.de#include "sim/root.hh" 6512027Sjungma@eit.uni-kl.de 6612027Sjungma@eit.uni-kl.deusing namespace std; 6712027Sjungma@eit.uni-kl.de 6812027Sjungma@eit.uni-kl.de// See async.h. 6912027Sjungma@eit.uni-kl.devolatile bool async_event = false; 7012027Sjungma@eit.uni-kl.devolatile bool async_dump = false; 7112027Sjungma@eit.uni-kl.devolatile bool async_dumpreset = false; 7212027Sjungma@eit.uni-kl.devolatile bool async_exit = false; 7312027Sjungma@eit.uni-kl.devolatile bool async_io = false; 7412027Sjungma@eit.uni-kl.devolatile bool async_alarm = false; 7512027Sjungma@eit.uni-kl.de 7612027Sjungma@eit.uni-kl.de/// Stats signal handler. 7712027Sjungma@eit.uni-kl.devoid 7812027Sjungma@eit.uni-kl.dedumpStatsHandler(int sigtype) 7912027Sjungma@eit.uni-kl.de{ 8012027Sjungma@eit.uni-kl.de async_event = true; 8112027Sjungma@eit.uni-kl.de async_dump = true; 8212027Sjungma@eit.uni-kl.de} 8312027Sjungma@eit.uni-kl.de 8412027Sjungma@eit.uni-kl.devoid 8512027Sjungma@eit.uni-kl.dedumprstStatsHandler(int sigtype) 8612027Sjungma@eit.uni-kl.de{ 8712027Sjungma@eit.uni-kl.de async_event = true; 8812027Sjungma@eit.uni-kl.de async_dumpreset = true; 8912027Sjungma@eit.uni-kl.de} 9012027Sjungma@eit.uni-kl.de 9112027Sjungma@eit.uni-kl.de/// Exit signal handler. 9212027Sjungma@eit.uni-kl.devoid 9312027Sjungma@eit.uni-kl.deexitNowHandler(int sigtype) 9412027Sjungma@eit.uni-kl.de{ 9512027Sjungma@eit.uni-kl.de async_event = true; 9612027Sjungma@eit.uni-kl.de async_exit = true; 9712027Sjungma@eit.uni-kl.de} 9812027Sjungma@eit.uni-kl.de 9912027Sjungma@eit.uni-kl.de/// Abort signal handler. 10012027Sjungma@eit.uni-kl.devoid 10112027Sjungma@eit.uni-kl.deabortHandler(int sigtype) 10212027Sjungma@eit.uni-kl.de{ 10312027Sjungma@eit.uni-kl.de cerr << "Program aborted at cycle " << curTick << endl; 10412027Sjungma@eit.uni-kl.de 10512027Sjungma@eit.uni-kl.de#if TRACING_ON 10612027Sjungma@eit.uni-kl.de // dump trace buffer, if there is one 10712027Sjungma@eit.uni-kl.de Trace::theLog.dump(cerr); 10812027Sjungma@eit.uni-kl.de#endif 10912027Sjungma@eit.uni-kl.de} 11012027Sjungma@eit.uni-kl.de 11112027Sjungma@eit.uni-kl.de/// Simulator executable name 11212027Sjungma@eit.uni-kl.dechar *myProgName = ""; 11312027Sjungma@eit.uni-kl.de 11412027Sjungma@eit.uni-kl.de/// Show brief help message. 11512027Sjungma@eit.uni-kl.devoid 11612027Sjungma@eit.uni-kl.deshowBriefHelp(ostream &out) 11712027Sjungma@eit.uni-kl.de{ 11812027Sjungma@eit.uni-kl.de char *prog = basename(myProgName); 11912027Sjungma@eit.uni-kl.de 12012027Sjungma@eit.uni-kl.de ccprintf(out, "Usage:\n"); 12112027Sjungma@eit.uni-kl.de ccprintf(out, 12212027Sjungma@eit.uni-kl.de"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n" 12312027Sjungma@eit.uni-kl.de" [--<var>=<val>] <config file>\n" 12412027Sjungma@eit.uni-kl.de"\n" 12512027Sjungma@eit.uni-kl.de" -d set the output directory to <dir>\n" 12612027Sjungma@eit.uni-kl.de" -E set the environment variable <var> to <val> (or 'True')\n" 12712027Sjungma@eit.uni-kl.de" -I add the directory <dir> to python's path\n" 12812027Sjungma@eit.uni-kl.de" -P execute <python> directly in the configuration\n" 12912027Sjungma@eit.uni-kl.de" --var=val set the python variable <var> to '<val>'\n" 13012027Sjungma@eit.uni-kl.de" <configfile> config file name (ends in .py)\n\n", 13112027Sjungma@eit.uni-kl.de prog); 13212027Sjungma@eit.uni-kl.de 13312027Sjungma@eit.uni-kl.de ccprintf(out, "%s -X\n -X extract embedded files\n\n", prog); 13412027Sjungma@eit.uni-kl.de ccprintf(out, "%s -h\n -h print short help\n\n", prog); 13512027Sjungma@eit.uni-kl.de ccprintf(out, "%s -H\n -H print long help\n\n", prog); 13612027Sjungma@eit.uni-kl.de} 13712027Sjungma@eit.uni-kl.de 13812027Sjungma@eit.uni-kl.de/// Show verbose help message. Includes parameter listing from 13912027Sjungma@eit.uni-kl.de/// showBriefHelp(), plus an exhaustive list of ini-file parameters 14012027Sjungma@eit.uni-kl.de/// and SimObjects (with their parameters). 14112027Sjungma@eit.uni-kl.devoid 14212027Sjungma@eit.uni-kl.deshowLongHelp(ostream &out) 14312027Sjungma@eit.uni-kl.de{ 14412027Sjungma@eit.uni-kl.de showBriefHelp(out); 14512027Sjungma@eit.uni-kl.de 14612027Sjungma@eit.uni-kl.de out << endl 14712027Sjungma@eit.uni-kl.de << endl 14812027Sjungma@eit.uni-kl.de << "-----------------" << endl 14912027Sjungma@eit.uni-kl.de << "Global Parameters" << endl 15012027Sjungma@eit.uni-kl.de << "-----------------" << endl 15112027Sjungma@eit.uni-kl.de << endl; 15212027Sjungma@eit.uni-kl.de 15312027Sjungma@eit.uni-kl.de ParamContext::describeAllContexts(out); 15412027Sjungma@eit.uni-kl.de 15512027Sjungma@eit.uni-kl.de out << endl 15612027Sjungma@eit.uni-kl.de << endl 15712027Sjungma@eit.uni-kl.de << "-----------------" << endl 15812027Sjungma@eit.uni-kl.de << "Simulator Objects" << endl 15912027Sjungma@eit.uni-kl.de << "-----------------" << endl 16012027Sjungma@eit.uni-kl.de << endl; 16112027Sjungma@eit.uni-kl.de 16212027Sjungma@eit.uni-kl.de SimObjectClass::describeAllClasses(out); 16312027Sjungma@eit.uni-kl.de} 16412027Sjungma@eit.uni-kl.de 16512027Sjungma@eit.uni-kl.de/// Print welcome message. 16612027Sjungma@eit.uni-kl.devoid 16712027Sjungma@eit.uni-kl.desayHello(ostream &out) 16812027Sjungma@eit.uni-kl.de{ 16912027Sjungma@eit.uni-kl.de extern const char *compileDate; // from date.cc 17012027Sjungma@eit.uni-kl.de 17112027Sjungma@eit.uni-kl.de ccprintf(out, "M5 Simulator System\n"); 17212027Sjungma@eit.uni-kl.de // display copyright 17312027Sjungma@eit.uni-kl.de ccprintf(out, "%s\n", briefCopyright); 17412027Sjungma@eit.uni-kl.de ccprintf(out, "M5 compiled on %d\n", compileDate); 17512027Sjungma@eit.uni-kl.de 17612027Sjungma@eit.uni-kl.de char *host = getenv("HOSTNAME"); 17712027Sjungma@eit.uni-kl.de if (!host) 17812027Sjungma@eit.uni-kl.de host = getenv("HOST"); 17912027Sjungma@eit.uni-kl.de 18012027Sjungma@eit.uni-kl.de if (host) 18112027Sjungma@eit.uni-kl.de ccprintf(out, "M5 executing on %s\n", host); 18212027Sjungma@eit.uni-kl.de 18312027Sjungma@eit.uni-kl.de ccprintf(out, "M5 simulation started %s\n", Time::start); 18412027Sjungma@eit.uni-kl.de} 18512027Sjungma@eit.uni-kl.de 18612027Sjungma@eit.uni-kl.de/// 18712027Sjungma@eit.uni-kl.de/// Echo the command line for posterity in such a way that it can be 18812027Sjungma@eit.uni-kl.de/// used to rerun the same simulation (given the same .ini files). 18912027Sjungma@eit.uni-kl.de/// 19012027Sjungma@eit.uni-kl.devoid 19112027Sjungma@eit.uni-kl.deechoCommandLine(int argc, char **argv, ostream &out) 19212027Sjungma@eit.uni-kl.de{ 19312027Sjungma@eit.uni-kl.de out << "command line: " << argv[0]; 19412027Sjungma@eit.uni-kl.de for (int i = 1; i < argc; i++) { 19512027Sjungma@eit.uni-kl.de string arg(argv[i]); 19612027Sjungma@eit.uni-kl.de 19712027Sjungma@eit.uni-kl.de out << ' '; 19812027Sjungma@eit.uni-kl.de 19912027Sjungma@eit.uni-kl.de // If the arg contains spaces, we need to quote it. 20012027Sjungma@eit.uni-kl.de // The rest of this is overkill to make it look purty. 20112027Sjungma@eit.uni-kl.de 20212027Sjungma@eit.uni-kl.de // print dashes first outside quotes 20312027Sjungma@eit.uni-kl.de int non_dash_pos = arg.find_first_not_of("-"); 20412027Sjungma@eit.uni-kl.de out << arg.substr(0, non_dash_pos); // print dashes 20512027Sjungma@eit.uni-kl.de string body = arg.substr(non_dash_pos); // the rest 20612027Sjungma@eit.uni-kl.de 20712027Sjungma@eit.uni-kl.de // if it's an assignment, handle the lhs & rhs separately 20812027Sjungma@eit.uni-kl.de int eq_pos = body.find("="); 20912027Sjungma@eit.uni-kl.de if (eq_pos == string::npos) { 21012027Sjungma@eit.uni-kl.de out << quote(body); 21112027Sjungma@eit.uni-kl.de } 21212027Sjungma@eit.uni-kl.de else { 21312027Sjungma@eit.uni-kl.de string lhs(body.substr(0, eq_pos)); 21412027Sjungma@eit.uni-kl.de string rhs(body.substr(eq_pos + 1)); 21512027Sjungma@eit.uni-kl.de 21612027Sjungma@eit.uni-kl.de out << quote(lhs) << "=" << quote(rhs); 21712027Sjungma@eit.uni-kl.de } 21812027Sjungma@eit.uni-kl.de } 21912027Sjungma@eit.uni-kl.de out << endl << endl; 22012027Sjungma@eit.uni-kl.de} 22112027Sjungma@eit.uni-kl.de 22212027Sjungma@eit.uni-kl.dechar * 22312027Sjungma@eit.uni-kl.degetOptionString(int &index, int argc, char **argv) 22412027Sjungma@eit.uni-kl.de{ 22512027Sjungma@eit.uni-kl.de char *option = argv[index] + 2; 22612027Sjungma@eit.uni-kl.de if (*option != '\0') 22712027Sjungma@eit.uni-kl.de return option; 22812027Sjungma@eit.uni-kl.de 22912027Sjungma@eit.uni-kl.de // We didn't find an argument, it must be in the next variable. 23012027Sjungma@eit.uni-kl.de if (++index >= argc) 23112027Sjungma@eit.uni-kl.de panic("option string for option '%s' not found", argv[index - 1]); 23212027Sjungma@eit.uni-kl.de 23312027Sjungma@eit.uni-kl.de return argv[index]; 23412027Sjungma@eit.uni-kl.de} 23512027Sjungma@eit.uni-kl.de 23612027Sjungma@eit.uni-kl.deint 23712027Sjungma@eit.uni-kl.demain(int argc, char **argv) 23812027Sjungma@eit.uni-kl.de{ 23912027Sjungma@eit.uni-kl.de // Save off program name 24012027Sjungma@eit.uni-kl.de myProgName = argv[0]; 24112027Sjungma@eit.uni-kl.de 24212027Sjungma@eit.uni-kl.de signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths 24312027Sjungma@eit.uni-kl.de signal(SIGTRAP, SIG_IGN); 24412027Sjungma@eit.uni-kl.de signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats 24512027Sjungma@eit.uni-kl.de signal(SIGUSR2, dumprstStatsHandler); // dump and reset stats 24612027Sjungma@eit.uni-kl.de signal(SIGINT, exitNowHandler); // dump final stats and exit 24712027Sjungma@eit.uni-kl.de signal(SIGABRT, abortHandler); 24812027Sjungma@eit.uni-kl.de 24912027Sjungma@eit.uni-kl.de bool configfile_found = false; 25012027Sjungma@eit.uni-kl.de PythonConfig pyconfig; 25112027Sjungma@eit.uni-kl.de string outdir; 25212027Sjungma@eit.uni-kl.de 25312027Sjungma@eit.uni-kl.de if (argc < 2) { 25412027Sjungma@eit.uni-kl.de showBriefHelp(cerr); 25512027Sjungma@eit.uni-kl.de exit(1); 25612027Sjungma@eit.uni-kl.de } 25712027Sjungma@eit.uni-kl.de 25812027Sjungma@eit.uni-kl.de sayHello(cerr); 25912027Sjungma@eit.uni-kl.de 26012027Sjungma@eit.uni-kl.de // Parse command-line options. 26112027Sjungma@eit.uni-kl.de // Since most of the complex options are handled through the 26212027Sjungma@eit.uni-kl.de // config database, we don't mess with getopts, and just parse 26312027Sjungma@eit.uni-kl.de // manually. 26412027Sjungma@eit.uni-kl.de for (int i = 1; i < argc; ++i) { 26512027Sjungma@eit.uni-kl.de char *arg_str = argv[i]; 26612027Sjungma@eit.uni-kl.de 26712027Sjungma@eit.uni-kl.de // if arg starts with '--', parse as a special python option 26812027Sjungma@eit.uni-kl.de // of the format --<python var>=<string value>, if the arg 26912027Sjungma@eit.uni-kl.de // starts with '-', it should be a simulator option with a 27012027Sjungma@eit.uni-kl.de // format similar to getopt. In any other case, treat the 27112027Sjungma@eit.uni-kl.de // option as a configuration file name and load it. 27212027Sjungma@eit.uni-kl.de if (arg_str[0] == '-' && arg_str[1] == '-') { 27312027Sjungma@eit.uni-kl.de string str = &arg_str[2]; 27412027Sjungma@eit.uni-kl.de string var, val; 27512027Sjungma@eit.uni-kl.de 27612027Sjungma@eit.uni-kl.de if (!split_first(str, var, val, '=')) 27712027Sjungma@eit.uni-kl.de panic("Could not parse configuration argument '%s'\n" 27812027Sjungma@eit.uni-kl.de "Expecting --<variable>=<value>\n", arg_str); 27912027Sjungma@eit.uni-kl.de 28012027Sjungma@eit.uni-kl.de pyconfig.setVariable(var, val); 28112027Sjungma@eit.uni-kl.de } else if (arg_str[0] == '-') { 28212027Sjungma@eit.uni-kl.de char *option; 28312027Sjungma@eit.uni-kl.de string var, val; 28412027Sjungma@eit.uni-kl.de 28512027Sjungma@eit.uni-kl.de // switch on second char 28612027Sjungma@eit.uni-kl.de switch (arg_str[1]) { 28712027Sjungma@eit.uni-kl.de case 'd': 28812027Sjungma@eit.uni-kl.de outdir = getOptionString(i, argc, argv); 28912027Sjungma@eit.uni-kl.de break; 29012027Sjungma@eit.uni-kl.de 29112027Sjungma@eit.uni-kl.de case 'h': 29212027Sjungma@eit.uni-kl.de showBriefHelp(cerr); 29312027Sjungma@eit.uni-kl.de exit(1); 29412027Sjungma@eit.uni-kl.de 29512027Sjungma@eit.uni-kl.de case 'H': 29612027Sjungma@eit.uni-kl.de showLongHelp(cerr); 29712027Sjungma@eit.uni-kl.de exit(1); 29812027Sjungma@eit.uni-kl.de 29912027Sjungma@eit.uni-kl.de case 'E': 30012027Sjungma@eit.uni-kl.de option = getOptionString(i, argc, argv); 30112027Sjungma@eit.uni-kl.de if (!split_first(option, var, val, '=')) 30212027Sjungma@eit.uni-kl.de val = "True"; 30312027Sjungma@eit.uni-kl.de 30412027Sjungma@eit.uni-kl.de if (setenv(var.c_str(), val.c_str(), true) == -1) 30512027Sjungma@eit.uni-kl.de panic("setenv: %s\n", strerror(errno)); 30612027Sjungma@eit.uni-kl.de break; 30712027Sjungma@eit.uni-kl.de 30812027Sjungma@eit.uni-kl.de case 'I': 30912027Sjungma@eit.uni-kl.de option = getOptionString(i, argc, argv); 31012027Sjungma@eit.uni-kl.de pyconfig.addPath(option); 31112027Sjungma@eit.uni-kl.de break; 31212027Sjungma@eit.uni-kl.de 31312027Sjungma@eit.uni-kl.de case 'P': 31412027Sjungma@eit.uni-kl.de option = getOptionString(i, argc, argv); 31512027Sjungma@eit.uni-kl.de pyconfig.writeLine(option); 31612027Sjungma@eit.uni-kl.de break; 31712027Sjungma@eit.uni-kl.de 31812027Sjungma@eit.uni-kl.de case 'X': { 31912027Sjungma@eit.uni-kl.de list<EmbedFile> lst; 32012027Sjungma@eit.uni-kl.de EmbedMap::all(lst); 32112027Sjungma@eit.uni-kl.de list<EmbedFile>::iterator i = lst.begin(); 32212027Sjungma@eit.uni-kl.de list<EmbedFile>::iterator end = lst.end(); 32312027Sjungma@eit.uni-kl.de 32412027Sjungma@eit.uni-kl.de while (i != end) { 32512027Sjungma@eit.uni-kl.de cprintf("Embedded File: %s\n", i->name); 32612027Sjungma@eit.uni-kl.de cout.write(i->data, i->length); 32712027Sjungma@eit.uni-kl.de ++i; 32812027Sjungma@eit.uni-kl.de } 32912027Sjungma@eit.uni-kl.de 33012027Sjungma@eit.uni-kl.de return 0; 33112027Sjungma@eit.uni-kl.de } 33212027Sjungma@eit.uni-kl.de 33312027Sjungma@eit.uni-kl.de default: 33412027Sjungma@eit.uni-kl.de showBriefHelp(cerr); 33512027Sjungma@eit.uni-kl.de panic("invalid argument '%s'\n", arg_str); 33612027Sjungma@eit.uni-kl.de } 33712027Sjungma@eit.uni-kl.de } else { 33812027Sjungma@eit.uni-kl.de string file(arg_str); 33912027Sjungma@eit.uni-kl.de string base, ext; 34012027Sjungma@eit.uni-kl.de 34112027Sjungma@eit.uni-kl.de if (!split_last(file, base, ext, '.') || ext != "py") 34212027Sjungma@eit.uni-kl.de panic("Config file '%s' must end in '.py'\n", file); 34312027Sjungma@eit.uni-kl.de 34412027Sjungma@eit.uni-kl.de pyconfig.load(file); 34512027Sjungma@eit.uni-kl.de configfile_found = true; 34612027Sjungma@eit.uni-kl.de } 34712027Sjungma@eit.uni-kl.de } 34812027Sjungma@eit.uni-kl.de 34912027Sjungma@eit.uni-kl.de if (outdir.empty()) { 35012027Sjungma@eit.uni-kl.de char *env = getenv("OUTPUT_DIR"); 35112027Sjungma@eit.uni-kl.de outdir = env ? env : "."; 35212027Sjungma@eit.uni-kl.de } 35312027Sjungma@eit.uni-kl.de 35412027Sjungma@eit.uni-kl.de simout.setDirectory(outdir); 35512027Sjungma@eit.uni-kl.de 35612027Sjungma@eit.uni-kl.de char *env = getenv("CONFIG_OUTPUT"); 35712027Sjungma@eit.uni-kl.de if (!env) 35812027Sjungma@eit.uni-kl.de env = "config.out"; 35912027Sjungma@eit.uni-kl.de configStream = simout.find(env); 36012027Sjungma@eit.uni-kl.de 36112027Sjungma@eit.uni-kl.de if (!configfile_found) 36212027Sjungma@eit.uni-kl.de panic("no configuration file specified!"); 36312027Sjungma@eit.uni-kl.de 36412027Sjungma@eit.uni-kl.de // The configuration database is now complete; start processing it. 36512027Sjungma@eit.uni-kl.de IniFile inifile; 36612027Sjungma@eit.uni-kl.de if (!pyconfig.output(inifile)) 36712027Sjungma@eit.uni-kl.de panic("Error processing python code"); 36812027Sjungma@eit.uni-kl.de 36912027Sjungma@eit.uni-kl.de // Initialize statistics database 37012027Sjungma@eit.uni-kl.de Stats::InitSimStats(); 37112027Sjungma@eit.uni-kl.de 37212027Sjungma@eit.uni-kl.de // Now process the configuration hierarchy and create the SimObjects. 37312027Sjungma@eit.uni-kl.de ConfigHierarchy configHierarchy(inifile); 37412027Sjungma@eit.uni-kl.de configHierarchy.build(); 37512027Sjungma@eit.uni-kl.de configHierarchy.createSimObjects(); 37612027Sjungma@eit.uni-kl.de 37712027Sjungma@eit.uni-kl.de // Parse and check all non-config-hierarchy parameters. 37812027Sjungma@eit.uni-kl.de ParamContext::parseAllContexts(inifile); 37912027Sjungma@eit.uni-kl.de ParamContext::checkAllContexts(); 38012027Sjungma@eit.uni-kl.de 38112027Sjungma@eit.uni-kl.de // Print hello message to stats file if it's actually a file. If 38212027Sjungma@eit.uni-kl.de // it's not (i.e. it's cout or cerr) then we already did it above. 38312027Sjungma@eit.uni-kl.de if (simout.isFile(*outputStream)) 38412027Sjungma@eit.uni-kl.de sayHello(*outputStream); 38512027Sjungma@eit.uni-kl.de 38612027Sjungma@eit.uni-kl.de // Echo command line and all parameter settings to stats file as well. 38712027Sjungma@eit.uni-kl.de echoCommandLine(argc, argv, *outputStream); 38812027Sjungma@eit.uni-kl.de ParamContext::showAllContexts(*configStream); 38912027Sjungma@eit.uni-kl.de 39012027Sjungma@eit.uni-kl.de // Do a second pass to finish initializing the sim objects 39112027Sjungma@eit.uni-kl.de SimObject::initAll(); 39212027Sjungma@eit.uni-kl.de 39312027Sjungma@eit.uni-kl.de // Restore checkpointed state, if any. 39412027Sjungma@eit.uni-kl.de configHierarchy.unserializeSimObjects(); 39512027Sjungma@eit.uni-kl.de 39612027Sjungma@eit.uni-kl.de // Done processing the configuration database. 39712027Sjungma@eit.uni-kl.de // Check for unreferenced entries. 39812027Sjungma@eit.uni-kl.de if (inifile.printUnreferenced()) 39912027Sjungma@eit.uni-kl.de panic("unreferenced sections/entries in the intermediate ini file"); 40012027Sjungma@eit.uni-kl.de 40112027Sjungma@eit.uni-kl.de SimObject::regAllStats(); 40212027Sjungma@eit.uni-kl.de 40312027Sjungma@eit.uni-kl.de // uncomment the following to get PC-based execution-time profile 40412027Sjungma@eit.uni-kl.de#ifdef DO_PROFILE 40512027Sjungma@eit.uni-kl.de init_profile((char *)&_init, (char *)&_fini); 40612027Sjungma@eit.uni-kl.de#endif 40712027Sjungma@eit.uni-kl.de 40812027Sjungma@eit.uni-kl.de // Check to make sure that the stats package is properly initialized 40912027Sjungma@eit.uni-kl.de Stats::check(); 41012027Sjungma@eit.uni-kl.de 41112027Sjungma@eit.uni-kl.de // Reset to put the stats in a consistent state. 41212027Sjungma@eit.uni-kl.de Stats::reset(); 41312027Sjungma@eit.uni-kl.de 41412027Sjungma@eit.uni-kl.de warn("Entering event queue. Starting simulation...\n"); 41512027Sjungma@eit.uni-kl.de SimStartup(); 41612027Sjungma@eit.uni-kl.de while (!mainEventQueue.empty()) { 41712027Sjungma@eit.uni-kl.de assert(curTick <= mainEventQueue.nextTick() && 41812027Sjungma@eit.uni-kl.de "event scheduled in the past"); 41912027Sjungma@eit.uni-kl.de 42012027Sjungma@eit.uni-kl.de // forward current cycle to the time of the first event on the 42112027Sjungma@eit.uni-kl.de // queue 42212027Sjungma@eit.uni-kl.de curTick = mainEventQueue.nextTick(); 42312027Sjungma@eit.uni-kl.de mainEventQueue.serviceOne(); 42412027Sjungma@eit.uni-kl.de 42512027Sjungma@eit.uni-kl.de if (async_event) { 42612027Sjungma@eit.uni-kl.de async_event = false; 42712027Sjungma@eit.uni-kl.de if (async_dump) { 42812027Sjungma@eit.uni-kl.de async_dump = false; 42912027Sjungma@eit.uni-kl.de 43012027Sjungma@eit.uni-kl.de using namespace Stats; 43112027Sjungma@eit.uni-kl.de SetupEvent(Dump, curTick); 43212027Sjungma@eit.uni-kl.de } 43312027Sjungma@eit.uni-kl.de 434 if (async_dumpreset) { 435 async_dumpreset = false; 436 437 using namespace Stats; 438 SetupEvent(Dump | Reset, curTick); 439 } 440 441 if (async_exit) { 442 async_exit = false; 443 new SimExitEvent("User requested STOP"); 444 } 445 446 if (async_io || async_alarm) { 447 async_io = false; 448 async_alarm = false; 449 pollQueue.service(); 450 } 451 } 452 } 453 454 // This should never happen... every conceivable way for the 455 // simulation to terminate (hit max cycles/insts, signal, 456 // simulated system halts/exits) generates an exit event, so we 457 // should never run out of events on the queue. 458 exitNow("no events on event loop! All CPUs must be idle.", 1); 459 460 return 0; 461} 462