X86: Reorganize segmentation and implement segment selector movs.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:03:39 +0000 (23:03 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:03:39 +0000 (23:03 -0800)
--HG--
extra : convert_revision : 553c3ffeda1f5312cf02493f602e7d4ba2fe66e8

13 files changed:
src/arch/x86/insts/static_inst.cc
src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/insts/general_purpose/data_transfer/move.py
src/arch/x86/isa/insts/system/segmentation.py
src/arch/x86/isa/microasm.isa
src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa/operands.isa
src/arch/x86/isa/specialize.isa
src/arch/x86/miscregfile.cc
src/arch/x86/miscregs.hh
src/arch/x86/segmentregs.hh
src/arch/x86/tlb.cc
src/arch/x86/utility.cc

index 183700fa9a9bd73a16ce829c2d5a92d0ac0c98a7..0c1508d5ab20d1e995f63d49debf1e232102e657 100644 (file)
@@ -94,8 +94,26 @@ namespace X86ISA
           case SEGMENT_REG_GS:
             ccprintf(os, "GS");
             break;
-          case SEGMENT_REG_INT:
-            ccprintf(os, "INT");
+          case SEGMENT_REG_HS:
+            ccprintf(os, "HS");
+            break;
+          case SEGMENT_REG_TSL:
+            ccprintf(os, "TSL");
+            break;
+          case SEGMENT_REG_TSG:
+            ccprintf(os, "TSG");
+            break;
+          case SEGMENT_REG_LS:
+            ccprintf(os, "LS");
+            break;
+          case SEGMENT_REG_MS:
+            ccprintf(os, "MS");
+            break;
+          case SYS_SEGMENT_REG_TR:
+            ccprintf(os, "TR");
+            break;
+          case SYS_SEGMENT_REG_IDTR:
+            ccprintf(os, "IDTR");
             break;
           default:
             panic("Unrecognized segment %d\n", segment);
index 62b8c8d597bca1b4a8e445d2e30110e26f8a5488..0d1d7aacdf33beaaadd727891b02569145cd6053 100644 (file)
             0x1: MOV(Ev,Gv);
             0x2: MOV(Gb,Eb);
             0x3: MOV(Gv,Ev);
-            0x4: WarnUnimpl::mov_MwRv_Sw(); //What to do with this one?
+            0x4: decode MODRM_REG {
+                0x0, 0x1, 0x2,
+                0x3, 0x4, 0x5: MOV(Ev,Sv);
+            }
             0x5: LEA(Gv,M);
-            0x6: WarnUnimpl::mov_Sw_MwRv();
+            0x6: decode MODE_SUBMODE {
+                0x3, 0x4: MOV_REAL(Sv,Ev);
+                default: decode MODRM_REG {
+                    0x1: UD2(); // Moving to the CS selector is illegal.
+                    0x2: MOVSS(Sv,Ev);
+                    0x0, 0x3,
+                    0x4, 0x5: MOV(Sv,Ev);
+                    default: UD2();
+                }
+            }
             //0x7: group10_Ev();
             0x7: decode MODRM_REG {
                 0x0: POP(Ev);
index a15fc21ef1537764071d2245c8d6ac5f6665c3fc..aaddcf96279c98778639ae60da5f6111de00f5d0 100644 (file)
@@ -192,6 +192,108 @@ def macroop MOVZX_W_R_P {
 def macroop MOV_C_R {
     wrcr reg, regm
 };
+
+def macroop MOV_R_S {
+    rdsel reg, regm
+};
+
+def macroop MOV_M_S {
+    rdsel t1, reg
+    st t1, seg, sib, disp, dataSize=2
+};
+
+def macroop MOV_P_S {
+    rdip t7
+    rdsel t1, reg
+    st t1, seg, riprel, disp, dataSize=2
+};
+
+def macroop MOV_REAL_S_R {
+    zext t2, regm, 15
+    slli t3, t2, 2, dataSize=8
+    wrsel reg, regm
+    wrbase reg, t3
+};
+
+def macroop MOV_REAL_S_M {
+    ld t1, seg, sib, disp, dataSize=2
+    zext t2, t1, 15
+    slli t3, t2, 2, dataSize=8
+    wrsel reg, t1
+    wrbase reg, t3
+};
+
+def macroop MOV_REAL_S_P {
+    rdip t7
+    ld t1, seg, riprel, disp, dataSize=2
+    zext t2, t1, 15
+    slli t3, t2, 2, dataSize=8
+    wrsel reg, t1
+    wrbase reg, t3
+};
+
+def macroop MOV_S_R {
+    chks t1, regm, flags=(EZF,), dataSize=8
+    bri t0, label("end"), flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, regm
+end:
+    wrsel reg, regm
+};
+
+def macroop MOV_S_M {
+    ld t1, seg, sib, disp, dataSize=2
+    chks t2, t1, flags=(EZF,), dataSize=8
+    bri t0, label("end"), flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, t1
+end:
+    wrsel reg, t1
+};
+
+def macroop MOV_S_P {
+    rdip t7
+    ld t1, seg, riprel, disp, dataSize=2
+    chks t2, t1, flags=(EZF,), dataSize=8
+    bri t0, label("end"), flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, t1
+end:
+    wrsel reg, t1
+};
+
+def macroop MOVSS_S_R {
+    chks t1, regm, flags=(EZF,), dataSize=8
+    # This actually needs to use the selector as the error code, but it would
+    # be hard to get that information into the instruction at the moment.
+    fault "new GeneralProtection(0)", flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, regm
+    wrsel reg, regm
+};
+
+def macroop MOVSS_S_M {
+    ld t1, seg, sib, disp, dataSize=2
+    chks t2, t1, flags=(EZF,), dataSize=8
+    # This actually needs to use the selector as the error code, but it would
+    # be hard to get that information into the instruction at the moment.
+    fault "new GeneralProtection(0)", flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, t1
+    wrsel reg, t1
+};
+
+def macroop MOVSS_S_P {
+    rdip t7
+    ld t1, seg, riprel, disp, dataSize=2
+    chks t2, t1, flags=(EZF,), dataSize=8
+    # This actually needs to use the selector as the error code, but it would
+    # be hard to get that information into the instruction at the moment.
+    fault "new GeneralProtection(0)", flags=(CEZF,)
+    ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8
+    wrdl reg, t2, t1
+    wrsel reg, t1
+};
 '''
 #let {{
 #    class MOVD(Inst):
index e46941e53a389e6619a73e0945a9e10f68d65537..97846f79c9e7120140370b06c20ab5d865d40410 100644 (file)
@@ -62,8 +62,8 @@ def macroop LGDT_M
     ld t1, seg, sib, disp, dataSize=2
     # Get the base
     ld t2, seg, sib, 'adjustedDisp + 2'
-    wrbase gdtr, t2
-    wrlimit gdtr, t1
+    wrbase tsg, t2
+    wrlimit tsg, t1
 };
 
 def macroop LGDT_P
@@ -75,8 +75,8 @@ def macroop LGDT_P
     ld t1, seg, riprel, disp, dataSize=2
     # Get the base
     ld t2, seg, riprel, 'adjustedDisp + 2'
-    wrbase gdtr, t2
-    wrlimit gdtr, t1
+    wrbase tsg, t2
+    wrlimit tsg, t1
 };
 
 #
@@ -93,8 +93,8 @@ def macroop LGDT_16_M
     # Get the base
     ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4
     zexti t2, t2, 23
-    wrbase gdtr, t2
-    wrlimit gdtr, t1
+    wrbase tsg, t2
+    wrlimit tsg, t1
 };
 
 def macroop LGDT_16_P
@@ -107,8 +107,8 @@ def macroop LGDT_16_P
     # Get the base
     ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4
     zexti t2, t2, 23
-    wrbase gdtr, t2
-    wrlimit gdtr, t1
+    wrbase tsg, t2
+    wrlimit tsg, t1
 };
 
 def macroop LIDT_M
index 8c499eeed0ac0317e7da284664dea77e35b2b647..9e8b65c4ed8387ec5cc4a1528f2c7ede81915651 100644 (file)
@@ -81,9 +81,12 @@ let {{
     for letter in ("C", "D", "E", "F", "G", "S"):
         assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
 
-    for reg in ("LDTR", "TR", "GDTR", "IDTR"):
+    for reg in ("TR", "IDTR"):
         assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
 
+    for reg in ("TSL", "TSG"):
+        assembler.symbols[reg.lower()] = "SEGMENT_REG_%s" % reg
+
     # Miscellaneous symbols
     symbols = {
         "reg" : "env.reg",
@@ -112,7 +115,10 @@ let {{
 
     # This segment selects an internal address space mapped to MSRs,
     # CPUID info, etc.
-    assembler.symbols["intseg"] = "SEGMENT_REG_INT"
+    assembler.symbols["intseg"] = "SEGMENT_REG_MS"
+    # This segment always has base 0, and doesn't imply any special handling
+    # like the internal segment above
+    assembler.symbols["flatseg"] = "SEGMENT_REG_LS"
 
     for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'):
         assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper()
index f37b4327bdafc8d1517ca93311455088a397f61e..7f72fcf1d15ed1e50bede584b251b26cbcdc63c1 100644 (file)
@@ -937,19 +937,100 @@ let {{
             }
             '''
 
-    class Wrbase(RegOp):
+    # Microops for manipulating segmentation registers
+    class SegOp(RegOp):
+        abstract = True
         def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
-            super(Wrbase, self).__init__(dest, \
+            super(SegOp, self).__init__(dest, \
                     src1, "NUM_INTREGS", flags, dataSize)
+
+    class Wrbase(SegOp):
         code = '''
-            SysSegBaseDest = psrc1;
+            SegBaseDest = psrc1;
         '''
 
-    class Wrlimit(RegOp):
-        def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"):
-            super(Wrlimit, self).__init__(dest, \
-                    src1, "NUM_INTREGS", flags, dataSize)
+    class Wrlimit(SegOp):
+        code = '''
+            SegLimitDest = psrc1;
+        '''
+
+    class Wrsel(SegOp):
+        code = '''
+            SegSelDest = psrc1;
+        '''
+
+    class Rdbase(SegOp):
+        code = '''
+            DestReg = SegBaseDest;
+        '''
+
+    class Rdlimit(SegOp):
+        code = '''
+            DestReg = SegLimitSrc1;
+        '''
+
+    class Rdsel(SegOp):
         code = '''
-            SysSegLimitDest = psrc1;
+            DestReg = SegSelSrc1;
+        '''
+
+    class Chks(SegOp):
+        code = '''
+            // The selector is in source 1.
+            SegSelector selector = psrc1;
+
+            // Compute the address of the descriptor and set DestReg to it.
+            if (selector.ti) {
+                // A descriptor in the LDT
+                Addr target = (selector.esi << 3) + LDTRBase;
+                if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit)
+                    fault = new GeneralProtection(selector & mask(16));
+                DestReg = target;
+            } else {
+                // A descriptor in the GDT
+                Addr target = (selector.esi << 3) + GDTRBase;
+                if ((selector.esi << 3) + dataSize > GDTRLimit)
+                    fault = new GeneralProtection(selector & mask(16));
+                DestReg = target;
+            }
+        '''
+        flag_code = '''
+            // Check for a NULL selector and set ZF,EZF appropriately.
+            ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit));
+            if (!selector.esi && !selector.ti)
+                ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit));
+        '''
+
+    class Wrdh(RegOp):
+        code = '''
+
+        '''
+
+    class Wrdl(RegOp):
+        code = '''
+            SegDescriptor desc = SrcReg1;
+            SegAttr attr = 0;
+            Addr base = 0, limit = 0;
+            attr.dpl = desc.dpl;
+            attr.defaultSize = desc.d;
+            if (!desc.p)
+                panic("Segment not present.\\n");
+            if (!desc.s)
+                panic("System segment encountered.\\n");
+            if (desc.type.codeOrData) {
+                panic("Code segment encountered with c = %d, r = %d, a = %d.\\n",
+                        desc.type.c, desc.type.r, desc.type.a);
+            } else {
+                attr.expandDown = desc.type.e;
+                attr.readable = 1;
+                attr.writable = desc.type.w;
+                base = desc.baseLow | (desc.baseHigh << 24);
+                limit = desc.limitLow | (desc.limitHigh << 16);
+                if (desc.g)
+                    limit = (limit << 12) | mask(12);
+            }
+            SegBaseDest = base;
+            SegLimitDest = limit;
+            SegAttrDest = attr;
         '''
 }};
index 40c8ee9c2168b942f0ba73ba0143a679b84dbed4..9345158e9291d957dcc8b98926dfc737aff12958 100644 (file)
@@ -121,14 +121,30 @@ def operands {{
         # The TOP register should needs to be more protected so that later
         # instructions don't map their indexes with an old value.
         'TOP':           ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61),
+        # The segment base as used by memory instructions.
         'SegBase':       ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70),
-        'ControlDest':   ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 71),
-        'ControlSrc1':   ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 72),
-        'EferOp':        ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 73),
-        'CR4Op':         ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 74),
-        'CSBase':        ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 80),
-        'SysSegBaseDest':  ('ControlReg', 'uqw', 'MISCREG_SYSSEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 75),
-        'SysSegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SYSSEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 76),
 
-        'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
+        # Operands to get and set registers indexed by the operands of the
+        # original instruction.
+        'ControlDest':   ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100),
+        'ControlSrc1':   ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101),
+        'SegBaseDest':  ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102),
+        'SegBaseSrc1':  ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103),
+        'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104),
+        'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105),
+        'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106),
+        'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107),
+        'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108),
+        'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109),
+
+        # Operands to access specific control registers directly.
+        'EferOp':        ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200),
+        'CR4Op':         ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201),
+        'LDTRBase':      ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202),
+        'LDTRLimit':     ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203),
+        'LDTRSel':       ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204),
+        'GDTRBase':      ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205),
+        'GDTRLimit':     ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206),
+        'CSBase':        ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207),
+        'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
 }};
