X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Froot.cc;h=9bb8b4f05cba5fcf886869915fa71e3a3b3e5518;hb=072f78471d11c31b6009beb572296f704912d0f7;hp=565b57269ca0290ca8bfb19c271f14758b59f7d5;hpb=c42a7bc4f6c03703e17fb55afe5ba8e2d920e5d5;p=gem5.git diff --git a/src/sim/root.cc b/src/sim/root.cc index 565b57269..9bb8b4f05 100644 --- a/src/sim/root.cc +++ b/src/sim/root.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2011 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,104 +28,147 @@ * * Authors: Nathan Binkert * Steve Reinhardt + * Gabe Black */ -#include -#include -#include -#include -#include - #include "base/misc.hh" -#include "base/output.hh" -#include "sim/builder.hh" -#include "sim/host.hh" -#include "sim/sim_events.hh" -#include "sim/sim_exit.hh" -#include "sim/sim_object.hh" +#include "base/trace.hh" +#include "config/the_isa.hh" +#include "debug/TimeSync.hh" +#include "sim/full_system.hh" #include "sim/root.hh" -using namespace std; - -Tick curTick = 0; -ostream *outputStream; -ostream *configStream; - -/// The simulated frequency of curTick. (This is only here for a short time) -Tick ticksPerSecond; - -namespace Clock { -/// The simulated frequency of curTick. (In ticks per second) -Tick Frequency; - -namespace Float { -double s; -double ms; -double us; -double ns; -double ps; +Root *Root::_root = NULL; -double Hz; -double kHz; -double MHz; -double GHZ; -/* namespace Float */ } +/* + * This function is called periodically by an event in M5 and ensures that + * at least as much real time has passed between invocations as simulated time. + * If not, the function either sleeps, or if the difference is small enough + * spin waits. + */ +void +Root::timeSync() +{ + Time cur_time, diff, period = timeSyncPeriod(); + + do { + cur_time.setTimer(); + diff = cur_time - lastTime; + Time remainder = period - diff; + if (diff < period && remainder > _spinThreshold) { + DPRINTF(TimeSync, "Sleeping to sync with real time.\n"); + // Sleep until the end of the period, or until a signal. + sleep(remainder); + // Refresh the current time. + cur_time.setTimer(); + } + } while (diff < period); + lastTime = cur_time; + schedule(&syncEvent, curTick() + _periodTick); +} -namespace Int { -Tick s; -Tick ms; -Tick us; -Tick ns; -Tick ps; -/* namespace Float */ } +void +Root::timeSyncEnable(bool en) +{ + if (en == _enabled) + return; + _enabled = en; + if (_enabled) { + // Get event going. + Tick periods = ((curTick() + _periodTick - 1) / _periodTick); + Tick nextPeriod = periods * _periodTick; + schedule(&syncEvent, nextPeriod); + } else { + // Stop event. + deschedule(&syncEvent); + } +} -/* namespace Clock */ } +/// Configure the period for time sync events. +void +Root::timeSyncPeriod(Time newPeriod) +{ + bool en = timeSyncEnabled(); + _period = newPeriod; + _periodTick = _period.getTick(); + timeSyncEnable(en); +} +/// Set the threshold for time remaining to spin wait. +void +Root::timeSyncSpinThreshold(Time newThreshold) +{ + bool en = timeSyncEnabled(); + _spinThreshold = newThreshold; + timeSyncEnable(en); +} -// Dummy Object -class Root : public SimObject +Root::Root(RootParams *p) : SimObject(p), _enabled(false), + _periodTick(p->time_sync_period), syncEvent(this) { - private: - Tick max_tick; - Tick progress_interval; + _period.setTick(p->time_sync_period); + _spinThreshold.setTick(p->time_sync_spin_threshold); - public: - Root(const std::string &name, Tick maxtick, Tick pi) - : SimObject(name), max_tick(maxtick), progress_interval(pi) - {} + assert(_root == NULL); + _root = this; + lastTime.setTimer(); - virtual void startup(); -}; + simQuantum = p->sim_quantum; +} void -Root::startup() +Root::initState() { - if (max_tick != 0) - schedExitSimLoop("reached maximum cycle count", curTick + max_tick); - - if (progress_interval != 0) - new ProgressEvent(&mainEventQueue, progress_interval); + timeSyncEnable(params()->time_sync_enable); } -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root) - - Param clock; - Param max_tick; - Param progress_interval; - Param output_file; +void +Root::loadState(Checkpoint *cp) +{ + SimObject::loadState(cp); + timeSyncEnable(params()->time_sync_enable); +} -END_DECLARE_SIM_OBJECT_PARAMS(Root) +void +Root::serialize(std::ostream &os) +{ + uint64_t cpt_ver = gem5CheckpointVersion; + SERIALIZE_SCALAR(cpt_ver); + SERIALIZE_SCALAR(FullSystem); + std::string isa = THE_ISA_STR; + SERIALIZE_SCALAR(isa); +} -BEGIN_INIT_SIM_OBJECT_PARAMS(Root) +void +Root::unserialize(Checkpoint *cp, const std::string §ion) +{ + uint64_t cpt_ver = 0; + UNSERIALIZE_OPT_SCALAR(cpt_ver); + if (cpt_ver < gem5CheckpointVersion) { + warn("**********************************************************\n"); + warn("!!!! Checkpoint ver %#x is older than current ver %#x !!!!\n", + cpt_ver, gem5CheckpointVersion); + warn("You might experience some issues when restoring and should run " + "the checkpoint upgrader (util/cpt_upgrader.py) on your " + "checkpoint\n"); + warn("**********************************************************\n"); + } else if (cpt_ver > gem5CheckpointVersion) { + warn("**********************************************************\n"); + warn("!!!! Checkpoint ver %#x is newer than current ver %#x !!!!\n", + cpt_ver, gem5CheckpointVersion); + warn("Running a new checkpoint with an older version of gem5 is not " + "supported. While it might work, you may experience incorrect " + "behavior or crashes.\n"); + warn("**********************************************************\n"); + } +} - INIT_PARAM(clock, "tick frequency"), - INIT_PARAM(max_tick, "maximum simulation time"), - INIT_PARAM(progress_interval, "print a progress message"), - INIT_PARAM(output_file, "file to dump simulator output to") -END_INIT_SIM_OBJECT_PARAMS(Root) +bool FullSystem; +unsigned int FullSystemInt; -CREATE_SIM_OBJECT(Root) +Root * +RootParams::create() { static bool created = false; if (created) @@ -132,29 +176,8 @@ CREATE_SIM_OBJECT(Root) created = true; - outputStream = simout.find(output_file); - Root *root = new Root(getInstanceName(), max_tick, progress_interval); - - using namespace Clock; - Frequency = clock; - Float::s = static_cast(Frequency); - Float::ms = Float::s / 1.0e3; - Float::us = Float::s / 1.0e6; - Float::ns = Float::s / 1.0e9; - Float::ps = Float::s / 1.0e12; - - Float::Hz = 1.0 / Float::s; - Float::kHz = 1.0 / Float::ms; - Float::MHz = 1.0 / Float::us; - Float::GHZ = 1.0 / Float::ns; - - Int::s = Frequency; - Int::ms = Int::s / 1000; - Int::us = Int::ms / 1000; - Int::ns = Int::us / 1000; - Int::ps = Int::ns / 1000; - - return root; -} + FullSystem = full_system; + FullSystemInt = full_system ? 1 : 0; -REGISTER_SIM_OBJECT("Root", Root) + return new Root(this); +}