serialize.cc revision 11076
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 ¶m) 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> ¶m) 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> ¶m) 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 21511076SCurtis.Dunham@arm.comarrayParamOut(CheckpointOut &os, const string &name, const set<T> ¶m) 21611076SCurtis.Dunham@arm.com{ 21711076SCurtis.Dunham@arm.com typename set<T>::const_iterator it = param.begin(); 21811076SCurtis.Dunham@arm.com 21911076SCurtis.Dunham@arm.com os << name << "="; 22011076SCurtis.Dunham@arm.com if (param.size() > 0) 22111076SCurtis.Dunham@arm.com showParam(os, *it); 22211076SCurtis.Dunham@arm.com it++; 22311076SCurtis.Dunham@arm.com while (it != param.end()) { 22411076SCurtis.Dunham@arm.com os << " "; 22511076SCurtis.Dunham@arm.com showParam(os, *it); 22611076SCurtis.Dunham@arm.com it++; 22711076SCurtis.Dunham@arm.com } 22811076SCurtis.Dunham@arm.com os << "\n"; 22911076SCurtis.Dunham@arm.com} 23011076SCurtis.Dunham@arm.com 23111076SCurtis.Dunham@arm.comtemplate <class T> 23211076SCurtis.Dunham@arm.comvoid 23310905Sandreas.sandberg@arm.comparamIn(CheckpointIn &cp, const string &name, T ¶m) 2342SN/A{ 23510905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2366225Snate@binkert.org string str; 23710905Sandreas.sandberg@arm.com if (!cp.find(section, name, str) || !parseParam(str, param)) { 238217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 239217SN/A } 2402SN/A} 2412SN/A 2426820SLisa.Hsu@amd.comtemplate <class T> 2436820SLisa.Hsu@amd.combool 24411075SCurtis.Dunham@arm.comoptParamIn(CheckpointIn &cp, const string &name, T ¶m, bool warn) 2456820SLisa.Hsu@amd.com{ 24610905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2476820SLisa.Hsu@amd.com string str; 24810905Sandreas.sandberg@arm.com if (!cp.find(section, name, str) || !parseParam(str, param)) { 24911075SCurtis.Dunham@arm.com if (warn) 25011075SCurtis.Dunham@arm.com warn("optional parameter %s:%s not present\n", section, name); 2516820SLisa.Hsu@amd.com return false; 2526820SLisa.Hsu@amd.com } else { 2536820SLisa.Hsu@amd.com return true; 2546820SLisa.Hsu@amd.com } 2556820SLisa.Hsu@amd.com} 256217SN/A 257217SN/Atemplate <class T> 258217SN/Avoid 25910905Sandreas.sandberg@arm.comarrayParamOut(CheckpointOut &os, const string &name, 26010905Sandreas.sandberg@arm.com const T *param, unsigned size) 261217SN/A{ 262217SN/A os << name << "="; 263217SN/A if (size > 0) 264217SN/A showParam(os, param[0]); 2656227Snate@binkert.org for (unsigned i = 1; i < size; ++i) { 266217SN/A os << " "; 267217SN/A showParam(os, param[i]); 268217SN/A } 269217SN/A os << "\n"; 270217SN/A} 271217SN/A 272217SN/A 273217SN/Atemplate <class T> 274217SN/Avoid 27510905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, T *param, unsigned size) 276217SN/A{ 27710905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 2786225Snate@binkert.org string str; 27910905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 280217SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 281217SN/A } 282217SN/A 283217SN/A // code below stolen from VectorParam<T>::parse(). 284217SN/A // it would be nice to unify these somehow... 285217SN/A 286217SN/A vector<string> tokens; 287217SN/A 288217SN/A tokenize(tokens, str, ' '); 289217SN/A 290217SN/A // Need this if we were doing a vector 291217SN/A // value.resize(tokens.size()); 292217SN/A 293217SN/A if (tokens.size() != size) { 294217SN/A fatal("Array size mismatch on %s:%s'\n", section, name); 295217SN/A } 296217SN/A 2976227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 298217SN/A // need to parse into local variable to handle vector<bool>, 299217SN/A // for which operator[] returns a special reference class 300217SN/A // that's not the same as 'bool&', (since it's a packed 301217SN/A // vector) 30210905Sandreas.sandberg@arm.com T scalar_value; 303217SN/A if (!parseParam(tokens[i], scalar_value)) { 304217SN/A string err("could not parse \""); 305217SN/A 306217SN/A err += str; 307217SN/A err += "\""; 308217SN/A 309217SN/A fatal(err); 310217SN/A } 311217SN/A 312217SN/A // assign parsed value to vector 313217SN/A param[i] = scalar_value; 314217SN/A } 315217SN/A} 316217SN/A 3174841Ssaidi@eecs.umich.edutemplate <class T> 3184841Ssaidi@eecs.umich.eduvoid 31910905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, vector<T> ¶m) 3204841Ssaidi@eecs.umich.edu{ 32110905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 3226225Snate@binkert.org string str; 32310905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 3244841Ssaidi@eecs.umich.edu fatal("Can't unserialize '%s:%s'\n", section, name); 3254841Ssaidi@eecs.umich.edu } 3264841Ssaidi@eecs.umich.edu 3274841Ssaidi@eecs.umich.edu // code below stolen from VectorParam<T>::parse(). 3284841Ssaidi@eecs.umich.edu // it would be nice to unify these somehow... 3294841Ssaidi@eecs.umich.edu 3304841Ssaidi@eecs.umich.edu vector<string> tokens; 3314841Ssaidi@eecs.umich.edu 3324841Ssaidi@eecs.umich.edu tokenize(tokens, str, ' '); 3334841Ssaidi@eecs.umich.edu 3344841Ssaidi@eecs.umich.edu // Need this if we were doing a vector 3354841Ssaidi@eecs.umich.edu // value.resize(tokens.size()); 3364841Ssaidi@eecs.umich.edu 3374841Ssaidi@eecs.umich.edu param.resize(tokens.size()); 3384841Ssaidi@eecs.umich.edu 3396227Snate@binkert.org for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 3404841Ssaidi@eecs.umich.edu // need to parse into local variable to handle vector<bool>, 3414841Ssaidi@eecs.umich.edu // for which operator[] returns a special reference class 3424841Ssaidi@eecs.umich.edu // that's not the same as 'bool&', (since it's a packed 3434841Ssaidi@eecs.umich.edu // vector) 34410905Sandreas.sandberg@arm.com T scalar_value; 3454841Ssaidi@eecs.umich.edu if (!parseParam(tokens[i], scalar_value)) { 3464841Ssaidi@eecs.umich.edu string err("could not parse \""); 3474841Ssaidi@eecs.umich.edu 3484841Ssaidi@eecs.umich.edu err += str; 3494841Ssaidi@eecs.umich.edu err += "\""; 3504841Ssaidi@eecs.umich.edu 3514841Ssaidi@eecs.umich.edu fatal(err); 3524841Ssaidi@eecs.umich.edu } 3534841Ssaidi@eecs.umich.edu 3544841Ssaidi@eecs.umich.edu // assign parsed value to vector 3554841Ssaidi@eecs.umich.edu param[i] = scalar_value; 3564841Ssaidi@eecs.umich.edu } 3574841Ssaidi@eecs.umich.edu} 3584841Ssaidi@eecs.umich.edu 3597948SAli.Saidi@ARM.comtemplate <class T> 3607948SAli.Saidi@ARM.comvoid 36110905Sandreas.sandberg@arm.comarrayParamIn(CheckpointIn &cp, const string &name, list<T> ¶m) 3627948SAli.Saidi@ARM.com{ 36310905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 3647948SAli.Saidi@ARM.com string str; 36510905Sandreas.sandberg@arm.com if (!cp.find(section, name, str)) { 3667948SAli.Saidi@ARM.com fatal("Can't unserialize '%s:%s'\n", section, name); 3677948SAli.Saidi@ARM.com } 3687948SAli.Saidi@ARM.com param.clear(); 3697948SAli.Saidi@ARM.com 3707948SAli.Saidi@ARM.com vector<string> tokens; 3717948SAli.Saidi@ARM.com tokenize(tokens, str, ' '); 3727948SAli.Saidi@ARM.com 3737948SAli.Saidi@ARM.com for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 37410905Sandreas.sandberg@arm.com T scalar_value; 3757948SAli.Saidi@ARM.com if (!parseParam(tokens[i], scalar_value)) { 3767948SAli.Saidi@ARM.com string err("could not parse \""); 3777948SAli.Saidi@ARM.com 3787948SAli.Saidi@ARM.com err += str; 3797948SAli.Saidi@ARM.com err += "\""; 3807948SAli.Saidi@ARM.com 3817948SAli.Saidi@ARM.com fatal(err); 3827948SAli.Saidi@ARM.com } 3837948SAli.Saidi@ARM.com 3847948SAli.Saidi@ARM.com // assign parsed value to vector 3857948SAli.Saidi@ARM.com param.push_back(scalar_value); 3867948SAli.Saidi@ARM.com } 3877948SAli.Saidi@ARM.com} 3887948SAli.Saidi@ARM.com 38911076SCurtis.Dunham@arm.comtemplate <class T> 39011076SCurtis.Dunham@arm.comvoid 39111076SCurtis.Dunham@arm.comarrayParamIn(CheckpointIn &cp, const string &name, set<T> ¶m) 39211076SCurtis.Dunham@arm.com{ 39311076SCurtis.Dunham@arm.com const string §ion(Serializable::currentSection()); 39411076SCurtis.Dunham@arm.com string str; 39511076SCurtis.Dunham@arm.com if (!cp.find(section, name, str)) { 39611076SCurtis.Dunham@arm.com fatal("Can't unserialize '%s:%s'\n", section, name); 39711076SCurtis.Dunham@arm.com } 39811076SCurtis.Dunham@arm.com param.clear(); 39911076SCurtis.Dunham@arm.com 40011076SCurtis.Dunham@arm.com vector<string> tokens; 40111076SCurtis.Dunham@arm.com tokenize(tokens, str, ' '); 40211076SCurtis.Dunham@arm.com 40311076SCurtis.Dunham@arm.com for (vector<string>::size_type i = 0; i < tokens.size(); i++) { 40411076SCurtis.Dunham@arm.com T scalar_value; 40511076SCurtis.Dunham@arm.com if (!parseParam(tokens[i], scalar_value)) { 40611076SCurtis.Dunham@arm.com string err("could not parse \""); 40711076SCurtis.Dunham@arm.com 40811076SCurtis.Dunham@arm.com err += str; 40911076SCurtis.Dunham@arm.com err += "\""; 41011076SCurtis.Dunham@arm.com 41111076SCurtis.Dunham@arm.com fatal(err); 41211076SCurtis.Dunham@arm.com } 41311076SCurtis.Dunham@arm.com 41411076SCurtis.Dunham@arm.com // assign parsed value to vector 41511076SCurtis.Dunham@arm.com param.insert(scalar_value); 41611076SCurtis.Dunham@arm.com } 41711076SCurtis.Dunham@arm.com} 41811076SCurtis.Dunham@arm.com 4197948SAli.Saidi@ARM.com 420237SN/Avoid 42110905Sandreas.sandberg@arm.comobjParamIn(CheckpointIn &cp, const string &name, SimObject * ¶m) 422237SN/A{ 42310905Sandreas.sandberg@arm.com const string §ion(Serializable::currentSection()); 42410905Sandreas.sandberg@arm.com if (!cp.findObj(section, name, param)) { 425237SN/A fatal("Can't unserialize '%s:%s'\n", section, name); 426237SN/A } 427237SN/A} 428237SN/A 429237SN/A 4305543Ssaidi@eecs.umich.edu#define INSTANTIATE_PARAM_TEMPLATES(type) \ 43110905Sandreas.sandberg@arm.com template void \ 43210905Sandreas.sandberg@arm.com paramOut(CheckpointOut &os, const string &name, type const ¶m); \ 43310905Sandreas.sandberg@arm.com template void \ 43410905Sandreas.sandberg@arm.com paramIn(CheckpointIn &cp, const string &name, type & param); \ 43510905Sandreas.sandberg@arm.com template bool \ 43611075SCurtis.Dunham@arm.com optParamIn(CheckpointIn &cp, const string &name, type & param, \ 43711075SCurtis.Dunham@arm.com bool warn); \ 43810905Sandreas.sandberg@arm.com template void \ 43910905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 44010905Sandreas.sandberg@arm.com type const *param, unsigned size); \ 44110905Sandreas.sandberg@arm.com template void \ 44210905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 44310905Sandreas.sandberg@arm.com type *param, unsigned size); \ 44410905Sandreas.sandberg@arm.com template void \ 44510905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 44610905Sandreas.sandberg@arm.com const vector<type> ¶m); \ 44710905Sandreas.sandberg@arm.com template void \ 44810905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 44910905Sandreas.sandberg@arm.com vector<type> ¶m); \ 45010905Sandreas.sandberg@arm.com template void \ 45110905Sandreas.sandberg@arm.com arrayParamOut(CheckpointOut &os, const string &name, \ 45210905Sandreas.sandberg@arm.com const list<type> ¶m); \ 45310905Sandreas.sandberg@arm.com template void \ 45410905Sandreas.sandberg@arm.com arrayParamIn(CheckpointIn &cp, const string &name, \ 45510905Sandreas.sandberg@arm.com list<type> ¶m); 456217SN/A 4577494Ssteve.reinhardt@amd.comINSTANTIATE_PARAM_TEMPLATES(char) 4581642SN/AINSTANTIATE_PARAM_TEMPLATES(signed char) 4591642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned char) 4601642SN/AINSTANTIATE_PARAM_TEMPLATES(signed short) 4611642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned short) 4621642SN/AINSTANTIATE_PARAM_TEMPLATES(signed int) 4631642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned int) 4641642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long) 4651642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long) 4661642SN/AINSTANTIATE_PARAM_TEMPLATES(signed long long) 4671642SN/AINSTANTIATE_PARAM_TEMPLATES(unsigned long long) 468219SN/AINSTANTIATE_PARAM_TEMPLATES(bool) 4695992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(float) 4705992Snate@binkert.orgINSTANTIATE_PARAM_TEMPLATES(double) 471217SN/AINSTANTIATE_PARAM_TEMPLATES(string) 47210907Sandreas.sandberg@arm.comINSTANTIATE_PARAM_TEMPLATES(Pixel) 473217SN/A 47411076SCurtis.Dunham@arm.com// set is only used with strings and furthermore doesn't agree with Pixel 47511076SCurtis.Dunham@arm.comtemplate void 47611076SCurtis.Dunham@arm.comarrayParamOut(CheckpointOut &, const string &, const set<string> &); 47711076SCurtis.Dunham@arm.comtemplate void 47811076SCurtis.Dunham@arm.comarrayParamIn(CheckpointIn &, const string &, set<string> &); 479217SN/A 480395SN/A///////////////////////////// 481395SN/A 482395SN/A/// Container for serializing global variables (not associated with 483395SN/A/// any serialized object). 484395SN/Aclass Globals : public Serializable 4852SN/A{ 486395SN/A public: 48710905Sandreas.sandberg@arm.com Globals() 48810905Sandreas.sandberg@arm.com : unserializedCurTick(0) {} 48910905Sandreas.sandberg@arm.com 49010905Sandreas.sandberg@arm.com void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 49110905Sandreas.sandberg@arm.com void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 49210905Sandreas.sandberg@arm.com 49310905Sandreas.sandberg@arm.com Tick unserializedCurTick; 494395SN/A}; 4952SN/A 496395SN/A/// The one and only instance of the Globals class. 497395SN/AGlobals globals; 4982SN/A 49910905Sandreas.sandberg@arm.comvoid 50010905Sandreas.sandberg@arm.comGlobals::serialize(CheckpointOut &cp) const 5012SN/A{ 50210905Sandreas.sandberg@arm.com paramOut(cp, "curTick", curTick()); 5032SN/A} 5042SN/A 5052SN/Avoid 50610905Sandreas.sandberg@arm.comGlobals::unserialize(CheckpointIn &cp) 5072SN/A{ 50810905Sandreas.sandberg@arm.com paramIn(cp, "curTick", unserializedCurTick); 5092SN/A} 5102SN/A 5115739Snate@binkert.orgSerializable::Serializable() 5125739Snate@binkert.org{ 5135739Snate@binkert.org} 5145739Snate@binkert.org 5155739Snate@binkert.orgSerializable::~Serializable() 5165739Snate@binkert.org{ 5175739Snate@binkert.org} 5185739Snate@binkert.org 5195739Snate@binkert.orgvoid 52010905Sandreas.sandberg@arm.comSerializable::serializeSection(CheckpointOut &cp, const char *name) const 5215739Snate@binkert.org{ 52210905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 52310905Sandreas.sandberg@arm.com serialize(cp); 5245739Snate@binkert.org} 5255739Snate@binkert.org 5265739Snate@binkert.orgvoid 52710905Sandreas.sandberg@arm.comSerializable::serializeSectionOld(CheckpointOut &cp, const char *name) 5285739Snate@binkert.org{ 52910905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 53010905Sandreas.sandberg@arm.com serializeOld(cp); 53110905Sandreas.sandberg@arm.com} 53210905Sandreas.sandberg@arm.com 53310905Sandreas.sandberg@arm.comvoid 53410905Sandreas.sandberg@arm.comSerializable::unserializeSection(CheckpointIn &cp, const char *name) 53510905Sandreas.sandberg@arm.com{ 53610905Sandreas.sandberg@arm.com Serializable::ScopedCheckpointSection sec(cp, name); 53710905Sandreas.sandberg@arm.com unserialize(cp); 5385739Snate@binkert.org} 5395739Snate@binkert.org 5402SN/Avoid 5416225Snate@binkert.orgSerializable::serializeAll(const string &cpt_dir) 5422SN/A{ 54310905Sandreas.sandberg@arm.com string dir = CheckpointIn::setDir(cpt_dir); 544363SN/A if (mkdir(dir.c_str(), 0775) == -1 && errno != EEXIST) 545449SN/A fatal("couldn't mkdir %s\n", dir); 546363SN/A 54710905Sandreas.sandberg@arm.com string cpt_file = dir + CheckpointIn::baseFilename; 548395SN/A ofstream outstream(cpt_file.c_str()); 5492SN/A time_t t = time(NULL); 5505581Ssaidi@eecs.umich.edu if (!outstream.is_open()) 5515581Ssaidi@eecs.umich.edu fatal("Unable to open file %s for writing\n", cpt_file.c_str()); 5526818SLisa.Hsu@amd.com outstream << "## checkpoint generated: " << ctime(&t); 5532SN/A 55410905Sandreas.sandberg@arm.com globals.serializeSection(outstream, "Globals"); 55510905Sandreas.sandberg@arm.com 556395SN/A SimObject::serializeAll(outstream); 557395SN/A} 5582SN/A 5592797Sktlim@umich.eduvoid 56010905Sandreas.sandberg@arm.comSerializable::unserializeGlobals(CheckpointIn &cp) 561395SN/A{ 56210905Sandreas.sandberg@arm.com globals.unserializeSection(cp, "Globals"); 56310905Sandreas.sandberg@arm.com 56411072Sandreas.sandberg@arm.com for (uint32_t i = 0; i < numMainEventQueues; ++i) 56510905Sandreas.sandberg@arm.com mainEventQueue[i]->setCurTick(globals.unserializedCurTick); 56610905Sandreas.sandberg@arm.com} 56710905Sandreas.sandberg@arm.com 56810905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::~ScopedCheckpointSection() 56910905Sandreas.sandberg@arm.com{ 57010905Sandreas.sandberg@arm.com assert(!path.empty()); 57110905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "Popping: %s\n", path.top()); 57210905Sandreas.sandberg@arm.com path.pop(); 57310905Sandreas.sandberg@arm.com} 57410905Sandreas.sandberg@arm.com 57510905Sandreas.sandberg@arm.comvoid 57610905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::pushName(const char *obj_name) 57710905Sandreas.sandberg@arm.com{ 57810905Sandreas.sandberg@arm.com if (path.empty()) { 57910905Sandreas.sandberg@arm.com path.push(obj_name); 58010905Sandreas.sandberg@arm.com } else { 58110905Sandreas.sandberg@arm.com path.push(csprintf("%s.%s", path.top(), obj_name)); 58210905Sandreas.sandberg@arm.com } 58310905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "ScopedCheckpointSection::pushName: %s\n", obj_name); 58410905Sandreas.sandberg@arm.com} 58510905Sandreas.sandberg@arm.com 58610905Sandreas.sandberg@arm.comvoid 58710905Sandreas.sandberg@arm.comSerializable::ScopedCheckpointSection::nameOut(CheckpointOut &cp) 58810905Sandreas.sandberg@arm.com{ 58910905Sandreas.sandberg@arm.com DPRINTF(Checkpoint, "ScopedCheckpointSection::nameOut: %s\n", 59010905Sandreas.sandberg@arm.com Serializable::currentSection()); 59110905Sandreas.sandberg@arm.com cp << "\n[" << Serializable::currentSection() << "]\n"; 592395SN/A} 5932SN/A 5942SN/Avoid 5956225Snate@binkert.orgdebug_serialize(const string &cpt_dir) 5962SN/A{ 5972868Sktlim@umich.edu Serializable::serializeAll(cpt_dir); 5982SN/A} 5992SN/A 60010905Sandreas.sandberg@arm.comconst std::string & 60110905Sandreas.sandberg@arm.comSerializable::currentSection() 60210905Sandreas.sandberg@arm.com{ 60310905Sandreas.sandberg@arm.com assert(!path.empty()); 60410905Sandreas.sandberg@arm.com 60510905Sandreas.sandberg@arm.com return path.top(); 60610905Sandreas.sandberg@arm.com} 607237SN/A 60810905Sandreas.sandberg@arm.comconst char *CheckpointIn::baseFilename = "m5.cpt"; 6097491Ssteve.reinhardt@amd.com 61010905Sandreas.sandberg@arm.comstring CheckpointIn::currentDirectory; 6117491Ssteve.reinhardt@amd.com 6127491Ssteve.reinhardt@amd.comstring 61310905Sandreas.sandberg@arm.comCheckpointIn::setDir(const string &name) 6147491Ssteve.reinhardt@amd.com{ 6157823Ssteve.reinhardt@amd.com // use csprintf to insert curTick() into directory name if it 6167491Ssteve.reinhardt@amd.com // appears to have a format placeholder in it. 6177491Ssteve.reinhardt@amd.com currentDirectory = (name.find("%") != string::npos) ? 6187823Ssteve.reinhardt@amd.com csprintf(name, curTick()) : name; 6197491Ssteve.reinhardt@amd.com if (currentDirectory[currentDirectory.size() - 1] != '/') 6207491Ssteve.reinhardt@amd.com currentDirectory += "/"; 6217491Ssteve.reinhardt@amd.com return currentDirectory; 6227491Ssteve.reinhardt@amd.com} 6237491Ssteve.reinhardt@amd.com 6247491Ssteve.reinhardt@amd.comstring 62510905Sandreas.sandberg@arm.comCheckpointIn::dir() 6267491Ssteve.reinhardt@amd.com{ 6277491Ssteve.reinhardt@amd.com return currentDirectory; 6287491Ssteve.reinhardt@amd.com} 6297491Ssteve.reinhardt@amd.com 6307491Ssteve.reinhardt@amd.com 63110905Sandreas.sandberg@arm.comCheckpointIn::CheckpointIn(const string &cpt_dir, SimObjectResolver &resolver) 63210453SAndrew.Bardsley@arm.com : db(new IniFile), objNameResolver(resolver), cptDir(setDir(cpt_dir)) 633237SN/A{ 63410905Sandreas.sandberg@arm.com string filename = cptDir + "/" + CheckpointIn::baseFilename; 635237SN/A if (!db->load(filename)) { 636237SN/A fatal("Can't load checkpoint file '%s'\n", filename); 637237SN/A } 638237SN/A} 639237SN/A 64010905Sandreas.sandberg@arm.comCheckpointIn::~CheckpointIn() 6419086Sandreas.hansson@arm.com{ 6429086Sandreas.hansson@arm.com delete db; 6439086Sandreas.hansson@arm.com} 644237SN/A 645237SN/Abool 64610905Sandreas.sandberg@arm.comCheckpointIn::find(const string §ion, const string &entry, string &value) 647237SN/A{ 648237SN/A return db->find(section, entry, value); 649237SN/A} 650237SN/A 651237SN/A 652237SN/Abool 65310905Sandreas.sandberg@arm.comCheckpointIn::findObj(const string §ion, const string &entry, 6544000Ssaidi@eecs.umich.edu SimObject *&value) 655237SN/A{ 656237SN/A string path; 657237SN/A 658237SN/A if (!db->find(section, entry, path)) 659237SN/A return false; 660237SN/A 66110453SAndrew.Bardsley@arm.com value = objNameResolver.resolveSimObject(path); 6624000Ssaidi@eecs.umich.edu return true; 663237SN/A} 664304SN/A 665304SN/A 666304SN/Abool 66710905Sandreas.sandberg@arm.comCheckpointIn::sectionExists(const string §ion) 668304SN/A{ 669304SN/A return db->sectionExists(section); 670304SN/A} 671