index 3802d89490fc3a796fcb88a230d2be4a64663e03..abf734307fd2b034d7e0d5c4f1758ed0de669943 100644 (file)
@@ -154,12 +154,18 @@ let {{
             elif opType.tag == None or opType.size == None:
                 raise Exception, "Problem parsing operand tag: %s" % opType.tag
             elif opType.tag == "C":
+                # A control register indexed by the "reg" field
                 env.addReg(ModRMRegIndex)
                 Name += "_C"
             elif opType.tag == "D":
+                # A debug register indexed by the "reg" field
                 env.addReg(ModRMRegIndex)
                 Name += "_D"
-            elif opType.tag in ("G", "P", "S", "T", "V"):
+            elif opType.tag == "S":
+                # A segment selector register indexed by the "reg" field
+                env.addReg(ModRMRegIndex)
+                Name += "_S"
+            elif opType.tag in ("G", "P", "T", "V"):
                 # Use the "reg" field of the ModRM byte to select the register
                 env.addReg(ModRMRegIndex)
                 Name += "_R"
index a019024783b09388849927b3fc70e759c631917c..05d64f73ff5b4385f74aad7832866213e19ef939 100644 (file)
@@ -205,6 +205,31 @@ void MiscRegFile::setReg(int miscReg,
                 }
             }
         }
