summaryrefslogtreecommitdiff
path: root/src/arch/arm/faults.cc
diff options
context:
space:
mode:
authorGeoffrey Blake <geoffrey.blake@arm.com>2011-08-19 15:08:07 -0500
committerGeoffrey Blake <geoffrey.blake@arm.com>2011-08-19 15:08:07 -0500
commit5f425b8bd1ac70b61fc57b7ec44c52cd7d8de9fb (patch)
treedecdd198675fc01637584a8ef65d50c216e992da /src/arch/arm/faults.cc
parentf125ef22b997d5ba6173d9d3f0d07ae741e279bd (diff)
downloadgem5-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/arch/arm/faults.cc')
-rw-r--r--src/arch/arm/faults.cc16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 3bd9f070c..3c361404e 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -78,6 +78,8 @@ template<> ArmFault::FaultVals ArmFaultVals<FlushPipe>::vals =
template<> ArmFault::FaultVals ArmFaultVals<ReExec>::vals =
{"ReExec Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
+template<> ArmFault::FaultVals ArmFaultVals<ArmSev>::vals =
+ {"ArmSev Flush", 0x00, MODE_SVC, 0, 0, true, true}; // some dummy values
Addr
ArmFault::getVector(ThreadContext *tc)
{
@@ -127,6 +129,8 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
cpsr.i = 1;
cpsr.e = sctlr.ee;
tc->setMiscReg(MISCREG_CPSR, cpsr);
+ // Make sure mailbox sets to one always
+ tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
tc->setIntReg(INTREG_LR, curPc +
(saved_cpsr.t ? thumbPcOffset() : armPcOffset()));
@@ -252,6 +256,18 @@ template void AbortFault<PrefetchAbort>::invoke(ThreadContext *tc,
template void AbortFault<DataAbort>::invoke(ThreadContext *tc,
StaticInstPtr inst);
+void
+ArmSev::invoke(ThreadContext *tc, StaticInstPtr inst) {
+ DPRINTF(Faults, "Invoking ArmSev Fault\n");
+#if FULL_SYSTEM
+ // Set sev_mailbox to 1, clear the pending interrupt from remote
+ // SEV execution and let pipeline continue as pcState is still
+ // valid.
+ tc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
+ tc->getCpuPtr()->clearInterrupt(INT_SEV, 0);
+#endif
+}
+
// return via SUBS pc, lr, xxx; rfe, movs, ldm
} // namespace ArmISA