X86: Add a flag to force memory accesses to happen at CPL 0.

This commit is contained in:
Gabe Black 2009-02-25 10:18:22 -08:00
parent 897c374892
commit dc53ca89f6
4 changed files with 64 additions and 38 deletions

View file

@ -60,9 +60,16 @@
#include "arch/x86/insts/microop.hh" #include "arch/x86/insts/microop.hh"
#include "mem/packet.hh" #include "mem/packet.hh"
#include "mem/request.hh"
namespace X86ISA namespace X86ISA
{ {
static const Request::FlagsType SegmentFlagMask = mask(4);
static const int FlagShift = 4;
enum FlagBit {
CPL0FlagBit = 1
};
/** /**
* Base class for load and store ops * Base class for load and store ops
*/ */
@ -77,6 +84,7 @@ namespace X86ISA
const RegIndex data; const RegIndex data;
const uint8_t dataSize; const uint8_t dataSize;
const uint8_t addressSize; const uint8_t addressSize;
const Request::FlagsType memFlags;
RegIndex foldOBit, foldABit; RegIndex foldOBit, foldABit;
//Constructor //Constructor
@ -87,13 +95,15 @@ namespace X86ISA
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize, uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags,
OpClass __opClass) : OpClass __opClass) :
X86MicroopBase(machInst, mnem, _instMnem, X86MicroopBase(machInst, mnem, _instMnem,
isMicro, isDelayed, isFirst, isLast, __opClass), isMicro, isDelayed, isFirst, isLast, __opClass),
scale(_scale), index(_index), base(_base), scale(_scale), index(_index), base(_base),
disp(_disp), segment(_segment), disp(_disp), segment(_segment),
data(_data), data(_data),
dataSize(_dataSize), addressSize(_addressSize) dataSize(_dataSize), addressSize(_addressSize),
memFlags(_memFlags | _segment)
{ {
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
foldABit = foldABit =

View file

@ -117,6 +117,7 @@ output decoder {{
#include "arch/x86/microcode_rom.hh" #include "arch/x86/microcode_rom.hh"
#include "arch/x86/miscregs.hh" #include "arch/x86/miscregs.hh"
#include "arch/x86/segmentregs.hh" #include "arch/x86/segmentregs.hh"
#include "arch/x86/tlb.hh"
#include "base/cprintf.hh" #include "base/cprintf.hh"
#include "base/loader/symtab.hh" #include "base/loader/symtab.hh"
#include "base/misc.hh" #include "base/misc.hh"

View file

@ -124,14 +124,16 @@ def template MicroLeaDeclare {{
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize); uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize); uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags);
%(BasicExecDeclare)s %(BasicExecDeclare)s
}; };
@ -151,7 +153,7 @@ def template MicroLoadExecute {{
%(ea_code)s; %(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); fault = read(xc, EA, Mem, memFlags);
if(fault == NoFault) if(fault == NoFault)
{ {
@ -178,7 +180,7 @@ def template MicroLoadInitiateAcc {{
%(ea_code)s; %(ea_code)s;
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); fault = read(xc, EA, Mem, memFlags);
return fault; return fault;
} }
@ -225,7 +227,7 @@ def template MicroStoreExecute {{
if(fault == NoFault) if(fault == NoFault)
{ {
fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); fault = write(xc, Mem, EA, memFlags);
if(fault == NoFault) if(fault == NoFault)
{ {
%(post_code)s; %(post_code)s;
@ -253,7 +255,7 @@ def template MicroStoreInitiateAcc {{
if(fault == NoFault) if(fault == NoFault)
{ {
write(xc, Mem, EA, (%(mem_flags)s) | segment); write(xc, Mem, EA, memFlags);
} }
return fault; return fault;
} }
@ -296,14 +298,16 @@ def template MicroLdStOpDeclare {{
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize); uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags);
%(class_name)s(ExtMachInst _machInst, %(class_name)s(ExtMachInst _machInst,
const char * instMnem, const char * instMnem,
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize); uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags);
%(BasicExecDeclare)s %(BasicExecDeclare)s
@ -325,12 +329,13 @@ def template MicroLdStOpConstructor {{
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize) : uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
false, false, false, false, false, false, false, false,
_scale, _index, _base, _scale, _index, _base,
_disp, _segment, _data, _disp, _segment, _data,
_dataSize, _addressSize, %(op_class)s) _dataSize, _addressSize, _memFlags, %(op_class)s)
{ {
buildMe(); buildMe();
} }
@ -341,12 +346,13 @@ def template MicroLdStOpConstructor {{
uint8_t _scale, RegIndex _index, RegIndex _base, uint8_t _scale, RegIndex _index, RegIndex _base,
uint64_t _disp, uint8_t _segment, uint64_t _disp, uint8_t _segment,
RegIndex _data, RegIndex _data,
uint8_t _dataSize, uint8_t _addressSize) : uint8_t _dataSize, uint8_t _addressSize,
Request::FlagsType _memFlags) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem, %(base_class)s(machInst, "%(mnemonic)s", instMnem,
isMicro, isDelayed, isFirst, isLast, isMicro, isDelayed, isFirst, isLast,
_scale, _index, _base, _scale, _index, _base,
_disp, _segment, _data, _disp, _segment, _data,
_dataSize, _addressSize, %(op_class)s) _dataSize, _addressSize, _memFlags, %(op_class)s)
{ {
buildMe(); buildMe();
} }
@ -354,26 +360,31 @@ def template MicroLdStOpConstructor {{
let {{ let {{
class LdStOp(X86Microop): class LdStOp(X86Microop):
def __init__(self, data, segment, addr, disp, dataSize, addressSize): def __init__(self, data, segment, addr, disp,
dataSize, addressSize, baseFlags, atCPL0):
self.data = data self.data = data
[self.scale, self.index, self.base] = addr [self.scale, self.index, self.base] = addr
self.disp = disp self.disp = disp
self.segment = segment self.segment = segment
self.dataSize = dataSize self.dataSize = dataSize
self.addressSize = addressSize self.addressSize = addressSize
self.memFlags = baseFlags
if atCPL0:
self.memFlags += " | (CPL0FlagBit << FlagShift)"
def getAllocator(self, *microFlags): def getAllocator(self, *microFlags):
allocator = '''new %(class_name)s(machInst, macrocodeBlock allocator = '''new %(class_name)s(machInst, macrocodeBlock
%(flags)s, %(scale)s, %(index)s, %(base)s, %(flags)s, %(scale)s, %(index)s, %(base)s,
%(disp)s, %(segment)s, %(data)s, %(disp)s, %(segment)s, %(data)s,
%(dataSize)s, %(addressSize)s)''' % { %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
"class_name" : self.className, "class_name" : self.className,
"flags" : self.microFlagsText(microFlags), "flags" : self.microFlagsText(microFlags),
"scale" : self.scale, "index" : self.index, "scale" : self.scale, "index" : self.index,
"base" : self.base, "base" : self.base,
"disp" : self.disp, "disp" : self.disp,
"segment" : self.segment, "data" : self.data, "segment" : self.segment, "data" : self.data,
"dataSize" : self.dataSize, "addressSize" : self.addressSize} "dataSize" : self.dataSize, "addressSize" : self.addressSize,
"memFlags" : self.memFlags}
return allocator return allocator
}}; }};
@ -387,7 +398,7 @@ let {{
calculateEA = "EA = SegBase + scale * Index + Base + disp;" calculateEA = "EA = SegBase + scale * Index + Base + disp;"
def defineMicroLoadOp(mnemonic, code, mem_flags=0): def defineMicroLoadOp(mnemonic, code, mem_flags="0"):
global header_output global header_output
global decoder_output global decoder_output
global exec_output global exec_output
@ -398,8 +409,7 @@ let {{
# Build up the all register version of this micro op # Build up the all register version of this micro op
iop = InstObjParams(name, Name, 'X86ISA::LdStOp', iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
{"code": code, {"code": code,
"ea_code": calculateEA, "ea_code": calculateEA})
"mem_flags": mem_flags})
header_output += MicroLdStOpDeclare.subst(iop) header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLoadExecute.subst(iop) exec_output += MicroLoadExecute.subst(iop)
@ -408,16 +418,19 @@ let {{
class LoadOp(LdStOp): class LoadOp(LdStOp):
def __init__(self, data, segment, addr, disp = 0, def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"): dataSize="env.dataSize",
super(LoadOp, self).__init__(data, segment, addressSize="env.addressSize",
addr, disp, dataSize, addressSize) atCPL0=False):
super(LoadOp, self).__init__(data, segment, addr,
disp, dataSize, addressSize, mem_flags, atCPL0)
self.className = Name self.className = Name
self.mnemonic = name self.mnemonic = name
microopClasses[name] = LoadOp microopClasses[name] = LoadOp
defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
'X86ISA::StoreCheck')
defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;')
def defineMicroStoreOp(mnemonic, code, \ def defineMicroStoreOp(mnemonic, code, \
@ -434,8 +447,7 @@ let {{
{"code": code, {"code": code,
"post_code": postCode, "post_code": postCode,
"complete_code": completeCode, "complete_code": completeCode,
"ea_code": calculateEA, "ea_code": calculateEA})
"mem_flags": mem_flags})
header_output += MicroLdStOpDeclare.subst(iop) header_output += MicroLdStOpDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroStoreExecute.subst(iop) exec_output += MicroStoreExecute.subst(iop)
@ -444,9 +456,11 @@ let {{
class StoreOp(LdStOp): class StoreOp(LdStOp):
def __init__(self, data, segment, addr, disp = 0, def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"): dataSize="env.dataSize",
super(StoreOp, self).__init__(data, segment, addressSize="env.addressSize",
addr, disp, dataSize, addressSize) atCPL0=False):
super(StoreOp, self).__init__(data, segment, addr,
disp, dataSize, addressSize, mem_flags, atCPL0)
self.className = Name self.className = Name
self.mnemonic = name self.mnemonic = name
@ -461,8 +475,7 @@ let {{
iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
{"code": "Data = merge(Data, EA, dataSize);", {"code": "Data = merge(Data, EA, dataSize);",
"ea_code": calculateEA, "ea_code": calculateEA})
"mem_flags": 0})
header_output += MicroLeaDeclare.subst(iop) header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop) exec_output += MicroLeaExecute.subst(iop)
@ -471,7 +484,7 @@ let {{
def __init__(self, data, segment, addr, disp = 0, def __init__(self, data, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"): dataSize="env.dataSize", addressSize="env.addressSize"):
super(LeaOp, self).__init__(data, segment, super(LeaOp, self).__init__(data, segment,
addr, disp, dataSize, addressSize) addr, disp, dataSize, addressSize, "0", False)
self.className = "Lea" self.className = "Lea"
self.mnemonic = "lea" self.mnemonic = "lea"
@ -480,17 +493,17 @@ let {{
iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
{"code": "xc->demapPage(EA, 0);", {"code": "xc->demapPage(EA, 0);",
"ea_code": calculateEA, "ea_code": calculateEA})
"mem_flags": 0})
header_output += MicroLeaDeclare.subst(iop) header_output += MicroLeaDeclare.subst(iop)
decoder_output += MicroLdStOpConstructor.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop)
exec_output += MicroLeaExecute.subst(iop) exec_output += MicroLeaExecute.subst(iop)
class TiaOp(LdStOp): class TiaOp(LdStOp):
def __init__(self, segment, addr, disp = 0, def __init__(self, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"): dataSize="env.dataSize",
addressSize="env.addressSize"):
super(TiaOp, self).__init__("NUM_INTREGS", segment, super(TiaOp, self).__init__("NUM_INTREGS", segment,
addr, disp, dataSize, addressSize) addr, disp, dataSize, addressSize, "0", False)
self.className = "Tia" self.className = "Tia"
self.mnemonic = "tia" self.mnemonic = "tia"
@ -498,9 +511,10 @@ let {{
class CdaOp(LdStOp): class CdaOp(LdStOp):
def __init__(self, segment, addr, disp = 0, def __init__(self, segment, addr, disp = 0,
dataSize="env.dataSize", addressSize="env.addressSize"): dataSize="env.dataSize",
addressSize="env.addressSize", atCPL0=False):
super(CdaOp, self).__init__("NUM_INTREGS", segment, super(CdaOp, self).__init__("NUM_INTREGS", segment,
addr, disp, dataSize, addressSize) addr, disp, dataSize, addressSize, "0", atCPL0)
self.className = "Cda" self.className = "Cda"
self.mnemonic = "cda" self.mnemonic = "cda"

View file

@ -59,6 +59,7 @@
#include "config/full_system.hh" #include "config/full_system.hh"
#include "arch/x86/insts/microldstop.hh"
#include "arch/x86/pagetable.hh" #include "arch/x86/pagetable.hh"
#include "arch/x86/tlb.hh" #include "arch/x86/tlb.hh"
#include "arch/x86/x86_traits.hh" #include "arch/x86/x86_traits.hh"
@ -195,7 +196,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
uint32_t flags = req->getFlags(); uint32_t flags = req->getFlags();
bool storeCheck = flags & StoreCheck; bool storeCheck = flags & StoreCheck;
int seg = flags & mask(4); int seg = flags & SegmentFlagMask;
//XXX Junk code to surpress the warning //XXX Junk code to surpress the warning
if (storeCheck); if (storeCheck);