+      // These segments always actually use their bases, or in other words
+      // their effective bases must stay equal to their actual bases.
+      case MISCREG_FS:
+      case MISCREG_GS:
+      case MISCREG_HS:
+      case MISCREG_TSL:
+      case MISCREG_TSG:
+      case MISCREG_TR:
+      case MISCREG_IDTR:
+        regVal[MISCREG_SEG_EFF_BASE(miscReg - MISCREG_SEG_SEL_BASE)] = val;
+        break;
+      // These segments ignore their bases in 64 bit mode.
+      // their effective bases must stay equal to their actual bases.
+      case MISCREG_ES:
+      case MISCREG_CS:
+      case MISCREG_SS:
+      case MISCREG_DS:
+        {
+            Efer efer = regVal[MISCREG_EFER];
+            SegAttr csAttr = regVal[MISCREG_CS_ATTR];
+            if (!efer.lma || !csAttr.longMode) // Check for non 64 bit mode.
+                regVal[MISCREG_SEG_EFF_BASE(miscReg -
+                        MISCREG_SEG_SEL_BASE)] = val;
+        }
+        break;
     }
     setRegNoEffect(miscReg, newVal);
 }
index d3960073a433e7ee8dd29a4b0106780aaf4b27ef..36b953526bdd5d9e26e7a1a22490f4f90d83d6cc 100644 (file)
@@ -58,6 +58,7 @@
 #ifndef __ARCH_X86_MISCREGS_HH__
 #define __ARCH_X86_MISCREGS_HH__
 
