main.cc revision 1696
112837Sgabeblack@google.com/*
212837Sgabeblack@google.com * Copyright (c) 2000-2004 The Regents of The University of Michigan
312837Sgabeblack@google.com * All rights reserved.
412837Sgabeblack@google.com *
512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412837Sgabeblack@google.com * this software without specific prior written permission.
1512837Sgabeblack@google.com *
1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712837Sgabeblack@google.com */
2812837Sgabeblack@google.com
2912837Sgabeblack@google.com///
3012901Sgabeblack@google.com/// @file sim/main.cc
3113135Sgabeblack@google.com///
3212901Sgabeblack@google.com#include <sys/types.h>
3312901Sgabeblack@google.com#include <sys/stat.h>
3412837Sgabeblack@google.com#include <errno.h>
3512982Sgabeblack@google.com#include <libgen.h>
3612951Sgabeblack@google.com#include <stdlib.h>
3712953Sgabeblack@google.com#include <signal.h>
3812837Sgabeblack@google.com
3912951Sgabeblack@google.com#include <list>
4013135Sgabeblack@google.com#include <string>
4112837Sgabeblack@google.com#include <vector>
4212952Sgabeblack@google.com
4312952Sgabeblack@google.com#include "base/copyright.hh"
4412952Sgabeblack@google.com#include "base/embedfile.hh"
4512952Sgabeblack@google.com#include "base/inifile.hh"
4612952Sgabeblack@google.com#include "base/misc.hh"
4712952Sgabeblack@google.com#include "base/output.hh"
4813135Sgabeblack@google.com#include "base/pollevent.hh"
4913135Sgabeblack@google.com#include "base/statistics.hh"
5013135Sgabeblack@google.com#include "base/str.hh"
5113135Sgabeblack@google.com#include "base/time.hh"
5213135Sgabeblack@google.com#include "cpu/base_cpu.hh"
5313135Sgabeblack@google.com#include "cpu/full_cpu/smt.hh"
5413135Sgabeblack@google.com#include "python/pyconfig.hh"
5513135Sgabeblack@google.com#include "sim/async.hh"
5612993Sgabeblack@google.com#include "sim/builder.hh"
5712993Sgabeblack@google.com#include "sim/configfile.hh"
5812952Sgabeblack@google.com#include "sim/host.hh"
5912952Sgabeblack@google.com#include "sim/sim_events.hh"
6012952Sgabeblack@google.com#include "sim/sim_exit.hh"
6112952Sgabeblack@google.com#include "sim/sim_object.hh"
6212952Sgabeblack@google.com#include "sim/stat_control.hh"
6313135Sgabeblack@google.com#include "sim/stats.hh"
6413135Sgabeblack@google.com#include "sim/root.hh"
6513135Sgabeblack@google.com
6613135Sgabeblack@google.comusing namespace std;
6713135Sgabeblack@google.com
6813135Sgabeblack@google.com// See async.h.
6913135Sgabeblack@google.comvolatile bool async_event = false;
7013135Sgabeblack@google.comvolatile bool async_dump = false;
7112993Sgabeblack@google.comvolatile bool async_dumpreset = false;
7212993Sgabeblack@google.comvolatile bool async_exit = false;
7312952Sgabeblack@google.comvolatile bool async_io = false;
7412952Sgabeblack@google.comvolatile bool async_alarm = false;
7512952Sgabeblack@google.com
7612952Sgabeblack@google.com/// Stats signal handler.
7712952Sgabeblack@google.comvoid
7813135Sgabeblack@google.comdumpStatsHandler(int sigtype)
7913135Sgabeblack@google.com{
8013135Sgabeblack@google.com    async_event = true;
8113135Sgabeblack@google.com    async_dump = true;
8213135Sgabeblack@google.com}
8313135Sgabeblack@google.com
8413135Sgabeblack@google.comvoid
8513135Sgabeblack@google.comdumprstStatsHandler(int sigtype)
8612993Sgabeblack@google.com{
8713060Sgabeblack@google.com    async_event = true;
8812993Sgabeblack@google.com    async_dumpreset = true;
8912952Sgabeblack@google.com}
9012952Sgabeblack@google.com
9113035Sgabeblack@google.com/// Exit signal handler.
9213035Sgabeblack@google.comvoid
9312952Sgabeblack@google.comexitNowHandler(int sigtype)
9412952Sgabeblack@google.com{
9512837Sgabeblack@google.com    async_event = true;
9612837Sgabeblack@google.com    async_exit = true;
9712837Sgabeblack@google.com}
9813091Sgabeblack@google.com
9912951Sgabeblack@google.com/// Abort signal handler.
10012951Sgabeblack@google.comvoid
10112837Sgabeblack@google.comabortHandler(int sigtype)
10213091Sgabeblack@google.com{
10312951Sgabeblack@google.com    cerr << "Program aborted at cycle " << curTick << endl;
10412951Sgabeblack@google.com
10512837Sgabeblack@google.com#if TRACING_ON
10613091Sgabeblack@google.com    // dump trace buffer, if there is one
10712837Sgabeblack@google.com    Trace::theLog.dump(cerr);
10812982Sgabeblack@google.com#endif
10912837Sgabeblack@google.com}
11013091Sgabeblack@google.com
11112837Sgabeblack@google.com/// Simulator executable name
11212837Sgabeblack@google.comchar *myProgName = "";
11312837Sgabeblack@google.com
11412837Sgabeblack@google.com/// Show brief help message.
11512837Sgabeblack@google.comvoid
11612837Sgabeblack@google.comshowBriefHelp(ostream &out)
11712837Sgabeblack@google.com{
11812837Sgabeblack@google.com    char *prog = basename(myProgName);
11912837Sgabeblack@google.com
12012837Sgabeblack@google.com    ccprintf(out, "Usage:\n");
12112837Sgabeblack@google.com    ccprintf(out,
12212837Sgabeblack@google.com"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n"
12312837Sgabeblack@google.com"        [--<var>=<val>] <config file>\n"
12412837Sgabeblack@google.com"\n"
12512837Sgabeblack@google.com"   -d            set the output directory to <dir>\n"
12612837Sgabeblack@google.com"   -E            set the environment variable <var> to <val> (or 'True')\n"
12712837Sgabeblack@google.com"   -I            add the directory <dir> to python's path\n"
12812837Sgabeblack@google.com"   -P            execute <python> directly in the configuration\n"
12912837Sgabeblack@google.com"   --var=val     set the python variable <var> to '<val>'\n"
13012837Sgabeblack@google.com"   <configfile>  config file name (.py or .mpy)\n",
13112837Sgabeblack@google.com             prog);
13212837Sgabeblack@google.com
13312837Sgabeblack@google.com    ccprintf(out, "%s -X\n    -X            extract embedded files\n", prog);
13412837Sgabeblack@google.com    ccprintf(out, "%s -h\n    -h            print long help\n", prog);
13512837Sgabeblack@google.com}
13612837Sgabeblack@google.com
13712837Sgabeblack@google.com/// Show verbose help message.  Includes parameter listing from
13812837Sgabeblack@google.com/// showBriefHelp(), plus an exhaustive list of ini-file parameters
13912837Sgabeblack@google.com/// and SimObjects (with their parameters).
14012837Sgabeblack@google.comvoid
14112837Sgabeblack@google.comshowLongHelp(ostream &out)
14212837Sgabeblack@google.com{
14312837Sgabeblack@google.com    showBriefHelp(out);
14412837Sgabeblack@google.com
14512837Sgabeblack@google.com    out << endl
14612837Sgabeblack@google.com        << endl
14712837Sgabeblack@google.com        << "-----------------" << endl
14812837Sgabeblack@google.com        << "Global Parameters" << endl
14912837Sgabeblack@google.com        << "-----------------" << endl
15012837Sgabeblack@google.com        << endl;
15112837Sgabeblack@google.com
15212837Sgabeblack@google.com    ParamContext::describeAllContexts(out);
15312837Sgabeblack@google.com
15412837Sgabeblack@google.com    out << endl
15512837Sgabeblack@google.com        << endl
15612837Sgabeblack@google.com        << "-----------------" << endl
15712837Sgabeblack@google.com        << "Simulator Objects" << endl
15812837Sgabeblack@google.com        << "-----------------" << endl
15912837Sgabeblack@google.com        << endl;
16012837Sgabeblack@google.com
16112837Sgabeblack@google.com    SimObjectClass::describeAllClasses(out);
16212837Sgabeblack@google.com}
16312837Sgabeblack@google.com
16412837Sgabeblack@google.com/// Print welcome message.
16512837Sgabeblack@google.comvoid
16612837Sgabeblack@google.comsayHello(ostream &out)
16712837Sgabeblack@google.com{
16812837Sgabeblack@google.com    extern const char *compileDate;	// from date.cc
16912837Sgabeblack@google.com
17012837Sgabeblack@google.com    ccprintf(out, "M5 Simulator System\n");
17112837Sgabeblack@google.com    // display copyright
17212837Sgabeblack@google.com    ccprintf(out, "%s\n", briefCopyright);
17312837Sgabeblack@google.com    ccprintf(out, "M5 compiled on %d\n", compileDate);
17412837Sgabeblack@google.com
17512837Sgabeblack@google.com    char *host = getenv("HOSTNAME");
17612837Sgabeblack@google.com    if (!host)
17712837Sgabeblack@google.com        host = getenv("HOST");
17813091Sgabeblack@google.com
17913091Sgabeblack@google.com    if (host)
18013091Sgabeblack@google.com        ccprintf(out, "M5 executing on %s\n", host);
18113091Sgabeblack@google.com
18213091Sgabeblack@google.com    ccprintf(out, "M5 simulation started %s\n", Time::start);
18313091Sgabeblack@google.com}
18413091Sgabeblack@google.com
18513091Sgabeblack@google.com///
18613091Sgabeblack@google.com/// Echo the command line for posterity in such a way that it can be
18713091Sgabeblack@google.com/// used to rerun the same simulation (given the same .ini files).
18813091Sgabeblack@google.com///
18913091Sgabeblack@google.comvoid
19013091Sgabeblack@google.comechoCommandLine(int argc, char **argv, ostream &out)
19113091Sgabeblack@google.com{
19213091Sgabeblack@google.com    out << "command line: " << argv[0];
19313091Sgabeblack@google.com    for (int i = 1; i < argc; i++) {
19413091Sgabeblack@google.com        string arg(argv[i]);
19513091Sgabeblack@google.com
19613091Sgabeblack@google.com        out << ' ';
19713091Sgabeblack@google.com
19813091Sgabeblack@google.com        // If the arg contains spaces, we need to quote it.
19913091Sgabeblack@google.com        // The rest of this is overkill to make it look purty.
20013091Sgabeblack@google.com
20113091Sgabeblack@google.com        // print dashes first outside quotes
20212837Sgabeblack@google.com        int non_dash_pos = arg.find_first_not_of("-");
20312837Sgabeblack@google.com        out << arg.substr(0, non_dash_pos);	// print dashes
20412837Sgabeblack@google.com        string body = arg.substr(non_dash_pos);	// the rest
20512837Sgabeblack@google.com
20612837Sgabeblack@google.com        // if it's an assignment, handle the lhs & rhs separately
20712951Sgabeblack@google.com        int eq_pos = body.find("=");
20812837Sgabeblack@google.com        if (eq_pos == string::npos) {
20912837Sgabeblack@google.com            out << quote(body);
21012837Sgabeblack@google.com        }
21112837Sgabeblack@google.com        else {
21212837Sgabeblack@google.com            string lhs(body.substr(0, eq_pos));
21312951Sgabeblack@google.com            string rhs(body.substr(eq_pos + 1));
21412837Sgabeblack@google.com
21512837Sgabeblack@google.com            out << quote(lhs) << "=" << quote(rhs);
21612951Sgabeblack@google.com        }
21713079Sgabeblack@google.com    }
21812951Sgabeblack@google.com    out << endl << endl;
21912951Sgabeblack@google.com}
22012837Sgabeblack@google.com
22112951Sgabeblack@google.comchar *
22212951Sgabeblack@google.comgetOptionString(int &index, int argc, char **argv)
22312951Sgabeblack@google.com{
22412951Sgabeblack@google.com    char *option = argv[index] + 2;
22512951Sgabeblack@google.com    if (*option != '\0')
22612928Sgabeblack@google.com        return option;
22712837Sgabeblack@google.com
22812837Sgabeblack@google.com    // We didn't find an argument, it must be in the next variable.
22912837Sgabeblack@google.com    if (++index >= argc)
23012837Sgabeblack@google.com        panic("option string for option '%s' not found", argv[index - 1]);
23112837Sgabeblack@google.com
23212837Sgabeblack@google.com    return argv[index];
23312837Sgabeblack@google.com}
23412837Sgabeblack@google.com
23512837Sgabeblack@google.comint
23612837Sgabeblack@google.commain(int argc, char **argv)
23712837Sgabeblack@google.com{
23812837Sgabeblack@google.com    // Save off program name
23912837Sgabeblack@google.com    myProgName = argv[0];
24012837Sgabeblack@google.com
24112837Sgabeblack@google.com    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
24212837Sgabeblack@google.com    signal(SIGTRAP, SIG_IGN);
24312837Sgabeblack@google.com    signal(SIGUSR1, dumpStatsHandler);		// dump intermediate stats
24412837Sgabeblack@google.com    signal(SIGUSR2, dumprstStatsHandler);	// dump and reset stats
24512837Sgabeblack@google.com    signal(SIGINT, exitNowHandler);		// dump final stats and exit
24612837Sgabeblack@google.com    signal(SIGABRT, abortHandler);
24712837Sgabeblack@google.com
24812837Sgabeblack@google.com    sayHello(cerr);
24912837Sgabeblack@google.com
25012837Sgabeblack@google.com    bool configfile_found = false;
25112837Sgabeblack@google.com    PythonConfig pyconfig;
25212837Sgabeblack@google.com    string outdir;
25312837Sgabeblack@google.com
25412837Sgabeblack@google.com    // Parse command-line options.
25512837Sgabeblack@google.com    // Since most of the complex options are handled through the
25612837Sgabeblack@google.com    // config database, we don't mess with getopts, and just parse
25712837Sgabeblack@google.com    // manually.
25812837Sgabeblack@google.com    for (int i = 1; i < argc; ++i) {
25912837Sgabeblack@google.com        char *arg_str = argv[i];
26012837Sgabeblack@google.com
26112837Sgabeblack@google.com        // if arg starts with '--', parse as a special python option
26212837Sgabeblack@google.com        // of the format --<python var>=<string value>, if the arg
26312837Sgabeblack@google.com        // starts with '-', it should be a simulator option with a
26412837Sgabeblack@google.com        // format similar to getopt.  In any other case, treat the
26512837Sgabeblack@google.com        // option as a configuration file name and load it.
26612837Sgabeblack@google.com        if (arg_str[0] == '-' && arg_str[1] == '-') {
26712837Sgabeblack@google.com            string str = &arg_str[2];
26812837Sgabeblack@google.com            string var, val;
26912837Sgabeblack@google.com
27012837Sgabeblack@google.com            if (!split_first(str, var, val, '='))
27112837Sgabeblack@google.com                panic("Could not parse configuration argument '%s'\n"
27212837Sgabeblack@google.com                      "Expecting --<variable>=<value>\n", arg_str);
27312837Sgabeblack@google.com
27412837Sgabeblack@google.com            pyconfig.setVariable(var, val);
27512837Sgabeblack@google.com        } else if (arg_str[0] == '-') {
27612837Sgabeblack@google.com            char *option;
27712837Sgabeblack@google.com            string var, val;
27812837Sgabeblack@google.com
27912837Sgabeblack@google.com            // switch on second char
28012953Sgabeblack@google.com            switch (arg_str[1]) {
28112837Sgabeblack@google.com              case 'd':
28212837Sgabeblack@google.com                outdir = getOptionString(i, argc, argv);
28312837Sgabeblack@google.com                break;
28412953Sgabeblack@google.com
28512837Sgabeblack@google.com              case 'h':
28612953Sgabeblack@google.com                showLongHelp(cerr);
28712837Sgabeblack@google.com                exit(1);
28812837Sgabeblack@google.com
28912837Sgabeblack@google.com              case 'E':
29012951Sgabeblack@google.com                option = getOptionString(i, argc, argv);
29112951Sgabeblack@google.com                if (!split_first(option, var, val, '='))
29212837Sgabeblack@google.com                    val = "True";
29312951Sgabeblack@google.com
29412837Sgabeblack@google.com                if (setenv(var.c_str(), val.c_str(), true) == -1)
29512951Sgabeblack@google.com                    panic("setenv: %s\n", strerror(errno));
29612837Sgabeblack@google.com                break;
29712837Sgabeblack@google.com
29812837Sgabeblack@google.com              case 'I':
29912951Sgabeblack@google.com                option = getOptionString(i, argc, argv);
30012837Sgabeblack@google.com                pyconfig.addPath(option);
30112951Sgabeblack@google.com                break;
30212837Sgabeblack@google.com
30312837Sgabeblack@google.com              case 'P':
30412837Sgabeblack@google.com                option = getOptionString(i, argc, argv);
30512951Sgabeblack@google.com                pyconfig.writeLine(option);
30612837Sgabeblack@google.com                break;
30712951Sgabeblack@google.com
30812837Sgabeblack@google.com              case 'X': {
30912837Sgabeblack@google.com                  list<EmbedFile> lst;
31012837Sgabeblack@google.com                  EmbedMap::all(lst);
31112951Sgabeblack@google.com                  list<EmbedFile>::iterator i = lst.begin();
31212837Sgabeblack@google.com                  list<EmbedFile>::iterator end = lst.end();
31312951Sgabeblack@google.com
31412837Sgabeblack@google.com                  while (i != end) {
31512837Sgabeblack@google.com                      cprintf("Embedded File: %s\n", i->name);
31612837Sgabeblack@google.com                      cout.write(i->data, i->length);
31712951Sgabeblack@google.com                      ++i;
31812837Sgabeblack@google.com                  }
31912951Sgabeblack@google.com
32012837Sgabeblack@google.com                  return 0;
32112837Sgabeblack@google.com              }
32212837Sgabeblack@google.com
32312951Sgabeblack@google.com              default:
32412837Sgabeblack@google.com                showBriefHelp(cerr);
32512951Sgabeblack@google.com                panic("invalid argument '%s'\n", arg_str);
32612837Sgabeblack@google.com            }
32712837Sgabeblack@google.com        } else {
32812837Sgabeblack@google.com            string file(arg_str);
32912951Sgabeblack@google.com            string base, ext;
33012837Sgabeblack@google.com
33112951Sgabeblack@google.com            if (!split_last(file, base, ext, '.') ||
33212837Sgabeblack@google.com                ext != "py" && ext != "mpy")
33312837Sgabeblack@google.com                panic("Config file '%s' must end in '.py' or '.mpy'\n", file);
33412837Sgabeblack@google.com
33512951Sgabeblack@google.com            pyconfig.load(file);
33612837Sgabeblack@google.com            configfile_found = true;
33712951Sgabeblack@google.com        }
33812837Sgabeblack@google.com    }
33912837Sgabeblack@google.com
34012837Sgabeblack@google.com    if (outdir.empty()) {
34112951Sgabeblack@google.com        char *env = getenv("OUTPUT_DIR");
34212837Sgabeblack@google.com        outdir = env ? env : ".";
34312951Sgabeblack@google.com    }
34412837Sgabeblack@google.com
34512837Sgabeblack@google.com    simout.setDirectory(outdir);
34612837Sgabeblack@google.com
34712951Sgabeblack@google.com    char *env = getenv("CONFIG_OUTPUT");
34812837Sgabeblack@google.com    if (!env)
34912951Sgabeblack@google.com        env = "config.out";
35012837Sgabeblack@google.com    configStream = simout.find(env);
35112837Sgabeblack@google.com
35212837Sgabeblack@google.com    if (!configfile_found)
35312951Sgabeblack@google.com        panic("no configuration file specified!");
35412837Sgabeblack@google.com
35512951Sgabeblack@google.com    // The configuration database is now complete; start processing it.
35612837Sgabeblack@google.com    IniFile inifile;
35712837Sgabeblack@google.com    if (!pyconfig.output(inifile))
35812837Sgabeblack@google.com        panic("Error processing python code");
35912929Sgabeblack@google.com
36012929Sgabeblack@google.com    // Initialize statistics database
36112929Sgabeblack@google.com    Stats::InitSimStats();
36212929Sgabeblack@google.com
36312929Sgabeblack@google.com    // Now process the configuration hierarchy and create the SimObjects.
36412929Sgabeblack@google.com    ConfigHierarchy configHierarchy(inifile);
36512929Sgabeblack@google.com    configHierarchy.build();
36612929Sgabeblack@google.com    configHierarchy.createSimObjects();
36712837Sgabeblack@google.com
36812837Sgabeblack@google.com    // Parse and check all non-config-hierarchy parameters.
36912837Sgabeblack@google.com    ParamContext::parseAllContexts(inifile);
37012951Sgabeblack@google.com    ParamContext::checkAllContexts();
37112837Sgabeblack@google.com
37212837Sgabeblack@google.com    // Print hello message to stats file if it's actually a file.  If
37312837Sgabeblack@google.com    // it's not (i.e. it's cout or cerr) then we already did it above.
37412951Sgabeblack@google.com    if (simout.isFile(*outputStream))
37512837Sgabeblack@google.com        sayHello(*outputStream);
37612951Sgabeblack@google.com
37712837Sgabeblack@google.com    // Echo command line and all parameter settings to stats file as well.
37812837Sgabeblack@google.com    echoCommandLine(argc, argv, *outputStream);
37912837Sgabeblack@google.com    ParamContext::showAllContexts(*configStream);
38012951Sgabeblack@google.com
38112837Sgabeblack@google.com    // Do a second pass to finish initializing the sim objects
38212951Sgabeblack@google.com    SimObject::initAll();
38312837Sgabeblack@google.com
38412837Sgabeblack@google.com    // Restore checkpointed state, if any.
38512837Sgabeblack@google.com    configHierarchy.unserializeSimObjects();
38612951Sgabeblack@google.com
38712837Sgabeblack@google.com    // Done processing the configuration database.
38812951Sgabeblack@google.com    // Check for unreferenced entries.
38912837Sgabeblack@google.com    if (inifile.printUnreferenced())
39012837Sgabeblack@google.com        panic("unreferenced sections/entries in the intermediate ini file");
39112837Sgabeblack@google.com
39212951Sgabeblack@google.com    SimObject::regAllStats();
39312837Sgabeblack@google.com
39412951Sgabeblack@google.com    // uncomment the following to get PC-based execution-time profile
39512837Sgabeblack@google.com#ifdef DO_PROFILE
39612837Sgabeblack@google.com    init_profile((char *)&_init, (char *)&_fini);
39712837Sgabeblack@google.com#endif
39812951Sgabeblack@google.com
39912837Sgabeblack@google.com    // Check to make sure that the stats package is properly initialized
40012951Sgabeblack@google.com    Stats::check();
40112837Sgabeblack@google.com
40212837Sgabeblack@google.com    // Reset to put the stats in a consistent state.
40312837Sgabeblack@google.com    Stats::reset();
40412951Sgabeblack@google.com
40512837Sgabeblack@google.com    warn("Entering event queue.  Starting simulation...\n");
40612951Sgabeblack@google.com    SimStartup();
40712837Sgabeblack@google.com    while (!mainEventQueue.empty()) {
40812837Sgabeblack@google.com        assert(curTick <= mainEventQueue.nextTick() &&
40912837Sgabeblack@google.com               "event scheduled in the past");
41012951Sgabeblack@google.com
41112837Sgabeblack@google.com        // forward current cycle to the time of the first event on the
41212951Sgabeblack@google.com        // queue
41312837Sgabeblack@google.com        curTick = mainEventQueue.nextTick();
41412837Sgabeblack@google.com        mainEventQueue.serviceOne();
41512837Sgabeblack@google.com
41612951Sgabeblack@google.com        if (async_event) {
41712837Sgabeblack@google.com            async_event = false;
41812951Sgabeblack@google.com            if (async_dump) {
41912837Sgabeblack@google.com                async_dump = false;
42012837Sgabeblack@google.com
42112837Sgabeblack@google.com                using namespace Stats;
42212951Sgabeblack@google.com                SetupEvent(Dump, curTick);
42312837Sgabeblack@google.com            }
42412951Sgabeblack@google.com
42512837Sgabeblack@google.com            if (async_dumpreset) {
42612837Sgabeblack@google.com                async_dumpreset = false;
42712837Sgabeblack@google.com
42812951Sgabeblack@google.com                using namespace Stats;
42912837Sgabeblack@google.com                SetupEvent(Dump | Reset, curTick);
43012951Sgabeblack@google.com            }
43112837Sgabeblack@google.com
43212837Sgabeblack@google.com            if (async_exit) {
43312837Sgabeblack@google.com                async_exit = false;
43412951Sgabeblack@google.com                new SimExitEvent("User requested STOP");
43512837Sgabeblack@google.com            }
43612951Sgabeblack@google.com
43712837Sgabeblack@google.com            if (async_io || async_alarm) {
43812837Sgabeblack@google.com                async_io = false;
43912837Sgabeblack@google.com                async_alarm = false;
44012951Sgabeblack@google.com                pollQueue.service();
44112837Sgabeblack@google.com            }
44212951Sgabeblack@google.com        }
44312837Sgabeblack@google.com    }
44412837Sgabeblack@google.com
44512837Sgabeblack@google.com    // This should never happen... every conceivable way for the
44612837Sgabeblack@google.com    // simulation to terminate (hit max cycles/insts, signal,
44712909Sgabeblack@google.com    // simulated system halts/exits) generates an exit event, so we
44812909Sgabeblack@google.com    // should never run out of events on the queue.
44912951Sgabeblack@google.com    exitNow("no events on event loop!  All CPUs must be idle.", 1);
45012909Sgabeblack@google.com
45112909Sgabeblack@google.com    return 0;
45212914Sgabeblack@google.com}
45312951Sgabeblack@google.com