summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/alpha/process.cc26
-rw-r--r--src/arch/alpha/process.hh6
-rw-r--r--src/arch/arm/process.cc4
-rw-r--r--src/arch/mips/process.cc5
-rw-r--r--src/arch/mips/process.hh2
-rw-r--r--src/arch/power/linux/process.cc4
-rw-r--r--src/arch/power/linux/process.hh2
-rw-r--r--src/arch/power/process.cc7
-rw-r--r--src/arch/power/process.hh2
-rw-r--r--src/arch/sparc/process.cc18
-rw-r--r--src/arch/sparc/process.hh6
-rw-r--r--src/arch/x86/linux/system.cc4
-rw-r--r--src/arch/x86/linux/system.hh2
-rw-r--r--src/arch/x86/process.cc14
-rw-r--r--src/arch/x86/process.hh4
-rw-r--r--src/arch/x86/system.cc5
-rw-r--r--src/arch/x86/system.hh2
-rw-r--r--src/python/m5/simulate.py6
-rw-r--r--src/python/swig/core.i5
-rw-r--r--src/python/swig/pyobject.hh10
-rw-r--r--src/python/swig/sim_object.i2
-rw-r--r--src/sim/process.cc9
-rw-r--r--src/sim/process.hh5
-rw-r--r--src/sim/serialize.cc15
-rw-r--r--src/sim/serialize.hh1
-rw-r--r--src/sim/sim_object.cc12
-rw-r--r--src/sim/sim_object.hh39
27 files changed, 131 insertions, 86 deletions
diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc
index 1c83f64b2..431ef86c0 100644
--- a/src/arch/alpha/process.cc
+++ b/src/arch/alpha/process.cc
@@ -173,19 +173,35 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize)
}
void
-AlphaLiveProcess::startup()
+AlphaLiveProcess::setupASNReg()
{
ThreadContext *tc = system->getThreadContext(contextIds[0]);
tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57);
+}
- if (checkpointRestored) {
- return;
- }
- Process::startup();
+void
+AlphaLiveProcess::loadState(Checkpoint *cp)
+{
+ LiveProcess::loadState(cp);
+ // need to set up ASN after unserialization since M5_pid value may
+ // come from checkpoint
+ setupASNReg();
+}
+
+
+void
+AlphaLiveProcess::initState()
+{
+ // need to set up ASN before further initialization since init
+ // will involve writing to virtual memory addresses
+ setupASNReg();
+
+ LiveProcess::initState();
argsInit(MachineBytes, VMPageSize);
+ ThreadContext *tc = system->getThreadContext(contextIds[0]);
tc->setIntReg(GlobalPointerReg, objFile->globalPointer());
//Operate in user mode
tc->setMiscRegNoEffect(IPR_ICM, 0x18);
diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh
index 36b25a48e..40d6bf48a 100644
--- a/src/arch/alpha/process.hh
+++ b/src/arch/alpha/process.hh
@@ -36,10 +36,14 @@
class AlphaLiveProcess : public LiveProcess
{
+ private:
+ void setupASNReg();
+
protected:
AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile);
- void startup();
+ void loadState(Checkpoint *cp);
+ void initState();
void argsInit(int intSize, int pageSize);
diff --git a/src/arch/arm/process.cc b/src/arch/arm/process.cc
index 555fdf56e..e7748ad50 100644
--- a/src/arch/arm/process.cc
+++ b/src/arch/arm/process.cc
@@ -76,6 +76,7 @@ ArmLiveProcess::ArmLiveProcess(LiveProcessParams *params, ObjectFile *objFile,
void
ArmLiveProcess::startup()
{
+ LiveProcess::startup();
argsInit(MachineBytes, VMPageSize);
}
@@ -114,9 +115,6 @@ ArmLiveProcess::argsInit(int intSize, int pageSize)
//We want 16 byte alignment
uint64_t align = 16;
- // Overloaded argsInit so that we can fine-tune for ARM architecture
- Process::startup();
-
// load object file into target memory
objFile->loadSections(initVirtMem);
diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc
index 2fd9114e9..7f1e94709 100644
--- a/src/arch/mips/process.cc
+++ b/src/arch/mips/process.cc
@@ -67,9 +67,9 @@ MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params,
}
void
-MipsLiveProcess::startup()
+MipsLiveProcess::initState()
{
- Process::startup();
+ LiveProcess::initState();
argsInit<uint32_t>(VMPageSize);
}
@@ -79,7 +79,6 @@ void
MipsLiveProcess::argsInit(int pageSize)
{
int intSize = sizeof(IntType);
- Process::startup();
// load object file into target memory
objFile->loadSections(initVirtMem);
diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh
index f1238b41f..a065feb8f 100644
--- a/src/arch/mips/process.hh
+++ b/src/arch/mips/process.hh
@@ -45,7 +45,7 @@ class MipsLiveProcess : public LiveProcess
protected:
MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
- void startup();
+ void initState();
template<class IntType>
void argsInit(int pageSize);
diff --git a/src/arch/power/linux/process.cc b/src/arch/power/linux/process.cc
index 504d0e334..c2587d5e7 100644
--- a/src/arch/power/linux/process.cc
+++ b/src/arch/power/linux/process.cc
@@ -432,9 +432,9 @@ PowerLinuxProcess::getDesc(int callnum)
}
void
-PowerLinuxProcess::startup()
+PowerLinuxProcess::initState()
{
- PowerLiveProcess::startup();
+ PowerLiveProcess::initState();
}
PowerISA::IntReg
diff --git a/src/arch/power/linux/process.hh b/src/arch/power/linux/process.hh
index db6759a77..bef7e8dae 100644
--- a/src/arch/power/linux/process.hh
+++ b/src/arch/power/linux/process.hh
@@ -44,7 +44,7 @@ class PowerLinuxProcess : public PowerLiveProcess
virtual SyscallDesc* getDesc(int callnum);
- void startup();
+ void initState();
PowerISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, PowerISA::IntReg val);
diff --git a/src/arch/power/process.cc b/src/arch/power/process.cc
index 12b216e50..9fb69b9f8 100644
--- a/src/arch/power/process.cc
+++ b/src/arch/power/process.cc
@@ -63,8 +63,10 @@ PowerLiveProcess::PowerLiveProcess(LiveProcessParams *params,
}
void
-PowerLiveProcess::startup()
+PowerLiveProcess::initState()
{
+ Process::initState();
+
argsInit(MachineBytes, VMPageSize);
}
@@ -83,9 +85,6 @@ PowerLiveProcess::argsInit(int intSize, int pageSize)
//We want 16 byte alignment
uint64_t align = 16;
- // Overloaded argsInit so that we can fine-tune for POWER architecture
- Process::startup();
-
// load object file into target memory
objFile->loadSections(initVirtMem);
diff --git a/src/arch/power/process.hh b/src/arch/power/process.hh
index ede75f05f..473b7e028 100644
--- a/src/arch/power/process.hh
+++ b/src/arch/power/process.hh
@@ -46,7 +46,7 @@ class PowerLiveProcess : public LiveProcess
protected:
PowerLiveProcess(LiveProcessParams * params, ObjectFile *objFile);
- void startup();
+ void initState();
public:
void argsInit(int intSize, int pageSize);
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 7e01f6b07..0cd8889a9 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -111,9 +111,9 @@ void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
}
void
-SparcLiveProcess::startup()
+SparcLiveProcess::initState()
{
- Process::startup();
+ LiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//From the SPARC ABI
@@ -157,12 +157,9 @@ SparcLiveProcess::startup()
}
void
-Sparc32LiveProcess::startup()
+Sparc32LiveProcess::initState()
{
- if (checkpointRestored)
- return;
-
- SparcLiveProcess::startup();
+ SparcLiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode with 32 bit addresses
@@ -172,12 +169,9 @@ Sparc32LiveProcess::startup()
}
void
-Sparc64LiveProcess::startup()
+Sparc64LiveProcess::initState()
{
- if (checkpointRestored)
- return;
-
- SparcLiveProcess::startup();
+ SparcLiveProcess::initState();
ThreadContext *tc = system->getThreadContext(contextIds[0]);
//The process runs in user mode
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index cca312e0a..2d68fb3fc 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -52,7 +52,7 @@ class SparcLiveProcess : public LiveProcess
SparcLiveProcess(LiveProcessParams * params,
ObjectFile *objFile, Addr _StackBias);
- void startup();
+ void initState();
template<class IntType>
void argsInit(int pageSize);
@@ -87,7 +87,7 @@ class Sparc32LiveProcess : public SparcLiveProcess
mmap_start = mmap_end = 0x70000000;
}
- void startup();
+ void initState();
public:
@@ -115,7 +115,7 @@ class Sparc64LiveProcess : public SparcLiveProcess
mmap_start = mmap_end = 0xfffff80000000000ULL;
}
- void startup();
+ void initState();
public:
diff --git a/src/arch/x86/linux/system.cc b/src/arch/x86/linux/system.cc
index 4ae6d0ca4..1a113d365 100644
--- a/src/arch/x86/linux/system.cc
+++ b/src/arch/x86/linux/system.cc
@@ -59,9 +59,9 @@ LinuxX86System::~LinuxX86System()
}
void
-LinuxX86System::startup()
+LinuxX86System::initState()
{
- X86System::startup();
+ X86System::initState();
// The location of the real mode data structure.
const Addr realModeData = 0x90200;
diff --git a/src/arch/x86/linux/system.hh b/src/arch/x86/linux/system.hh
index e3c52ae50..ae7e93f3d 100644
--- a/src/arch/x86/linux/system.hh
+++ b/src/arch/x86/linux/system.hh
@@ -58,7 +58,7 @@ class LinuxX86System : public X86System
LinuxX86System(Params *p);
~LinuxX86System();
- void startup();
+ void initState();
};
#endif
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 2a2d43d3b..02cd45478 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -157,12 +157,9 @@ X86LiveProcess::getDesc(int callnum)
}
void
-X86_64LiveProcess::startup()
+X86_64LiveProcess::initState()
{
- LiveProcess::startup();
-
- if (checkpointRestored)
- return;
+ X86LiveProcess::initState();
argsInit(sizeof(uint64_t), VMPageSize);
@@ -255,12 +252,9 @@ X86_64LiveProcess::startup()
}
void
-I386LiveProcess::startup()
+I386LiveProcess::initState()
{
- LiveProcess::startup();
-
- if (checkpointRestored)
- return;
+ X86LiveProcess::initState();
argsInit(sizeof(uint32_t), VMPageSize);
diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh
index 8063898d7..34275b2d3 100644
--- a/src/arch/x86/process.hh
+++ b/src/arch/x86/process.hh
@@ -99,7 +99,7 @@ namespace X86ISA
public:
void argsInit(int intSize, int pageSize);
- void startup();
+ void initState();
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val);
@@ -123,7 +123,7 @@ namespace X86ISA
public:
void argsInit(int intSize, int pageSize);
- void startup();
+ void initState();
void syscall(int64_t callnum, ThreadContext *tc);
X86ISA::IntReg getSyscallArg(ThreadContext *tc, int &i);
diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc
index 01416e544..46d17cdb3 100644
--- a/src/arch/x86/system.cc
+++ b/src/arch/x86/system.cc
@@ -109,9 +109,10 @@ installSegDesc(ThreadContext *tc, SegmentRegIndex seg,
}
void
-X86System::startup()
+X86System::initState()
{
- System::startup();
+ System::initState();
+
ThreadContext *tc = threadContexts[0];
// This is the boot strap processor (BSP). Initialize it to look like
// the boot loader has just turned control over to the 64 bit OS. We
diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh
index 4a61193e6..0b5da3145 100644
--- a/src/arch/x86/system.hh
+++ b/src/arch/x86/system.hh
@@ -77,7 +77,7 @@ class X86System : public System
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
- void startup();
+ void initState();
protected:
diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py
index 0cf0a254e..cd2f8bb64 100644
--- a/src/python/m5/simulate.py
+++ b/src/python/m5/simulate.py
@@ -88,8 +88,12 @@ def instantiate(ckpt_dir=None):
# Restore checkpoint (if any)
if ckpt_dir:
- internal.core.unserializeAll(ckpt_dir)
+ ckpt = internal.core.getCheckpoint(ckpt_dir)
+ internal.core.unserializeGlobals(ckpt);
+ for obj in root.descendants(): obj.loadState(ckpt)
need_resume.append(root)
+ else:
+ for obj in root.descendants(): obj.initState()
# Reset to put the stats in a consistent state.
stats.reset()
diff --git a/src/python/swig/core.i b/src/python/swig/core.i
index 81085dd06..f48fe9590 100644
--- a/src/python/swig/core.i
+++ b/src/python/swig/core.i
@@ -75,8 +75,11 @@ void setClockFrequency(Tick ticksPerSecond);
%immutable curTick;
Tick curTick;
+class Checkpoint;
+
void serializeAll(const std::string &cpt_dir);
-void unserializeAll(const std::string &cpt_dir);
+Checkpoint *getCheckpoint(const std::string &cpt_dir);
+void unserializeGlobals(Checkpoint *cp);
bool want_warn, warn_verbose;
bool want_info, info_verbose;
diff --git a/src/python/swig/pyobject.hh b/src/python/swig/pyobject.hh
index a27080d08..b18a2a76c 100644
--- a/src/python/swig/pyobject.hh
+++ b/src/python/swig/pyobject.hh
@@ -52,8 +52,14 @@ serializeAll(const std::string &cpt_dir)
Serializable::serializeAll(cpt_dir);
}
+inline Checkpoint *
+getCheckpoint(const std::string &cpt_dir)
+{
+ return new Checkpoint(cpt_dir);
+}
+
inline void
-unserializeAll(const std::string &cpt_dir)
+unserializeGlobals(Checkpoint *cp)
{
- Serializable::unserializeAll(cpt_dir);
+ Serializable::unserializeGlobals(cp);
}
diff --git a/src/python/swig/sim_object.i b/src/python/swig/sim_object.i
index 8cd8e8beb..af9afd057 100644
--- a/src/python/swig/sim_object.i
+++ b/src/python/swig/sim_object.i
@@ -51,6 +51,8 @@ class SimObject {
};
void init();
+ void loadState(Checkpoint *cp);
+ void initState();
void regStats();
void regFormulas();
void resetStats();
diff --git a/src/sim/process.cc b/src/sim/process.cc
index f11fdcac8..d4b1fba90 100644
--- a/src/sim/process.cc
+++ b/src/sim/process.cc
@@ -100,8 +100,8 @@ template class AuxVector<uint32_t>;
template class AuxVector<uint64_t>;
Process::Process(ProcessParams * params)
- : SimObject(params), system(params->system), checkpointRestored(false),
- max_stack_size(params->max_stack_size)
+ : SimObject(params), system(params->system),
+ max_stack_size(params->max_stack_size)
{
string in = params->input;
string out = params->output;
@@ -233,7 +233,7 @@ Process::findFreeContext()
}
void
-Process::startup()
+Process::initState()
{
if (contextIds.empty())
fatal("Process %s is not associated with any HW contexts!\n", name());
@@ -537,9 +537,6 @@ Process::unserialize(Checkpoint *cp, const std::string &section)
// find the param in the checkpoint if you wanted to, like set a default
// but in this case we'll just stick with the instantianted value if not
// found.
-
- checkpointRestored = true;
-
}
diff --git a/src/sim/process.hh b/src/sim/process.hh
index e73f93fa5..3b78cb001 100644
--- a/src/sim/process.hh
+++ b/src/sim/process.hh
@@ -79,8 +79,6 @@ class Process : public SimObject
/// running on.
System *system;
- bool checkpointRestored;
-
// thread contexts associated with this process
std::vector<int> contextIds;
@@ -130,8 +128,7 @@ class Process : public SimObject
// constructor
Process(ProcessParams * params);
- // post initialization startup
- virtual void startup();
+ virtual void initState();
protected:
/// Memory object for initialization (image loading)
diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc
index d95092629..d6d5ac094 100644
--- a/src/sim/serialize.cc
+++ b/src/sim/serialize.cc
@@ -452,17 +452,6 @@ Serializable::serializeAll(const string &cpt_dir)
}
void
-Serializable::unserializeAll(const string &cpt_dir)
-{
- string dir = Checkpoint::setDir(cpt_dir);
-
- DPRINTFR(Config, "Loading checkpoint dir '%s'\n", dir);
- Checkpoint *cp = new Checkpoint(dir);
- unserializeGlobals(cp);
- SimObject::unserializeAll(cp);
-}
-
-void
Serializable::unserializeGlobals(Checkpoint *cp)
{
globals.unserialize(cp);
@@ -561,9 +550,9 @@ Checkpoint::dir()
Checkpoint::Checkpoint(const string &cpt_dir)
- : db(new IniFile), cptDir(cpt_dir)
+ : db(new IniFile), cptDir(setDir(cpt_dir))
{
- string filename = cpt_dir + "/" + Checkpoint::baseFilename;
+ string filename = cptDir + "/" + Checkpoint::baseFilename;
if (!db->load(filename)) {
fatal("Can't load checkpoint file '%s'\n", filename);
}
diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh
index 677a3fd92..d785605f3 100644
--- a/src/sim/serialize.hh
+++ b/src/sim/serialize.hh
@@ -141,7 +141,6 @@ class Serializable
static int ckptMaxCount;
static int ckptPrevCount;
static void serializeAll(const std::string &cpt_dir);
- static void unserializeAll(const std::string &cpt_dir);
static void unserializeGlobals(Checkpoint *cp);
};
diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc
index 157bf1395..503ac5650 100644
--- a/src/sim/sim_object.cc
+++ b/src/sim/sim_object.cc
@@ -74,6 +74,18 @@ SimObject::init()
}
void
+SimObject::loadState(Checkpoint *cp)
+{
+ if (cp->sectionExists(name()))
+ unserialize(cp, name());
+}
+
+void
+SimObject::initState()
+{
+}
+
+void
SimObject::startup()
{
}
diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh
index 1b22c5825..876501be2 100644
--- a/src/sim/sim_object.hh
+++ b/src/sim/sim_object.hh
@@ -91,17 +91,48 @@ class SimObject : public EventManager, public Serializable
virtual const std::string name() const { return params()->name; }
- // initialization pass of all objects.
- // Gets invoked after construction, before unserialize.
+ // The following SimObject initialization methods are called from
+ // the instantiate() method in src/python/m5/simulate.py. See
+ // that function for details on how/when these methods are
+ // invoked.
+
+ /**
+ * init() is called after all C++ SimObjects have been created and
+ * all ports are connected. Initializations that are independent
+ * of unserialization but rely on a fully instantiated and
+ * connected SimObject graph should be done here.
+ */
virtual void init();
+ /**
+ * loadState() is called on each SimObject when restoring from a
+ * checkpoint. The default implementation simply calls
+ * unserialize() if there is a corresponding section in the
+ * checkpoint. However, objects can override loadState() to get
+ * other behaviors, e.g., doing other programmed initializations
+ * after unserialize(), or complaining if no checkpoint section is
+ * found.
+ */
+ virtual void loadState(Checkpoint *cp);
+
+ /**
+ * initState() is called on each SimObject when *not* restoring
+ * from a checkpoint. This provides a hook for state
+ * initializations that are only required for a "cold start".
+ */
+ virtual void initState();
+
// register statistics for this object
virtual void regStats();
virtual void regFormulas();
virtual void resetStats();
- // final initialization before simulation
- // all state is unserialized so
+ /**
+ * startup() is the final initialization call before simulation.
+ * All state is initialized (including unserialized state, if any,
+ * such as the curTick value), so this is the appropriate place to
+ * schedule initial event(s) for objects that need them.
+ */
virtual void startup();
// static: call nameOut() & serialize() on all SimObjects