+#include "arch/x86/segmentregs.hh"
 #include "arch/x86/x86_traits.hh"
 #include "base/bitunion.hh"
 
@@ -258,76 +259,83 @@ namespace X86ISA
         MISCREG_DS,
         MISCREG_FS,
         MISCREG_GS,
-        MISCREG_INT, // This isn't actually used.
+        MISCREG_HS,
+        MISCREG_TSL,
+        MISCREG_TSG,
+        MISCREG_LS,
+        MISCREG_MS,
+        MISCREG_TR,
+        MISCREG_IDTR,
 
         // Hidden segment base field
-        MISCREG_SEG_BASE_BASE = MISCREG_SEG_SEL_BASE + NumSegments,
+        MISCREG_SEG_BASE_BASE = MISCREG_SEG_SEL_BASE + NUM_SEGMENTREGS,
         MISCREG_ES_BASE = MISCREG_SEG_BASE_BASE,
         MISCREG_CS_BASE,
         MISCREG_SS_BASE,
         MISCREG_DS_BASE,
         MISCREG_FS_BASE,
         MISCREG_GS_BASE,
-        MISCREG_INT_BASE,
+        MISCREG_HS_BASE,
+        MISCREG_TSL_BASE,
+        MISCREG_TSG_BASE,
+        MISCREG_LS_BASE,
+        MISCREG_MS_BASE,
+        MISCREG_TR_BASE,
+        MISCREG_IDTR_BASE,
 
         // The effective segment base, ie what is actually added to an
         // address. In 64 bit mode this can be different from the above,
         // namely 0.
