summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/isa/decoder/two_byte_opcodes.isa8
-rw-r--r--src/arch/x86/isa/insts/general_purpose/system_calls.py107
2 files changed, 111 insertions, 4 deletions
diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
index 67845fe8d..887b5bb14 100644
--- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa
@@ -254,7 +254,13 @@
}
}
#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
diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py
index b3a57eca9..bb08282d2 100644
--- a/src/arch/x86/isa/insts/general_purpose/system_calls.py
+++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py
@@ -53,14 +53,115 @@
#
# 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}"
#}};