X86: Change what the microop chks does.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:50:10 +0000 (00:50 -0400)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 12 Jun 2008 04:50:10 +0000 (00:50 -0400)
Instead of computing the segment descriptor address, this now checks if a
selector value/descriptor are legal for a particular purpose.

src/arch/x86/isa/microasm.isa
src/arch/x86/isa/microops/regop.isa
src/arch/x86/isa/operands.isa

index 18abdf09bd5186589f8ae90c203481c7b2435c27..735a7722cbc84d9caa431e7f9c204c3a32b932c9 100644 (file)
@@ -81,6 +81,11 @@ let {{
     for letter in ("C", "D", "E", "F", "G", "S"):
         assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter
 
+    # Add in symbols for the various checks of segment selectors.
+    for check in ("NoCheck", "CSCheck", "CallGateCheck",
+                  "SSCheck", "IretCheck", "IntCSCheck"):
+        assembler.symbols[check] = "Seg%s" % check
+
     for reg in ("TR", "IDTR"):
         assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg
 
index 48aecf138d6162bd259fa328a3d7d8a0a1611cb1..6bd26608e9ba0f751dbb8ef45eeb2c2536d326c1 100644 (file)
@@ -231,6 +231,11 @@ output header {{
     void
     divide(uint64_t dividend, uint64_t divisor,
             uint64_t &quotient, uint64_t &remainder);
+
+    enum SegmentSelectorCheck {
+      SegNoCheck, SegCSCheck, SegCallGateCheck,
+      SegSSCheck, SegIretCheck, SegIntCSCheck
+    };
 }};
 
 output decoder {{
@@ -1018,11 +1023,46 @@ let {{
             DestReg = SegSelSrc1;
         '''
 
-    class Chks(SegOp):
+    class Chks(RegOp):
+        def __init__(self, dest, src1, src2=0,
+                flags=None, dataSize="env.dataSize"):
+            super(Chks, self).__init__(dest,
+                    src1, src2, flags, dataSize)
         code = '''
             // The selector is in source 1 and can be at most 16 bits.
             SegSelector selector = psrc1;
 
+            switch (imm8)
+            {
+              case SegNoCheck:
+                break;
+              case SegCSCheck:
+                panic("CS checks for far calls/jumps not implemented.\\n");
+                break;
+              case SegCallGateCheck:
+                panic("CS checks for far calls/jumps through call gates"
+                        "not implemented.\\n");
+                break;
+              case SegSSCheck:
+                panic("SS selector checks not implemented.\\n");
+                break;
+              case SegIretCheck:
+                {
+                    SegAttr csAttr = CSAttr;
+                    if (!selector.si && !selector.ti)
+                        return new GeneralProtection(psrc1 & 0xFFFF);
+                    if (selector.rpl < csAttr.dpl)
+                        return new GeneralProtection(psrc1 & 0xFFFF);
+                    break;
+                }
+              case SegIntCSCheck:
+                panic("CS selector checks for interrupts and exceptions"
+                        "not implemented.\\n");
+                break;
+              default:
+                panic("Undefined segment check type.\\n");
+            }
+
             // Compute the address of the descriptor and set DestReg to it.
             if (selector.ti) {
                 // A descriptor in the LDT
index b48e8759fcf8780c0ca2b7934ee1efae364663a8..f002b2cea39d8df4e3c4b53b253073c03ebf24b5 100644 (file)
@@ -149,6 +149,7 @@ def operands {{
         '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),
-        'TscOp':         ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 208),
+        'CSAttr':        ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208),
+        'TscOp':         ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209),
         'Mem':           ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300)
 }};