X86: Add a flag to force memory accesses to happen at CPL 0.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 25 Feb 2009 18:18:22 +0000 (10:18 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 25 Feb 2009 18:18:22 +0000 (10:18 -0800)
src/arch/x86/insts/microldstop.hh
src/arch/x86/isa/includes.isa
src/arch/x86/isa/microops/ldstop.isa
src/arch/x86/tlb.cc

index eccd37dc2c57093763c23993f32e196cc36ec44c..f0051e2cf61b78ec116c3056dd62c9e020d85b04 100644 (file)
 
 #include "arch/x86/insts/microop.hh"
 #include "mem/packet.hh"
+#include "mem/request.hh"
 
 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
      */
@@ -77,6 +84,7 @@ namespace X86ISA
         const RegIndex data;
         const uint8_t dataSize;
         const uint8_t addressSize;
+        const Request::FlagsType memFlags;
         RegIndex foldOBit, foldABit;
 
         //Constructor
@@ -87,13 +95,15 @@ namespace X86ISA
                 uint64_t _disp, uint8_t _segment,
                 RegIndex _data,
                 uint8_t _dataSize, uint8_t _addressSize,
+                Request::FlagsType _memFlags,
                 OpClass __opClass) :
         X86MicroopBase(machInst, mnem, _instMnem,
                 isMicro, isDelayed, isFirst, isLast, __opClass),
                 scale(_scale), index(_index), base(_base),
                 disp(_disp), segment(_segment),
                 data(_data),
