diff options
Diffstat (limited to 'arch/x86_64/src/kernel')
| -rw-r--r-- | arch/x86_64/src/kernel/cpu/segment_register.cpp | 34 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/cpu/ss.cpp | 16 | ||||
| -rw-r--r-- | arch/x86_64/src/kernel/main.cpp | 35 |
3 files changed, 69 insertions, 16 deletions
diff --git a/arch/x86_64/src/kernel/cpu/segment_register.cpp b/arch/x86_64/src/kernel/cpu/segment_register.cpp new file mode 100644 index 0000000..f70c558 --- /dev/null +++ b/arch/x86_64/src/kernel/cpu/segment_register.cpp @@ -0,0 +1,34 @@ +#include "arch/kernel/cpu/segment_register.hpp" + +#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" + +namespace teachos::arch::kernel::cpu +{ + [[gnu::naked]] + auto reload_segment_registers() -> void + { + asm volatile("xor %rax, %rax\n" + "mov %rax, %ss\n" + "mov %rax, %ds\n" + "mov %rax, %es\n" + "mov %rax, %fs\n" + "mov %rax, %gs\n" + "ret"); + } + + [[gnu::naked]] + auto set_segment_registers(context_switching::interrupt_descriptor_table::segment_selector segment_selector) -> void + { + asm volatile("xor %%rax, %%rax\n" + "mov %[input], %%ax\n" + "mov %%rax, %%ss\n" + "mov %%rax, %%ds\n" + "mov %%rax, %%es\n" + "mov %%rax, %%fs\n" + "mov %%rax, %%gs\n" + "ret" + : /* No output from call */ + : [input] "m"(segment_selector)); + } + +} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/cpu/ss.cpp b/arch/x86_64/src/kernel/cpu/ss.cpp deleted file mode 100644 index 0978eca..0000000 --- a/arch/x86_64/src/kernel/cpu/ss.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "arch/kernel/cpu/ss.hpp" - -namespace teachos::arch::kernel::cpu -{ - auto read_ss() -> context_switching::interrupt_descriptor_table::segment_selector - { - context_switching::interrupt_descriptor_table::segment_selector segment_selector{}; - asm volatile("mov %%ss, %[output]" : [output] "=m"(segment_selector)); - return segment_selector; - } - - auto write_ss(context_switching::interrupt_descriptor_table::segment_selector selector) -> void - { - asm volatile("mov %[input], %%ss" : /* no output from call */ : [input] "m"(selector)); - } -} // namespace teachos::arch::kernel::cpu diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp index 7782d30..7d4173e 100644 --- a/arch/x86_64/src/kernel/main.cpp +++ b/arch/x86_64/src/kernel/main.cpp @@ -1,9 +1,11 @@ #include "arch/kernel/main.hpp" #include "arch/boot/pointers.hpp" +#include "arch/context_switching/interrupt_descriptor_table/segment_selector.hpp" #include "arch/context_switching/main.hpp" #include "arch/kernel/cpu/if.hpp" #include "arch/kernel/cpu/jmp.hpp" +#include "arch/kernel/cpu/segment_register.hpp" #include "arch/memory/heap/bump_allocator.hpp" #include "arch/memory/heap/global_heap_allocator.hpp" #include "arch/memory/main.hpp" @@ -49,6 +51,23 @@ namespace teachos::arch::kernel delete test9; } + [[gnu::naked]] + auto push_code_segment(context_switching::interrupt_descriptor_table::segment_selector segment_selector) -> void + { + asm volatile("push %%rbp\n" + "push %[input]" + : /* No output from call */ + : [input] "m"(segment_selector)); + } + + [[gnu::naked]] + auto iret() -> void + { + asm volatile("iret" + : /* No output from call */ + : /* No input to call */); + } + auto main() -> void { video::vga::text::clear(); @@ -64,6 +83,22 @@ namespace teachos::arch::kernel heap_test(); decltype(auto) descriptor_tables = context_switching::initialize_descriptor_tables(); + + // - Clear NT flag in EFLAGS register (for far return) + + // - Push return instruction pointer + // - Push return code segment selector + context_switching::interrupt_descriptor_table::segment_selector user_code_segment_selector{ + 3U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + push_code_segment(user_code_segment_selector); + + context_switching::interrupt_descriptor_table::segment_selector user_data_segment_selector{ + 4U, context_switching::interrupt_descriptor_table::segment_selector::REQUEST_LEVEL_USER}; + kernel::cpu::set_segment_registers(user_data_segment_selector); + + // IRET + iret(); + (void)descriptor_tables; } } // namespace teachos::arch::kernel |
