diff options
author | Geoffrey Blake <geoffrey.blake@arm.com> | 2011-08-19 15:08:07 -0500 |
---|---|---|
committer | Geoffrey Blake <geoffrey.blake@arm.com> | 2011-08-19 15:08:07 -0500 |
commit | 5f425b8bd1ac70b61fc57b7ec44c52cd7d8de9fb (patch) | |
tree | decdd198675fc01637584a8ef65d50c216e992da /src/cpu | |
parent | f125ef22b997d5ba6173d9d3f0d07ae741e279bd (diff) | |
download | gem5-5f425b8bd1ac70b61fc57b7ec44c52cd7d8de9fb.tar.xz |
Fix bugs due to interaction between SEV instructions and O3 pipeline
SEV instructions were originally implemented to cause asynchronous squashes
via the generateTCSquash() function in the O3 pipeline when updating the
SEV_MAILBOX miscReg. This caused race conditions between CPUs in an MP system
that would lead to a pipeline either going inactive indefinitely or not being
able to commit squashed instructions. Fixed SEV instructions to behave like
interrupts and cause synchronous sqaushes inside the pipeline, eliminating
the race conditions. Also fixed up the semantics of the WFE instruction to
behave as documented in the ARMv7 ISA description to not sleep if SEV_MAILBOX=1
or unmasked interrupts are pending.
Diffstat (limited to 'src/cpu')
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 1 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 16 | ||||
-rwxr-xr-x | src/cpu/o3/thread_context_impl.hh | 3 |
3 files changed, 15 insertions, 5 deletions
diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index 0d9952df4..f218cc76a 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -505,6 +505,7 @@ DefaultCommit<Impl>::generateTrapEvent(ThreadID tid) cpu->schedule(trap, curTick() + trapLatency); trapInFlight[tid] = true; + thread[tid]->trapPending = true; } template <class Impl> diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 7095e52ec..dd9f5d40f 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -184,9 +184,19 @@ class FullO3CPU : public BaseO3CPU if (activateThreadEvent[tid].squashed()) reschedule(activateThreadEvent[tid], nextCycle(curTick() + ticks(delay))); - else if (!activateThreadEvent[tid].scheduled()) - schedule(activateThreadEvent[tid], - nextCycle(curTick() + ticks(delay))); + else if (!activateThreadEvent[tid].scheduled()) { + Tick when = nextCycle(curTick() + ticks(delay)); + + // Check if the deallocateEvent is also scheduled, and make + // sure they do not happen at same time causing a sleep that + // is never woken from. + if (deallocateContextEvent[tid].scheduled() && + deallocateContextEvent[tid].when() == when) { + when++; + } + + schedule(activateThreadEvent[tid], when); + } } /** Unschedule actiavte thread event, regardless of its current state. */ diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index c3b7d2248..4888cf92e 100755 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -351,8 +351,7 @@ O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val) template <class Impl> void -O3ThreadContext<Impl>::setMiscReg(int misc_reg, - const MiscReg &val) +O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val) { cpu->setMiscReg(misc_reg, val, thread->threadId()); |