summaryrefslogtreecommitdiff
path: root/util/systemc/main.cc
diff options
context:
space:
mode:
Diffstat (limited to 'util/systemc/main.cc')
-rw-r--r--util/systemc/main.cc105
1 files changed, 54 insertions, 51 deletions
diff --git a/util/systemc/main.cc b/util/systemc/main.cc
index 6ffaeb6da..2ca6bbe65 100644
--- a/util/systemc/main.cc
+++ b/util/systemc/main.cc
@@ -120,8 +120,6 @@ class SimControl : public Gem5SystemC::Module
SimControl(sc_core::sc_module_name name, int argc_, char **argv_);
- void before_end_of_elaboration();
-
void run();
};
@@ -141,14 +139,26 @@ SimControl::SimControl(sc_core::sc_module_name name,
cxxConfigInit();
+ /* Pass DPRINTF messages to SystemC */
Trace::setDebugLogger(&logger);
+ /* @todo need this as an option */
Gem5SystemC::setTickFrequency();
- sc_core::sc_set_time_resolution(1, sc_core::SC_PS);
+ /* Make a SystemC-synchronising event queue and install it as the
+ * sole top level gem5 EventQueue */
Gem5SystemC::Module::setupEventQueues(*this);
+
+ if (sc_core::sc_get_time_resolution() !=
+ sc_core::sc_time(1, sc_core::SC_PS))
+ {
+ fatal("Time resolution must be set to 1 ps for gem5 to work");
+ }
+
+ /* Enable keyboard interrupt, async I/O etc. */
initSignals();
+ /* Enable stats */
Stats::initSimStats();
Stats::registerHandlers(CxxConfig::statsReset, CxxConfig::statsDump);
@@ -168,10 +178,9 @@ SimControl::SimControl(sc_core::sc_module_name name,
CxxConfigFileBase *conf = new CxxIniFile();
- if (!conf->load(config_file.c_str())) {
- std::cerr << "Can't open config file: " << config_file << '\n';
- std::exit(EXIT_FAILURE);
- }
+ if (!conf->load(config_file.c_str()))
+ fatal("Can't open config file: %s", config_file);
+
arg_ptr++;
config_manager = new CxxConfigManager(*conf);
@@ -231,8 +240,7 @@ SimControl::SimControl(sc_core::sc_module_name name,
}
}
} catch (CxxConfigManager::Exception &e) {
- std::cerr << e.name << ": " << e.message << "\n";
- std::exit(EXIT_FAILURE);
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
}
CxxConfig::statsEnable();
@@ -241,31 +249,51 @@ SimControl::SimControl(sc_core::sc_module_name name,
try {
config_manager->instantiate();
} catch (CxxConfigManager::Exception &e) {
- std::cerr << "Config problem in sim object " << e.name
- << ": " << e.message << "\n";
-
- std::exit(EXIT_FAILURE);
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
}
}
-void SimControl::before_end_of_elaboration()
+void SimControl::run()
{
- if (!checkpoint_restore) {
- try {
+ EventQueue *eventq = getEventQueue(0);
+ GlobalSimLoopExitEvent *exit_event = NULL;
+
+ /* There *must* be no scheduled events yet */
+ fatal_if(!eventq->empty(), "There must be no posted events"
+ " before SimControl::run");
+
+ try {
+ if (checkpoint_restore) {
+ std::cerr << "Restoring checkpoint\n";
+
+ Checkpoint *checkpoint = new Checkpoint(checkpoint_dir,
+ config_manager->getSimObjectResolver());
+
+ /* Catch SystemC up with gem5 after checkpoint restore.
+ * Note that gem5 leading SystemC is always a violation of the
+ * required relationship between the two, hence this careful
+ * catchup */
+ Tick systemc_time = sc_core::sc_time_stamp().value();
+ if (curTick() > systemc_time) {
+ Tick wait_period = curTick() - systemc_time;
+
+ std::cerr << "Waiting for " << wait_period << "ps for"
+ " SystemC to catch up to gem5\n";
+ wait(sc_core::sc_time(wait_period, sc_core::SC_PS));
+ }
+
+ config_manager->loadState(checkpoint);
+ config_manager->startup();
+ config_manager->drainResume();
+ } else {
config_manager->initState();
config_manager->startup();
- } catch (CxxConfigManager::Exception &e) {
- std::cerr << "Config problem in sim object " << e.name
- << ": " << e.message << "\n";
-
- std::exit(EXIT_FAILURE);
}
+ } catch (CxxConfigManager::Exception &e) {
+ fatal("Config problem in sim object %s: %s", e.name, e.message);
}
-}
-void SimControl::run()
-{
- GlobalSimLoopExitEvent *exit_event = NULL;
+ fatal_if(eventq->empty(), "No events to process after system startup");
if (checkpoint_save) {
exit_event = simulate(pre_run_time);
@@ -299,32 +327,6 @@ void SimControl::run()
config_manager->drainResume();
}
- if (checkpoint_restore) {
- std::cerr << "Restoring checkpoint\n";
-
- Checkpoint *checkpoint = new Checkpoint(checkpoint_dir,
- config_manager->getSimObjectResolver());
-
- Serializable::unserializeGlobals(checkpoint);
-
- /* gem5 time can have changed, so lets wait until SystemC
- * catches up */
- Tick systemc_time = sc_core::sc_time_stamp().value();
- if (curTick() > systemc_time) {
- Tick wait_period = curTick() - systemc_time;
-
- std::cerr << "Waiting for " << wait_period << "ps for"
- " SystemC to catch up to gem5\n";
- wait(sc_core::sc_time(wait_period, sc_core::SC_PS));
- }
-
- config_manager->loadState(checkpoint);
-
- config_manager->drainResume();
-
- std::cerr << "Restored from checkpoint\n";
- }
-
if (switch_cpus) {
exit_event = simulate(pre_switch_time);
@@ -350,6 +352,7 @@ void SimControl::run()
old_cpu.switchOut();
system.setMemoryMode(Enums::timing);
+
new_cpu.takeOverFrom(&old_cpu);
config_manager->drainResume();