diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-01-16 17:39:23 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-01-16 17:39:23 +0100 |
| commit | 7ba274d0838e5cd4e48e85f81557bbb837ed4349 (patch) | |
| tree | b792f550634b856e3401ea42dd0ee7089494be28 /arch/x86_64/kapi | |
| parent | f7fc4cb67c8c7c6ec1833f6ac6f0ad3a2837251d (diff) | |
| download | teachos-7ba274d0838e5cd4e48e85f81557bbb837ed4349.tar.xz teachos-7ba274d0838e5cd4e48e85f81557bbb837ed4349.zip | |
x86_64/cpu: port GDT reload procedure
Diffstat (limited to 'arch/x86_64/kapi')
| -rw-r--r-- | arch/x86_64/kapi/system.cpp | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/arch/x86_64/kapi/system.cpp b/arch/x86_64/kapi/system.cpp index 5bcae4d..ca4418e 100644 --- a/arch/x86_64/kapi/system.cpp +++ b/arch/x86_64/kapi/system.cpp @@ -1,14 +1,122 @@ #include "kapi/system.hpp" +#include "arch/cpu/global_descriptor_table.hpp" +#include "arch/cpu/segment_descriptor.hpp" +#include "arch/cpu/task_state_segment.hpp" + #include <kstd/print> +#include <bit> +#include <cstdint> + namespace kapi::system { + namespace + { + constexpr auto gdt_null_descriptor = arch::cpu::segment_descriptor{}; + + constexpr auto gdt_kernel_code_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_kernel_data_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = true, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_code_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_data_descriptor = arch::cpu::segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::page, + .base_high = 0, + }; + } // namespace + auto memory_initialized() -> void { + auto static tss = arch::cpu::task_state_segment{}; + auto static tss_descriptor = arch::cpu::system_segment_descriptor{ + { + .limit_low = (sizeof(tss) - 1) & 0xffff, // NOLINT(readability-magic-numbers) + .base_low = std::bit_cast<std::uintptr_t>(&tss) & 0xffffff, // NOLINT(readability-magic-numbers) + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = false, + .type = arch::cpu::segment_type::system, + .privilege_level = 0, + .present = true, + .limit_high = ((sizeof(tss) - 1) >> 16) & 0xf, // NOLINT(readability-magic-numbers) + .long_mode = false, + .protected_mode = false, + .granularity = arch::cpu::segment_granularity::byte, + .base_high = (std::bit_cast<std::uintptr_t>(&tss) >> 24) & 0xff, // NOLINT(readability-magic-numbers) + }, + (std::bit_cast<std::uintptr_t>(&tss) >> 32) & 0xffff'ffff, // NOLINT(readability-magic-numbers) + }; + + auto static gdt = arch::cpu::global_descriptor_table{ + gdt_null_descriptor, gdt_kernel_code_descriptor, gdt_kernel_data_descriptor, + gdt_user_code_descriptor, gdt_user_data_descriptor, tss_descriptor, + }; + + kstd::println("[x86_64:SYS] Reloading Global Descriptor Table."); + gdt.load(1, 2); + kstd::println("[x86_64:SYS] TODO: initialize Interrupt Descriptor Table."); - kstd::println("[x86_64:SYS] TODO: reload Global Descriptor Table."); } } // namespace kapi::system
\ No newline at end of file |