-        MISCREG_SEG_EFF_BASE_BASE = MISCREG_SEG_BASE_BASE + NumSegments,
+        MISCREG_SEG_EFF_BASE_BASE = MISCREG_SEG_BASE_BASE + NUM_SEGMENTREGS,
         MISCREG_ES_EFF_BASE = MISCREG_SEG_EFF_BASE_BASE,
         MISCREG_CS_EFF_BASE,
         MISCREG_SS_EFF_BASE,
         MISCREG_DS_EFF_BASE,
         MISCREG_FS_EFF_BASE,
         MISCREG_GS_EFF_BASE,
-        MISCREG_INT_EFF_BASE,
+        MISCREG_HS_EFF_BASE,
+        MISCREG_TSL_EFF_BASE,
+        MISCREG_TSG_EFF_BASE,
+        MISCREG_LS_EFF_BASE,
+        MISCREG_MS_EFF_BASE,
+        MISCREG_TR_EFF_BASE,
+        MISCREG_IDTR_EFF_BASE,
 
         // Hidden segment limit field
-        MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_EFF_BASE_BASE + NumSegments,
+        MISCREG_SEG_LIMIT_BASE = MISCREG_SEG_EFF_BASE_BASE + NUM_SEGMENTREGS,
         MISCREG_ES_LIMIT = MISCREG_SEG_LIMIT_BASE,
         MISCREG_CS_LIMIT,
         MISCREG_SS_LIMIT,
         MISCREG_DS_LIMIT,
         MISCREG_FS_LIMIT,
         MISCREG_GS_LIMIT,
-        MISCREG_INT_LIMIT, // This isn't actually used.
+        MISCREG_HS_LIMIT,
+        MISCREG_TSL_LIMIT,
+        MISCREG_TSG_LIMIT,
+        MISCREG_LS_LIMIT,
+        MISCREG_MS_LIMIT,
+        MISCREG_TR_LIMIT,
+        MISCREG_IDTR_LIMIT,
 
         // Hidden segment limit attributes
