aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/CMakeLists.txt1
-rw-r--r--arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp7
-rw-r--r--arch/x86_64/include/arch/context_switching/main.hpp2
-rw-r--r--arch/x86_64/include/arch/context_switching/syscall_handler.hpp9
-rw-r--r--arch/x86_64/src/context_switching/main.cpp59
-rw-r--r--arch/x86_64/src/context_switching/syscall_handler.cpp19
-rw-r--r--arch/x86_64/src/kernel/cpu/msr.cpp2
-rw-r--r--arch/x86_64/src/kernel/main.cpp1
8 files changed, 46 insertions, 54 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt
index d5fb913..71b1946 100644
--- a/arch/x86_64/CMakeLists.txt
+++ b/arch/x86_64/CMakeLists.txt
@@ -105,7 +105,6 @@ target_sources("_context" PRIVATE
"src/context_switching/interrupt_descriptor_table/interrupt_descriptor_table.cpp"
"src/context_switching/interrupt_descriptor_table/ist_offset.cpp"
"src/context_switching/interrupt_descriptor_table/segment_selector.cpp"
- "src/context_switching/syscall_handler.cpp"
)
#[============================================================================[
diff --git a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
index e8854f9..7bfb563 100644
--- a/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
+++ b/arch/x86_64/include/arch/context_switching/interrupt_descriptor_table/segment_selector.hpp
@@ -82,6 +82,13 @@ namespace teachos::arch::context_switching::interrupt_descriptor_table
*/
auto operator|=(std::bitset<3U> other) -> void;
+ /**
+ * @brief Combines all bits in the underlying data in the correct order to return a raw value containing all bits.
+ *
+ * @return Underlying value combined into it's full size.
+ */
+ operator uint16_t() const { return static_cast<uint64_t>(_flags) | (static_cast<uint64_t>(_index) << 3U); }
+
private:
uint8_t _flags : 3 = {}; ///< Underlying bits used to read the flags from.
uint16_t _index : 13 =
diff --git a/arch/x86_64/include/arch/context_switching/main.hpp b/arch/x86_64/include/arch/context_switching/main.hpp
index 5537174..f8477ea 100644
--- a/arch/x86_64/include/arch/context_switching/main.hpp
+++ b/arch/x86_64/include/arch/context_switching/main.hpp
@@ -46,8 +46,6 @@ namespace teachos::arch::context_switching
auto switch_context(interrupt_descriptor_table::segment_selector data_segment,
interrupt_descriptor_table::segment_selector code_segment, void (*return_function)()) -> void;
- auto setup_syscall() -> void;
-
} // namespace teachos::arch::context_switching
#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_MAIN_HPP
diff --git a/arch/x86_64/include/arch/context_switching/syscall_handler.hpp b/arch/x86_64/include/arch/context_switching/syscall_handler.hpp
deleted file mode 100644
index 5a46924..0000000
--- a/arch/x86_64/include/arch/context_switching/syscall_handler.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_HANDLER_HPP
-#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_SYSCALL_HANDLER_HPP
-
-namespace teachos::arch::context_switching
-{
- [[gnu::naked]]
- auto syscall_handler() -> void;
-}
-#endif \ No newline at end of file
diff --git a/arch/x86_64/src/context_switching/main.cpp b/arch/x86_64/src/context_switching/main.cpp
index 155d150..f73cb19 100644
--- a/arch/x86_64/src/context_switching/main.cpp
+++ b/arch/x86_64/src/context_switching/main.cpp
@@ -1,7 +1,6 @@
#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"
@@ -30,6 +29,43 @@ namespace teachos::arch::context_switching
auto reload_global_descriptor_table_register() -> void { kernel::cpu::call(KERNEL_CODE_POINTER); }
+ auto user_mode_main() -> void
+ {
+ kernel::cpu::validate_segment_registers(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR);
+
+ video::vga::text::write("Successfully entered user mode!", video::vga::text::common_attributes::green_on_black);
+
+ asm volatile("syscall");
+
+ kernel::cpu::validate_segment_registers(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR);
+
+ video::vga::text::write("Successfully made a SYSCALL and returned back with SYSRET!",
+ video::vga::text::common_attributes::green_on_black);
+ }
+
+ auto syscall_handler() -> void
+ {
+ uint64_t dummy{};
+ switch (dummy)
+ {
+ case 0:
+ break;
+ default:
+ break;
+ }
+
+ asm volatile("sysretq");
+ }
+
+ auto enable_systemcall() -> void
+ {
+ uint64_t const syscall_function = reinterpret_cast<uint64_t>(syscall_handler);
+ kernel::cpu::write_msr(IA32_LSTAR_ADDRESS, syscall_function);
+ kernel::cpu::write_msr(IA32_FMASK_ADDRESS, 0U);
+ kernel::cpu::write_msr(IA32_STAR_ADDRESS, KERNEL_CODE_SEGMENT_SELECTOR);
+ kernel::cpu::set_efer_bit(kernel::cpu::efer_flags::SCE);
+ }
+
} // namespace
auto initialize_descriptor_tables() -> descriptor_tables
@@ -55,17 +91,9 @@ namespace teachos::arch::context_switching
return tables;
}
- auto user_mode_main() -> void
- {
- kernel::cpu::validate_segment_registers(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR);
-
- asm volatile("SYSCALL");
-
- video::vga::text::write("Successfully entered user mode!", video::vga::text::common_attributes::green_on_black);
- }
-
auto switch_to_user_mode() -> void
{
+ enable_systemcall();
switch_context(USER_DATA_SEGMENT_SELECTOR, USER_CODE_SEGMENT_SELECTOR, user_mode_main);
}
@@ -77,15 +105,4 @@ 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 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
deleted file mode 100644
index 283d297..0000000
--- a/arch/x86_64/src/context_switching/syscall_handler.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "arch/context_switching/syscall_handler.hpp"
-
-#include <cstdint>
-
-namespace teachos::arch::context_switching
-{
- 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/cpu/msr.cpp b/arch/x86_64/src/kernel/cpu/msr.cpp
index 6249f8f..9c474a1 100644
--- a/arch/x86_64/src/kernel/cpu/msr.cpp
+++ b/arch/x86_64/src/kernel/cpu/msr.cpp
@@ -16,7 +16,7 @@ namespace teachos::arch::kernel::cpu
auto write_msr(uint32_t msr, uint64_t value) -> void
{
- uint32_t low = value & 0xFFFFFFFF;
+ uint32_t low = value;
uint32_t high = value >> 32;
asm volatile("wrmsr"
: /* no output from call */
diff --git a/arch/x86_64/src/kernel/main.cpp b/arch/x86_64/src/kernel/main.cpp
index e737d44..05c879e 100644
--- a/arch/x86_64/src/kernel/main.cpp
+++ b/arch/x86_64/src/kernel/main.cpp
@@ -63,7 +63,6 @@ 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