diff options
-rw-r--r-- | src/arch/alpha/process.cc | 26 | ||||
-rw-r--r-- | src/arch/alpha/process.hh | 6 | ||||
-rw-r--r-- | src/arch/arm/process.cc | 4 | ||||
-rw-r--r-- | src/arch/mips/process.cc | 5 | ||||
-rw-r--r-- | src/arch/mips/process.hh | 2 | ||||
-rw-r--r-- | src/arch/power/linux/process.cc | 4 | ||||
-rw-r--r-- | src/arch/power/linux/process.hh | 2 | ||||
-rw-r--r-- | src/arch/power/process.cc | 7 | ||||
-rw-r--r-- | src/arch/power/process.hh | 2 | ||||
-rw-r--r-- | src/arch/sparc/process.cc | 18 | ||||
-rw-r--r-- | src/arch/sparc/process.hh | 6 | ||||
-rw-r--r-- | src/arch/x86/linux/system.cc | 4 | ||||
-rw-r--r-- | src/arch/x86/linux/system.hh | 2 | ||||
-rw-r--r-- | src/arch/x86/process.cc | 14 | ||||
-rw-r--r-- | src/arch/x86/process.hh | 4 | ||||
-rw-r--r-- | src/arch/x86/system.cc | 5 | ||||
-rw-r--r-- | src/arch/x86/system.hh | 2 | ||||
-rw-r--r-- | src/python/m5/simulate.py | 6 | ||||
-rw-r--r-- | src/python/swig/core.i | 5 | ||||
-rw-r--r-- | src/python/swig/pyobject.hh | 10 | ||||
-rw-r--r-- | src/python/swig/sim_object.i | 2 | ||||
-rw-r--r-- | src/sim/process.cc | 9 | ||||
-rw-r--r-- | src/sim/process.hh | 5 | ||||
-rw-r--r-- | src/sim/serialize.cc | 15 | ||||
-rw-r--r-- | src/sim/serialize.hh | 1 | ||||
-rw-r--r-- | src/sim/sim_object.cc | 12 | ||||
-rw-r--r-- | src/sim/sim_object.hh | 39 |
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 §ion); - 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 §ion) // 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 |