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>
This commit is contained in:
Marc Orr
2014-11-06 05:42:22 -06:00
parent 3947f88d0f
commit bf80734b2c
26 changed files with 381 additions and 16 deletions

View File

@@ -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();

View File

@@ -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"

View File

@@ -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)
}};