summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorMarc Orr <morr@cs.wisc.edu>2014-11-06 05:42:22 -0600
committerMarc Orr <morr@cs.wisc.edu>2014-11-06 05:42:22 -0600
commitbf80734b2ce080cd75f4b57be47e37465e8901f1 (patch)
tree0ba9cbba64cd017e95b5a3f637d58435208ebc3c /src/arch
parent3947f88d0fa35d2134fa3e999e05bb184a01e396 (diff)
downloadgem5-bf80734b2ce080cd75f4b57be47e37465e8901f1.tar.xz
x86 isa: This patch attempts an implementation at mwait.
Mwait works as follows: 1. A cpu monitors an address of interest (monitor instruction) 2. A cpu calls mwait - this loads the cache line into that cpu's cache. 3. The cpu goes to sleep. 4. When another processor requests write permission for the line, it is evicted from the sleeping cpu's cache. This eviction is forwarded to the sleeping cpu, which then wakes up. Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa16
-rw-r--r--src/arch/x86/isa/formats/formats.isa3
-rw-r--r--src/arch/x86/isa/formats/monitor_mwait.isa131
3 files changed, 148 insertions, 2 deletions
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index eb395fce2..081bad971 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -71,8 +71,20 @@
}
0x1: decode MODRM_MOD {
0x3: decode MODRM_RM {
- 0x0: monitor();
- 0x1: mwait();
+ 0x0: MonitorInst::monitor({{
+ xc->armMonitor(Rax);
+ }});
+ 0x1: MwaitInst::mwait({{
+ uint64_t m = 0; //mem
+ unsigned s = 0x8; //size
+ unsigned f = 0; //flags
+ readMemAtomic(xc, traceData,
+ xc->getAddrMonitor()->vAddr,
+ m, s, f);
+ xc->mwaitAtomic(xc->tcBase());
+ MicroHalt hltObj(machInst, mnemonic, 0x0);
+ hltObj.execute(xc, traceData);
+ }});
default: Inst::UD2();
}
default: sidt_Ms();
diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa
index cc0eb9acf..b5ffd4d59 100644
--- a/src/arch/x86/isa/formats/formats.isa
+++ b/src/arch/x86/isa/formats/formats.isa
@@ -45,6 +45,9 @@
//Include a format to generate a CPUID instruction.
##include "cpuid.isa"
+//Include a format to generate a monitor/mwait instructions.
+##include "monitor_mwait.isa"
+
//Include the "unknown" format
##include "unknown.isa"
diff --git a/src/arch/x86/isa/formats/monitor_mwait.isa b/src/arch/x86/isa/formats/monitor_mwait.isa
new file mode 100644
index 000000000..493b7c58a
--- /dev/null
+++ b/src/arch/x86/isa/formats/monitor_mwait.isa
@@ -0,0 +1,131 @@
+// Copyright (c) AMD
+// All rights reserved.
+//
+// Authors: Marc Orr
+
+// Monitor Instruction
+
+output header {{
+ class MonitorInst : public X86ISA::X86StaticInst
+ {
+ public:
+ static const RegIndex foldOBit = 0;
+ /// Constructor
+ MonitorInst(const char *_mnemonic, ExtMachInst _machInst,
+ OpClass __opClass) :
+ X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
+ { }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string MonitorInst::generateDisassembly(Addr PC,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+ ccprintf(response, " ");
+ printReg(response, _srcRegIdx[0], machInst.opSize);
+ return response.str();
+ }
+}};
+
+def format MonitorInst(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'MonitorInst', code, opt_flags)
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+}};
+
+
+// Mwait instruction
+
+// Declarations for execute() methods.
+def template MwaitExecDeclare {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
+ Trace::InstRecord *) const;
+}};
+
+def template MwaitDeclare {{
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ // Constructor.
+ %(class_name)s(ExtMachInst machInst);
+ %(MwaitExecDeclare)s
+ };
+}};
+
+def template MwaitInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
+ Trace::InstRecord * traceData) const
+ {
+ uint64_t m = 0; //mem
+ unsigned s = 0x8; //size
+ unsigned f = 0; //flags
+ readMemTiming(xc, traceData, xc->getAddrMonitor()->vAddr, m, s, f);
+ return NoFault;
+ }
+}};
+
+def template MwaitCompleteAcc {{
+ Fault %(class_name)s::completeAcc(PacketPtr pkt, CPU_EXEC_CONTEXT *xc,
+ Trace::InstRecord *traceData) const
+ {
+ MicroHalt hltObj(machInst, mnemonic, 0x0);
+ if(xc->mwait(pkt)) {
+ hltObj.execute(xc, traceData);
+ }
+ return NoFault;
+ }
+}};
+
+output header {{
+ class MwaitInst : public X86ISA::X86StaticInst
+ {
+ public:
+ static const RegIndex foldOBit = 0;
+ /// Constructor
+ MwaitInst(const char *_mnemonic, ExtMachInst _machInst,
+ OpClass __opClass) :
+ X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
+ {
+ flags[IsMemRef] = 1;
+ flags[IsLoad] = 1;
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string MwaitInst::generateDisassembly(Addr PC,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+ ccprintf(response, " ");
+ printReg(response, _srcRegIdx[0], machInst.opSize);
+ return response.str();
+ }
+}};
+
+def format MwaitInst(code, *opt_flags) {{
+ iop = InstObjParams(name, Name, 'MwaitInst', code, opt_flags)
+ header_output = MwaitDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
+ exec_output += MwaitInitiateAcc.subst(iop)
+ exec_output += MwaitCompleteAcc.subst(iop)
+}};
+