X86: First crack at far returns. This is grossly approximate.
authorGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:05:01 +0000 (23:05 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 2 Dec 2007 07:05:01 +0000 (23:05 -0800)
--HG--
extra : convert_revision : 23da0338af1f7663ae5ddf2289fb45dd32f37c42

src/arch/x86/isa/decoder/one_byte_opcodes.isa
src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py
src/arch/x86/isa/microops/regop.isa

index 0d1d7aacdf33beaaadd727891b02569145cd6053..332ae1641b14538bb65a5bd4c6ea863b5aefb47a 100644 (file)
                 0x0: Inst::ENTER(Iw,Iw);
                 0x1: Inst::LEAVE();
                 0x2: ret_far_Iw();
-                0x3: ret_far();
+                0x3: decode MODE_SUBMODE {
+                    0x3, 0x4: ret_far_real();
+                    default: Inst::RET_FAR();
+                }
                 0x4: int3();
                 0x5: int_Ib();
                 0x6: decode MODE_SUBMODE {
index 8993f5ac42c5797799c71a8ae8c0541e955a854c..0b2e81cbdacd788f0db84f0e568d3f79e9f9096b 100644 (file)
@@ -77,4 +77,36 @@ def macroop RET_NEAR_I
     add rsp, rsp, t2
     wripi t1, 0
 };
+
+def macroop RET_FAR {
+    .adjust_env oszIn64Override
+
+    # Get the return RIP
+    ld t1, ss, [1, t0, rsp]
+
+    # Get the return CS
+    ld t2, ss, [1, t0, rsp], dsz
+
+    # Get the rpl
+    andi t3, t2, 0x3
+
+    # Get the cpl
+
+    # Here we'd check if we're changing priviledge levels. We'll just hope
+    # that doesn't happen yet.
+
+    # Do stuff if they're equal
+    chks t4, t2, flags=(EZF,)
+    fault "new GeneralProtection(0)", flags=(CEZF,)
+    ld t3, flatseg, [1, t0, t4], addressSize=8, dataSize=8
+    wrdl cs, t3, t2
+    # There should be validity checks on the RIP checks here, but I'll do
+    # that later.
+    wrip t0, t1
+    bri t0, label("end")
+
+    # Do other stuff if they're not.
+end:
+    fault "NoFault"
+};
 '''
index 7f72fcf1d15ed1e50bede584b251b26cbcdc63c1..de9f76e736854dc1c8223a5f1937449c9f69fc9a 100644 (file)
@@ -1010,27 +1010,31 @@ let {{
         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)
+            if (!desc.s) {
+                SegBaseDest = SegBaseDest;
+                SegLimitDest = SegLimitDest;
+                SegAttrDest = SegAttrDest;
                 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.p)
+                    panic("Segment not present.\\n");
+                if (desc.type.codeOrData) {
+                    attr.readable = desc.type.r;
+                    attr.longMode = desc.l;
+                } else {
+                    attr.expandDown = desc.type.e;
+                    attr.readable = 1;
+                    attr.writable = desc.type.w;
+                }
+                Addr base = desc.baseLow | (desc.baseHigh << 24);
+                Addr limit = desc.limitLow | (desc.limitHigh << 16);
                 if (desc.g)
                     limit = (limit << 12) | mask(12);
+                SegBaseDest = base;
+                SegLimitDest = limit;
+                SegAttrDest = attr;
             }
-            SegBaseDest = base;
-            SegLimitDest = limit;
-            SegAttrDest = attr;
         '''
 }};