aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/boot/boot.s25
-rw-r--r--arch/x86_64/src/context_switching/main.cpp4
2 files changed, 28 insertions, 1 deletions
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s
index 7932045..24b38ca 100644
--- a/arch/x86_64/src/boot/boot.s
+++ b/arch/x86_64/src/boot/boot.s
@@ -352,6 +352,31 @@ prepare_page_maps:
.section .boot_text, "ax", @progbits
.code64
+syscall_target:
+ iretq
+
+.global syscall_trampoline
+syscall_trampoline:
+ /* Write target function pointer in IA32_LSTAR MSR */
+ mov $0xC0000082, %ecx /* IA32_LSTAR MSR */
+ lea [syscall_target], %rax
+ lea [syscall_target], %rdx
+ shr $32, %rdx
+ wrmsr
+
+ /* Write ... in IA32_LSTAR MSR */
+ mov $0xC0000084, %ecx /* IA32_FMASK MSR */
+ mov $0x0, %rax /* ... lower 32 bits */
+ mov $0x0, %rdx /* ... upper 32 bits */
+ wrmsr
+
+ /* Write Segment selector in IA32_STAR MSR */
+ mov $0xC0000081, %ecx /* IA32_STAR MSR */
+ mov $0x10, %rax /* SS lower 32 bits */
+ mov $0x0, %rdx /* SS upper 32 bits */
+ wrmsr
+
+
_transition_to_long_mode:
xor %rax, %rax
mov %rax, %ss
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp
index faaf831..c949488 100644
--- a/arch/x86_64/src/context_switching/main.cpp
+++ b/arch/x86_64/src/context_switching/main.cpp
@@ -1,5 +1,6 @@
#include "arch/context_switching/main.hpp"
+#include "arch/boot/pointers.hpp"
#include "arch/exception_handling/assert.hpp"
#include "arch/kernel/cpu/call.hpp"
#include "arch/kernel/cpu/control_register.hpp"
@@ -59,7 +60,8 @@ namespace teachos::arch::context_switching
// People claim that SYSENTER is for 32-Bit, while SYSCALL is for 64-Bit!
// asm volatile("INT $0x80");
- asm volatile("SYSCALL");
+ // asm volatile("SYSCALL");
+ boot::syscall_trampoline();
video::vga::text::write("Successfully entered user mode!", video::vga::text::common_attributes::green_on_black);
}