diff options
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/cpu/initialization.hpp | 6 | ||||
| -rw-r--r-- | arch/x86_64/kapi/system.cpp | 113 | ||||
| -rw-r--r-- | arch/x86_64/src/cpu/initialization.cpp | 122 |
4 files changed, 133 insertions, 111 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 4ae09ff..f053982 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -18,6 +18,9 @@ target_sources("x86_64" PRIVATE "kapi/memory.cpp" "kapi/system.cpp" + # CPU Initialization + "src/cpu/initialization.cpp" + # Low-level bootstrap "src/boot/boot32.S" "src/boot/entry64.s" diff --git a/arch/x86_64/include/arch/cpu/initialization.hpp b/arch/x86_64/include/arch/cpu/initialization.hpp new file mode 100644 index 0000000..b2ce864 --- /dev/null +++ b/arch/x86_64/include/arch/cpu/initialization.hpp @@ -0,0 +1,6 @@ +#pragma once + +namespace arch::cpu +{ + auto initialize_descriptors() -> void; +} // namespace arch::cpu diff --git a/arch/x86_64/kapi/system.cpp b/arch/x86_64/kapi/system.cpp index ca4418e..ffb6a46 100644 --- a/arch/x86_64/kapi/system.cpp +++ b/arch/x86_64/kapi/system.cpp @@ -1,122 +1,13 @@ #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> +#include "arch/cpu/initialization.hpp" 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."); + arch::cpu::initialize_descriptors(); } } // namespace kapi::system
\ No newline at end of file diff --git a/arch/x86_64/src/cpu/initialization.cpp b/arch/x86_64/src/cpu/initialization.cpp new file mode 100644 index 0000000..aae4f1f --- /dev/null +++ b/arch/x86_64/src/cpu/initialization.cpp @@ -0,0 +1,122 @@ +#include "arch/cpu/initialization.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 arch::cpu +{ + + namespace + { + constexpr auto gdt_null_descriptor = segment_descriptor{}; + + constexpr auto gdt_kernel_code_descriptor = segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_kernel_data_descriptor = segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = segment_type::code_or_data, + .privilege_level = 0, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = true, + .granularity = segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_code_descriptor = segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = false, + .direction_or_conforming = false, + .executable = true, + .type = segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = true, + .protected_mode = false, + .granularity = segment_granularity::page, + .base_high = 0, + }; + + constexpr auto gdt_user_data_descriptor = segment_descriptor{ + .limit_low = 0xffff, + .base_low = 0, + .accessed = false, + .read_write = true, + .direction_or_conforming = false, + .executable = false, + .type = segment_type::code_or_data, + .privilege_level = 3, + .present = true, + .limit_high = 0xf, + .long_mode = false, + .protected_mode = false, + .granularity = segment_granularity::page, + .base_high = 0, + }; + } // namespace + + auto initialize_descriptors() -> void + { + auto static tss = task_state_segment{}; + auto static tss_descriptor = 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 = 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 = 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 = 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."); + } + +} // namespace arch::cpu |
