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/context_switching/main.cpp40
-rw-r--r--arch/x86_64/src/context_switching/syscall_handler.cpp1
-rw-r--r--arch/x86_64/src/kernel/cpu/segment_register.cpp1
3 files changed, 12 insertions, 30 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{};
diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp
index b59cd1b..b08c9c4 100644
--- a/arch/x86_64/src/kernel/cpu/segment_register.cpp
+++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp
@@ -78,7 +78,6 @@ namespace teachos::arch::kernel::cpu
validate_code_segment_register(code_segment);
}
- [[gnu::naked]]
auto set_code_segment_register(context_switching::interrupt_descriptor_table::segment_selector data_segment,
context_switching::interrupt_descriptor_table::segment_selector code_segment,
uint64_t address) -> void