-        MISCREG_SEG_ATTR_BASE = MISCREG_SEG_LIMIT_BASE + NumSegments,
+        MISCREG_SEG_ATTR_BASE = MISCREG_SEG_LIMIT_BASE + NUM_SEGMENTREGS,
         MISCREG_ES_ATTR = MISCREG_SEG_ATTR_BASE,
         MISCREG_CS_ATTR,
         MISCREG_SS_ATTR,
         MISCREG_DS_ATTR,
         MISCREG_FS_ATTR,
         MISCREG_GS_ATTR,
-        MISCREG_INT_ATTR, // This isn't actually used.
-
-        // System segment selectors
-        MISCREG_SYSSEG_SEL_BASE = MISCREG_SEG_ATTR_BASE + NumSegments,
-        MISCREG_LDTR = MISCREG_SYSSEG_SEL_BASE,
-        MISCREG_TR,
-
-        // Hidden system segment base field
-        MISCREG_SYSSEG_BASE_BASE = MISCREG_SYSSEG_SEL_BASE + NumSysSegments,
-        MISCREG_LDTR_BASE = MISCREG_SYSSEG_BASE_BASE,
-        MISCREG_TR_BASE,
-        MISCREG_GDTR_BASE,
-        MISCREG_IDTR_BASE,
-
-        // Hidden system segment limit field
-        MISCREG_SYSSEG_LIMIT_BASE = MISCREG_SYSSEG_BASE_BASE + NumSysSegments,
-        MISCREG_LDTR_LIMIT = MISCREG_SYSSEG_LIMIT_BASE,
-        MISCREG_TR_LIMIT,
-        MISCREG_GDTR_LIMIT,
-        MISCREG_IDTR_LIMIT,
-
-        // Hidden system segment attribute field
-        MISCREG_SYSSEG_ATTR_BASE = MISCREG_SYSSEG_LIMIT_BASE + NumSysSegments,
-        MISCREG_LDTR_ATTR = MISCREG_SYSSEG_ATTR_BASE,
+        MISCREG_HS_ATTR,
+        MISCREG_TSL_ATTR,
+        MISCREG_TSG_ATTR,
+        MISCREG_LS_ATTR,
+        MISCREG_MS_ATTR,
         MISCREG_TR_ATTR,
+        MISCREG_IDTR_ATTR,
 
         // Floating point control registers
-        MISCREG_X87_TOP = MISCREG_SYSSEG_ATTR_BASE + NumSysSegments,
+        MISCREG_X87_TOP =
+            MISCREG_SEG_ATTR_BASE + NUM_SEGMENTREGS,
 
         //XXX Add "Model-Specific Registers"
 
@@ -436,30 +444,6 @@ namespace X86ISA
         return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index);
     }
 
-    static inline MiscRegIndex
-    MISCREG_SYSSEG_SEL(int index)
-    {
-        return (MiscRegIndex)(MISCREG_SYSSEG_SEL_BASE + index);
-    }
-
-    static inline MiscRegIndex
-    MISCREG_SYSSEG_BASE(int index)
-    {
-        return (MiscRegIndex)(MISCREG_SYSSEG_BASE_BASE + index);
-    }
-
-    static inline MiscRegIndex
-    MISCREG_SYSSEG_LIMIT(int index)
-    {
-        return (MiscRegIndex)(MISCREG_SYSSEG_LIMIT_BASE + index);
-    }
-
-    static inline MiscRegIndex
-    MISCREG_SYSSEG_ATTR(int index)
-    {
-        return (MiscRegIndex)(MISCREG_SYSSEG_ATTR_BASE + index);
-    }
-
     /**
      * A type to describe the condition code bits of the RFLAGS register,
      * plus two flags, EZF and ECF, which are only visible to microcode.
@@ -729,6 +713,10 @@ namespace X86ISA
      * Segment Selector
      */
     BitUnion64(SegSelector)
+        // The following bitfield is not defined in the ISA, but it's useful
+        // when checking selectors in larger data types to make sure they
+        // aren't too large.
+        Bitfield<63, 3> esi; // Extended selector
         Bitfield<15, 3> si; // Selector Index
         Bitfield<2> ti; // Table Indicator
         Bitfield<1, 0> rpl; // Requestor Privilege Level
