serialize.cc revision 11075
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
22611075SCurtis.Dunham@arm.comoptParamIn(CheckpointIn &cp, const string &name, T &param, bool warn)
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)) {
23111075SCurtis.Dunham@arm.com        if (warn)
23211075SCurtis.Dunham@arm.com            warn("optional parameter %s:%s not present\n", section, name);
2336820SLisa.Hsu@amd.com        return false;
2346820SLisa.Hsu@amd.com    } else {
2356820SLisa.Hsu@amd.com        return true;
2366820SLisa.Hsu@amd.com    }
2376820SLisa.Hsu@amd.com}
238217SN/A
239217SN/Atemplate <class T>
240217SN/Avoid
24110905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name,
24210905Sandreas.sandberg@arm.com              const T *param, unsigned size)
243217SN/A{
244217SN/A    os << name << "=";
245217SN/A    if (size > 0)
246217SN/A        showParam(os, param[0]);
2476227Snate@binkert.org    for (unsigned i = 1; i < size; ++i) {
248217SN/A        os << " ";
249217SN/A        showParam(os, param[i]);
250217SN/A    }
251217SN/A    os << "\n";
252217SN/A}
253217SN/A
254217SN/A
255217SN/Atemplate <class T>
256217SN/Avoid
25710905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size)
258217SN/A{
25910905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
2606225Snate@binkert.org    string str;
26110905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
262217SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
263217SN/A    }
264217SN/A
265217SN/A    // code below stolen from VectorParam<T>::parse().
266217SN/A    // it would be nice to unify these somehow...
267217SN/A
268217SN/A    vector<string> tokens;
269217SN/A
270217SN/A    tokenize(tokens, str, ' ');
271217SN/A
272217SN/A    // Need this if we were doing a vector
273217SN/A    // value.resize(tokens.size());
274217SN/A
275217SN/A    if (tokens.size() != size) {
276217SN/A        fatal("Array size mismatch on %s:%s'\n", section, name);
277217SN/A    }
278217SN/A
2796227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
280217SN/A        // need to parse into local variable to handle vector<bool>,
281217SN/A        // for which operator[] returns a special reference class
282217SN/A        // that's not the same as 'bool&', (since it's a packed
283217SN/A        // vector)
28410905Sandreas.sandberg@arm.com        T scalar_value;
285217SN/A        if (!parseParam(tokens[i], scalar_value)) {
286217SN/A            string err("could not parse \"");
287217SN/A
288217SN/A            err += str;
289217SN/A            err += "\"";
290217SN/A
291217SN/A            fatal(err);
292217SN/A        }
293217SN/A
294217SN/A        // assign parsed value to vector
295217SN/A        param[i] = scalar_value;
296217SN/A    }
297217SN/A}
298217SN/A
2994841Ssaidi@eecs.umich.edutemplate <class T>
3004841Ssaidi@eecs.umich.eduvoid
30110905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, vector<T> &param)
3024841Ssaidi@eecs.umich.edu{
30310905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3046225Snate@binkert.org    string str;
30510905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3064841Ssaidi@eecs.umich.edu        fatal("Can't unserialize '%s:%s'\n", section, name);
3074841Ssaidi@eecs.umich.edu    }
3084841Ssaidi@eecs.umich.edu
3094841Ssaidi@eecs.umich.edu    // code below stolen from VectorParam<T>::parse().
3104841Ssaidi@eecs.umich.edu    // it would be nice to unify these somehow...
3114841Ssaidi@eecs.umich.edu
3124841Ssaidi@eecs.umich.edu    vector<string> tokens;
3134841Ssaidi@eecs.umich.edu
3144841Ssaidi@eecs.umich.edu    tokenize(tokens, str, ' ');
3154841Ssaidi@eecs.umich.edu
3164841Ssaidi@eecs.umich.edu    // Need this if we were doing a vector
3174841Ssaidi@eecs.umich.edu    // value.resize(tokens.size());
3184841Ssaidi@eecs.umich.edu
3194841Ssaidi@eecs.umich.edu    param.resize(tokens.size());
3204841Ssaidi@eecs.umich.edu
3216227Snate@binkert.org    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
3224841Ssaidi@eecs.umich.edu        // need to parse into local variable to handle vector<bool>,
3234841Ssaidi@eecs.umich.edu        // for which operator[] returns a special reference class
3244841Ssaidi@eecs.umich.edu        // that's not the same as 'bool&', (since it's a packed
3254841Ssaidi@eecs.umich.edu        // vector)
32610905Sandreas.sandberg@arm.com        T scalar_value;
3274841Ssaidi@eecs.umich.edu        if (!parseParam(tokens[i], scalar_value)) {
3284841Ssaidi@eecs.umich.edu            string err("could not parse \"");
3294841Ssaidi@eecs.umich.edu
3304841Ssaidi@eecs.umich.edu            err += str;
3314841Ssaidi@eecs.umich.edu            err += "\"";
3324841Ssaidi@eecs.umich.edu
3334841Ssaidi@eecs.umich.edu            fatal(err);
3344841Ssaidi@eecs.umich.edu        }
3354841Ssaidi@eecs.umich.edu
3364841Ssaidi@eecs.umich.edu        // assign parsed value to vector
3374841Ssaidi@eecs.umich.edu        param[i] = scalar_value;
3384841Ssaidi@eecs.umich.edu    }
3394841Ssaidi@eecs.umich.edu}
3404841Ssaidi@eecs.umich.edu
3417948SAli.Saidi@ARM.comtemplate <class T>
3427948SAli.Saidi@ARM.comvoid
34310905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, list<T> &param)
3447948SAli.Saidi@ARM.com{
34510905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
3467948SAli.Saidi@ARM.com    string str;
34710905Sandreas.sandberg@arm.com    if (!cp.find(section, name, str)) {
3487948SAli.Saidi@ARM.com        fatal("Can't unserialize '%s:%s'\n", section, name);
3497948SAli.Saidi@ARM.com    }
3507948SAli.Saidi@ARM.com    param.clear();
3517948SAli.Saidi@ARM.com
3527948SAli.Saidi@ARM.com    vector<string> tokens;
3537948SAli.Saidi@ARM.com    tokenize(tokens, str, ' ');
3547948SAli.Saidi@ARM.com
3557948SAli.Saidi@ARM.com    for (vector<string>::size_type i = 0; i < tokens.size(); i++) {
35610905Sandreas.sandberg@arm.com        T scalar_value;
3577948SAli.Saidi@ARM.com        if (!parseParam(tokens[i], scalar_value)) {
3587948SAli.Saidi@ARM.com            string err("could not parse \"");
3597948SAli.Saidi@ARM.com
3607948SAli.Saidi@ARM.com            err += str;
3617948SAli.Saidi@ARM.com            err += "\"";
3627948SAli.Saidi@ARM.com
3637948SAli.Saidi@ARM.com            fatal(err);
3647948SAli.Saidi@ARM.com        }
3657948SAli.Saidi@ARM.com
3667948SAli.Saidi@ARM.com        // assign parsed value to vector
3677948SAli.Saidi@ARM.com        param.push_back(scalar_value);
3687948SAli.Saidi@ARM.com    }
3697948SAli.Saidi@ARM.com}
3707948SAli.Saidi@ARM.com
3717948SAli.Saidi@ARM.com
372237SN/Avoid
37310905Sandreas.sandberg@arm.comobjParamIn(CheckpointIn &cp, const string &name, SimObject * &param)
374237SN/A{
37510905Sandreas.sandberg@arm.com    const string &section(Serializable::currentSection());
37610905Sandreas.sandberg@arm.com    if (!cp.findObj(section, name, param)) {
377237SN/A        fatal("Can't unserialize '%s:%s'\n", section, name);
378237SN/A    }
379237SN/A}
380237SN/A
381237SN/A
3825543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type)                               \
38310905Sandreas.sandberg@arm.com    template void                                                       \
38410905Sandreas.sandberg@arm.com    paramOut(CheckpointOut &os, const string &name, type const &param); \
38510905Sandreas.sandberg@arm.com    template void                                                       \
38610905Sandreas.sandberg@arm.com    paramIn(CheckpointIn &cp, const string &name, type & param);        \
38710905Sandreas.sandberg@arm.com    template bool                                                       \
38811075SCurtis.Dunham@arm.com    optParamIn(CheckpointIn &cp, const string &name, type & param,      \
38911075SCurtis.Dunham@arm.com               bool warn);                                              \
39010905Sandreas.sandberg@arm.com    template void                                                       \
39110905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
39210905Sandreas.sandberg@arm.com                  type const *param, unsigned size);                    \
39310905Sandreas.sandberg@arm.com    template void                                                       \
39410905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
39510905Sandreas.sandberg@arm.com                 type *param, unsigned size);                           \
39610905Sandreas.sandberg@arm.com    template void                                                       \
39710905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
39810905Sandreas.sandberg@arm.com                  const vector<type> &param);                           \
39910905Sandreas.sandberg@arm.com    template void                                                       \
40010905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
40110905Sandreas.sandberg@arm.com                 vector<type> &param);                                  \
40210905Sandreas.sandberg@arm.com    template void                                                       \
40310905Sandreas.sandberg@arm.com    arrayParamOut(CheckpointOut &os, const string &name,                \
40410905Sandreas.sandberg@arm.com                  const list<type> &param);                             \
40510905Sandreas.sandberg@arm.com    template void                                                       \
40610905Sandreas.sandberg@arm.com    arrayParamIn(CheckpointIn &cp, const string &name,                  \
40710905Sandreas.sandberg@arm.com                 list<type> &param);
408217SN/A
4097494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char)
4101642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char)
4111642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char)
4121642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short)
4131642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short)
4141642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int)
4151642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int)
4161642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long)
4171642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long)
4181642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long)
4191642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long)
420219SN/AINSTANTIATE_PARAM_TEMPLATES(bool)
4215992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float)
4225992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double)
423217SN/AINSTANTIATE_PARAM_TEMPLATES(string)
42410907Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(Pixel)
425217SN/A
426217SN/A
427395SN/A/////////////////////////////
428395SN/A
429395SN/A/// Container for serializing global variables (not associated with
430395SN/A/// any serialized object).
431395SN/Aclass Globals : public Serializable
4322SN/A{
433395SN/A  public:
43410905Sandreas.sandberg@arm.com    Globals()
43510905Sandreas.sandberg@arm.com        : unserializedCurTick(0) {}
43610905Sandreas.sandberg@arm.com
43710905Sandreas.sandberg@arm.com    void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
43810905Sandreas.sandberg@arm.com    void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
43910905Sandreas.sandberg@arm.com
44010905Sandreas.sandberg@arm.com    Tick unserializedCurTick;
441395SN/A};
4422SN/A
443395SN/A/// The one and only instance of the Globals class.
444395SN/AGlobals globals;
4452SN/A
44610905Sandreas.sandberg@arm.comvoid
44710905Sandreas.sandberg@arm.comGlobals::serialize(CheckpointOut &cp) const
4482SN/A{
44910905Sandreas.sandberg@arm.com    paramOut(cp, "curTick", curTick());
4502SN/A}
4512SN/A
4522SN/Avoid
45310905Sandreas.sandberg@arm.comGlobals::unserialize(CheckpointIn &cp)
4542SN/A{
45510905Sandreas.sandberg@arm.com    paramIn(cp, "curTick", unserializedCurTick);
4562SN/A}
4572SN/A
4585739Snate@binkert.orgSerializable::Serializable()
4595739Snate@binkert.org{
4605739Snate@binkert.org}
4615739Snate@binkert.org
4625739Snate@binkert.orgSerializable::~Serializable()
4635739Snate@binkert.org{
4645739Snate@binkert.org}
4655739Snate@binkert.org
4665739Snate@binkert.orgvoid
46710905Sandreas.sandberg@arm.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const
4685739Snate@binkert.org{
46910905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
47010905Sandreas.sandberg@arm.com    serialize(cp);
4715739Snate@binkert.org}
4725739Snate@binkert.org
4735739Snate@binkert.orgvoid
47410905Sandreas.sandberg@arm.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name)
4755739Snate@binkert.org{
47610905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
47710905Sandreas.sandberg@arm.com    serializeOld(cp);
47810905Sandreas.sandberg@arm.com}
47910905Sandreas.sandberg@arm.com
48010905Sandreas.sandberg@arm.comvoid
48110905Sandreas.sandberg@arm.comSerializable::unserializeSection(CheckpointIn &cp, const char *name)
48210905Sandreas.sandberg@arm.com{
48310905Sandreas.sandberg@arm.com    Serializable::ScopedCheckpointSection sec(cp, name);
48410905Sandreas.sandberg@arm.com    unserialize(cp);
4855739Snate@binkert.org}
4865739Snate@binkert.org
4872SN/Avoid
4886225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir)
4892SN/A{
49010905Sandreas.sandberg@arm.com    string dir = CheckpointIn::setDir(cpt_dir);
491363SN/A    if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST)
492449SN/A            fatal("couldn't mkdir %s\n", dir);
493363SN/A
49410905Sandreas.sandberg@arm.com    string cpt_file = dir + CheckpointIn::baseFilename;
495395SN/A    ofstream outstream(cpt_file.c_str());
4962SN/A    time_t t = time(NULL);
4975581Ssaidi@eecs.umich.edu    if (!outstream.is_open())
4985581Ssaidi@eecs.umich.edu        fatal("Unable to open file %s for writing\n", cpt_file.c_str());
4996818SLisa.Hsu@amd.com    outstream << "## checkpoint generated: " << ctime(&t);
5002SN/A
50110905Sandreas.sandberg@arm.com    globals.serializeSection(outstream, "Globals");
50210905Sandreas.sandberg@arm.com
503395SN/A    SimObject::serializeAll(outstream);
504395SN/A}
5052SN/A
5062797Sktlim@umich.eduvoid
50710905Sandreas.sandberg@arm.comSerializable::unserializeGlobals(CheckpointIn &cp)
508395SN/A{
50910905Sandreas.sandberg@arm.com    globals.unserializeSection(cp, "Globals");
51010905Sandreas.sandberg@arm.com
51111072Sandreas.sandberg@arm.com    for (uint32_t i = 0; i < numMainEventQueues; ++i)
51210905Sandreas.sandberg@arm.com        mainEventQueue[i]->setCurTick(globals.unserializedCurTick);
51310905Sandreas.sandberg@arm.com}
51410905Sandreas.sandberg@arm.com
51510905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection()
51610905Sandreas.sandberg@arm.com{
51710905Sandreas.sandberg@arm.com    assert(!path.empty());
51810905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "Popping: %s\n", path.top());
51910905Sandreas.sandberg@arm.com    path.pop();
52010905Sandreas.sandberg@arm.com}
52110905Sandreas.sandberg@arm.com
52210905Sandreas.sandberg@arm.comvoid
52310905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::pushName(const char *obj_name)
52410905Sandreas.sandberg@arm.com{
52510905Sandreas.sandberg@arm.com    if (path.empty()) {
52610905Sandreas.sandberg@arm.com        path.push(obj_name);
52710905Sandreas.sandberg@arm.com    } else {
52810905Sandreas.sandberg@arm.com        path.push(csprintf("%s.%s", path.top(), obj_name));
52910905Sandreas.sandberg@arm.com    }
53010905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name);
53110905Sandreas.sandberg@arm.com}
53210905Sandreas.sandberg@arm.com
53310905Sandreas.sandberg@arm.comvoid
53410905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp)
53510905Sandreas.sandberg@arm.com{
53610905Sandreas.sandberg@arm.com    DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n",
53710905Sandreas.sandberg@arm.com            Serializable::currentSection());
53810905Sandreas.sandberg@arm.com    cp << "\n[" << Serializable::currentSection() << "]\n";
539395SN/A}
5402SN/A
5412SN/Avoid
5426225Snate@binkert.orgdebug_serialize(const string &cpt_dir)
5432SN/A{
5442868Sktlim@umich.edu    Serializable::serializeAll(cpt_dir);
5452SN/A}
5462SN/A
54710905Sandreas.sandberg@arm.comconst std::string &
54810905Sandreas.sandberg@arm.comSerializable::currentSection()
54910905Sandreas.sandberg@arm.com{
55010905Sandreas.sandberg@arm.com    assert(!path.empty());
55110905Sandreas.sandberg@arm.com
55210905Sandreas.sandberg@arm.com    return path.top();
55310905Sandreas.sandberg@arm.com}
554237SN/A
55510905Sandreas.sandberg@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt";
5567491Ssteve.reinhardt@amd.com
55710905Sandreas.sandberg@arm.comstring CheckpointIn::currentDirectory;
5587491Ssteve.reinhardt@amd.com
5597491Ssteve.reinhardt@amd.comstring
56010905Sandreas.sandberg@arm.comCheckpointIn::setDir(const string &name)
5617491Ssteve.reinhardt@amd.com{
5627823Ssteve.reinhardt@amd.com    // use csprintf to insert curTick() into directory name if it
5637491Ssteve.reinhardt@amd.com    // appears to have a format placeholder in it.
5647491Ssteve.reinhardt@amd.com    currentDirectory = (name.find("%") != string::npos) ?
5657823Ssteve.reinhardt@amd.com        csprintf(name, curTick()) : name;
5667491Ssteve.reinhardt@amd.com    if (currentDirectory[currentDirectory.size() - 1] != '/')
5677491Ssteve.reinhardt@amd.com        currentDirectory += "/";
5687491Ssteve.reinhardt@amd.com    return currentDirectory;
5697491Ssteve.reinhardt@amd.com}
5707491Ssteve.reinhardt@amd.com
5717491Ssteve.reinhardt@amd.comstring
57210905Sandreas.sandberg@arm.comCheckpointIn::dir()
5737491Ssteve.reinhardt@amd.com{
5747491Ssteve.reinhardt@amd.com    return currentDirectory;
5757491Ssteve.reinhardt@amd.com}
5767491Ssteve.reinhardt@amd.com
5777491Ssteve.reinhardt@amd.com
57810905Sandreas.sandberg@arm.comCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver)
57910453SAndrew.Bardsley@arm.com    : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir))
580237SN/A{
58110905Sandreas.sandberg@arm.com    string filename = cptDir + "/" + CheckpointIn::baseFilename;
582237SN/A    if (!db->load(filename)) {
583237SN/A        fatal("Can't load checkpoint file '%s'\n", filename);
584237SN/A    }
585237SN/A}
586237SN/A
58710905Sandreas.sandberg@arm.comCheckpointIn::~CheckpointIn()
5889086Sandreas.hansson@arm.com{
5899086Sandreas.hansson@arm.com    delete db;
5909086Sandreas.hansson@arm.com}
591237SN/A
592237SN/Abool
59310905Sandreas.sandberg@arm.comCheckpointIn::find(const string &section, const string &entry, string &value)
594237SN/A{
595237SN/A    return db->find(section, entry, value);
596237SN/A}
597237SN/A
598237SN/A
599237SN/Abool
60010905Sandreas.sandberg@arm.comCheckpointIn::findObj(const string &section, const string &entry,
6014000Ssaidi@eecs.umich.edu                    SimObject *&value)
602237SN/A{
603237SN/A    string path;
604237SN/A
605237SN/A    if (!db->find(section, entry, path))
606237SN/A        return false;
607237SN/A
60810453SAndrew.Bardsley@arm.com    value = objNameResolver.resolveSimObject(path);
6094000Ssaidi@eecs.umich.edu    return true;
610237SN/A}
611304SN/A
612304SN/A
613304SN/Abool
61410905Sandreas.sandberg@arm.comCheckpointIn::sectionExists(const string &section)
615304SN/A{
616304SN/A    return db->sectionExists(section);
617304SN/A}
618