-                dataSize(_dataSize), addressSize(_addressSize)
+                dataSize(_dataSize), addressSize(_addressSize),
+                memFlags(_memFlags | _segment)
         {
             foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
             foldABit =
index 909f2f3896cb6b195af3ea128d72122468ef4a71..10bac86ed23a702dabdd070ce3e90c84e56bb4a4 100644 (file)
@@ -117,6 +117,7 @@ output decoder {{
 #include "arch/x86/microcode_rom.hh"
 #include "arch/x86/miscregs.hh"
 #include "arch/x86/segmentregs.hh"
+#include "arch/x86/tlb.hh"
 #include "base/cprintf.hh"
 #include "base/loader/symtab.hh"
 #include "base/misc.hh"
index 5697f781b9f2481e561cd4fbcaf12103cfabd495..097b0e3112f19563f30d7938a5e3d0749b1d1f8e 100644 (file)
@@ -124,14 +124,16 @@ def template MicroLeaDeclare {{
                 uint8_t _scale, RegIndex _index, RegIndex _base,
                 uint64_t _disp, uint8_t _segment,
                 RegIndex _data,
-                uint8_t _dataSize, uint8_t _addressSize);
+                uint8_t _dataSize, uint8_t _addressSize,
+                Request::FlagsType _memFlags);
 
         %(class_name)s(ExtMachInst _machInst,
                 const char * instMnem,
                 uint8_t _scale, RegIndex _index, RegIndex _base,
                 uint64_t _disp, uint8_t _segment,
                 RegIndex _data,
-                uint8_t _dataSize, uint8_t _addressSize);
+                uint8_t _dataSize, uint8_t _addressSize,
+                Request::FlagsType _memFlags);
 
         %(BasicExecDeclare)s
     };
@@ -151,7 +153,7 @@ def template MicroLoadExecute {{
         %(ea_code)s;
         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)
         {
@@ -178,7 +180,7 @@ def template MicroLoadInitiateAcc {{
         %(ea_code)s;
         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;
     }
@@ -225,7 +227,7 @@ def template MicroStoreExecute {{
 
         if(fault == NoFault)
         {
-            fault = write(xc, Mem, EA, (%(mem_flags)s) | segment);
+            fault = write(xc, Mem, EA, memFlags);
             if(fault == NoFault)
             {
                 %(post_code)s;
@@ -253,7 +255,7 @@ def template MicroStoreInitiateAcc {{
 
         if(fault == NoFault)
         {
-            write(xc, Mem, EA, (%(mem_flags)s) | segment);
+            write(xc, Mem, EA, memFlags);
         }
         return fault;
     }
@@ -296,14 +298,16 @@ def template MicroLdStOpDeclare {{
                 uint8_t _scale, RegIndex _index, RegIndex _base,
                 uint64_t _disp, uint8_t _segment,
                 RegIndex _data,
-                uint8_t _dataSize, uint8_t _addressSize);
+                uint8_t _dataSize, uint8_t _addressSize,
+                Request::FlagsType _memFlags);
 
         %(class_name)s(ExtMachInst _machInst,
                 const char * instMnem,
                 uint8_t _scale, RegIndex _index, RegIndex _base,
                 uint64_t _disp, uint8_t _segment,
                 RegIndex _data,
-                uint8_t _dataSize, uint8_t _addressSize);
+                uint8_t _dataSize, uint8_t _addressSize,
+                Request::FlagsType _memFlags);
 
         %(BasicExecDeclare)s
 
@@ -325,12 +329,13 @@ def template MicroLdStOpConstructor {{
             uint8_t _scale, RegIndex _index, RegIndex _base,
             uint64_t _disp, uint8_t _segment,
             RegIndex _data,
-            uint8_t _dataSize, uint8_t _addressSize) :
+            uint8_t _dataSize, uint8_t _addressSize,
+            Request::FlagsType _memFlags) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                 false, false, false, false,
                 _scale, _index, _base,
                 _disp, _segment, _data,
-                _dataSize, _addressSize, %(op_class)s)
+                _dataSize, _addressSize, _memFlags, %(op_class)s)
     {
         buildMe();
     }
@@ -341,12 +346,13 @@ def template MicroLdStOpConstructor {{
             uint8_t _scale, RegIndex _index, RegIndex _base,
             uint64_t _disp, uint8_t _segment,
             RegIndex _data,
-            uint8_t _dataSize, uint8_t _addressSize) :
+            uint8_t _dataSize, uint8_t _addressSize,
+            Request::FlagsType _memFlags) :
         %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                 isMicro, isDelayed, isFirst, isLast,
                 _scale, _index, _base,
                 _disp, _segment, _data,
-                _dataSize, _addressSize, %(op_class)s)
+                _dataSize, _addressSize, _memFlags, %(op_class)s)
     {
         buildMe();
     }
@@ -354,26 +360,31 @@ def template MicroLdStOpConstructor {{
 
 let {{
     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.scale, self.index, self.base] = addr
             self.disp = disp
             self.segment = segment
             self.dataSize = dataSize
             self.addressSize = addressSize
+            self.memFlags = baseFlags
+            if atCPL0:
+                self.memFlags += " | (CPL0FlagBit << FlagShift)"
 
         def getAllocator(self, *microFlags):
             allocator = '''new %(class_name)s(machInst, macrocodeBlock
                     %(flags)s, %(scale)s, %(index)s, %(base)s,
                     %(disp)s, %(segment)s, %(data)s,
-                    %(dataSize)s, %(addressSize)s)''' % {
+                    %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
                 "class_name" : self.className,
                 "flags" : self.microFlagsText(microFlags),
                 "scale" : self.scale, "index" : self.index,
                 "base" : self.base,
                 "disp" : self.disp,
                 "segment" : self.segment, "data" : self.data,
-                "dataSize" : self.dataSize, "addressSize" : self.addressSize}
+                "dataSize" : self.dataSize, "addressSize" : self.addressSize,
+                "memFlags" : self.memFlags}
             return allocator
 }};
 
@@ -387,7 +398,7 @@ let {{
 
     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 decoder_output
         global exec_output
@@ -398,8 +409,7 @@ let {{
         # Build up the all register version of this micro op
         iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
                 {"code": code,
-                 "ea_code": calculateEA,
-                 "mem_flags": mem_flags})
+                 "ea_code": calculateEA})
         header_output += MicroLdStOpDeclare.subst(iop)
         decoder_output += MicroLdStOpConstructor.subst(iop)
         exec_output += MicroLoadExecute.subst(iop)
@@ -408,16 +418,19 @@ let {{
 
         class LoadOp(LdStOp):
             def __init__(self, data, segment, addr, disp = 0,
-                    dataSize="env.dataSize", addressSize="env.addressSize"):
-                super(LoadOp, self).__init__(data, segment,
-                        addr, disp, dataSize, addressSize)
+                    dataSize="env.dataSize",
+                    addressSize="env.addressSize",
+                    atCPL0=False):
+                super(LoadOp, self).__init__(data, segment, addr,
+                        disp, dataSize, addressSize, mem_flags, atCPL0)
                 self.className = Name
                 self.mnemonic = name
 
         microopClasses[name] = LoadOp
 
     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;')
 
     def defineMicroStoreOp(mnemonic, code, \
@@ -434,8 +447,7 @@ let {{
                 {"code": code,
                  "post_code": postCode,
                  "complete_code": completeCode,
-                 "ea_code": calculateEA,
-                 "mem_flags": mem_flags})
+                 "ea_code": calculateEA})
         header_output += MicroLdStOpDeclare.subst(iop)
         decoder_output += MicroLdStOpConstructor.subst(iop)
         exec_output += MicroStoreExecute.subst(iop)
@@ -444,9 +456,11 @@ let {{
 
         class StoreOp(LdStOp):
             def __init__(self, data, segment, addr, disp = 0,
-                    dataSize="env.dataSize", addressSize="env.addressSize"):
-                super(StoreOp, self).__init__(data, segment,
-                        addr, disp, dataSize, addressSize)
+                    dataSize="env.dataSize",
+                    addressSize="env.addressSize",
+                    atCPL0=False):
+                super(StoreOp, self).__init__(data, segment, addr,
+                        disp, dataSize, addressSize, mem_flags, atCPL0)
                 self.className = Name
                 self.mnemonic = name
 
@@ -461,8 +475,7 @@ let {{
 
     iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
             {"code": "Data = merge(Data, EA, dataSize);",
-             "ea_code": calculateEA,
-             "mem_flags": 0})
+             "ea_code": calculateEA})
     header_output += MicroLeaDeclare.subst(iop)
     decoder_output += MicroLdStOpConstructor.subst(iop)
     exec_output += MicroLeaExecute.subst(iop)
@@ -471,7 +484,7 @@ let {{
         def __init__(self, data, segment, addr, disp = 0,
                 dataSize="env.dataSize", addressSize="env.addressSize"):
             super(LeaOp, self).__init__(data, segment,
-                    addr, disp, dataSize, addressSize)
+                    addr, disp, dataSize, addressSize, "0", False)
             self.className = "Lea"
             self.mnemonic = "lea"
 
@@ -480,17 +493,17 @@ let {{
 
     iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
             {"code": "xc->demapPage(EA, 0);",
-             "ea_code": calculateEA,
-             "mem_flags": 0})
+             "ea_code": calculateEA})
     header_output += MicroLeaDeclare.subst(iop)
     decoder_output += MicroLdStOpConstructor.subst(iop)
     exec_output += MicroLeaExecute.subst(iop)
 
     class TiaOp(LdStOp):
         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,
-                    addr, disp, dataSize, addressSize)
+                    addr, disp, dataSize, addressSize, "0", False)
             self.className = "Tia"
             self.mnemonic = "tia"
 
@@ -498,9 +511,10 @@ let {{
 
     class CdaOp(LdStOp):
         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,
-                    addr, disp, dataSize, addressSize)
+                    addr, disp, dataSize, addressSize, "0", atCPL0)
             self.className = "Cda"
             self.mnemonic = "cda"
 
index 3962cd6076340c5898fb0e945bd766dc685d079e..372c8b997c413c3a1162a0b727127e6e2c2bd4b9 100644 (file)
@@ -59,6 +59,7 @@
 
 #include "config/full_system.hh"
 
+#include "arch/x86/insts/microldstop.hh"
 #include "arch/x86/pagetable.hh"
 #include "arch/x86/tlb.hh"
 #include "arch/x86/x86_traits.hh"
@@ -195,7 +196,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc,
     uint32_t flags = req->getFlags();
     bool storeCheck = flags & StoreCheck;
 
-    int seg = flags & mask(4);
+    int seg = flags & SegmentFlagMask;
 
     //XXX Junk code to surpress the warning
     if (storeCheck);