X86: Implement the longmode versions of the syscall instruction.
authorGabe Black <gblack@eecs.umich.edu>
Wed, 25 Feb 2009 18:17:49 +0000 (10:17 -0800)
committerGabe Black <gblack@eecs.umich.edu>
Wed, 25 Feb 2009 18:17:49 +0000 (10:17 -0800)
src/arch/x86/isa/decoder/two_byte_opcodes.isa
src/arch/x86/isa/insts/general_purpose/system_calls.py

index 67845fe8df88504910c78cf0c1c8e28ba07a27dd..887b5bb14313d3a4b17e2b491ea9957a5c09796b 100644 (file)
                     }
                 }
 #if FULL_SYSTEM
-                0x05: syscall();
+                0x05: decode MODE_MODE {
+                    0x0: decode MODE_SUBMODE {
+                        0x0: Inst::SYSCALL_64();
+                        0x1: Inst::SYSCALL_COMPAT();
+                    }
+                    0x1: Inst::SYSCALL_LEGACY();
+                }
 #else
                 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
 #endif
index b3a57eca96893b5d99421fee5a64948bc1145ff6..bb08282d2ed565ac37244d249fa81cb38cb51461 100644 (file)
 #
 # Authors: Gabe Black
 
-microcode = ""
+microcode = '''
+def macroop SYSCALL_64
+{
+    # All 1s.
+    limm t1, "(uint64_t)(-1)"
+
+    # Save the next RIP.
+    rdip rcx
+    
+    # Stick rflags with RF masked into r11.
+    rflags t2
+    limm t3, "~RFBit"
+    andi r11, t2, t3, dataSize=8
+
+    rdval t3, star
+    srli t3, t3, 32, dataSize=8
+    andi t3, t3, 0xFC, dataSize=1
+
+    # Set up CS.
+    wrsel cs, t3
+    wrbase cs, t0, dataSize=8
+    wrlimit cs, t1, dataSize=4
+    # Not writable, read/execute-able, not expandDown,
+    # dpl=0, defaultSize=0, long mode
+    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+              (0 << 3) | (0 << 5) | (1 << 6))
+    wrattr cs, t4
+
+    # Set up SS.
+    addi t3, t3, 8
+    wrsel ss, t3
+    wrbase ss, t0, dataSize=8
+    wrlimit ss, t1, dataSize=4
+    # Writable, readable, not expandDown,
+    # dpl=0, defaultSize=0, not long mode
+    limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
+              (0 << 3) | (0 << 5) | (0 << 6))
+    wrattr ss, t4
+
+    # Set the new rip.
+    rdval t7, lstar
+    wrip t0, t7
+
+    # Mask the flags against sf_mask and leave RF turned off.
+    rdval t3, sf_mask, dataSize=8
+    xor t3, t3, t1, dataSize=8
+    and t3, t3, r11, dataSize=8
+    wrflags t3, t0
+};
+
+def macroop SYSCALL_COMPAT
+{
+    # All 1s.
+    limm t1, "(uint64_t)(-1)"
+
+    # Save the next RIP.
+    rdip rcx
+    
+    # Stick rflags with RF masked into r11.
+    rflags t2
+    limm t3, "~RFBit"
+    andi r11, t2, t3, dataSize=8
+
+    rdval t3, star
+    srli t3, t3, 32, dataSize=8
+    andi t3, t3, 0xFC, dataSize=1
+
+    # Set up CS.
+    wrsel cs, t3
+    wrbase cs, t0, dataSize=8
+    wrlimit cs, t1, dataSize=4
+    # Not writable, read/execute-able, not expandDown,
+    # dpl=0, defaultSize=0, long mode
+    limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \
+              (0 << 3) | (0 << 5) | (1 << 6))
+    wrattr cs, t4
+
+    # Set up SS.
+    addi t3, t3, 8
+    wrsel ss, t3
+    wrbase ss, t0, dataSize=8
+    wrlimit ss, t1, dataSize=4
+    # Writable, readable, not expandDown,
+    # dpl=0, defaultSize=0, not long mode
+    limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \
+              (0 << 3) | (0 << 5) | (0 << 6))
+    wrattr ss, t4
+
+    # Set the new rip.
+    rdval t7, cstar
+    wrip t0, t7
+
+    # Mask the flags against sf_mask and leave RF turned off.
+    rdval t3, sf_mask, dataSize=8
+    xor t3, t3, t1, dataSize=8
+    and t3, t3, r11, dataSize=8
+    wrflags t3, t0
+};
+
+def macroop SYSCALL_LEGACY
+{
+    panic "The syscall instruction isn't implemented in legacy mode."
+};
+'''
 #let {{
 #    class SYSENTER(Inst):
 #       "GenFault ${new UnimpInstFault}"
 #    class SYSEXIT(Inst):
 #       "GenFault ${new UnimpInstFault}"
-#    class SYSCALL(Inst):
-#       "GenFault ${new UnimpInstFault}"
 #    class SYSRET(Inst):
 #       "GenFault ${new UnimpInstFault}"
 #}};