summaryrefslogtreecommitdiff
path: root/src/cpu/o3
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/o3')
-rw-r--r--src/cpu/o3/commit_impl.hh18
-rw-r--r--src/cpu/o3/cpu.cc10
-rw-r--r--src/cpu/o3/dyn_inst.hh6
-rw-r--r--src/cpu/o3/dyn_inst_impl.hh18
-rwxr-xr-xsrc/cpu/o3/thread_context.hh10
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh40
-rw-r--r--src/cpu/o3/thread_state.hh13
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;