diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-04-27 13:18:49 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2025-04-27 13:18:49 +0000 |
| commit | 187eba4eca3ea46d8c26419168e525242338dae4 (patch) | |
| tree | 4fa918de9948b8d081bb9b24c0626a88740a4bd8 /arch/x86_64/src/context_switching | |
| parent | 7261c64bb236a313ed8846a9c9dbded6890a9e98 (diff) | |
| download | teachos-187eba4eca3ea46d8c26419168e525242338dae4.tar.xz teachos-187eba4eca3ea46d8c26419168e525242338dae4.zip | |
Simplify syscall setup
Diffstat (limited to 'arch/x86_64/src/context_switching')
| -rw-r--r-- | arch/x86_64/src/context_switching/main.cpp | 40 | ||||
| -rw-r--r-- | arch/x86_64/src/context_switching/syscall_handler.cpp | 1 |
2 files changed, 12 insertions, 29 deletions
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp index 85cefe5..155d150 100644 --- a/arch/x86_64/src/context_switching/main.cpp +++ b/arch/x86_64/src/context_switching/main.cpp @@ -6,6 +6,7 @@ #include "arch/kernel/cpu/call.hpp" #include "arch/kernel/cpu/control_register.hpp" #include "arch/kernel/cpu/if.hpp" +#include "arch/kernel/cpu/msr.hpp" #include "arch/kernel/cpu/segment_register.hpp" #include "arch/kernel/cpu/tr.hpp" #include "arch/video/vga/text.hpp" @@ -14,6 +15,10 @@ namespace teachos::arch::context_switching { namespace { + auto constexpr IA32_STAR_ADDRESS = 0xC0000081; + auto constexpr IA32_LSTAR_ADDRESS = 0xC0000082; + auto constexpr IA32_FMASK_ADDRESS = 0xC0000084; + constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; constexpr kernel::cpu::far_pointer KERNEL_CODE_POINTER{&kernel::cpu::reload_data_segment_registers, @@ -74,34 +79,13 @@ namespace teachos::arch::context_switching auto setup_syscall() -> void { - uint64_t handler = reinterpret_cast<uint64_t>(syscall_handler); - asm volatile( - /* Write syscall_handler pointer in IA32_LSTAR MSR */ - "mov $0xC0000082, %%ecx\n" /* IA32_LSTAR MSR */ - "mov %[syscall_handler], %%rax" - "mov %[syscall_handler], %%rdx" - "shr $32, %%rdx\n" - "wrmsr\n" - - /* Write RFLAGS Mask in IA32_LSTAR MSR */ - "mov $0xC0000084, %%ecx\n" /* IA32_FMASK MSR */ - "mov $0x0, %%rax\n" /* RFLAGS Mask lower 32 bits */ - "mov $0x0, %%rdx\n" /* RFLAGS Mask upper 32 bits */ - "wrmsr\n" - - /* Write kernel code segment offset in IA32_STAR MSR */ - "mov $0xC0000081, %%ecx\n" /* IA32_STAR MSR */ - "mov $0x10, %%rax\n" /* kernel code segment offset lower 32 bits */ - "mov $0x0, %%rdx\n" /* kernel code segment offset upper 32 bits */ - "wrmsr\n" - - /* Set SCE bit in MSR_EFER (enabling syscall instruction)*/ - "mov $0xC0000080, %%ecx\n" - "rdmsr\n" - "or $0x1, %%eax\n" - "wrmsr" - : /* no output from call */ - : [syscall_handler] "r"(handler)); + uint64_t const syscall_function = reinterpret_cast<uint64_t>(syscall_handler); + uint64_t const segment_selector = *reinterpret_cast<uint64_t const *>(&KERNEL_CODE_SEGMENT_SELECTOR); + + kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function); + kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); + kernel::cpu::write_msr(IA32_STAR_ADDRESS, segment_selector); + kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE); } } // namespace teachos::arch::context_switching diff --git a/arch/x86_64/src/context_switching/syscall_handler.cpp b/arch/x86_64/src/context_switching/syscall_handler.cpp index 1bc4ef9..283d297 100644 --- a/arch/x86_64/src/context_switching/syscall_handler.cpp +++ b/arch/x86_64/src/context_switching/syscall_handler.cpp @@ -4,7 +4,6 @@ namespace teachos::arch::context_switching { - [[gnu::naked]] auto syscall_handler() -> void { uint64_t dummy{}; |
