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