serialize.cc revision 11072
12SN/A/*
210905Sandreas.sandberg@arm.com * Copyright (c) 2015 ARM Limited
310905Sandreas.sandberg@arm.com * All rights reserved
410905Sandreas.sandberg@arm.com *
510905Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610905Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710905Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810905Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910905Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010905Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110905Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210905Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310905Sandreas.sandberg@arm.com *
141762SN/A * Copyright (c) 2002-2005 The Regents of The University of Michigan
159983Sstever@gmail.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
169983Sstever@gmail.com * Copyright (c) 2013 Mark D. Hill and David A. Wood
172SN/A * All rights reserved.
182SN/A *
192SN/A * Redistribution and use in source and binary forms, with or without
202SN/A * modification, are permitted provided that the following conditions are
212SN/A * met: redistributions of source code must retain the above copyright
222SN/A * notice, this list of conditions and the following disclaimer;
232SN/A * redistributions in binary form must reproduce the above copyright
242SN/A * notice, this list of conditions and the following disclaimer in the
252SN/A * documentation and/or other materials provided with the distribution;
262SN/A * neither the name of the copyright holders nor the names of its
272SN/A * contributors may be used to endorse or promote products derived from
282SN/A * this software without specific prior written permission.
292SN/A *
302SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
312SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
322SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
332SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
342SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
352SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
362SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
372SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
382SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
392SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
402SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
412665Ssaidi@eecs.umich.edu *
422760Sbinkertn@umich.edu * Authors: Nathan Binkert
432760Sbinkertn@umich.edu *          Erik Hallnor
442665Ssaidi@eecs.umich.edu *          Steve Reinhardt
4510905Sandreas.sandberg@arm.com *          Andreas Sandberg
462SN/A */
472SN/A
488229Snate@binkert.org#include <sys/stat.h>
492SN/A#include <sys/time.h>
50363SN/A#include <sys/types.h>
512SN/A
528229Snate@binkert.org#include <cerrno>
532SN/A#include <fstream>
542SN/A#include <list>
552SN/A#include <string>
562SN/A#include <vector>
572SN/A
5810907Sandreas.sandberg@arm.com#include "base/framebuffer.hh"
59363SN/A#include "base/inifile.hh"
6056SN/A#include "base/misc.hh"
611388SN/A#include "base/output.hh"
62217SN/A#include "base/str.hh"
63363SN/A#include "base/trace.hh"
6410905Sandreas.sandberg@arm.com#include "debug/Checkpoint.hh"
6556SN/A#include "sim/eventq.hh"
6656SN/A#include "sim/serialize.hh"
6756SN/A#include "sim/sim_events.hh"
681638SN/A#include "sim/sim_exit.hh"
6956SN/A#include "sim/sim_object.hh"
702SN/A
712356SN/A// For stat reset hack
722356SN/A#include "sim/stat_control.hh"
732356SN/A
742SN/Ausing namespace std;
752SN/A
764762Snate@binkert.org//
774762Snate@binkert.org// The base implementations use to_number for parsing and '<<' for
784762Snate@binkert.org// displaying, suitable for integer types.
794762Snate@binkert.org//
804762Snate@binkert.orgtemplate <class T>
814762Snate@binkert.orgbool
824762Snate@binkert.orgparseParam(const string &s, T &value)
834762Snate@binkert.org{
844762Snate@binkert.org    return to_number(s, value);
854762Snate@binkert.org}
864762Snate@binkert.org
874762Snate@binkert.orgtemplate <class T>
884762Snate@binkert.orgvoid
8910905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const T &value)
904762Snate@binkert.org{
914762Snate@binkert.org    os << value;
924762Snate@binkert.org}
934762Snate@binkert.org
944762Snate@binkert.org//
954762Snate@binkert.org// Template specializations:
964762Snate@binkert.org// - char (8-bit integer)
974762Snate@binkert.org// - floating-point types
984762Snate@binkert.org// - bool
994762Snate@binkert.org// - string
1004762Snate@binkert.org//
1014762Snate@binkert.org
1024762Snate@binkert.org// Treat 8-bit ints (chars) as ints on output, not as chars
1034762Snate@binkert.orgtemplate <>
1044762Snate@binkert.orgvoid
10510905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const char &value)
1067494Ssteve.reinhardt@amd.com{
1077494Ssteve.reinhardt@amd.com    os << (int)value;
1087494Ssteve.reinhardt@amd.com}
1097494Ssteve.reinhardt@amd.com
1107494Ssteve.reinhardt@amd.com
1117494Ssteve.reinhardt@amd.comtemplate <>
1127494Ssteve.reinhardt@amd.comvoid
11310905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const signed char &value)
1144762Snate@binkert.org{
1154762Snate@binkert.org    os << (int)value;
1164762Snate@binkert.org}
1174762Snate@binkert.org
1184762Snate@binkert.org
1194762Snate@binkert.orgtemplate <>
1204762Snate@binkert.orgvoid
12110905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const unsigned char &value)
1224762Snate@binkert.org{
1234762Snate@binkert.org    os << (unsigned int)value;
1244762Snate@binkert.org}
1254762Snate@binkert.org
1264762Snate@binkert.org
1274762Snate@binkert.orgtemplate <>
1284762Snate@binkert.orgbool
1294762Snate@binkert.orgparseParam(const string &s, float &value)
1304762Snate@binkert.org{
13110386Sandreas.hansson@arm.com    return to_number(s, value);
1324762Snate@binkert.org}
1334762Snate@binkert.org
1344762Snate@binkert.orgtemplate <>
1354762Snate@binkert.orgbool
1364762Snate@binkert.orgparseParam(const string &s, double &value)
1374762Snate@binkert.org{
13810386Sandreas.hansson@arm.com    return to_number(s, value);
1394762Snate@binkert.org}
1404762Snate@binkert.org
1414762Snate@binkert.orgtemplate <>
1424762Snate@binkert.orgbool
1434762Snate@binkert.orgparseParam(const string &s, bool &value)
1444762Snate@binkert.org{
14510386Sandreas.hansson@arm.com    return to_bool(s, value);
1464762Snate@binkert.org}
1474762Snate@binkert.org
1484762Snate@binkert.org// Display bools as strings
1494762Snate@binkert.orgtemplate <>
1504762Snate@binkert.orgvoid
15110905Sandreas.sandberg@arm.comshowParam(CheckpointOut &os, const bool &value)
1524762Snate@binkert.org{
1534762Snate@binkert.org    os << (value ? "true" : "false");
1544762Snate@binkert.org}
1554762Snate@binkert.org
1564762Snate@binkert.org
1574762Snate@binkert.org// String requires no processing to speak of
1584762Snate@binkert.orgtemplate <>
1594762Snate@binkert.orgbool
1604762Snate@binkert.orgparseParam(const string &s, string &value)
1614762Snate@binkert.org{
1624762Snate@binkert.org    value = s;
1634762Snate@binkert.org    return true;
1644762Snate@binkert.org}
1654762Snate@binkert.org
1662287SN/Aint Serializable::ckptMaxCount = 0;
1672287SN/Aint Serializable::ckptCount = 0;
1682287SN/Aint Serializable::ckptPrevCount = -1;
16910905Sandreas.sandberg@arm.comstd::stack<std::string> Serializable::path;
1702SN/A
171217SN/Atemplate <class T>
1722SN/Avoid
17310905Sandreas.sandberg@arm.comparamOut(CheckpointOut &os, const string &name, const T &param)
1742SN/A{
175217SN/A    os << name << "=";
176217SN/A    showParam(os, param);
177217SN/A    os << "\n";
1782SN/A}
1792SN/A
1804841Ssaidi@eecs.umich.edutemplate <class T>
1814841Ssaidi@eecs.umich.eduvoid
18210905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const vector<T> &param)
1834841Ssaidi@eecs.umich.edu{
1846227Snate@binkert.org    typename vector<T>::size_type size = param.size();
1854841Ssaidi@eecs.umich.edu    os << name << "=";
1864841Ssaidi@eecs.umich.edu    if (size > 0)
1874841Ssaidi@eecs.umich.edu        showParam(os, param[0]);
1886227Snate@binkert.org    for (typename vector<T>::size_type i = 1; i < size; ++i) {
1894841Ssaidi@eecs.umich.edu        os << " ";
1904841Ssaidi@eecs.umich.edu        showParam(os, param[i]);
1914841Ssaidi@eecs.umich.edu    }
1924841Ssaidi@eecs.umich.edu    os << "\n";
1934841Ssaidi@eecs.umich.edu}
1944841Ssaidi@eecs.umich.edu
1957948SAli.Saidi@ARM.comtemplate <class T>
1967948SAli.Saidi@ARM.comvoid
19710905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, const list<T> &param)
1987948SAli.Saidi@ARM.com{
1997948SAli.Saidi@ARM.com    typename list<T>::const_iterator it = param.begin();
2007948SAli.Saidi@ARM.com
2017948SAli.Saidi@ARM.com    os << name << "=";
2027948SAli.Saidi@ARM.com    if (param.size() > 0)
2037948SAli.Saidi@ARM.com        showParam(os, *it);
2047948SAli.Saidi@ARM.com    it++;
2057948SAli.Saidi@ARM.com    while (it != param.end()) {
2067948SAli.Saidi@ARM.com        os << " ";
2077948SAli.Saidi@ARM.com        showParam(os, *it);
2087948SAli.Saidi@ARM.com        it++;
2097948SAli.Saidi@ARM.com    }
2107948SAli.Saidi@ARM.com    os << "\n";
2117948SAli.Saidi@ARM.com}
212217SN/A
213217SN/Atemplate <class T>
214217SN/Avoid
21510905Sandreas.sandberg@arm.comparamIn(CheckpointIn &cp, const string &name, T &param)
2162SN/A{
21710905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2186225Snate@binkert.org    string str;
21910905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
220217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
221217SN/A    }
2222SN/A}
2232SN/A
2246820SLisa.Hsu@amd.comtemplate <class T>
2256820SLisa.Hsu@amd.combool
22610905Sandreas.sandberg@arm.comoptParamIn(CheckpointIn &cp, const string &name, T &param)
2276820SLisa.Hsu@amd.com{
22810905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2296820SLisa.Hsu@amd.com    string str;
23010905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str) || !parseParam(str, param)) {
2316820SLisa.Hsu@amd.com        warn("optional parameter %s:%s not present\n", section, name);
2326820SLisa.Hsu@amd.com        return false;
2336820SLisa.Hsu@amd.com    } else {
2346820SLisa.Hsu@amd.com        return true;
2356820SLisa.Hsu@amd.com    }
2366820SLisa.Hsu@amd.com}
237217SN/A
238217SN/Atemplate <class T>
239217SN/Avoid
24010905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name,
24110905Sandreas.sandberg@arm.com              const T *param, unsigned size)
242217SN/A{
243217SN/A    os << name << "=";
244217SN/A    if (size > 0)
245217SN/A        showParam(os, param[0]);
2466227Snate@binkert.org    for (unsigned i = 1; i < size; ++i) {
247217SN/A        os << " ";
248217SN/A        showParam(os, param[i]);
249217SN/A    }
250217SN/A    os << "\n";
251217SN/A}
252217SN/A
253217SN/A
254217SN/Atemplate <class T>
255217SN/Avoid
25610905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
257217SN/A{
25810905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2596225Snate@binkert.org    string str;
26010905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
261217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
262217SN/A    }
263217SN/A
264217SN/A    // code below stolen from VectorParam<T>::parse().
265217SN/A    // it would be nice to unify these somehow...
266217SN/A
267217SN/A    vector<string> tokens;
268217SN/A
269217SN/A    tokenize(tokens, str, ' ');
270217SN/A
271217SN/A    // Need this if we were doing a vector
272217SN/A    // value.resize(tokens.size());
273217SN/A
274217SN/A    if (tokens.size() != size) {
275217SN/A        fatal("Array size mismatch on %s:%s'\n", section, name);
276217SN/A    }
277217SN/A
2786227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
279217SN/A        // need to parse into local variable to handle vector<bool>,
280217SN/A        // for which operator[] returns a special reference class
281217SN/A        // that's not the same as 'bool&', (since it's a packed
282217SN/A        // vector)
28310905Sandreas.sandberg@arm.com        T scalar_value;
284217SN/A        if (!parseParam(tokens[i], scalar_value)) {
285217SN/A            string err("could not parse \"");
286217SN/A
287217SN/A            err += str;
288217SN/A            err += "\"";
289217SN/A
290217SN/A            fatal(err);
291217SN/A        }
292217SN/A
293217SN/A        // assign parsed value to vector
294217SN/A        param[i] = scalar_value;
295217SN/A    }
296217SN/A}
297217SN/A
2984841Ssaidi@eecs.umich.edutemplate <class T>
2994841Ssaidi@eecs.umich.eduvoid
30010905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
3014841Ssaidi@eecs.umich.edu{
30210905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3036225Snate@binkert.org    string str;
30410905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3054841Ssaidi@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3064841Ssaidi@eecs.umich.edu    }
3074841Ssaidi@eecs.umich.edu
3084841Ssaidi@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
3094841Ssaidi@eecs.umich.edu    // it would be nice to unify these somehow...
3104841Ssaidi@eecs.umich.edu
3114841Ssaidi@eecs.umich.edu    vector<string> tokens;
3124841Ssaidi@eecs.umich.edu
3134841Ssaidi@eecs.umich.edu    tokenize(tokens, str, ' ');
3144841Ssaidi@eecs.umich.edu
3154841Ssaidi@eecs.umich.edu    // Need this if we were doing a vector
3164841Ssaidi@eecs.umich.edu    // value.resize(tokens.size());
3174841Ssaidi@eecs.umich.edu
3184841Ssaidi@eecs.umich.edu    param.resize(tokens.size());
3194841Ssaidi@eecs.umich.edu
3206227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3214841Ssaidi@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3224841Ssaidi@eecs.umich.edu        // for which operator[] returns a special reference class
3234841Ssaidi@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3244841Ssaidi@eecs.umich.edu        // vector)
32510905Sandreas.sandberg@arm.com        T scalar_value;
3264841Ssaidi@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3274841Ssaidi@eecs.umich.edu            string err("could not parse \"");
3284841Ssaidi@eecs.umich.edu
3294841Ssaidi@eecs.umich.edu            err += str;
3304841Ssaidi@eecs.umich.edu            err += "\"";
3314841Ssaidi@eecs.umich.edu
3324841Ssaidi@eecs.umich.edu            fatal(err);
3334841Ssaidi@eecs.umich.edu        }
3344841Ssaidi@eecs.umich.edu
3354841Ssaidi@eecs.umich.edu        // assign parsed value to vector
3364841Ssaidi@eecs.umich.edu        param[i] = scalar_value;
3374841Ssaidi@eecs.umich.edu    }
3384841Ssaidi@eecs.umich.edu}
3394841Ssaidi@eecs.umich.edu
3407948SAli.Saidi@ARM.comtemplate <class T>
3417948SAli.Saidi@ARM.comvoid
34210905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
3437948SAli.Saidi@ARM.com{
34410905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3457948SAli.Saidi@ARM.com    string str;
34610905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3477948SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
3487948SAli.Saidi@ARM.com    }
3497948SAli.Saidi@ARM.com    param.clear();
3507948SAli.Saidi@ARM.com
3517948SAli.Saidi@ARM.com    vector<string> tokens;
3527948SAli.Saidi@ARM.com    tokenize(tokens, str, ' ');
3537948SAli.Saidi@ARM.com
3547948SAli.Saidi@ARM.com    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
35510905Sandreas.sandberg@arm.com        T scalar_value;
3567948SAli.Saidi@ARM.com        if (!parseParam(tokens[i], scalar_value)) {
3577948SAli.Saidi@ARM.com            string err("could not parse \"");
3587948SAli.Saidi@ARM.com
3597948SAli.Saidi@ARM.com            err += str;
3607948SAli.Saidi@ARM.com            err += "\"";
3617948SAli.Saidi@ARM.com
3627948SAli.Saidi@ARM.com            fatal(err);
3637948SAli.Saidi@ARM.com        }
3647948SAli.Saidi@ARM.com
3657948SAli.Saidi@ARM.com        // assign parsed value to vector
3667948SAli.Saidi@ARM.com        param.push_back(scalar_value);
3677948SAli.Saidi@ARM.com    }
3687948SAli.Saidi@ARM.com}
3697948SAli.Saidi@ARM.com
3707948SAli.Saidi@ARM.com
371237SN/Avoid
37210905Sandreas.sandberg@arm.comobjParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
373237SN/A{
37410905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
37510905Sandreas.sandberg@arm.com    if (!cp.findObj(section, name, param)) {
376237SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
377237SN/A    }
378237SN/A}
379237SN/A
380237SN/A
3815543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
38210905Sandreas.sandberg@arm.com    template void                                                       \
38310905Sandreas.sandberg@arm.com    paramOut(CheckpointOut &os, const string &name, type const &param); \
38410905Sandreas.sandberg@arm.com    template void                                                       \
38510905Sandreas.sandberg@arm.com    paramIn(CheckpointIn &cp, const string &name, type & param);        \
38610905Sandreas.sandberg@arm.com    template bool                                                       \
38710905Sandreas.sandberg@arm.com    optParamIn(CheckpointIn &cp, const string &name, type & param);     \
38810905Sandreas.sandberg@arm.com    template void                                                       \
38910905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
39010905Sandreas.sandberg@arm.com                  type const *param, unsigned size);                    \
39110905Sandreas.sandberg@arm.com    template void                                                       \
39210905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
39310905Sandreas.sandberg@arm.com                 type *param, unsigned size);                           \
39410905Sandreas.sandberg@arm.com    template void                                                       \
39510905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
39610905Sandreas.sandberg@arm.com                  const vector<type> &param);                           \
39710905Sandreas.sandberg@arm.com    template void                                                       \
39810905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
39910905Sandreas.sandberg@arm.com                 vector<type> &param);                                  \
40010905Sandreas.sandberg@arm.com    template void                                                       \
40110905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
40210905Sandreas.sandberg@arm.com                  const list<type> &param);                             \
40310905Sandreas.sandberg@arm.com    template void                                                       \
40410905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
40510905Sandreas.sandberg@arm.com                 list<type> &param);
406217SN/A
4077494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char)
4081642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char)
4091642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char)
4101642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short)
4111642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short)
4121642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int)
4131642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int)
4141642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long)
4151642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long)
4161642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long)
4171642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
418219SN/AINSTANTIATE_PARAM_TEMPLATES(bool)
4195992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float)
4205992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double)
421217SN/AINSTANTIATE_PARAM_TEMPLATES(string)
42210907Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(Pixel)
423217SN/A
424217SN/A
425395SN/A/////////////////////////////
426395SN/A
427395SN/A/// Container for serializing global variables (not associated with
428395SN/A/// any serialized object).
429395SN/Aclass Globals : public Serializable
4302SN/A{
431395SN/A  public:
43210905Sandreas.sandberg@arm.com    Globals()
43310905Sandreas.sandberg@arm.com        : unserializedCurTick(0) {}
43410905Sandreas.sandberg@arm.com
43510905Sandreas.sandberg@arm.com    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
43610905Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
43710905Sandreas.sandberg@arm.com
43810905Sandreas.sandberg@arm.com    Tick unserializedCurTick;
439395SN/A};
4402SN/A
441395SN/A/// The one and only instance of the Globals class.
442395SN/AGlobals globals;
4432SN/A
44410905Sandreas.sandberg@arm.comvoid
44510905Sandreas.sandberg@arm.comGlobals::serialize(CheckpointOut &cp) const
4462SN/A{
44710905Sandreas.sandberg@arm.com    paramOut(cp, "curTick", curTick());
4482SN/A}
4492SN/A
4502SN/Avoid
45110905Sandreas.sandberg@arm.comGlobals::unserialize(CheckpointIn &cp)
4522SN/A{
45310905Sandreas.sandberg@arm.com    paramIn(cp, "curTick", unserializedCurTick);
4542SN/A}
4552SN/A
4565739Snate@binkert.orgSerializable::Serializable()
4575739Snate@binkert.org{
4585739Snate@binkert.org}
4595739Snate@binkert.org
4605739Snate@binkert.orgSerializable::~Serializable()
4615739Snate@binkert.org{
4625739Snate@binkert.org}
4635739Snate@binkert.org
4645739Snate@binkert.orgvoid
46510905Sandreas.sandberg@arm.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const
4665739Snate@binkert.org{
46710905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
46810905Sandreas.sandberg@arm.com    serialize(cp);
4695739Snate@binkert.org}
4705739Snate@binkert.org
4715739Snate@binkert.orgvoid
47210905Sandreas.sandberg@arm.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name)
4735739Snate@binkert.org{
47410905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
47510905Sandreas.sandberg@arm.com    serializeOld(cp);
47610905Sandreas.sandberg@arm.com}
47710905Sandreas.sandberg@arm.com
47810905Sandreas.sandberg@arm.comvoid
47910905Sandreas.sandberg@arm.comSerializable::unserializeSection(CheckpointIn &cp, const char *name)
48010905Sandreas.sandberg@arm.com{
48110905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
48210905Sandreas.sandberg@arm.com    unserialize(cp);
4835739Snate@binkert.org}
4845739Snate@binkert.org
4852SN/Avoid
4866225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir)
4872SN/A{
48810905Sandreas.sandberg@arm.com    string dir = CheckpointIn::setDir(cpt_dir);
489363SN/A    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
490449SN/A            fatal("couldn't mkdir %s\n", dir);
491363SN/A
49210905Sandreas.sandberg@arm.com    string cpt_file = dir + CheckpointIn::baseFilename;
493395SN/A    ofstream outstream(cpt_file.c_str());
4942SN/A    time_t t = time(NULL);
4955581Ssaidi@eecs.umich.edu    if (!outstream.is_open())
4965581Ssaidi@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
4976818SLisa.Hsu@amd.com    outstream << "## checkpoint generated: " << ctime(&t);
4982SN/A
49910905Sandreas.sandberg@arm.com    globals.serializeSection(outstream, "Globals");
50010905Sandreas.sandberg@arm.com
501395SN/A    SimObject::serializeAll(outstream);
502395SN/A}
5032SN/A
5042797Sktlim@umich.eduvoid
50510905Sandreas.sandberg@arm.comSerializable::unserializeGlobals(CheckpointIn &cp)
506395SN/A{
50710905Sandreas.sandberg@arm.com    globals.unserializeSection(cp, "Globals");
50810905Sandreas.sandberg@arm.com
50911072Sandreas.sandberg@arm.com    for (uint32_t i = 0; i < numMainEventQueues; ++i)
51010905Sandreas.sandberg@arm.com        mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
51110905Sandreas.sandberg@arm.com}
51210905Sandreas.sandberg@arm.com
51310905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection()
51410905Sandreas.sandberg@arm.com{
51510905Sandreas.sandberg@arm.com    assert(!path.empty());
51610905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "Popping: %s\n", path.top());
51710905Sandreas.sandberg@arm.com    path.pop();
51810905Sandreas.sandberg@arm.com}
51910905Sandreas.sandberg@arm.com
52010905Sandreas.sandberg@arm.comvoid
52110905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::pushName(const char *obj_name)
52210905Sandreas.sandberg@arm.com{
52310905Sandreas.sandberg@arm.com    if (path.empty()) {
52410905Sandreas.sandberg@arm.com        path.push(obj_name);
52510905Sandreas.sandberg@arm.com    } else {
52610905Sandreas.sandberg@arm.com        path.push(csprintf("%s.%s", path.top(), obj_name));
52710905Sandreas.sandberg@arm.com    }
52810905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
52910905Sandreas.sandberg@arm.com}
53010905Sandreas.sandberg@arm.com
53110905Sandreas.sandberg@arm.comvoid
53210905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
53310905Sandreas.sandberg@arm.com{
53410905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
53510905Sandreas.sandberg@arm.com            Serializable::currentSection());
53610905Sandreas.sandberg@arm.com    cp << "\n[" << Serializable::currentSection() << "]\n";
537395SN/A}
5382SN/A
5392SN/Avoid
5406225Snate@binkert.orgdebug_serialize(const string &cpt_dir)
5412SN/A{
5422868Sktlim@umich.edu    Serializable::serializeAll(cpt_dir);
5432SN/A}
5442SN/A
54510905Sandreas.sandberg@arm.comconst std::string &
54610905Sandreas.sandberg@arm.comSerializable::currentSection()
54710905Sandreas.sandberg@arm.com{
54810905Sandreas.sandberg@arm.com    assert(!path.empty());
54910905Sandreas.sandberg@arm.com
55010905Sandreas.sandberg@arm.com    return path.top();
55110905Sandreas.sandberg@arm.com}
552237SN/A
55310905Sandreas.sandberg@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt";
5547491Ssteve.reinhardt@amd.com
55510905Sandreas.sandberg@arm.comstring CheckpointIn::currentDirectory;
5567491Ssteve.reinhardt@amd.com
5577491Ssteve.reinhardt@amd.comstring
55810905Sandreas.sandberg@arm.comCheckpointIn::setDir(const string &name)
5597491Ssteve.reinhardt@amd.com{
5607823Ssteve.reinhardt@amd.com    // use csprintf to insert curTick() into directory name if it
5617491Ssteve.reinhardt@amd.com    // appears to have a format placeholder in it.
5627491Ssteve.reinhardt@amd.com    currentDirectory = (name.find("%") != string::npos) ?
5637823Ssteve.reinhardt@amd.com        csprintf(name, curTick()) : name;
5647491Ssteve.reinhardt@amd.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
5657491Ssteve.reinhardt@amd.com        currentDirectory += "/";
5667491Ssteve.reinhardt@amd.com    return currentDirectory;
5677491Ssteve.reinhardt@amd.com}
5687491Ssteve.reinhardt@amd.com
5697491Ssteve.reinhardt@amd.comstring
57010905Sandreas.sandberg@arm.comCheckpointIn::dir()
5717491Ssteve.reinhardt@amd.com{
5727491Ssteve.reinhardt@amd.com    return currentDirectory;
5737491Ssteve.reinhardt@amd.com}
5747491Ssteve.reinhardt@amd.com
5757491Ssteve.reinhardt@amd.com
57610905Sandreas.sandberg@arm.comCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
57710453SAndrew.Bardsley@arm.com    : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
578237SN/A{
57910905Sandreas.sandberg@arm.com    string filename = cptDir + "/" + CheckpointIn::baseFilename;
580237SN/A    if (!db->load(filename)) {
581237SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
582237SN/A    }
583237SN/A}
584237SN/A
58510905Sandreas.sandberg@arm.comCheckpointIn::~CheckpointIn()
5869086Sandreas.hansson@arm.com{
5879086Sandreas.hansson@arm.com    delete db;
5889086Sandreas.hansson@arm.com}
589237SN/A
590237SN/Abool
59110905Sandreas.sandberg@arm.comCheckpointIn::find(const string &section, const string &entry, string &value)
592237SN/A{
593237SN/A    return db->find(section, entry, value);
594237SN/A}
595237SN/A
596237SN/A
597237SN/Abool
59810905Sandreas.sandberg@arm.comCheckpointIn::findObj(const string &section, const string &entry,
5994000Ssaidi@eecs.umich.edu                    SimObject *&value)
600237SN/A{
601237SN/A    string path;
602237SN/A
603237SN/A    if (!db->find(section, entry, path))
604237SN/A        return false;
605237SN/A
60610453SAndrew.Bardsley@arm.com    value = objNameResolver.resolveSimObject(path);
6074000Ssaidi@eecs.umich.edu    return true;
608237SN/A}
609304SN/A
610304SN/A
611304SN/Abool
61210905Sandreas.sandberg@arm.comCheckpointIn::sectionExists(const string &section)
613304SN/A{
614304SN/A    return db->sectionExists(section);
615304SN/A}
616