summaryrefslogtreecommitdiff
path: root/src/arch/arm/faults.cc
diff options
context:
space:
mode:
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