#include "arch/context_switching/syscall/main.hpp" #include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" #include "arch/exception_handling/assert.hpp" #include "arch/exception_handling/panic.hpp" #include "arch/kernel/cpu/msr.hpp" #include namespace teachos::arch::context_switching::syscall { namespace { constexpr interrupt_descriptor_table::segment_selector KERNEL_CODE_SEGMENT_SELECTOR{ 1U, interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_KERNEL}; auto constexpr IA32_STAR_ADDRESS = 0xC0000081; auto constexpr IA32_LSTAR_ADDRESS = 0xC0000082; auto constexpr IA32_FMASK_ADDRESS = 0xC0000084; } // namespace auto enable_syscall() -> void { uint64_t const syscall_function = reinterpret_cast(syscall_handler); kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function); kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U); uint64_t const kernel_cs = KERNEL_CODE_SEGMENT_SELECTOR; uint64_t const star_value = (kernel_cs << 32) | (kernel_cs << 48); kernel::cpu::write_msr(IA32_STAR_ADDRESS, star_value); kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE); } auto syscall(type syscall_number, arguments args) -> uint64_t { asm volatile("mov %[input], %%rax" : /* no output from call */ : [input] "m"(syscall_number) : "memory"); asm volatile("mov %[input], %%rdi " : /* no output from call */ : [input] "m"(args.arg_0) : "memory"); asm volatile("mov %[input], %%rsi" : /* no output from call */ : [input] "m"(args.arg_1) : "memory"); asm volatile("mov %[input], %%rdx" : /* no output from call */ : [input] "m"(args.arg_2) : "memory"); asm volatile("mov %[input], %%r10" : /* no output from call */ : [input] "m"(args.arg_3) : "memory"); asm volatile("mov %[input], %%r8" : /* no output from call */ : [input] "m"(args.arg_4) : "memory"); asm volatile("mov %[input], %%r9" : /* no output from call */ : [input] "m"(args.arg_5) : "memory"); asm volatile("syscall"); uint64_t error{}; asm volatile("mov %%rax, %[output]" : [output] "=m"(error)); return error; } } // namespace teachos::arch::context_switching::syscall