X86: Implement the longmode versions of the syscall instruction.

This commit is contained in:
Gabe Black 2009-02-25 10:17:49 -08:00
parent dadc30b0a4
commit 6325245e3e
2 changed files with 111 additions and 4 deletions

View file

@ -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

View file

@ -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}"
#}};