main.cc revision 1388
1955SN/A/* 2955SN/A * Copyright (c) 2000-2004 The Regents of The University of Michigan 313576Sciro.santilli@arm.com * All rights reserved. 413576Sciro.santilli@arm.com * 513576Sciro.santilli@arm.com * Redistribution and use in source and binary forms, with or without 613576Sciro.santilli@arm.com * modification, are permitted provided that the following conditions are 713576Sciro.santilli@arm.com * met: redistributions of source code must retain the above copyright 813576Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer; 913576Sciro.santilli@arm.com * redistributions in binary form must reproduce the above copyright 1013576Sciro.santilli@arm.com * notice, this list of conditions and the following disclaimer in the 1113576Sciro.santilli@arm.com * documentation and/or other materials provided with the distribution; 1213576Sciro.santilli@arm.com * neither the name of the copyright holders nor the names of its 1313576Sciro.santilli@arm.com * contributors may be used to endorse or promote products derived from 141762SN/A * this software without specific prior written permission. 15955SN/A * 16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27955SN/A */ 28955SN/A 29955SN/A/// 30955SN/A/// @file sim/main.cc 31955SN/A/// 32955SN/A#include <sys/types.h> 33955SN/A#include <sys/stat.h> 34955SN/A#include <stdlib.h> 35955SN/A#include <signal.h> 36955SN/A 37955SN/A#include <list> 38955SN/A#include <string> 392665Ssaidi@eecs.umich.edu#include <vector> 404762Snate@binkert.org 41955SN/A#include "base/copyright.hh" 4212563Sgabeblack@google.com#include "base/embedfile.hh" 4312563Sgabeblack@google.com#include "base/inifile.hh" 445522Snate@binkert.org#include "base/misc.hh" 456143Snate@binkert.org#include "base/output.hh" 4612371Sgabeblack@google.com#include "base/pollevent.hh" 474762Snate@binkert.org#include "base/statistics.hh" 485522Snate@binkert.org#include "base/str.hh" 49955SN/A#include "base/time.hh" 505522Snate@binkert.org#include "cpu/base_cpu.hh" 5111974Sgabeblack@google.com#include "cpu/full_cpu/smt.hh" 52955SN/A#include "sim/async.hh" 535522Snate@binkert.org#include "sim/builder.hh" 544202Sbinkertn@umich.edu#include "sim/configfile.hh" 555742Snate@binkert.org#include "sim/host.hh" 56955SN/A#include "sim/sim_events.hh" 574381Sbinkertn@umich.edu#include "sim/sim_exit.hh" 584381Sbinkertn@umich.edu#include "sim/sim_object.hh" 5912246Sgabeblack@google.com#include "sim/stat_control.hh" 6012246Sgabeblack@google.com#include "sim/stats.hh" 618334Snate@binkert.org#include "sim/universe.hh" 62955SN/A#include "sim/pyconfig/pyconfig.hh" 63955SN/A 644202Sbinkertn@umich.eduusing namespace std; 65955SN/A 664382Sbinkertn@umich.edu// See async.h. 674382Sbinkertn@umich.eduvolatile bool async_event = false; 684382Sbinkertn@umich.eduvolatile bool async_dump = false; 696654Snate@binkert.orgvolatile bool async_dumpreset = false; 705517Snate@binkert.orgvolatile bool async_exit = false; 718614Sgblack@eecs.umich.eduvolatile bool async_io = false; 727674Snate@binkert.orgvolatile bool async_alarm = false; 736143Snate@binkert.org 746143Snate@binkert.org/// Stats signal handler. 756143Snate@binkert.orgvoid 7612302Sgabeblack@google.comdumpStatsHandler(int sigtype) 7712302Sgabeblack@google.com{ 7812302Sgabeblack@google.com async_event = true; 7912371Sgabeblack@google.com async_dump = true; 8012371Sgabeblack@google.com} 8112371Sgabeblack@google.com 8212371Sgabeblack@google.comvoid 8312371Sgabeblack@google.comdumprstStatsHandler(int sigtype) 8412371Sgabeblack@google.com{ 8512371Sgabeblack@google.com async_event = true; 8612371Sgabeblack@google.com async_dumpreset = true; 8712371Sgabeblack@google.com} 8812371Sgabeblack@google.com 8912371Sgabeblack@google.com/// Exit signal handler. 9012371Sgabeblack@google.comvoid 9112371Sgabeblack@google.comexitNowHandler(int sigtype) 9212371Sgabeblack@google.com{ 9312371Sgabeblack@google.com async_event = true; 9412371Sgabeblack@google.com async_exit = true; 9512371Sgabeblack@google.com} 9612371Sgabeblack@google.com 9712371Sgabeblack@google.com/// Abort signal handler. 9812371Sgabeblack@google.comvoid 9912371Sgabeblack@google.comabortHandler(int sigtype) 10012371Sgabeblack@google.com{ 10112371Sgabeblack@google.com cerr << "Program aborted at cycle " << curTick << endl; 10212371Sgabeblack@google.com 10312371Sgabeblack@google.com#if TRACING_ON 10412371Sgabeblack@google.com // dump trace buffer, if there is one 10512371Sgabeblack@google.com Trace::theLog.dump(cerr); 10612371Sgabeblack@google.com#endif 10712371Sgabeblack@google.com} 10812371Sgabeblack@google.com 10912371Sgabeblack@google.com/// Simulator executable name 11012371Sgabeblack@google.comconst char *myProgName = ""; 11112371Sgabeblack@google.com 11212371Sgabeblack@google.com/// Show brief help message. 11312371Sgabeblack@google.comvoid 11412371Sgabeblack@google.comshowBriefHelp(ostream &out) 11512371Sgabeblack@google.com{ 11612371Sgabeblack@google.com char *prog = basename(myProgName); 11712371Sgabeblack@google.com 11812371Sgabeblack@google.com ccprintf(out, "Usage:\n"); 11912371Sgabeblack@google.com ccprintf(out, 12012371Sgabeblack@google.com"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n" 12112371Sgabeblack@google.com" [--<var>=<val>] <config file>\n" 12212371Sgabeblack@google.com"\n" 12312371Sgabeblack@google.com" -d set the output directory to <dir>\n" 12412371Sgabeblack@google.com" -E set the environment variable <var> to <val> (or 'True')\n" 12512371Sgabeblack@google.com" -I add the directory <dir> to python's path\n" 12612302Sgabeblack@google.com" -P execute <python> directly in the configuration\n" 12712371Sgabeblack@google.com" --var=val set the python variable <var> to '<val>'\n" 12812302Sgabeblack@google.com" <configfile> config file name (.py or .mpy)\n", 12912371Sgabeblack@google.com prog); 13012302Sgabeblack@google.com 13112302Sgabeblack@google.com ccprintf(out, "%s -X\n -X extract embedded files\n", prog); 13212371Sgabeblack@google.com ccprintf(out, "%s -h\n -h print long help\n", prog); 13312371Sgabeblack@google.com} 13412371Sgabeblack@google.com 13512371Sgabeblack@google.com/// Show verbose help message. Includes parameter listing from 13612302Sgabeblack@google.com/// showBriefHelp(), plus an exhaustive list of ini-file parameters 13712371Sgabeblack@google.com/// and SimObjects (with their parameters). 13812371Sgabeblack@google.comvoid 13912371Sgabeblack@google.comshowLongHelp(ostream &out) 14012371Sgabeblack@google.com{ 14111983Sgabeblack@google.com showBriefHelp(out); 1426143Snate@binkert.org 1438233Snate@binkert.org out << endl 14412302Sgabeblack@google.com << endl 1456143Snate@binkert.org << "-----------------" << endl 1466143Snate@binkert.org << "Global Parameters" << endl 14712302Sgabeblack@google.com << "-----------------" << endl 1484762Snate@binkert.org << endl; 1496143Snate@binkert.org 1508233Snate@binkert.org ParamContext::describeAllContexts(out); 1518233Snate@binkert.org 15212302Sgabeblack@google.com out << endl 15312302Sgabeblack@google.com << endl 1546143Snate@binkert.org << "-----------------" << endl 15512362Sgabeblack@google.com << "Simulator Objects" << endl 15612362Sgabeblack@google.com << "-----------------" << endl 15712362Sgabeblack@google.com << endl; 15812362Sgabeblack@google.com 15912302Sgabeblack@google.com SimObjectClass::describeAllClasses(out); 16012302Sgabeblack@google.com} 16112302Sgabeblack@google.com 16212302Sgabeblack@google.com/// Print welcome message. 16312302Sgabeblack@google.comvoid 16412363Sgabeblack@google.comsayHello(ostream &out) 16512363Sgabeblack@google.com{ 16612363Sgabeblack@google.com extern const char *compileDate; // from date.cc 16712363Sgabeblack@google.com 16812302Sgabeblack@google.com ccprintf(out, "M5 Simulator System\n"); 16912363Sgabeblack@google.com // display copyright 17012363Sgabeblack@google.com ccprintf(out, "%s\n", briefCopyright); 17112363Sgabeblack@google.com ccprintf(out, "M5 compiled on %d\n", compileDate); 17212363Sgabeblack@google.com 17312363Sgabeblack@google.com char *host = getenv("HOSTNAME"); 1748233Snate@binkert.org if (!host) 1756143Snate@binkert.org host = getenv("HOST"); 1766143Snate@binkert.org 1776143Snate@binkert.org if (host) 1786143Snate@binkert.org ccprintf(out, "M5 executing on %s\n", host); 1796143Snate@binkert.org 1806143Snate@binkert.org ccprintf(out, "M5 simulation started %s\n", Time::start); 1816143Snate@binkert.org} 1826143Snate@binkert.org 1836143Snate@binkert.org/// 1847065Snate@binkert.org/// Echo the command line for posterity in such a way that it can be 1856143Snate@binkert.org/// used to rerun the same simulation (given the same .ini files). 18612362Sgabeblack@google.com/// 18712362Sgabeblack@google.comvoid 18812362Sgabeblack@google.comechoCommandLine(int argc, char **argv, ostream &out) 18912362Sgabeblack@google.com{ 19012362Sgabeblack@google.com out << "command line: " << argv[0]; 19112362Sgabeblack@google.com for (int i = 1; i < argc; i++) { 19212362Sgabeblack@google.com string arg(argv[i]); 19312362Sgabeblack@google.com 19412362Sgabeblack@google.com out << ' '; 19512362Sgabeblack@google.com 19612362Sgabeblack@google.com // If the arg contains spaces, we need to quote it. 19712362Sgabeblack@google.com // The rest of this is overkill to make it look purty. 1988233Snate@binkert.org 1998233Snate@binkert.org // print dashes first outside quotes 2008233Snate@binkert.org int non_dash_pos = arg.find_first_not_of("-"); 2018233Snate@binkert.org out << arg.substr(0, non_dash_pos); // print dashes 2028233Snate@binkert.org string body = arg.substr(non_dash_pos); // the rest 2038233Snate@binkert.org 2048233Snate@binkert.org // if it's an assignment, handle the lhs & rhs separately 2058233Snate@binkert.org int eq_pos = body.find("="); 2068233Snate@binkert.org if (eq_pos == string::npos) { 2078233Snate@binkert.org out << quote(body); 2088233Snate@binkert.org } 2098233Snate@binkert.org else { 2108233Snate@binkert.org string lhs(body.substr(0, eq_pos)); 2118233Snate@binkert.org string rhs(body.substr(eq_pos + 1)); 2128233Snate@binkert.org 2138233Snate@binkert.org out << quote(lhs) << "=" << quote(rhs); 2148233Snate@binkert.org } 2158233Snate@binkert.org } 2168233Snate@binkert.org out << endl << endl; 2178233Snate@binkert.org} 2188233Snate@binkert.org 2196143Snate@binkert.orgchar * 2206143Snate@binkert.orggetOptionString(int &index, int argc, char **argv) 2216143Snate@binkert.org{ 2226143Snate@binkert.org char *option = argv[index] + 2; 2236143Snate@binkert.org if (*option != '\0') 2246143Snate@binkert.org return option; 2259982Satgutier@umich.edu 22613576Sciro.santilli@arm.com // We didn't find an argument, it must be in the next variable. 22713576Sciro.santilli@arm.com if (++index >= argc) 22813576Sciro.santilli@arm.com panic("option string for option '%s' not found", argv[index - 1]); 22913576Sciro.santilli@arm.com 23013576Sciro.santilli@arm.com return argv[index]; 23113576Sciro.santilli@arm.com} 23213576Sciro.santilli@arm.com 23313576Sciro.santilli@arm.comint 23413576Sciro.santilli@arm.commain(int argc, char **argv) 23513576Sciro.santilli@arm.com{ 23613576Sciro.santilli@arm.com // Save off program name 23713576Sciro.santilli@arm.com myProgName = argv[0]; 23813576Sciro.santilli@arm.com 23913576Sciro.santilli@arm.com signal(SIGFPE, SIG_IGN); // may occur on misspeculated paths 24013576Sciro.santilli@arm.com signal(SIGTRAP, SIG_IGN); 24113576Sciro.santilli@arm.com signal(SIGUSR1, dumpStatsHandler); // dump intermediate stats 24213576Sciro.santilli@arm.com signal(SIGUSR2, dumprstStatsHandler); // dump and reset stats 24313576Sciro.santilli@arm.com signal(SIGINT, exitNowHandler); // dump final stats and exit 24413576Sciro.santilli@arm.com signal(SIGABRT, abortHandler); 24513576Sciro.santilli@arm.com 24613576Sciro.santilli@arm.com sayHello(cerr); 24713576Sciro.santilli@arm.com 24813576Sciro.santilli@arm.com bool configfile_found = false; 24913576Sciro.santilli@arm.com PythonConfig pyconfig; 25013576Sciro.santilli@arm.com string outdir; 25113576Sciro.santilli@arm.com 25213576Sciro.santilli@arm.com // Parse command-line options. 25313576Sciro.santilli@arm.com // Since most of the complex options are handled through the 25413576Sciro.santilli@arm.com // config database, we don't mess with getopts, and just parse 25513576Sciro.santilli@arm.com // manually. 25613576Sciro.santilli@arm.com for (int i = 1; i < argc; ++i) { 25713576Sciro.santilli@arm.com char *arg_str = argv[i]; 25813630Sciro.santilli@arm.com 25913630Sciro.santilli@arm.com // if arg starts with '--', parse as a special python option 26013576Sciro.santilli@arm.com // of the format --<python var>=<string value>, if the arg 26113576Sciro.santilli@arm.com // starts with '-', it should be a simulator option with a 26213576Sciro.santilli@arm.com // format similar to getopt. In any other case, treat the 26313576Sciro.santilli@arm.com // option as a configuration file name and load it. 26413576Sciro.santilli@arm.com if (arg_str[0] == '-' && arg_str[1] == '-') { 26513576Sciro.santilli@arm.com string str = &arg_str[2]; 26613576Sciro.santilli@arm.com string var, val; 26713576Sciro.santilli@arm.com 26813576Sciro.santilli@arm.com if (!split_first(str, var, val, '=')) 26913576Sciro.santilli@arm.com panic("Could not parse configuration argument '%s'\n" 27013576Sciro.santilli@arm.com "Expecting --<variable>=<value>\n", arg_str); 27113576Sciro.santilli@arm.com 27213576Sciro.santilli@arm.com pyconfig.setVariable(var, val); 27313576Sciro.santilli@arm.com } else if (arg_str[0] == '-') { 27413576Sciro.santilli@arm.com char *option; 27513576Sciro.santilli@arm.com string var, val; 27613576Sciro.santilli@arm.com 27713576Sciro.santilli@arm.com // switch on second char 27813576Sciro.santilli@arm.com switch (arg_str[1]) { 27913576Sciro.santilli@arm.com case 'd': 28013576Sciro.santilli@arm.com outdir = getOptionString(i, argc, argv); 28113576Sciro.santilli@arm.com break; 28213576Sciro.santilli@arm.com 28313576Sciro.santilli@arm.com case 'h': 28413576Sciro.santilli@arm.com showLongHelp(cerr); 28513576Sciro.santilli@arm.com exit(1); 28613576Sciro.santilli@arm.com 28713576Sciro.santilli@arm.com case 'E': 28813576Sciro.santilli@arm.com option = getOptionString(i, argc, argv); 28913576Sciro.santilli@arm.com if (!split_first(option, var, val, '=')) 29013576Sciro.santilli@arm.com val = "True"; 29113576Sciro.santilli@arm.com 29213576Sciro.santilli@arm.com if (setenv(var.c_str(), val.c_str(), true) == -1) 29313576Sciro.santilli@arm.com panic("setenv: %s\n", strerror(errno)); 29413576Sciro.santilli@arm.com break; 29513576Sciro.santilli@arm.com 29613576Sciro.santilli@arm.com case 'I': 29713577Sciro.santilli@arm.com option = getOptionString(i, argc, argv); 29813577Sciro.santilli@arm.com pyconfig.addPath(option); 29913577Sciro.santilli@arm.com break; 3006143Snate@binkert.org 30112302Sgabeblack@google.com case 'P': 30212302Sgabeblack@google.com option = getOptionString(i, argc, argv); 30312302Sgabeblack@google.com pyconfig.writeLine(option); 30412302Sgabeblack@google.com break; 30512302Sgabeblack@google.com 30612302Sgabeblack@google.com case 'X': { 30712302Sgabeblack@google.com list<EmbedFile> lst; 30812302Sgabeblack@google.com EmbedMap::all(lst); 30911983Sgabeblack@google.com list<EmbedFile>::iterator i = lst.begin(); 31011983Sgabeblack@google.com list<EmbedFile>::iterator end = lst.end(); 31111983Sgabeblack@google.com 31212302Sgabeblack@google.com while (i != end) { 31312302Sgabeblack@google.com cprintf("Embedded File: %s\n", i->name); 31412302Sgabeblack@google.com cout.write(i->data, i->length); 31512302Sgabeblack@google.com ++i; 31612302Sgabeblack@google.com } 31712302Sgabeblack@google.com 31811983Sgabeblack@google.com return 0; 3196143Snate@binkert.org } 32012305Sgabeblack@google.com 32112302Sgabeblack@google.com default: 32212302Sgabeblack@google.com showBriefHelp(cerr); 32312302Sgabeblack@google.com panic("invalid argument '%s'\n", arg_str); 3246143Snate@binkert.org } 3256143Snate@binkert.org } else { 3266143Snate@binkert.org string file(arg_str); 3275522Snate@binkert.org string base, ext; 3286143Snate@binkert.org 3296143Snate@binkert.org if (!split_last(file, base, ext, '.') || 3306143Snate@binkert.org ext != "py" && ext != "mpy") 3319982Satgutier@umich.edu panic("Config file '%s' must end in '.py' or '.mpy'\n", file); 33212302Sgabeblack@google.com 33312302Sgabeblack@google.com pyconfig.load(file); 33412302Sgabeblack@google.com configfile_found = true; 3356143Snate@binkert.org } 3366143Snate@binkert.org } 3376143Snate@binkert.org 3386143Snate@binkert.org if (outdir.empty()) { 3395522Snate@binkert.org char *env = getenv("OUTPUT_DIR"); 3405522Snate@binkert.org outdir = env ? env : "."; 3415522Snate@binkert.org } 3425522Snate@binkert.org 3435604Snate@binkert.org simout.setDirectory(outdir); 3445604Snate@binkert.org 3456143Snate@binkert.org char *env = getenv("CONFIG_OUTPUT"); 3466143Snate@binkert.org if (!env) 3474762Snate@binkert.org env = "config.out"; 3484762Snate@binkert.org configStream = simout.find(env); 3496143Snate@binkert.org 3506727Ssteve.reinhardt@amd.com if (!configfile_found) 3516727Ssteve.reinhardt@amd.com panic("no configuration file specified!"); 3526727Ssteve.reinhardt@amd.com 3534762Snate@binkert.org // The configuration database is now complete; start processing it. 3546143Snate@binkert.org IniFile inifile; 3556143Snate@binkert.org if (!pyconfig.output(inifile)) 3566143Snate@binkert.org panic("Error processing python code"); 3576143Snate@binkert.org 3586727Ssteve.reinhardt@amd.com // Initialize statistics database 3596143Snate@binkert.org Stats::InitSimStats(); 3607674Snate@binkert.org 3617674Snate@binkert.org // Now process the configuration hierarchy and create the SimObjects. 3625604Snate@binkert.org ConfigHierarchy configHierarchy(inifile); 3636143Snate@binkert.org configHierarchy.build(); 3646143Snate@binkert.org configHierarchy.createSimObjects(); 3656143Snate@binkert.org 3664762Snate@binkert.org // Parse and check all non-config-hierarchy parameters. 3676143Snate@binkert.org ParamContext::parseAllContexts(inifile); 3684762Snate@binkert.org ParamContext::checkAllContexts(); 3694762Snate@binkert.org 3704762Snate@binkert.org // Print hello message to stats file if it's actually a file. If 3716143Snate@binkert.org // it's not (i.e. it's cout or cerr) then we already did it above. 3726143Snate@binkert.org if (simout.isFile(*outputStream)) 3734762Snate@binkert.org sayHello(*outputStream); 37412302Sgabeblack@google.com 37512302Sgabeblack@google.com // Echo command line and all parameter settings to stats file as well. 3768233Snate@binkert.org echoCommandLine(argc, argv, *outputStream); 37712302Sgabeblack@google.com ParamContext::showAllContexts(*configStream); 3786143Snate@binkert.org 3796143Snate@binkert.org // Do a second pass to finish initializing the sim objects 3804762Snate@binkert.org SimObject::initAll(); 3816143Snate@binkert.org 3824762Snate@binkert.org // Restore checkpointed state, if any. 3839396Sandreas.hansson@arm.com configHierarchy.unserializeSimObjects(); 3849396Sandreas.hansson@arm.com 3859396Sandreas.hansson@arm.com // Done processing the configuration database. 38612302Sgabeblack@google.com // Check for unreferenced entries. 38712302Sgabeblack@google.com if (inifile.printUnreferenced()) 38812302Sgabeblack@google.com panic("unreferenced sections/entries in the intermediate ini file"); 3899396Sandreas.hansson@arm.com 3909396Sandreas.hansson@arm.com SimObject::regAllStats(); 3919396Sandreas.hansson@arm.com 3929396Sandreas.hansson@arm.com // uncomment the following to get PC-based execution-time profile 3939396Sandreas.hansson@arm.com#ifdef DO_PROFILE 3949396Sandreas.hansson@arm.com init_profile((char *)&_init, (char *)&_fini); 3959396Sandreas.hansson@arm.com#endif 3969930Sandreas.hansson@arm.com 3979930Sandreas.hansson@arm.com // Check to make sure that the stats package is properly initialized 3989396Sandreas.hansson@arm.com Stats::check(); 3996143Snate@binkert.org 40012797Sgabeblack@google.com // Reset to put the stats in a consistent state. 40112797Sgabeblack@google.com Stats::reset(); 40212797Sgabeblack@google.com 4038235Snate@binkert.org // Nothing to simulate if we don't have at least one CPU somewhere. 40412797Sgabeblack@google.com if (BaseCPU::numSimulatedCPUs() == 0) { 40512797Sgabeblack@google.com cerr << "Fatal: no CPUs to simulate." << endl; 40612797Sgabeblack@google.com exit(1); 40712797Sgabeblack@google.com } 40812797Sgabeblack@google.com 40912797Sgabeblack@google.com warn("Entering event queue. Starting simulation...\n"); 41012797Sgabeblack@google.com SimStartup(); 41112797Sgabeblack@google.com while (!mainEventQueue.empty()) { 41212797Sgabeblack@google.com assert(curTick <= mainEventQueue.nextTick() && 41312797Sgabeblack@google.com "event scheduled in the past"); 41412797Sgabeblack@google.com 41512797Sgabeblack@google.com // forward current cycle to the time of the first event on the 41612797Sgabeblack@google.com // queue 41712797Sgabeblack@google.com curTick = mainEventQueue.nextTick(); 41812797Sgabeblack@google.com mainEventQueue.serviceOne(); 41912757Sgabeblack@google.com 42012757Sgabeblack@google.com if (async_event) { 42112797Sgabeblack@google.com async_event = false; 42212797Sgabeblack@google.com if (async_dump) { 42312797Sgabeblack@google.com async_dump = false; 42412757Sgabeblack@google.com 42512757Sgabeblack@google.com using namespace Stats; 42612757Sgabeblack@google.com SetupEvent(Dump, curTick); 42712757Sgabeblack@google.com } 4288235Snate@binkert.org 42912302Sgabeblack@google.com if (async_dumpreset) { 4308235Snate@binkert.org async_dumpreset = false; 4318235Snate@binkert.org 43212757Sgabeblack@google.com using namespace Stats; 4338235Snate@binkert.org SetupEvent(Dump | Reset, curTick); 4348235Snate@binkert.org } 4358235Snate@binkert.org 43612757Sgabeblack@google.com if (async_exit) { 43712313Sgabeblack@google.com async_exit = false; 43812797Sgabeblack@google.com new SimExitEvent("User requested STOP"); 43912797Sgabeblack@google.com } 44012797Sgabeblack@google.com 44112797Sgabeblack@google.com if (async_io || async_alarm) { 44212797Sgabeblack@google.com async_io = false; 44312797Sgabeblack@google.com async_alarm = false; 44412797Sgabeblack@google.com pollQueue.service(); 44512797Sgabeblack@google.com } 44612797Sgabeblack@google.com } 44712797Sgabeblack@google.com } 44812797Sgabeblack@google.com 44912797Sgabeblack@google.com // This should never happen... every conceivable way for the 45012797Sgabeblack@google.com // simulation to terminate (hit max cycles/insts, signal, 45112797Sgabeblack@google.com // simulated system halts/exits) generates an exit event, so we 45213706Sgabeblack@google.com // should never run out of events on the queue. 45313706Sgabeblack@google.com exitNow("no events on event loop! All CPUs must be idle.", 1); 45413706Sgabeblack@google.com 45513706Sgabeblack@google.com return 0; 45612797Sgabeblack@google.com} 45712797Sgabeblack@google.com