index e6079da6d1a076f4d98a95568710bac6dd6fed00..7473c5ea902ec64c34eeb1d8f6bddb6038042754 100644 (file)
@@ -68,19 +68,18 @@ namespace X86ISA
         SEGMENT_REG_DS,
         SEGMENT_REG_FS,
         SEGMENT_REG_GS,
-        SEGMENT_REG_INT,
-
-        NUM_SEGMENTREGS
-    };
-
-    enum SysSegmentRegIndex
-    {
-        SYS_SEGMENT_REG_LDTR,
+        SEGMENT_REG_HS, // Temporary descriptor
+        SEGMENT_REG_TSL, // Local descriptor table
+        SEGMENT_REG_TSG, // Global descriptor table
+        SEGMENT_REG_LS, // Flat segment
+        SEGMENT_REG_MS, // Emulation memory
+        // These shouldn't be used directly in a load or store since they
+        // are likely accessed in other ways in a real machine. For instance,
+        // they may be loaded into the temporary segment register on demand.
         SYS_SEGMENT_REG_TR,
-        SYS_SEGMENT_REG_GDTR,
         SYS_SEGMENT_REG_IDTR,
 
-        NUM_SYSSEGMENTREGS
+        NUM_SEGMENTREGS
     };
 };
 
index 68a22bc1686d9581aa0586c00c2c1e1678acc342..08c6216154c1a47f547e04f7ae86272e41ee091b 100644 (file)
@@ -176,14 +176,14 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute)
     uint32_t flags = req->getFlags();
     bool storeCheck = flags & StoreCheck;
 
-    int seg = flags & mask(3);
+    int seg = flags & mask(4);
 
     //XXX Junk code to surpress the warning
     if (storeCheck);
 
     // If this is true, we're dealing with a request to read an internal
     // value.
-    if (seg == SEGMENT_REG_INT) {
+    if (seg == SEGMENT_REG_MS) {
         DPRINTF(TLB, "Addresses references internal memory.\n");
         Addr prefix = vaddr & IntAddrPrefixMask;
         if (prefix == IntAddrPrefixCPUID) {
index 69179c1f4540c7f02c2cb3ae41be53d91ae3d298..f45d9083b263182c2e0e3a0960fa6e3d124c658a 100644 (file)
@@ -143,16 +143,16 @@ void initCPU(ThreadContext *tc, int cpuId)
             tc->readMiscReg(MISCREG_CS_BASE));
     tc->setNextPC(tc->readPC() + sizeof(MachInst));
 
-    tc->setMiscReg(MISCREG_GDTR_BASE, 0);
-    tc->setMiscReg(MISCREG_GDTR_LIMIT, 0xffff);
+    tc->setMiscReg(MISCREG_TSG_BASE, 0);
+    tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);
 
     tc->setMiscReg(MISCREG_IDTR_BASE, 0);
     tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);
 
-    tc->setMiscReg(MISCREG_LDTR, 0);
-    tc->setMiscReg(MISCREG_LDTR_BASE, 0);
-    tc->setMiscReg(MISCREG_LDTR_LIMIT, 0xffff);
-    tc->setMiscReg(MISCREG_LDTR_ATTR, 0);
+    tc->setMiscReg(MISCREG_TSL, 0);
+    tc->setMiscReg(MISCREG_TSL_BASE, 0);
+    tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
+    tc->setMiscReg(MISCREG_TSL_ATTR, 0);
 
     tc->setMiscReg(MISCREG_TR, 0);
     tc->setMiscReg(MISCREG_TR_BASE, 0);
@@ -306,8 +306,8 @@ void startupCPU(ThreadContext *tc, int cpuId)
         uint64_t csDescVal = csDesc;
         physPort->writeBlob(GDTBase, (uint8_t *)(&csDescVal), 8);
 
-        tc->setMiscReg(MISCREG_GDTR_BASE, GDTBase);
-        tc->setMiscReg(MISCREG_GDTR_LIMIT, 0xF);
+        tc->setMiscReg(MISCREG_TSG_BASE, GDTBase);
+        tc->setMiscReg(MISCREG_TSG_LIMIT, 0xF);
 
         /*
          * Identity map the first 4GB of memory. In order to map this region