main.cc revision 400
111598Sandreas.sandberg@arm.com/*
27586SAli.Saidi@arm.com * Copyright (c) 2003 The Regents of The University of Michigan
37586SAli.Saidi@arm.com * All rights reserved.
47586SAli.Saidi@arm.com *
57586SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without
67586SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are
77586SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright
87586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer;
97586SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright
107586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the
117586SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution;
127586SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its
1310118Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from
1410118Snilay@cs.wisc.edu * this software without specific prior written permission.
153970Sgblack@eecs.umich.edu *
163005Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
173005Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
183005Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
193005Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
203005Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
213005Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
223005Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233005Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243005Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253005Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
263005Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273005Sstever@eecs.umich.edu */
283005Sstever@eecs.umich.edu
293005Sstever@eecs.umich.edu///
303005Sstever@eecs.umich.edu/// @file sim/main.cc
313005Sstever@eecs.umich.edu///
323005Sstever@eecs.umich.edu#include <sys/types.h>
333005Sstever@eecs.umich.edu#include <sys/stat.h>
343005Sstever@eecs.umich.edu#include <stdlib.h>
353005Sstever@eecs.umich.edu#include <signal.h>
363005Sstever@eecs.umich.edu
373005Sstever@eecs.umich.edu#include <string>
383005Sstever@eecs.umich.edu#include <vector>
393005Sstever@eecs.umich.edu
403005Sstever@eecs.umich.edu#include "base/copyright.hh"
413005Sstever@eecs.umich.edu#include "base/inifile.hh"
4210118Snilay@cs.wisc.edu#include "base/misc.hh"
433005Sstever@eecs.umich.edu#include "base/pollevent.hh"
446654Snate@binkert.org#include "base/statistics.hh"
456654Snate@binkert.org#include "base/time.hh"
462889SN/A#include "cpu/base_cpu.hh"
472710SN/A#include "cpu/full_cpu/smt.hh"
486654Snate@binkert.org#include "sim/async.hh"
496654Snate@binkert.org#include "sim/builder.hh"
506654Snate@binkert.org#include "sim/configfile.hh"
515457Ssaidi@eecs.umich.edu#include "sim/host.hh"
5211670Sandreas.hansson@arm.com#include "sim/sim_events.hh"
5310118Snilay@cs.wisc.edu#include "sim/sim_exit.hh"
5411670Sandreas.hansson@arm.com#include "sim/sim_object.hh"
556654Snate@binkert.org#include "sim/sim_stats.hh"
5611682Sandreas.hansson@arm.com
5711682Sandreas.hansson@arm.comusing namespace std;
5811682Sandreas.hansson@arm.com
5911682Sandreas.hansson@arm.com// See async.h.
6011682Sandreas.hansson@arm.comvolatile bool async_event = false;
6111682Sandreas.hansson@arm.comvolatile bool async_dump = false;
6211790Sjungma@eit.uni-kl.devolatile bool async_dumpreset = false;
6311682Sandreas.hansson@arm.comvolatile bool async_exit = false;
6411682Sandreas.hansson@arm.comvolatile bool async_io = false;
653444Sktlim@umich.eduvolatile bool async_alarm = false;
663304Sstever@eecs.umich.edu
679653SAndreas.Sandberg@ARM.com/// Stats signal handler.
689653SAndreas.Sandberg@ARM.comvoid
699653SAndreas.Sandberg@ARM.comdumpStatsHandler(int sigtype)
709653SAndreas.Sandberg@ARM.com{
719653SAndreas.Sandberg@ARM.com    async_event = true;
729653SAndreas.Sandberg@ARM.com    async_dump = true;
739653SAndreas.Sandberg@ARM.com}
7410594Sgabeblack@google.com
7510594Sgabeblack@google.comvoid
7610594Sgabeblack@google.comdumprstStatsHandler(int sigtype)
7710594Sgabeblack@google.com{
7810594Sgabeblack@google.com    async_event = true;
7910594Sgabeblack@google.com    async_dumpreset = true;
8010594Sgabeblack@google.com}
8110594Sgabeblack@google.com
8210594Sgabeblack@google.com/// Exit signal handler.
8310594Sgabeblack@google.comvoid
8410594Sgabeblack@google.comexitNowHandler(int sigtype)
8510119Snilay@cs.wisc.edu{
8610594Sgabeblack@google.com    async_event = true;
8710119Snilay@cs.wisc.edu    async_exit = true;
8810594Sgabeblack@google.com}
8910594Sgabeblack@google.com
9010119Snilay@cs.wisc.edu/// Simulator executable name
9110594Sgabeblack@google.comconst char *myProgName = "";
9210119Snilay@cs.wisc.edu
9310594Sgabeblack@google.com/// Show brief help message.
9410119Snilay@cs.wisc.edustatic void
9510119Snilay@cs.wisc.edushowBriefHelp(ostream &out)
9610594Sgabeblack@google.com{
9710119Snilay@cs.wisc.edu    out << "Usage: " << myProgName
9810512SAli.Saidi@ARM.com         << " [-hn] [-Dname[=def]] [-Uname] [-I[dir]] "
9910512SAli.Saidi@ARM.com         << "[--<section>:<param>=<value>] [<config file> ...]" << endl
10010594Sgabeblack@google.com         << "   -h: print long help (including parameter listing)" << endl
10110780SCurtis.Dunham@arm.com         << "   -n: don't load default.ini" << endl
10211598Sandreas.sandberg@arm.com         << "   -u: don't quit on unreferenced parameters" << endl
10311598Sandreas.sandberg@arm.com         << "   -D,-U,-I: passed to cpp for preprocessing .ini files" << endl;
10410119Snilay@cs.wisc.edu}
10510119Snilay@cs.wisc.edu
10610119Snilay@cs.wisc.edu/// Show verbose help message.  Includes parameter listing from
10710119Snilay@cs.wisc.edu/// showBriefHelp(), plus an exhaustive list of ini-file parameters
1082566SN/A/// and SimObjects (with their parameters).
10910119Snilay@cs.wisc.edustatic void
11010119Snilay@cs.wisc.edushowLongHelp(ostream &out)
1119665Sandreas.hansson@arm.com{
11210119Snilay@cs.wisc.edu    showBriefHelp(out);
11310119Snilay@cs.wisc.edu
11410119Snilay@cs.wisc.edu    out << endl
11510119Snilay@cs.wisc.edu        << endl
11610119Snilay@cs.wisc.edu        << "-----------------" << endl
11710119Snilay@cs.wisc.edu        << "Global Parameters" << endl
11810119Snilay@cs.wisc.edu        << "-----------------" << endl
11910119Snilay@cs.wisc.edu        << endl;
12010119Snilay@cs.wisc.edu
12110119Snilay@cs.wisc.edu    ParamContext::describeAllContexts(out);
12210119Snilay@cs.wisc.edu
12310119Snilay@cs.wisc.edu    out << endl
12410119Snilay@cs.wisc.edu        << endl
12510119Snilay@cs.wisc.edu        << "-----------------" << endl
12610119Snilay@cs.wisc.edu        << "Simulator Objects" << endl
12710119Snilay@cs.wisc.edu        << "-----------------" << endl
12810119Snilay@cs.wisc.edu        << endl;
12910119Snilay@cs.wisc.edu
13010119Snilay@cs.wisc.edu    SimObjectClass::describeAllClasses(out);
13110119Snilay@cs.wisc.edu}
13210119Snilay@cs.wisc.edu
13310119Snilay@cs.wisc.edu/// Print welcome message.
13410119Snilay@cs.wisc.edustatic void
13510119Snilay@cs.wisc.edusayHello(ostream &out)
13610119Snilay@cs.wisc.edu{
13710119Snilay@cs.wisc.edu    extern const char *compileDate;	// from date.cc
13810119Snilay@cs.wisc.edu
13910119Snilay@cs.wisc.edu    ccprintf(out, "M5 Simulator System\n");
14010119Snilay@cs.wisc.edu    // display copyright
14110119Snilay@cs.wisc.edu    ccprintf(out, "%s\n", briefCopyright);
14210119Snilay@cs.wisc.edu    ccprintf(out, "M5 compiled on %d\n", compileDate);
14310119Snilay@cs.wisc.edu
14410119Snilay@cs.wisc.edu    char *host = getenv("HOSTNAME");
14510119Snilay@cs.wisc.edu    if (!host)
14611839SCurtis.Dunham@arm.com        host = getenv("HOST");
14710119Snilay@cs.wisc.edu
14810119Snilay@cs.wisc.edu    if (host)
14910119Snilay@cs.wisc.edu        ccprintf(out, "M5 executing on %s\n", host);
15012014Sgabeblack@google.com
15112014Sgabeblack@google.com    ccprintf(out, "M5 simulation started %s\n", Time::start);
15210119Snilay@cs.wisc.edu}
15310119Snilay@cs.wisc.edu
15410119Snilay@cs.wisc.edu///
15510519Snilay@cs.wisc.edu/// Echo the command line for posterity in such a way that it can be
15610519Snilay@cs.wisc.edu/// used to rerun the same simulation (given the same .ini files).
15710119Snilay@cs.wisc.edu///
15810119Snilay@cs.wisc.edustatic void
15910119Snilay@cs.wisc.eduechoCommandLine(int argc, char **argv, ostream &out)
16010119Snilay@cs.wisc.edu{
16110119Snilay@cs.wisc.edu    out << "command line: " << argv[0];
16210547Snilay@cs.wisc.edu    for (int i = 1; i < argc; i++) {
16310547Snilay@cs.wisc.edu        string arg(argv[i]);
16410547Snilay@cs.wisc.edu
16510547Snilay@cs.wisc.edu        out << ' ';
16610119Snilay@cs.wisc.edu
16710119Snilay@cs.wisc.edu        // If the arg contains spaces, we need to quote it.
16810119Snilay@cs.wisc.edu        // The rest of this is overkill to make it look purty.
16910119Snilay@cs.wisc.edu
17010119Snilay@cs.wisc.edu        // print dashes first outside quotes
17110119Snilay@cs.wisc.edu        int non_dash_pos = arg.find_first_not_of("-");
17210119Snilay@cs.wisc.edu        out << arg.substr(0, non_dash_pos);	// print dashes
17310119Snilay@cs.wisc.edu        string body = arg.substr(non_dash_pos);	// the rest
17410120Snilay@cs.wisc.edu
17510120Snilay@cs.wisc.edu        // if it's an assignment, handle the lhs & rhs separately
17610119Snilay@cs.wisc.edu        int eq_pos = body.find("=");
17711598Sandreas.sandberg@arm.com        if (eq_pos == string::npos) {
17810120Snilay@cs.wisc.edu            out << quote(body);
17910120Snilay@cs.wisc.edu        }
18010119Snilay@cs.wisc.edu        else {
18111598Sandreas.sandberg@arm.com            string lhs(body.substr(0, eq_pos));
18211150Smitch.hayenga@arm.com            string rhs(body.substr(eq_pos + 1));
18311150Smitch.hayenga@arm.com
18411150Smitch.hayenga@arm.com            out << quote(lhs) << "=" << quote(rhs);
18510119Snilay@cs.wisc.edu        }
1862995SN/A    }
18710119Snilay@cs.wisc.edu    out << endl << endl;
18810119Snilay@cs.wisc.edu}
18910119Snilay@cs.wisc.edu
19010119Snilay@cs.wisc.edu
19110119Snilay@cs.wisc.edu///
19210780SCurtis.Dunham@arm.com/// The simulator configuration database.  This is the union of all
19310119Snilay@cs.wisc.edu/// specified .ini files.  This shouldn't need to be visible outside
19410119Snilay@cs.wisc.edu/// this file, as it is passed as a parameter to all the param-parsing
19510119Snilay@cs.wisc.edu/// routines.
1963304Sstever@eecs.umich.edu///
19710119Snilay@cs.wisc.edustatic IniFile simConfigDB;
19810119Snilay@cs.wisc.edu
19910119Snilay@cs.wisc.edu/// Check for a default.ini file and load it if necessary.
20010119Snilay@cs.wisc.edustatic void
20110119Snilay@cs.wisc.eduhandleDefaultIni(bool &loadIt, vector<char *> &cppArgs)
20210119Snilay@cs.wisc.edu{
2036135Sgblack@eecs.umich.edu    struct stat sb;
20410608Sdam.sunwoo@arm.com
20510608Sdam.sunwoo@arm.com    if (loadIt) {
20610608Sdam.sunwoo@arm.com        if (stat("default.ini", &sb) == 0) {
20710608Sdam.sunwoo@arm.com            if (!simConfigDB.loadCPP("default.ini", cppArgs)) {
20810608Sdam.sunwoo@arm.com                cout << "Error processing file default.ini" << endl;
20910608Sdam.sunwoo@arm.com                exit(1);
21010608Sdam.sunwoo@arm.com            }
21110119Snilay@cs.wisc.edu        }
21210119Snilay@cs.wisc.edu
21310119Snilay@cs.wisc.edu        // set this whether it actually was found or not, so we don't
21410608Sdam.sunwoo@arm.com        // bother to check again next time
21510608Sdam.sunwoo@arm.com        loadIt = false;
21610119Snilay@cs.wisc.edu    }
21710119Snilay@cs.wisc.edu}
21810119Snilay@cs.wisc.edu
2193819Shsul@eecs.umich.edu
22011251Sradhika.jagtap@ARM.com/// M5 entry point.
22111251Sradhika.jagtap@ARM.comint
22211251Sradhika.jagtap@ARM.commain(int argc, char **argv)
22311251Sradhika.jagtap@ARM.com{
22411251Sradhika.jagtap@ARM.com    // Save off program name
22511251Sradhika.jagtap@ARM.com    myProgName = argv[0];
22611251Sradhika.jagtap@ARM.com
22711251Sradhika.jagtap@ARM.com    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
22811251Sradhika.jagtap@ARM.com    signal(SIGTRAP, SIG_IGN);
22911251Sradhika.jagtap@ARM.com    signal(SIGUSR1, dumpStatsHandler);		// dump intermediate stats
23011251Sradhika.jagtap@ARM.com    signal(SIGUSR2, dumprstStatsHandler);	// dump and reset stats
23110119Snilay@cs.wisc.edu    signal(SIGINT, exitNowHandler);		// dump final stats and exit
23211183Serfan.azarkhish@unibo.it
23310119Snilay@cs.wisc.edu    sayHello(cerr);
23410118Snilay@cs.wisc.edu
23510119Snilay@cs.wisc.edu    // Initialize statistics database
2369827Sakash.bagdia@arm.com    initBaseStats();
23710119Snilay@cs.wisc.edu
23810119Snilay@cs.wisc.edu    vector<char *> cppArgs;
23910119Snilay@cs.wisc.edu
24010119Snilay@cs.wisc.edu    // Should we use default.ini if it exists?  By default, yes.  (Use
24110119Snilay@cs.wisc.edu    // -n to override.)
24210119Snilay@cs.wisc.edu    bool loadDefaultIni = true;
2439827Sakash.bagdia@arm.com
24410594Sgabeblack@google.com    // Should we quit if there are unreferenced parameters?  By
2456654Snate@binkert.org    // default, yes... it's a good way of catching typos in
24610594Sgabeblack@google.com    // section/parameter names (which otherwise go by silently).  Use
2476654Snate@binkert.org    // -u to override.
24810594Sgabeblack@google.com    bool quitOnUnreferenced = true;
2496654Snate@binkert.org
25010594Sgabeblack@google.com    // Parse command-line options.  The tricky part here is figuring
2516654Snate@binkert.org    // out whether to look for & load default.ini, and if needed,
25210594Sgabeblack@google.com    // doing so at the right time w.r.t. processing the other
25310594Sgabeblack@google.com    // parameters.
2547586SAli.Saidi@arm.com    //
25510635Satgutier@umich.edu    // Since most of the complex options are handled through the
25610635Satgutier@umich.edu    // config database, we don't mess with getopts, and just parse
2578661SAli.Saidi@ARM.com    // manually.
2589827Sakash.bagdia@arm.com    for (int i = 1; i < argc; ++i) {
2599827Sakash.bagdia@arm.com        char *arg_str = argv[i];
2609827Sakash.bagdia@arm.com
2619793Sakash.bagdia@arm.com        // if arg starts with '-', parse as option,
26210119Snilay@cs.wisc.edu        // else treat it as a configuration file name and load it
26310119Snilay@cs.wisc.edu        if (arg_str[0] == '-') {
2649790Sakash.bagdia@arm.com
2659827Sakash.bagdia@arm.com            // switch on second char
2669827Sakash.bagdia@arm.com            switch (arg_str[1]) {
2679827Sakash.bagdia@arm.com              case 'h':
2689793Sakash.bagdia@arm.com                // -h: show help
2699827Sakash.bagdia@arm.com                showLongHelp(cerr);
2709827Sakash.bagdia@arm.com                exit(1);
2719827Sakash.bagdia@arm.com
2729793Sakash.bagdia@arm.com              case 'n':
2739793Sakash.bagdia@arm.com                // -n: don't load default.ini
2749793Sakash.bagdia@arm.com                if (!loadDefaultIni) {
2759384SAndreas.Sandberg@arm.com                    cerr << "Warning: -n option needs to precede any "
2768863Snilay@cs.wisc.edu                         << "explicit configuration file name " << endl
2777876Sgblack@eecs.umich.edu                         << "         or command-line configuration parameter."
2784968Sacolyte@umich.edu                         << endl;
2798926Sandreas.hansson@arm.com                }
2804837Ssaidi@eecs.umich.edu                loadDefaultIni = false;
2814837Ssaidi@eecs.umich.edu                break;
2829408Sandreas.hansson@arm.com
2839653SAndreas.Sandberg@ARM.com              case 'u':
28411839SCurtis.Dunham@arm.com                // -u: don't quit on unreferenced parameters
2859653SAndreas.Sandberg@ARM.com                quitOnUnreferenced = false;
2869164Sandreas.hansson@arm.com                break;
2879408Sandreas.hansson@arm.com
2888845Sandreas.hansson@arm.com              case 'D':
2898845Sandreas.hansson@arm.com              case 'U':
2904837Ssaidi@eecs.umich.edu              case 'I':
2919826Sandreas.hansson@arm.com                // cpp options: record & pass to cpp.  Note that these
2929826Sandreas.hansson@arm.com                // cannot have spaces, i.e., '-Dname=val' is OK, but
2939835Sandreas.hansson@arm.com                // '-D name=val' is not.  I don't consider this a
2949826Sandreas.hansson@arm.com                // problem, since even though gnu cpp accepts the
2959826Sandreas.hansson@arm.com                // latter, other cpp implementations do not (Tru64,
2969826Sandreas.hansson@arm.com                // for one).
2979826Sandreas.hansson@arm.com                cppArgs.push_back(arg_str);
2988659SAli.Saidi@ARM.com                break;
29910119Snilay@cs.wisc.edu
30010119Snilay@cs.wisc.edu              case '-':
30110119Snilay@cs.wisc.edu                // command-line configuration parameter:
30210119Snilay@cs.wisc.edu                // '--<section>:<parameter>=<value>'
30310119Snilay@cs.wisc.edu
30410119Snilay@cs.wisc.edu                // Load default.ini if necessary -- see comment in
30510119Snilay@cs.wisc.edu                // else clause below.
30610119Snilay@cs.wisc.edu                handleDefaultIni(loadDefaultIni, cppArgs);
30710119Snilay@cs.wisc.edu
30810119Snilay@cs.wisc.edu                if (!simConfigDB.add(arg_str + 2)) {
30910119Snilay@cs.wisc.edu                    // parse error
31010119Snilay@cs.wisc.edu                    ccprintf(cerr,
31110119Snilay@cs.wisc.edu                             "Could not parse configuration argument '%s'\n"
31210119Snilay@cs.wisc.edu                             "Expecting --<section>:<parameter>=<value>\n",
31310119Snilay@cs.wisc.edu                             arg_str);
31410119Snilay@cs.wisc.edu                    exit(0);
31510119Snilay@cs.wisc.edu                }
31610119Snilay@cs.wisc.edu                break;
31710119Snilay@cs.wisc.edu
31810119Snilay@cs.wisc.edu              default:
31910119Snilay@cs.wisc.edu                showBriefHelp(cerr);
32010119Snilay@cs.wisc.edu                ccprintf(cerr, "Fatal: invalid argument '%s'\n", arg_str);
32110119Snilay@cs.wisc.edu                exit(0);
32210119Snilay@cs.wisc.edu            }
32310119Snilay@cs.wisc.edu        }
32410119Snilay@cs.wisc.edu        else {
32510119Snilay@cs.wisc.edu            // no '-', treat as config file name
32610119Snilay@cs.wisc.edu
32710119Snilay@cs.wisc.edu            // If we haven't loaded default.ini yet, and we want to,
32810119Snilay@cs.wisc.edu            // now is the time.  Can't do it sooner because we need to
32910119Snilay@cs.wisc.edu            // look for '-n', can't do it later since we want
33010119Snilay@cs.wisc.edu            // default.ini loaded first (so that any other settings
33110119Snilay@cs.wisc.edu            // override it).
33210697SCurtis.Dunham@arm.com            handleDefaultIni(loadDefaultIni, cppArgs);
33310747SChris.Emmons@arm.com
33410697SCurtis.Dunham@arm.com            if (!simConfigDB.loadCPP(arg_str, cppArgs)) {
33510747SChris.Emmons@arm.com                cprintf("Error processing file %s\n", arg_str);
33610119Snilay@cs.wisc.edu                exit(1);
33710697SCurtis.Dunham@arm.com            }
33810747SChris.Emmons@arm.com        }
33910119Snilay@cs.wisc.edu    }
34010119Snilay@cs.wisc.edu
34110119Snilay@cs.wisc.edu    // Final check for default.ini, in case no config files or
34210119Snilay@cs.wisc.edu    // command-line config parameters were given.
34310119Snilay@cs.wisc.edu    handleDefaultIni(loadDefaultIni, cppArgs);
34410119Snilay@cs.wisc.edu
3458801Sgblack@eecs.umich.edu    // The configuration database is now complete; start processing it.
34611291Sgabor.dozsa@arm.com
34711291Sgabor.dozsa@arm.com    // Parse and check all non-config-hierarchy parameters.
34811291Sgabor.dozsa@arm.com    ParamContext::parseAllContexts(simConfigDB);
34911291Sgabor.dozsa@arm.com    ParamContext::checkAllContexts();
35011291Sgabor.dozsa@arm.com
35111291Sgabor.dozsa@arm.com    // Print header info into stats file.  Can't do this sooner since
35211291Sgabor.dozsa@arm.com    // the stat file name is set via a .ini param... thus it just got
35311291Sgabor.dozsa@arm.com    // opened above during ParamContext::checkAllContexts().
35411291Sgabor.dozsa@arm.com
35511291Sgabor.dozsa@arm.com    // Print hello message to stats file if it's actually a file.  If
35611291Sgabor.dozsa@arm.com    // it's not (i.e. it's cout or cerr) then we already did it above.
35711291Sgabor.dozsa@arm.com    if (statStreamIsFile)
3583005Sstever@eecs.umich.edu        sayHello(*statStream);
3598801Sgblack@eecs.umich.edu
3603005Sstever@eecs.umich.edu    // Echo command line and all parameter settings to stats file as well.
3613005Sstever@eecs.umich.edu    echoCommandLine(argc, argv, *statStream);
3623005Sstever@eecs.umich.edu    ParamContext::showAllContexts(*statStream);
3632566SN/A
3647861Sgblack@eecs.umich.edu    // Now process the configuration hierarchy and create the SimObjects.
3657861Sgblack@eecs.umich.edu    ConfigHierarchy configHierarchy(simConfigDB);
3667861Sgblack@eecs.umich.edu    configHierarchy.build();
3678635Schris.emmons@arm.com    configHierarchy.createSimObjects();
3688635Schris.emmons@arm.com
3698635Schris.emmons@arm.com    // Restore checkpointed state, if any.
3709061Snilay@cs.wisc.edu    configHierarchy.unserializeSimObjects();
3713481Shsul@eecs.umich.edu
372    // Done processing the configuration database.
373    // Check for unreferenced entries.
374    if (simConfigDB.printUnreferenced() && quitOnUnreferenced) {
375        cerr << "Fatal: unreferenced .ini sections/entries." << endl
376             << "If this is not an error, add 'unref_section_ok=y' or "
377             << "'unref_entries_ok=y' to the appropriate sections "
378             << "to suppress this message." << endl;
379        exit(1);
380    }
381
382    SimObject::regAllStats();
383
384    // uncomment the following to get PC-based execution-time profile
385#ifdef DO_PROFILE
386    init_profile((char *)&_init, (char *)&_fini);
387#endif
388
389    // Check to make sure that the stats package is properly initialized
390    Statistics::check();
391
392    // Reset to put the stats in a consistent state.
393    Statistics::reset();
394
395    // Nothing to simulate if we don't have at least one CPU somewhere.
396    if (BaseCPU::numSimulatedCPUs() == 0) {
397        cerr << "Fatal: no CPUs to simulate." << endl;
398        exit(1);
399    }
400
401    while (!mainEventQueue.empty()) {
402        assert(curTick <= mainEventQueue.nextTick() &&
403               "event scheduled in the past");
404
405        // forward current cycle to the time of the first event on the
406        // queue
407        curTick = mainEventQueue.nextTick();
408        mainEventQueue.serviceOne();
409
410        if (async_event) {
411            async_event = false;
412            if (async_dump) {
413                async_dump = false;
414
415                using namespace Statistics;
416                SetupEvent(Dump, curTick);
417            }
418
419            if (async_dumpreset) {
420                async_dumpreset = false;
421
422                using namespace Statistics;
423                SetupEvent(Dump | Reset, curTick);
424            }
425
426            if (async_exit) {
427                async_exit = false;
428                new SimExitEvent("User requested STOP");
429            }
430
431            if (async_io || async_alarm) {
432                async_io = false;
433                async_alarm = false;
434                pollQueue.service();
435            }
436        }
437    }
438
439    // This should never happen... every conceivable way for the
440    // simulation to terminate (hit max cycles/insts, signal,
441    // simulated system halts/exits) generates an exit event, so we
442    // should never run out of events on the queue.
443    exitNow("no events on event loop!  All CPUs must be idle.", 1);
444
445    return 0;
446}
447