X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fsim%2Froot.cc;h=9bb8b4f05cba5fcf886869915fa71e3a3b3e5518;hb=072f78471d11c31b6009beb572296f704912d0f7;hp=f4743af0a49d2b2151f231de19ad688699f09b32;hpb=d55b25cde6d2c072885a2c468d209fb18d6628e6;p=gem5.git diff --git a/src/sim/root.cc b/src/sim/root.cc index f4743af0a..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,37 +28,147 @@ * * Authors: Nathan Binkert * Steve Reinhardt + * Gabe Black */ -#include -#include -#include -#include -#include - #include "base/misc.hh" -#include "sim/builder.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" + +Root *Root::_root = NULL; + +/* + * 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); +} + +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); + } +} + +/// 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 -struct Root : public SimObject +Root::Root(RootParams *p) : SimObject(p), _enabled(false), + _periodTick(p->time_sync_period), syncEvent(this) { - Root(const std::string &name) : SimObject(name) {} -}; + _period.setTick(p->time_sync_period); + _spinThreshold.setTick(p->time_sync_spin_threshold); -BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root) + assert(_root == NULL); + _root = this; + lastTime.setTimer(); - Param dummy; // needed below + simQuantum = p->sim_quantum; +} -END_DECLARE_SIM_OBJECT_PARAMS(Root) +void +Root::initState() +{ + timeSyncEnable(params()->time_sync_enable); +} -BEGIN_INIT_SIM_OBJECT_PARAMS(Root) +void +Root::loadState(Checkpoint *cp) +{ + SimObject::loadState(cp); + timeSyncEnable(params()->time_sync_enable); +} - INIT_PARAM(dummy, "") // All SimObjects must have params +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); +} + +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"); + } +} -END_INIT_SIM_OBJECT_PARAMS(Root) -CREATE_SIM_OBJECT(Root) +bool FullSystem; +unsigned int FullSystemInt; + +Root * +RootParams::create() { static bool created = false; if (created) @@ -65,7 +176,8 @@ CREATE_SIM_OBJECT(Root) created = true; - return new Root(getInstanceName()); -} + FullSystem = full_system; + FullSystemInt = full_system ? 1 : 0; -REGISTER_SIM_OBJECT("Root", Root) + return new Root(this); +}