root.cc revision 9983
12SN/A/*
21762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
38332Snate@binkert.org * Copyright (c) 2011 Advanced Micro Devices, Inc.
42SN/A * All rights reserved.
52SN/A *
62SN/A * Redistribution and use in source and binary forms, with or without
72SN/A * modification, are permitted provided that the following conditions are
82SN/A * met: redistributions of source code must retain the above copyright
92SN/A * notice, this list of conditions and the following disclaimer;
102SN/A * redistributions in binary form must reproduce the above copyright
112SN/A * notice, this list of conditions and the following disclaimer in the
122SN/A * documentation and/or other materials provided with the distribution;
132SN/A * neither the name of the copyright holders nor the names of its
142SN/A * contributors may be used to endorse or promote products derived from
152SN/A * this software without specific prior written permission.
162SN/A *
172SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
212SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
222SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
232SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
242SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
252SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
262SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
272SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282665Ssaidi@eecs.umich.edu *
292665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
302665Ssaidi@eecs.umich.edu *          Steve Reinhardt
317861Sgblack@eecs.umich.edu *          Gabe Black
322SN/A */
332SN/A
34488SN/A#include "base/misc.hh"
359356Snilay@cs.wisc.edu#include "base/trace.hh"
369048SAli.Saidi@ARM.com#include "config/the_isa.hh"
378232Snate@binkert.org#include "debug/TimeSync.hh"
388801Sgblack@eecs.umich.edu#include "sim/full_system.hh"
397861Sgblack@eecs.umich.edu#include "sim/root.hh"
401609SN/A
417861Sgblack@eecs.umich.eduRoot *Root::_root = NULL;
427861Sgblack@eecs.umich.edu
437861Sgblack@eecs.umich.edu/*
447861Sgblack@eecs.umich.edu * This function is called periodically by an event in M5 and ensures that
457861Sgblack@eecs.umich.edu * at least as much real time has passed between invocations as simulated time.
467861Sgblack@eecs.umich.edu * If not, the function either sleeps, or if the difference is small enough
477861Sgblack@eecs.umich.edu * spin waits.
487861Sgblack@eecs.umich.edu */
497861Sgblack@eecs.umich.eduvoid
507861Sgblack@eecs.umich.eduRoot::timeSync()
512SN/A{
527861Sgblack@eecs.umich.edu    Time cur_time, diff, period = timeSyncPeriod();
537861Sgblack@eecs.umich.edu
547861Sgblack@eecs.umich.edu    do {
557861Sgblack@eecs.umich.edu        cur_time.setTimer();
567861Sgblack@eecs.umich.edu        diff = cur_time - lastTime;
577861Sgblack@eecs.umich.edu        Time remainder = period - diff;
587861Sgblack@eecs.umich.edu        if (diff < period && remainder > _spinThreshold) {
597861Sgblack@eecs.umich.edu            DPRINTF(TimeSync, "Sleeping to sync with real time.\n");
607861Sgblack@eecs.umich.edu            // Sleep until the end of the period, or until a signal.
617861Sgblack@eecs.umich.edu            sleep(remainder);
627861Sgblack@eecs.umich.edu            // Refresh the current time.
637861Sgblack@eecs.umich.edu            cur_time.setTimer();
647861Sgblack@eecs.umich.edu        }
657861Sgblack@eecs.umich.edu    } while (diff < period);
667861Sgblack@eecs.umich.edu    lastTime = cur_time;
677861Sgblack@eecs.umich.edu    schedule(&syncEvent, curTick() + _periodTick);
687861Sgblack@eecs.umich.edu}
697861Sgblack@eecs.umich.edu
707861Sgblack@eecs.umich.eduvoid
717861Sgblack@eecs.umich.eduRoot::timeSyncEnable(bool en)
727861Sgblack@eecs.umich.edu{
737861Sgblack@eecs.umich.edu    if (en == _enabled)
747861Sgblack@eecs.umich.edu        return;
757861Sgblack@eecs.umich.edu    _enabled = en;
767861Sgblack@eecs.umich.edu    if (_enabled) {
777861Sgblack@eecs.umich.edu        // Get event going.
787861Sgblack@eecs.umich.edu        Tick periods = ((curTick() + _periodTick - 1) / _periodTick);
797861Sgblack@eecs.umich.edu        Tick nextPeriod = periods * _periodTick;
807861Sgblack@eecs.umich.edu        schedule(&syncEvent, nextPeriod);
817861Sgblack@eecs.umich.edu    } else {
827861Sgblack@eecs.umich.edu        // Stop event.
837861Sgblack@eecs.umich.edu        deschedule(&syncEvent);
847861Sgblack@eecs.umich.edu    }
857861Sgblack@eecs.umich.edu}
867861Sgblack@eecs.umich.edu
877861Sgblack@eecs.umich.edu/// Configure the period for time sync events.
887861Sgblack@eecs.umich.eduvoid
897861Sgblack@eecs.umich.eduRoot::timeSyncPeriod(Time newPeriod)
907861Sgblack@eecs.umich.edu{
917861Sgblack@eecs.umich.edu    bool en = timeSyncEnabled();
927861Sgblack@eecs.umich.edu    _period = newPeriod;
937863Sgblack@eecs.umich.edu    _periodTick = _period.getTick();
947861Sgblack@eecs.umich.edu    timeSyncEnable(en);
957861Sgblack@eecs.umich.edu}
967861Sgblack@eecs.umich.edu
977861Sgblack@eecs.umich.edu/// Set the threshold for time remaining to spin wait.
987861Sgblack@eecs.umich.eduvoid
997861Sgblack@eecs.umich.eduRoot::timeSyncSpinThreshold(Time newThreshold)
1007861Sgblack@eecs.umich.edu{
1017861Sgblack@eecs.umich.edu    bool en = timeSyncEnabled();
1027861Sgblack@eecs.umich.edu    _spinThreshold = newThreshold;
1037861Sgblack@eecs.umich.edu    timeSyncEnable(en);
1047861Sgblack@eecs.umich.edu}
1057861Sgblack@eecs.umich.edu
1067861Sgblack@eecs.umich.eduRoot::Root(RootParams *p) : SimObject(p), _enabled(false),
1077861Sgblack@eecs.umich.edu    _periodTick(p->time_sync_period), syncEvent(this)
1087861Sgblack@eecs.umich.edu{
1097863Sgblack@eecs.umich.edu    _period.setTick(p->time_sync_period);
1107863Sgblack@eecs.umich.edu    _spinThreshold.setTick(p->time_sync_spin_threshold);
1117861Sgblack@eecs.umich.edu
1127861Sgblack@eecs.umich.edu    assert(_root == NULL);
1137861Sgblack@eecs.umich.edu    _root = this;
1147861Sgblack@eecs.umich.edu    lastTime.setTimer();
1159983Sstever@gmail.com
1169983Sstever@gmail.com    simQuantum = p->sim_quantum;
1177942SAli.Saidi@ARM.com}
1187942SAli.Saidi@ARM.com
1197942SAli.Saidi@ARM.comvoid
1207942SAli.Saidi@ARM.comRoot::initState()
1217942SAli.Saidi@ARM.com{
1227942SAli.Saidi@ARM.com    timeSyncEnable(params()->time_sync_enable);
1237942SAli.Saidi@ARM.com}
1247942SAli.Saidi@ARM.com
1257942SAli.Saidi@ARM.comvoid
1267942SAli.Saidi@ARM.comRoot::loadState(Checkpoint *cp)
1277942SAli.Saidi@ARM.com{
1289048SAli.Saidi@ARM.com    SimObject::loadState(cp);
1297942SAli.Saidi@ARM.com    timeSyncEnable(params()->time_sync_enable);
1307861Sgblack@eecs.umich.edu}
1311104SN/A
1329048SAli.Saidi@ARM.comvoid
1339048SAli.Saidi@ARM.comRoot::serialize(std::ostream &os)
1349048SAli.Saidi@ARM.com{
1359048SAli.Saidi@ARM.com    uint64_t cpt_ver = gem5CheckpointVersion;
1369048SAli.Saidi@ARM.com    SERIALIZE_SCALAR(cpt_ver);
1379048SAli.Saidi@ARM.com    SERIALIZE_SCALAR(FullSystem);
1389048SAli.Saidi@ARM.com    std::string isa = THE_ISA_STR;
1399048SAli.Saidi@ARM.com    SERIALIZE_SCALAR(isa);
1409048SAli.Saidi@ARM.com}
1419048SAli.Saidi@ARM.com
1429048SAli.Saidi@ARM.comvoid
1439048SAli.Saidi@ARM.comRoot::unserialize(Checkpoint *cp, const std::string &section)
1449048SAli.Saidi@ARM.com{
1459048SAli.Saidi@ARM.com    uint64_t cpt_ver = 0;
1469048SAli.Saidi@ARM.com    UNSERIALIZE_OPT_SCALAR(cpt_ver);
1479048SAli.Saidi@ARM.com    if (cpt_ver < gem5CheckpointVersion) {
1489048SAli.Saidi@ARM.com        warn("**********************************************************\n");
1499048SAli.Saidi@ARM.com        warn("!!!! Checkpoint ver %#x is older than current ver %#x !!!!\n",
1509048SAli.Saidi@ARM.com                cpt_ver, gem5CheckpointVersion);
1519048SAli.Saidi@ARM.com        warn("You might experience some issues when restoring and should run "
1529293Sandreas.hansson@arm.com             "the checkpoint upgrader (util/cpt_upgrader.py) on your "
1539048SAli.Saidi@ARM.com             "checkpoint\n");
1549048SAli.Saidi@ARM.com        warn("**********************************************************\n");
1559048SAli.Saidi@ARM.com    } else if (cpt_ver > gem5CheckpointVersion) {
1569048SAli.Saidi@ARM.com        warn("**********************************************************\n");
1579048SAli.Saidi@ARM.com        warn("!!!! Checkpoint ver %#x is newer than current ver %#x !!!!\n",
1589048SAli.Saidi@ARM.com                cpt_ver, gem5CheckpointVersion);
1599048SAli.Saidi@ARM.com        warn("Running a new checkpoint with an older version of gem5 is not "
1609048SAli.Saidi@ARM.com             "supported. While it might work, you may experience incorrect "
1619048SAli.Saidi@ARM.com             "behavior or crashes.\n");
1629048SAli.Saidi@ARM.com        warn("**********************************************************\n");
1639048SAli.Saidi@ARM.com     }
1649048SAli.Saidi@ARM.com}
1659048SAli.Saidi@ARM.com
1669048SAli.Saidi@ARM.com
1678801Sgblack@eecs.umich.edubool FullSystem;
1688901Sandreas.hansson@arm.comunsigned int FullSystemInt;
1698801Sgblack@eecs.umich.edu
1704762Snate@binkert.orgRoot *
1714762Snate@binkert.orgRootParams::create()
1721310SN/A{
1731388SN/A    static bool created = false;
1741388SN/A    if (created)
1751388SN/A        panic("only one root object allowed!");
1761388SN/A
1771388SN/A    created = true;
1781310SN/A
1798801Sgblack@eecs.umich.edu    FullSystem = full_system;
1808901Sandreas.hansson@arm.com    FullSystemInt = full_system ? 1 : 0;
1818801Sgblack@eecs.umich.edu
1824762Snate@binkert.org    return new Root(this);
1831310SN/A}
184