From: Ali Saidi Date: Tue, 30 Jan 2007 23:25:39 +0000 (-0500) Subject: Make SPARC checkpointing work X-Git-Tag: m5_2.0_beta3~227^2~1 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=fc79ace5023048e5f73e5c1e21b8f86f09f72bf0;p=gem5.git Make SPARC checkpointing work src/arch/sparc/floatregfile.cc: Fix serialization for fpreg src/arch/sparc/intregfile.cc: fix serialization for intreg src/arch/sparc/miscregfile.cc: fix serialization from miscreg src/arch/sparc/pagetable.cc: fix serialization for page table src/arch/sparc/regfile.cc: need to serialize nnpc src/arch/sparc/tlb.cc: write serialization code for tlb src/cpu/base.cc: provide a way to find the thread number a context is serialize the instruction counter src/cpu/base.hh: provide a way to find the thread number a context is and given a thread number find a context pointer src/cpu/cpuevent.hh: provide method to get thread context from a cpu event for serialization src/dev/sparc/t1000.cc: src/dev/sparc/t1000.hh: nothing to serialize in t1000 src/sim/serialize.cc: src/sim/serialize.hh: Make findObj() work (it hasn't since we did the python conversion stuff) --HG-- extra : convert_revision : a95bc4e3c3354304171efbe3797556fdb146bea2 --- diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index 6f04ca829..585782ddb 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -183,13 +183,15 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width) void FloatRegFile::serialize(std::ostream &os) { - SERIALIZE_ARRAY((unsigned char *)regSpace, + uint8_t *float_reg = (uint8_t*)regSpace; + SERIALIZE_ARRAY(float_reg, SingleWidth / 8 * NumFloatRegs); } void FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) { - UNSERIALIZE_ARRAY((unsigned char *)regSpace, + uint8_t *float_reg = (uint8_t*)regSpace; + UNSERIALIZE_ARRAY(float_reg, SingleWidth / 8 * NumFloatRegs); } diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 2c9d9b162..39a613a0d 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -81,6 +81,8 @@ IntReg IntRegFile::readReg(int intReg) { DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); return regs[intReg]; + /* XXX Currently not used. When used again regView/offset need to be + * serialized! IntReg val; if(intReg < NumIntArchRegs) val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; @@ -92,6 +94,7 @@ IntReg IntRegFile::readReg(int intReg) DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); return val; + */ } void IntRegFile::setReg(int intReg, const IntReg &val) @@ -102,6 +105,8 @@ void IntRegFile::setReg(int intReg, const IntReg &val) regs[intReg] = val; } return; + /* XXX Currently not used. When used again regView/offset need to be + * serialized! if(intReg) { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); @@ -111,7 +116,7 @@ void IntRegFile::setReg(int intReg, const IntReg &val) microRegs[intReg] = val; else panic("Tried to set non-existant integer register\n"); - } + } */ } //This doesn't effect the actual CWP register. @@ -148,20 +153,26 @@ void IntRegFile::setGlobals(int gl) void IntRegFile::serialize(std::ostream &os) { + SERIALIZE_ARRAY(regs, NumIntRegs); + SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); + + /* the below doesn't seem needed unless gabe makes regview work*/ unsigned int x; for(x = 0; x < MaxGL; x++) SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(x = 0; x < 2 * NWindows; x++) SERIALIZE_ARRAY(regSegments[x], RegsPerFrame); - SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_ARRAY(regs, NumIntRegs); + UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); + + /* the below doesn't seem needed unless gabe makes regview work*/ unsigned int x; for(x = 0; x < MaxGL; x++) UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(unsigned int x = 0; x < 2 * NWindows; x++) UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame); - UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 422bc2fbe..0fe3e96b2 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -125,6 +125,11 @@ void MiscRegFile::clear() dTlbTagAccess = 0; memset(scratchPad, 0, sizeof(scratchPad)); +#if FULL_SYSTEM + tickCompare = NULL; + sTickCompare = NULL; + hSTickCompare = NULL; +#endif } MiscReg MiscRegFile::readReg(int miscReg) @@ -675,32 +680,31 @@ void MiscRegFile::setRegWithEffect(int miscReg, void MiscRegFile::serialize(std::ostream & os) { - SERIALIZE_SCALAR(pstate); - SERIALIZE_SCALAR(tba); -// SERIALIZE_SCALAR(y); - SERIALIZE_SCALAR(pil); - SERIALIZE_SCALAR(gl); - SERIALIZE_SCALAR(cwp); - SERIALIZE_ARRAY(tt, MaxTL); -// SERIALIZE_SCALAR(ccr); SERIALIZE_SCALAR(asi); - SERIALIZE_SCALAR(tl); - SERIALIZE_ARRAY(tpc, MaxTL); - SERIALIZE_ARRAY(tnpc, MaxTL); - SERIALIZE_ARRAY(tstate, MaxTL); SERIALIZE_SCALAR(tick); -// SERIALIZE_SCALAR(cansave); -// SERIALIZE_SCALAR(canrestore); -// SERIALIZE_SCALAR(otherwin); -// SERIALIZE_SCALAR(cleanwin); -// SERIALIZE_SCALAR(wstate); - SERIALIZE_SCALAR(fsr); SERIALIZE_SCALAR(fprs); + SERIALIZE_SCALAR(gsr); + SERIALIZE_SCALAR(softint); + SERIALIZE_SCALAR(tick_cmpr); + SERIALIZE_SCALAR(stick); + SERIALIZE_SCALAR(stick_cmpr); + SERIALIZE_ARRAY(tpc,MaxTL); + SERIALIZE_ARRAY(tnpc,MaxTL); + SERIALIZE_ARRAY(tstate,MaxTL); + SERIALIZE_ARRAY(tt,MaxTL); + SERIALIZE_SCALAR(tba); + SERIALIZE_SCALAR(pstate); + SERIALIZE_SCALAR(tl); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(cwp); + SERIALIZE_SCALAR(gl); SERIALIZE_SCALAR(hpstate); - SERIALIZE_ARRAY(htstate, MaxTL); + SERIALIZE_ARRAY(htstate,MaxTL); + SERIALIZE_SCALAR(hintp); SERIALIZE_SCALAR(htba); SERIALIZE_SCALAR(hstick_cmpr); SERIALIZE_SCALAR(strandStatusReg); + SERIALIZE_SCALAR(fsr); SERIALIZE_SCALAR(priContext); SERIALIZE_SCALAR(secContext); SERIALIZE_SCALAR(partId); @@ -718,6 +722,7 @@ void MiscRegFile::serialize(std::ostream & os) SERIALIZE_SCALAR(dTlbC0Config); SERIALIZE_SCALAR(dTlbCXTsbPs0); SERIALIZE_SCALAR(dTlbCXTsbPs1); + SERIALIZE_SCALAR(dTlbCXConfig); SERIALIZE_SCALAR(dTlbSfsr); SERIALIZE_SCALAR(dTlbSfar); SERIALIZE_SCALAR(dTlbTagAccess); @@ -730,36 +735,70 @@ void MiscRegFile::serialize(std::ostream & os) SERIALIZE_SCALAR(res_error_tail); SERIALIZE_SCALAR(nres_error_head); SERIALIZE_SCALAR(nres_error_tail); +#if FULL_SYSTEM + Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0; + ThreadContext *tc = NULL; + BaseCPU *cpu = NULL; + int tc_num = 0; + bool tick_intr_sched = true; + + if (tickCompare) + tc = tickCompare->getTC(); + else if (sTickCompare) + tc = sTickCompare->getTC(); + else if (hSTickCompare) + tc = hSTickCompare->getTC(); + else + tick_intr_sched = false; + + SERIALIZE_SCALAR(tick_intr_sched); + + if (tc) { + cpu = tc->getCpuPtr(); + tc_num = cpu->findContext(tc); + if (tickCompare && tickCompare->scheduled()) + tick_cmp = tickCompare->when(); + if (sTickCompare && sTickCompare->scheduled()) + stick_cmp = sTickCompare->when(); + if (hSTickCompare && hSTickCompare->scheduled()) + hstick_cmp = hSTickCompare->when(); + + SERIALIZE_OBJPTR(cpu); + SERIALIZE_SCALAR(tc_num); + SERIALIZE_SCALAR(tick_cmp); + SERIALIZE_SCALAR(stick_cmp); + SERIALIZE_SCALAR(hstick_cmp); + } +#endif } void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) { - UNSERIALIZE_SCALAR(pstate); - UNSERIALIZE_SCALAR(tba); -// UNSERIALIZE_SCALAR(y); - UNSERIALIZE_SCALAR(pil); - UNSERIALIZE_SCALAR(gl); - UNSERIALIZE_SCALAR(cwp); - UNSERIALIZE_ARRAY(tt, MaxTL); -// UNSERIALIZE_SCALAR(ccr); UNSERIALIZE_SCALAR(asi); - UNSERIALIZE_SCALAR(tl); - UNSERIALIZE_ARRAY(tpc, MaxTL); - UNSERIALIZE_ARRAY(tnpc, MaxTL); - UNSERIALIZE_ARRAY(tstate, MaxTL); UNSERIALIZE_SCALAR(tick); -// UNSERIALIZE_SCALAR(cansave); -// UNSERIALIZE_SCALAR(canrestore); -// UNSERIALIZE_SCALAR(otherwin); -// UNSERIALIZE_SCALAR(cleanwin); -// UNSERIALIZE_SCALAR(wstate); - UNSERIALIZE_SCALAR(fsr); UNSERIALIZE_SCALAR(fprs); + UNSERIALIZE_SCALAR(gsr); + UNSERIALIZE_SCALAR(softint); + UNSERIALIZE_SCALAR(tick_cmpr); + UNSERIALIZE_SCALAR(stick); + UNSERIALIZE_SCALAR(stick_cmpr); + UNSERIALIZE_ARRAY(tpc,MaxTL); + UNSERIALIZE_ARRAY(tnpc,MaxTL); + UNSERIALIZE_ARRAY(tstate,MaxTL); + UNSERIALIZE_ARRAY(tt,MaxTL); + UNSERIALIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(pstate); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_SCALAR(gl); UNSERIALIZE_SCALAR(hpstate); - UNSERIALIZE_ARRAY(htstate, MaxTL); + UNSERIALIZE_ARRAY(htstate,MaxTL); + UNSERIALIZE_SCALAR(hintp); UNSERIALIZE_SCALAR(htba); UNSERIALIZE_SCALAR(hstick_cmpr); UNSERIALIZE_SCALAR(strandStatusReg); + UNSERIALIZE_SCALAR(fsr); UNSERIALIZE_SCALAR(priContext); UNSERIALIZE_SCALAR(secContext); UNSERIALIZE_SCALAR(partId); @@ -777,6 +816,7 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) UNSERIALIZE_SCALAR(dTlbC0Config); UNSERIALIZE_SCALAR(dTlbCXTsbPs0); UNSERIALIZE_SCALAR(dTlbCXTsbPs1); + UNSERIALIZE_SCALAR(dTlbCXConfig); UNSERIALIZE_SCALAR(dTlbSfsr); UNSERIALIZE_SCALAR(dTlbSfar); UNSERIALIZE_SCALAR(dTlbTagAccess); @@ -788,4 +828,38 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) UNSERIALIZE_SCALAR(res_error_head); UNSERIALIZE_SCALAR(res_error_tail); UNSERIALIZE_SCALAR(nres_error_head); - UNSERIALIZE_SCALAR(nres_error_tail);} + UNSERIALIZE_SCALAR(nres_error_tail); + +#if FULL_SYSTEM + Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0; + ThreadContext *tc = NULL; + BaseCPU *cpu = NULL; + int tc_num; + bool tick_intr_sched; + UNSERIALIZE_SCALAR(tick_intr_sched); + if (tick_intr_sched) { + UNSERIALIZE_OBJPTR(cpu); + if (cpu) { + UNSERIALIZE_SCALAR(tc_num); + UNSERIALIZE_SCALAR(tick_cmp); + UNSERIALIZE_SCALAR(stick_cmp); + UNSERIALIZE_SCALAR(hstick_cmp); + tc = cpu->getContext(tc_num); + + if (tick_cmp) { + tickCompare = new TickCompareEvent(this, tc); + tickCompare->schedule(tick_cmp); + } + if (stick_cmp) { + sTickCompare = new STickCompareEvent(this, tc); + sTickCompare->schedule(stick_cmp); + } + if (hstick_cmp) { + hSTickCompare = new HSTickCompareEvent(this, tc); + hSTickCompare->schedule(hstick_cmp); + } + } + } + + #endif +} diff --git a/src/arch/sparc/pagetable.cc b/src/arch/sparc/pagetable.cc index 22130d41c..e91c0599f 100644 --- a/src/arch/sparc/pagetable.cc +++ b/src/arch/sparc/pagetable.cc @@ -41,9 +41,12 @@ TlbEntry::serialize(std::ostream &os) SERIALIZE_SCALAR(range.contextId); SERIALIZE_SCALAR(range.partitionId); SERIALIZE_SCALAR(range.real); - uint64_t entry4u = pte(); + uint64_t entry4u = 0; + if (valid) + entry4u = pte(); SERIALIZE_SCALAR(entry4u); SERIALIZE_SCALAR(used); + SERIALIZE_SCALAR(valid); } @@ -57,8 +60,10 @@ TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(range.real); uint64_t entry4u; UNSERIALIZE_SCALAR(entry4u); - pte.populate(entry4u); + if (entry4u) + pte.populate(entry4u); UNSERIALIZE_SCALAR(used); + UNSERIALIZE_SCALAR(valid); } diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index d39892e73..827e22c31 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -226,6 +226,7 @@ void RegFile::serialize(std::ostream &os) miscRegFile.serialize(os); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); + SERIALIZE_SCALAR(nnpc); } void RegFile::unserialize(Checkpoint *cp, const std::string §ion) @@ -235,6 +236,7 @@ void RegFile::unserialize(Checkpoint *cp, const std::string §ion) miscRegFile.unserialize(cp, section); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); + UNSERIALIZE_SCALAR(nnpc); } void RegFile::changeContext(RegContextParam param, RegContextVal val) diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index bc3c39294..32e172957 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1250,13 +1250,55 @@ doMmuWriteError: void TLB::serialize(std::ostream &os) { - panic("Need to implement serialize tlb for SPARC\n"); + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(usedEntries); + SERIALIZE_SCALAR(lastReplaced); + + // convert the pointer based free list into an index based one + int *free_list = (int*)malloc(sizeof(int) * size); + int cntr = 0; + std::list::iterator i; + i = freeList.begin(); + while (i != freeList.end()) { + free_list[cntr++] = ((size_t)*i - (size_t)tlb)/ sizeof(TlbEntry); + i++; + } + SERIALIZE_SCALAR(cntr); + SERIALIZE_ARRAY(free_list, cntr); + + for (int x = 0; x < size; x++) { + nameOut(os, csprintf("%s.PTE%d", name(), x)); + tlb[x].serialize(os); + } } void TLB::unserialize(Checkpoint *cp, const std::string §ion) { - panic("Need to implement unserialize tlb for SPARC\n"); + int oldSize; + + paramIn(cp, section, "size", oldSize); + if (oldSize != size) + panic("Don't support unserializing different sized TLBs\n"); + UNSERIALIZE_SCALAR(usedEntries); + UNSERIALIZE_SCALAR(lastReplaced); + + int cntr; + UNSERIALIZE_SCALAR(cntr); + + int *free_list = (int*)malloc(sizeof(int) * cntr); + freeList.clear(); + UNSERIALIZE_ARRAY(free_list, cntr); + for (int x = 0; x < cntr; x++) + freeList.push_back(&tlb[free_list[x]]); + + lookupTable.clear(); + for (int x = 0; x < size; x++) { + tlb[x].unserialize(cp, csprintf("%s.PTE%d", section, x)); + if (tlb[x].valid) + lookupTable.insert(tlb[x].range, &tlb[x]); + + } } diff --git a/src/cpu/base.cc b/src/cpu/base.cc index deb4e02c4..8440d2320 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -298,6 +298,16 @@ BaseCPU::registerThreadContexts() } +int +BaseCPU::findContext(ThreadContext *tc) +{ + for (int i = 0; i < threadContexts.size(); ++i) { + if (tc == threadContexts[i]) + return i; + } + return 0; +} + void BaseCPU::switchOut() { @@ -389,12 +399,14 @@ BaseCPU::clear_interrupts() void BaseCPU::serialize(std::ostream &os) { + SERIALIZE_SCALAR(instCnt); interrupts.serialize(os); } void BaseCPU::unserialize(Checkpoint *cp, const std::string §ion) { + UNSERIALIZE_SCALAR(instCnt); interrupts.unserialize(cp, section); } diff --git a/src/cpu/base.hh b/src/cpu/base.hh index 3ae9c60b6..a1265b748 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -142,6 +142,12 @@ class BaseCPU : public MemObject /// Notify the CPU that the indicated context is now halted. virtual void haltContext(int thread_num) {} + /// Given a Thread Context pointer return the thread num + int findContext(ThreadContext *tc); + + /// Given a thread num get tho thread context for it + ThreadContext *getContext(int tn) { return threadContexts[tn]; } + public: struct Params { diff --git a/src/cpu/cpuevent.hh b/src/cpu/cpuevent.hh index c973621c0..5816c6ca1 100644 --- a/src/cpu/cpuevent.hh +++ b/src/cpu/cpuevent.hh @@ -71,6 +71,7 @@ class CpuEvent : public Event */ static void replaceThreadContext(ThreadContext *oldTc, ThreadContext *newTc); + ThreadContext* getTC() { return tc; } }; template diff --git a/src/dev/sparc/t1000.cc b/src/dev/sparc/t1000.cc index 233808631..3a2f881f1 100644 --- a/src/dev/sparc/t1000.cc +++ b/src/dev/sparc/t1000.cc @@ -101,18 +101,6 @@ T1000::calcConfigAddr(int bus, int dev, int func) M5_DUMMY_RETURN } -void -T1000::serialize(std::ostream &os) -{ - panic("Need implementation\n"); -} - -void -T1000::unserialize(Checkpoint *cp, const std::string §ion) -{ - panic("Need implementation\n"); -} - BEGIN_DECLARE_SIM_OBJECT_PARAMS(T1000) SimObjectParam system; diff --git a/src/dev/sparc/t1000.hh b/src/dev/sparc/t1000.hh index 2955763a9..8e28d90e5 100644 --- a/src/dev/sparc/t1000.hh +++ b/src/dev/sparc/t1000.hh @@ -90,19 +90,6 @@ class T1000 : public Platform * Calculate the configuration address given a bus/dev/func. */ virtual Addr calcConfigAddr(int bus, int dev, int func); - - /** - * Serialize this object to the given output stream. - * @param os The stream to serialize to. - */ - virtual void serialize(std::ostream &os); - - /** - * Reconstruct the state of this object from a checkpoint. - * @param cp The checkpoint use. - * @param section The section name of this object - */ - virtual void unserialize(Checkpoint *cp, const std::string §ion); }; #endif // __DEV_T1000_HH__ diff --git a/src/sim/serialize.cc b/src/sim/serialize.cc index 941f0b1c6..1ff16976d 100644 --- a/src/sim/serialize.cc +++ b/src/sim/serialize.cc @@ -57,6 +57,8 @@ using namespace std; +extern SimObject *resolveSimObject(const string &); + int Serializable::ckptMaxCount = 0; int Serializable::ckptCount = 0; int Serializable::ckptPrevCount = -1; @@ -158,7 +160,7 @@ arrayParamIn(Checkpoint *cp, const std::string §ion, void objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, Serializable * ¶m) + const std::string &name, SimObject * ¶m) { if (!cp->findObj(section, name, param)) { fatal("Can't unserialize '%s:%s'\n", section, name); @@ -388,17 +390,15 @@ Checkpoint::find(const std::string §ion, const std::string &entry, bool Checkpoint::findObj(const std::string §ion, const std::string &entry, - Serializable *&value) + SimObject *&value) { string path; if (!db->find(section, entry, path)) return false; - if ((value = objMap[path]) != NULL) - return true; - - return false; + value = resolveSimObject(path); + return true; } diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 880fb0785..43cd4ecf4 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -47,6 +47,7 @@ class IniFile; class Serializable; class Checkpoint; +class SimObject; template void paramOut(std::ostream &os, const std::string &name, const T ¶m); @@ -65,7 +66,7 @@ void arrayParamIn(Checkpoint *cp, const std::string §ion, void objParamIn(Checkpoint *cp, const std::string §ion, - const std::string &name, Serializable * ¶m); + const std::string &name, SimObject * ¶m); // @@ -96,7 +97,7 @@ objParamIn(Checkpoint *cp, const std::string §ion, #define UNSERIALIZE_OBJPTR(objptr) \ do { \ - Serializable *sptr; \ + SimObject *sptr; \ objParamIn(cp, section, #objptr, sptr); \ objptr = dynamic_cast(sptr); \ } while (0) @@ -225,7 +226,7 @@ class Checkpoint std::string &value); bool findObj(const std::string §ion, const std::string &entry, - Serializable *&value); + SimObject *&value); bool sectionExists(const std::string §ion);