diff options
| author | Fabian Imhof <fabian.imhof@ost.ch> | 2025-04-27 11:20:02 +0000 |
|---|---|---|
| committer | Fabian Imhof <fabian.imhof@ost.ch> | 2025-04-27 11:20:02 +0000 |
| commit | 7261c64bb236a313ed8846a9c9dbded6890a9e98 (patch) | |
| tree | 3f43ab7d1e87025dd622bbc9cd56aad5d37a2f78 /arch/x86_64/src | |
| parent | c865eff02ae1978b4f665432d853374d1ffacecf (diff) | |
| download | teachos-7261c64bb236a313ed8846a9c9dbded6890a9e98.tar.xz teachos-7261c64bb236a313ed8846a9c9dbded6890a9e98.zip | |
wip implement syscall in cpp
Diffstat (limited to 'arch/x86_64/src')
| -rw-r--r-- | arch/x86_64/src/boot/boot.s | 25 | ||||
| -rw-r--r-- | arch/x86_64/src/context_switching/main.cpp | 43 | ||||
| -rw-r--r-- | arch/x86_64/src/context_switching/syscall_handler.cpp | 20 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 1 |
4 files changed, 55 insertions, 34 deletions
diff --git a/arch/x86_64/src/boot/boot.s b/arch/x86_64/src/boot/boot.s index 24b38ca..7932045 100644 --- a/arch/x86_64/src/boot/boot.s +++ b/arch/x86_64/src/boot/boot.s @@ -352,31 +352,6 @@ 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 c949488..85cefe5 100644 --- a/arch/x86_64/src/context_switching/main.cpp +++ b/arch/x86_64/src/context_switching/main.cpp @@ -1,6 +1,7 @@ #include "arch/context_switching/main.hpp" #include "arch/boot/pointers.hpp" +#include "arch/context_switching/syscall_handler.hpp" #include "arch/exception_handling/assert.hpp" #include "arch/kernel/cpu/call.hpp" #include "arch/kernel/cpu/control_register.hpp" @@ -53,15 +54,7 @@ namespace teachos::arch::context_switching { kernel::cpu::validate_segment_registers(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR); - // TODO/INFO: - // https://stackoverflow.com/questions/46022184/osdev-syscall-sysret-and-sysenter-sysexit-instructions-enabling - // https://stackoverflow.com/questions/12806584/what-is-better-int-0x80-or-syscall-in-32-bit-code-on-linux - // - // People claim that SYSENTER is for 32-Bit, while SYSCALL is for 64-Bit! - - // asm volatile("INT $0x80"); - // asm volatile("SYSCALL"); - boot::syscall_trampoline(); + asm volatile("SYSCALL"); video::vga::text::write("Successfully entered user mode!", video::vga::text::common_attributes::green_on_black); } @@ -79,4 +72,36 @@ namespace teachos::arch::context_switching kernel::cpu::set_code_segment_register(data_segment, code_segment, reinterpret_cast<uint64_t>(return_function)); } + 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)); + } + } // 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 new file mode 100644 index 0000000..1bc4ef9 --- /dev/null +++ b/arch/x86_64/src/context_switching/syscall_handler.cpp @@ -0,0 +1,20 @@ +#include "arch/context_switching/syscall_handler.hpp" + +#include <cstdint> + +namespace teachos::arch::context_switching +{ + [[gnu::naked]] + auto syscall_handler() -> void + { + uint64_t dummy{}; + switch (dummy) + { + case 0: + break; + default: + break; + } + asm volatile("SYSRET"); + } +} // namespace teachos::arch::context_switching
\ No newline at end of file diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 05c879e..e737d44 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -63,6 +63,7 @@ namespace teachos::arch::kernel memory::heap::global_heap_allocator::register_heap_allocator(memory::heap::heap_allocator_type::LINKED_LIST); // heap_test(); + context_switching::setup_syscall(); context_switching::switch_to_user_mode(); } } // namespace teachos::arch::kernel |
