diff options
Diffstat (limited to 'src/cpu/o3')
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 18 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 10 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/dyn_inst_impl.hh | 18 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context.hh | 10 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context_impl.hh | 40 | ||||
-rw-r--r-- | src/cpu/o3/thread_state.hh | 13 |
7 files changed, 55 insertions, 60 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index f6c868720..351b4794d 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -559,7 +559,7 @@ DefaultCommit<Impl>::squashFromTrap(ThreadID tid) DPRINTF(Commit, "Squashing from trap, restarting at PC %s\n", pc[tid]); thread[tid]->trapPending = false; - thread[tid]->inSyscall = false; + thread[tid]->noSquashFromTC = false; trapInFlight[tid] = false; trapSquash[tid] = false; @@ -576,7 +576,7 @@ DefaultCommit<Impl>::squashFromTC(ThreadID tid) DPRINTF(Commit, "Squashing from TC, restarting at PC %s\n", pc[tid]); - thread[tid]->inSyscall = false; + thread[tid]->noSquashFromTC = false; assert(!thread[tid]->trapPending); commitStatus[tid] = ROBSquashing; @@ -721,8 +721,8 @@ DefaultCommit<Impl>::handleInterrupt() // Clear the interrupt now that it's going to be handled toIEW->commitInfo[0].clearInterrupt = true; - assert(!thread[0]->inSyscall); - thread[0]->inSyscall = true; + assert(!thread[0]->noSquashFromTC); + thread[0]->noSquashFromTC = true; if (cpu->checker) { cpu->checker->handlePendingInt(); @@ -731,7 +731,7 @@ DefaultCommit<Impl>::handleInterrupt() // CPU will handle interrupt. cpu->processInterrupts(interrupt); - thread[0]->inSyscall = false; + thread[0]->noSquashFromTC = false; commitStatus[0] = TrapPending; @@ -1014,7 +1014,7 @@ DefaultCommit<Impl>::commitInsts() Addr oldpc; // Debug statement. Checks to make sure we're not // currently updating state while handling PC events. - assert(!thread[tid]->inSyscall && !thread[tid]->trapPending); + assert(!thread[tid]->noSquashFromTC && !thread[tid]->trapPending); do { oldpc = pc[tid].instAddr(); cpu->system->pcEventQueue.service(thread[tid]->getTC()); @@ -1140,11 +1140,11 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) cpu->checker->verify(head_inst); } - assert(!thread[tid]->inSyscall); + assert(!thread[tid]->noSquashFromTC); // Mark that we're in state update mode so that the trap's // execution doesn't generate extra squashes. - thread[tid]->inSyscall = true; + thread[tid]->noSquashFromTC = true; // Execute the trap. Although it's slightly unrealistic in // terms of timing (as it doesn't wait for the full timing of @@ -1155,7 +1155,7 @@ DefaultCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num) cpu->trap(inst_fault, tid, head_inst->staticInst); // Exit state update mode to avoid accidental updating. - thread[tid]->inSyscall = false; + thread[tid]->noSquashFromTC = false; commitStatus[tid] = TrapPending; diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index bc5f096e6..c5421302d 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -644,9 +644,9 @@ FullO3CPU<Impl>::init() BaseCPU::init(); for (ThreadID tid = 0; tid < numThreads; ++tid) { - // Set inSyscall so that the CPU doesn't squash when initially + // Set noSquashFromTC so that the CPU doesn't squash when initially // setting up registers. - thread[tid]->inSyscall = true; + thread[tid]->noSquashFromTC = true; // Initialise the ThreadContext's memory proxies thread[tid]->initMemProxies(thread[tid]->getTC()); } @@ -665,9 +665,9 @@ FullO3CPU<Impl>::init() } } - // Clear inSyscall. + // Clear noSquashFromTC. for (int tid = 0; tid < numThreads; ++tid) - thread[tid]->inSyscall = false; + thread[tid]->noSquashFromTC = false; // Initialize stages. fetch.initStage(); @@ -1464,7 +1464,7 @@ template <class Impl> void FullO3CPU<Impl>::squashFromTC(ThreadID tid) { - this->thread[tid]->inSyscall = true; + this->thread[tid]->noSquashFromTC = true; this->commit.generateTCEvent(tid); } diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh index b5344f875..de50bbda9 100644 --- a/src/cpu/o3/dyn_inst.hh +++ b/src/cpu/o3/dyn_inst.hh @@ -183,14 +183,14 @@ class BaseO3DynInst : public BaseDynInst<Impl> // using the TC during an instruction's execution (specifically for // instructions that have side-effects that use the TC). Fix this. // See cpu/o3/dyn_inst_impl.hh. - bool in_syscall = this->thread->inSyscall; - this->thread->inSyscall = true; + bool no_squash_from_TC = this->thread->noSquashFromTC; + this->thread->noSquashFromTC = true; for (int i = 0; i < _numDestMiscRegs; i++) this->cpu->setMiscReg( _destMiscRegIdx[i], _destMiscRegVal[i], this->threadNumber); - this->thread->inSyscall = in_syscall; + this->thread->noSquashFromTC = no_squash_from_TC; } void forwardOldRegs() diff --git a/src/cpu/o3/dyn_inst_impl.hh b/src/cpu/o3/dyn_inst_impl.hh index 7f8d5a030..e37caf7f0 100644 --- a/src/cpu/o3/dyn_inst_impl.hh +++ b/src/cpu/o3/dyn_inst_impl.hh @@ -130,12 +130,12 @@ BaseO3DynInst<Impl>::execute() // when using the TC during an instruction's execution // (specifically for instructions that have side-effects that use // the TC). Fix this. - bool in_syscall = this->thread->inSyscall; - this->thread->inSyscall = true; + bool no_squash_from_TC = this->thread->noSquashFromTC; + this->thread->noSquashFromTC = true; this->fault = this->staticInst->execute(this, this->traceData); - this->thread->inSyscall = in_syscall; + this->thread->noSquashFromTC = no_squash_from_TC; return this->fault; } @@ -148,12 +148,12 @@ BaseO3DynInst<Impl>::initiateAcc() // when using the TC during an instruction's execution // (specifically for instructions that have side-effects that use // the TC). Fix this. - bool in_syscall = this->thread->inSyscall; - this->thread->inSyscall = true; + bool no_squash_from_TC = this->thread->noSquashFromTC; + this->thread->noSquashFromTC = true; this->fault = this->staticInst->initiateAcc(this, this->traceData); - this->thread->inSyscall = in_syscall; + this->thread->noSquashFromTC = no_squash_from_TC; return this->fault; } @@ -166,8 +166,8 @@ BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt) // when using the TC during an instruction's execution // (specifically for instructions that have side-effects that use // the TC). Fix this. - bool in_syscall = this->thread->inSyscall; - this->thread->inSyscall = true; + bool no_squash_from_TC = this->thread->noSquashFromTC; + this->thread->noSquashFromTC = true; if (this->cpu->checker) { if (this->isStoreConditional()) { @@ -177,7 +177,7 @@ BaseO3DynInst<Impl>::completeAcc(PacketPtr pkt) this->fault = this->staticInst->completeAcc(pkt, this, this->traceData); - this->thread->inSyscall = in_syscall; + this->thread->noSquashFromTC = no_squash_from_TC; return this->fault; } diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh index 520f07b0f..c6fa178b5 100755 --- a/src/cpu/o3/thread_context.hh +++ b/src/cpu/o3/thread_context.hh @@ -257,6 +257,16 @@ class O3ThreadContext : public ThreadContext { return this->thread->quiesceEvent; } + /** check if the cpu is currently in state update mode and squash if not. + * This function will return true if a trap is pending or if a fault or + * similar is currently writing to the thread context and doesn't want + * reset all the state (see noSquashFromTC). + */ + inline void conditionalSquash() + { + if (!thread->trapPending && !thread->noSquashFromTC) + cpu->squashFromTC(thread->threadId()); + } }; diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 8a8ee636a..38e7c5dec 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -96,7 +96,7 @@ O3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context) old_context->setStatus(ThreadContext::Halted); - thread->inSyscall = false; + thread->noSquashFromTC = false; thread->trapPending = false; } @@ -207,9 +207,9 @@ void O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc) { // Prevent squashing - thread->inSyscall = true; + thread->noSquashFromTC = true; TheISA::copyRegs(tc, this); - thread->inSyscall = false; + thread->noSquashFromTC = false; if (!FullSystem) this->thread->funcExeInst = tc->readFuncExeInst(); @@ -253,10 +253,7 @@ O3ThreadContext<Impl>::setIntReg(int reg_idx, uint64_t val) reg_idx = cpu->isa[thread->threadId()].flattenIntIndex(reg_idx); cpu->setArchIntReg(reg_idx, val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -266,9 +263,7 @@ O3ThreadContext<Impl>::setFloatReg(int reg_idx, FloatReg val) reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx); cpu->setArchFloatReg(reg_idx, val, thread->threadId()); - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -278,10 +273,7 @@ O3ThreadContext<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) reg_idx = cpu->isa[thread->threadId()].flattenFloatIndex(reg_idx); cpu->setArchFloatRegInt(reg_idx, val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -290,10 +282,7 @@ O3ThreadContext<Impl>::pcState(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -302,10 +291,7 @@ O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -328,10 +314,7 @@ O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } template <class Impl> @@ -340,9 +323,6 @@ O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val) { cpu->setMiscReg(misc_reg, val, thread->threadId()); - // Squash if we're not already in a state update mode. - if (!thread->trapPending && !thread->inSyscall) { - cpu->squashFromTC(thread->threadId()); - } + conditionalSquash(); } diff --git a/src/cpu/o3/thread_state.hh b/src/cpu/o3/thread_state.hh index 9273b00da..96ccfc95c 100644 --- a/src/cpu/o3/thread_state.hh +++ b/src/cpu/o3/thread_state.hh @@ -61,10 +61,15 @@ struct O3ThreadState : public ThreadState { /** Pointer to the CPU. */ O3CPU *cpu; public: - /** Whether or not the thread is currently in syscall mode, and - * thus able to be externally updated without squashing. + /* This variable controls if writes to a thread context should cause a all + * dynamic/speculative state to be thrown away. Nominally this is the + * desired behavior because the external thread context write has updated + * some state that could be used by an inflight instruction, however there + * are some cases like in a fault/trap handler where this behavior would + * lead to successive restarts and forward progress couldn't be made. This + * variable controls if the squashing will occur. */ - bool inSyscall; + bool noSquashFromTC; /** Whether or not the thread is currently waiting on a trap, and * thus able to be externally updated without squashing. @@ -73,7 +78,7 @@ struct O3ThreadState : public ThreadState { O3ThreadState(O3CPU *_cpu, int _thread_num, Process *_process) : ThreadState(_cpu, _thread_num, _process), - cpu(_cpu), inSyscall(0), trapPending(0) + cpu(_cpu), noSquashFromTC(false), trapPending(false) { if (!FullSystem) return; |