summaryrefslogtreecommitdiff
path: root/src/arch/arm/isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/arm/isa')
-rw-r--r--src/arch/arm/isa/insts/misc.isa25
-rw-r--r--src/arch/arm/isa/templates/pred.isa28
2 files changed, 47 insertions, 6 deletions
diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa
index 4a4f1e314..4d8ea66a2 100644
--- a/src/arch/arm/isa/insts/misc.isa
+++ b/src/arch/arm/isa/insts/misc.isa
@@ -502,20 +502,32 @@ let {{
wfeCode = '''
#if FULL_SYSTEM
+ // WFE Sleeps if SevMailbox==0 and no unmasked interrupts are pending
if (SevMailbox == 1) {
SevMailbox = 0;
PseudoInst::quiesceSkip(xc->tcBase());
+ } else if (xc->tcBase()->getCpuPtr()->getInterruptController()->checkInterrupts(xc->tcBase())) {
+ PseudoInst::quiesceSkip(xc->tcBase());
} else {
PseudoInst::quiesce(xc->tcBase());
}
#endif
'''
+ wfePredFixUpCode = '''
+#if FULL_SYSTEM
+ // WFE is predicated false, reset SevMailbox to reduce spurious sleeps
+ // and SEV interrupts
+ SevMailbox = 1;
+#endif
+ '''
wfeIop = InstObjParams("wfe", "WfeInst", "PredOp", \
- { "code" : wfeCode, "predicate_test" : predicateTest },
+ { "code" : wfeCode,
+ "pred_fixup" : wfePredFixUpCode,
+ "predicate_test" : predicateTest },
["IsNonSpeculative", "IsQuiesce", "IsSerializeAfter"])
header_output += BasicDeclare.subst(wfeIop)
decoder_output += BasicConstructor.subst(wfeIop)
- exec_output += QuiescePredOpExecute.subst(wfeIop)
+ exec_output += QuiescePredOpExecuteWithFixup.subst(wfeIop)
wfiCode = '''
#if FULL_SYSTEM
@@ -535,19 +547,20 @@ let {{
exec_output += QuiescePredOpExecute.subst(wfiIop)
sevCode = '''
- // Need a way for O3 to not scoreboard these accesses as pipe flushes.
+#if FULL_SYSTEM
SevMailbox = 1;
System *sys = xc->tcBase()->getSystemPtr();
for (int x = 0; x < sys->numContexts(); x++) {
ThreadContext *oc = sys->getThreadContext(x);
if (oc == xc->tcBase())
continue;
- // Only wake if they were sleeping
+ // Wake CPU with interrupt if they were sleeping
if (oc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
- oc->setMiscReg(MISCREG_SEV_MAILBOX, 1);
- PseudoInst::wakeCPU(xc->tcBase(), x);
+ // Post Interrupt and wake cpu if needed
+ oc->getCpuPtr()->postInterrupt(INT_SEV, 0);
}
}
+#endif
'''
sevIop = InstObjParams("sev", "SevInst", "PredOp", \
{ "code" : sevCode, "predicate_test" : predicateTest },
diff --git a/src/arch/arm/isa/templates/pred.isa b/src/arch/arm/isa/templates/pred.isa
index 04f253ca9..8b7ff69e7 100644
--- a/src/arch/arm/isa/templates/pred.isa
+++ b/src/arch/arm/isa/templates/pred.isa
@@ -205,6 +205,34 @@ def template QuiescePredOpExecute {{
}
}};
+def template QuiescePredOpExecuteWithFixup {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t resTemp = 0;
+ resTemp = resTemp;
+ %(op_decl)s;
+ %(op_rd)s;
+
+ if (%(predicate_test)s)
+ {
+ %(code)s;
+ if (fault == NoFault)
+ {
+ %(op_wb)s;
+ }
+ } else {
+ xc->setPredicate(false);
+ %(pred_fixup)s;
+#if FULL_SYSTEM
+ PseudoInst::quiesceSkip(xc->tcBase());
+#endif
+ }
+
+ return fault;
+ }
+}};
+
def template DataDecode {{
if (machInst.opcode4 == 0) {
if (machInst.sField == 0)