From 2e4cbd473ff3bb7ac7371af39becf830b4fb753b Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Thu, 13 Mar 2025 14:05:45 +0000 Subject: IN_PROGRESS implement gdt initialization --- .../descriptor_table/global_descriptor_table.hpp | 19 ++++++ .../global_descriptor_table_pointer.hpp | 23 +++++++ .../include/arch/kernel/cpu/control_register.hpp | 71 ++++++++++++++++++++++ arch/x86_64/include/arch/kernel/cpu/msr.hpp | 64 +++++++++++++++++++ arch/x86_64/include/arch/kernel/cpu/ss.hpp | 56 +++++++++++++++++ arch/x86_64/include/arch/kernel/cpu/tlb.hpp | 27 ++++++++ .../include/arch/memory/cpu/control_register.hpp | 71 ---------------------- arch/x86_64/include/arch/memory/cpu/msr.hpp | 64 ------------------- arch/x86_64/include/arch/memory/cpu/tlb.hpp | 27 -------- .../arch/memory/paging/active_page_table.hpp | 6 +- .../include/arch/memory/paging/kernel_mapper.hpp | 2 +- 11 files changed, 264 insertions(+), 166 deletions(-) create mode 100644 arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp create mode 100644 arch/x86_64/include/arch/kernel/cpu/control_register.hpp create mode 100644 arch/x86_64/include/arch/kernel/cpu/msr.hpp create mode 100644 arch/x86_64/include/arch/kernel/cpu/ss.hpp create mode 100644 arch/x86_64/include/arch/kernel/cpu/tlb.hpp delete mode 100644 arch/x86_64/include/arch/memory/cpu/control_register.hpp delete mode 100644 arch/x86_64/include/arch/memory/cpu/msr.hpp delete mode 100644 arch/x86_64/include/arch/memory/cpu/tlb.hpp (limited to 'arch/x86_64/include') diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp index e69de29..daba1fe 100644 --- a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table.hpp @@ -0,0 +1,19 @@ +#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP +#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP + +#include "arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp" +#include "arch/context_switching/descriptor_table/segment_descriptor.hpp" +#include "arch/stl/vector.hpp" + +namespace teachos::arch::context_switching::descriptor_table +{ + typedef stl::vector global_descriptor_table; + + auto create_global_descriptor_table() -> global_descriptor_table; + + auto load_global_descriptor_table(global_descriptor_table_pointer gdt_pointer) -> void; + + auto initialize_global_descriptor_table() -> global_descriptor_table; +} // namespace teachos::arch::context_switching::descriptor_table + +#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_HPP diff --git a/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp new file mode 100644 index 0000000..c2925fd --- /dev/null +++ b/arch/x86_64/include/arch/context_switching/descriptor_table/global_descriptor_table_pointer.hpp @@ -0,0 +1,23 @@ +#ifndef TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP +#define TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP + +#include "arch/context_switching/descriptor_table/global_descriptor_table.hpp" + +#include + +namespace teachos::arch::context_switching::descriptor_table +{ + /** + * @brief Represents a pointer to the Global Descriptor Table (GDT). + * + * This structure is used to store the base address and length of the GDT. + * It is used when loading or modifying the GDT during context switching. + */ + struct global_descriptor_table_pointer + { + uint16_t table_length; ///< The size of the GDT in bytes. + global_descriptor_table * address; ///< Pointer to the GDT base address. + }; +} // namespace teachos::arch::context_switching::descriptor_table + +#endif // TEACHOS_ARCH_X86_64_CONTEXT_SWITCHING_DESCRIPTOR_TABLE_GLOBAL_DESCRIPTOR_TABLE_POINTER_HPP diff --git a/arch/x86_64/include/arch/kernel/cpu/control_register.hpp b/arch/x86_64/include/arch/kernel/cpu/control_register.hpp new file mode 100644 index 0000000..27c7777 --- /dev/null +++ b/arch/x86_64/include/arch/kernel/cpu/control_register.hpp @@ -0,0 +1,71 @@ +#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_CR3_HPP +#define TEACHOS_ARCH_X86_64_KERNEL_CPU_CR3_HPP + +#include + +namespace teachos::arch::memory::cpu +{ + /** + * @brief Control registers that can be read and written to. + * + * @note CR1 and CR5 - 7 are reserved and will throw an exception if they are accessed, therefore they are not defined + * in the enum. See https://en.wikipedia.org/wiki/Control_register#Control_registers_in_Intel_x86_series for more + * information. + */ + enum struct control_register : uint8_t + { + CR0, ///< Contains various control flags that modify basic operation of the processor, Machine Status World (MSW) + ///< register. + CR2 = 2U, ///< Contains Page Fault Linear Address (PFLA), when page fault occurs address program attended to accces + ///< is stored here. + CR3, ///< Enables process to translate linear addresses into physical addresses using paging, CR0 bit 32 Paging + ///< (PG) needs to be enabled simply contains the register value that represents the physical address of the + ///< level 4 page table used for paging in the system. Therefore reading this value allows to access the level + ///< 4 page table directly. Instead of over the virtual address 0xffffffff'fffff000, which then has to be + ///< first translated into a physical address. + CR4 ///< Used in protected mode to control operations. + }; + + /** + * @brief Control register 0 flags that can be set. + * + * @note Modifies the basic operation of the processor. Only the most important extensions are listed below, the rest + * are excluded for brevity. See https://en.wikipedia.org/wiki/Control_register#CR0 for more information. + */ + enum struct cr0_flags : uint64_t + { + PROTECTED_MODE_ENABLED = 1U << 0U, ///< System is in protected or system is in real mode. + TASK_SWITCHED = 1U << 3U, ///< Allows saving x87 task context upon a task switch only after x87 instruction used. + WRITE_PROTECT = 1U << 16U, ///< When set, the CPU cannot write to read-only pages when privilege level is 0. + PAGING = 1U << 31U, // Enable paging using the CR3 register. + }; + + /** + * @brief Reads the value of the given control register. + * + * @param cr Control register that should be read. + * @return Value of the control register. + */ + auto read_control_register(control_register cr) -> uint64_t; + + /** + * @brief Sets a specific bit in the Extended Feature Enable Register (EFER) Model-Specific Register (MSR) register. + * + * @param cr Control register that should be written. + * @param new_value New value that should be written. + */ + auto write_control_register(control_register cr, uint64_t new_value) -> void; + + /** + * @brief Sets a specific bit in the CR0. + * + * @note This function reads the current value of the CR0 register, ORs the specified + * bit with the current value, and writes the updated value back to the CR0. + * + * @param flag he flag to set in the CR0. + */ + auto set_cr0_bit(cr0_flags flag) -> void; + +} // namespace teachos::arch::memory::cpu + +#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_CR3_HPP diff --git a/arch/x86_64/include/arch/kernel/cpu/msr.hpp b/arch/x86_64/include/arch/kernel/cpu/msr.hpp new file mode 100644 index 0000000..52d74bd --- /dev/null +++ b/arch/x86_64/include/arch/kernel/cpu/msr.hpp @@ -0,0 +1,64 @@ +#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP +#define TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP + +#include +#include + +namespace teachos::arch::memory::cpu +{ + /** + * @brief Important flags that can be writen into the Extended Feature Enable Register (EFER). + * + * @note EFER is a model-specific register allowing to configure CPU extensions. Only the most important extensions + * are listed below, the rest are excluded for brevity. See https://en.wikipedia.org/wiki/Control_register#EFER for + * more information. + */ + enum class efer_flags : uint64_t + { + SCE = 1UL << 0UL, ///< System Call Extensions. + LME = 1UL << 8UL, ///< Long Mode Enabled. + LMA = 1UL << 10UL, ///< Long Mode Active. + NXE = 1UL << 11UL, ///< No-Execute Enable. + SVME = 1UL << 12UL, ///< Secure Virtual Machine Enable. + LMSLE = 1UL << 13UL, ///< Long Mode Segment Limit Enable. + FFXSR = 1UL << 14UL, ///< Fast FXSAVE/FXSTOR. + TCE = 1UL << 15UL, ///< Translation Cache Extension. + }; + + /** + * @brief Reads a 64-bit from the Model-Specific Register (MSR). + * + * @note This function reads the value of an MSR specified by the given address. It combines the lower and upper + * 32-bits of the MSR value read using the 'rdmsr' instruction and returns it as a 64-bit unsigned integer. + * + * @param msr The address of the MSR to read. + * @return The 64-bit value read from the MSR. + */ + auto read_msr(uint32_t msr) -> uint64_t; + + /** + * @brief Writes a 64-bit value to a Model-Specific Register (MSR). + * + * @note This function writes a 64-bit value to the MSR specified by the given address. + * It splits the 64-bit value into two 32-bit parts and writes them using the + * `wrmsr` instruction. + * + * @param msr The address of the MSR to write to. + * @param new_value The 64-bit value to write to the MSR. + */ + auto write_msr(uint32_t msr, uint64_t new_value) -> void; + + /** + * @brief Sets a specific bit in the Extended Feature Enable Register (EFER), which is a Model-Specific Register + * (MSR). + * + * @note This function reads the current value of the EFER register, ORs the specified + * bit with the current value, and writes the updated value back to the EFER register. + * + * @param flag The flag to set in the EFER register. + */ + auto set_efer_bit(efer_flags flag) -> void; + +} // namespace teachos::arch::memory::cpu + +#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_NXE_HPP \ No newline at end of file diff --git a/arch/x86_64/include/arch/kernel/cpu/ss.hpp b/arch/x86_64/include/arch/kernel/cpu/ss.hpp new file mode 100644 index 0000000..2d3518e --- /dev/null +++ b/arch/x86_64/include/arch/kernel/cpu/ss.hpp @@ -0,0 +1,56 @@ +#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_SS_HPP +#define TEACHOS_ARCH_X86_64_KERNEL_CPU_SS_HPP + +#include +#include + +namespace teachos::arch::memory::cpu +{ + /** + * @brief Represents a segment selector in the x86_64 architecture. + * + * A segment selector is a 16-bit identifier used to select a segment descriptor + * from the Global Descriptor Table (GDT) or the Local Descriptor Table (LDT). + * It contains an index, a table indicator (TI), and a requested privilege level (RPL). + */ + struct segment_selector + { + /** + * @brief Constructs a segment selector. + * + * @param index The index of the segment descriptor. + * @param table_indicator The table indicator (0 for GDT, 1 for LDT). + * @param requested_privilege_level The requested privilege level (0-3). + */ + segment_selector(uint16_t index, std::bitset<1U> table_indicator, std::bitset<2U> requested_privilege_level); + + /** + * @brief Converts the segment selector to a 16-bit value. + * + * @return uint16_t The 16-bit representation of the segment selector. + */ + auto to_uint16() const -> uint16_t; + + private: + uint16_t index; + std::bitset<1U> table_indicator; + std::bitset<2U> requested_privilege_level; + }; + + /** + * @brief Reads the current value of the stack segment (SS) register. + * + * @return uint16_t The current SS register value. + */ + auto read_ss() -> uint16_t; + + /** + * @brief Writes a new value to the stack segment (SS) register. + * + * @param selector The segment selector to be written to SS. + */ + auto write_ss(segment_selector selector) -> void; + +} // namespace teachos::arch::memory::cpu + +#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_SS_HPP diff --git a/arch/x86_64/include/arch/kernel/cpu/tlb.hpp b/arch/x86_64/include/arch/kernel/cpu/tlb.hpp new file mode 100644 index 0000000..333cd58 --- /dev/null +++ b/arch/x86_64/include/arch/kernel/cpu/tlb.hpp @@ -0,0 +1,27 @@ +#ifndef TEACHOS_ARCH_X86_64_KERNEL_CPU_TLB_HPP +#define TEACHOS_ARCH_X86_64_KERNEL_CPU_TLB_HPP + +#include "arch/memory/paging/virtual_page.hpp" + +namespace teachos::arch::memory::cpu +{ + /** + * @brief Invalidates any translation lookaside buffer (TLB) entry for the page table the given address is cotained + * in. See https://www.felixcloutier.com/x86/invlpg for more information on the used x86 instruction. + * + * @param address Memory address, which will be used to determine the contained page and flush the TLB entry for + * that page. + */ + auto tlb_flush(paging::virtual_address address) -> void; + + /** + * @brief Invalidates the translation lookaside buffer (TLB) entry for all page tables. + * + * @note Simply reassigns the CR3 register the value of the CR3 register, causing a flush of the TLB buffer, because + * the system has to assume that the location of the level 4 page table moved. + */ + auto tlb_flush_all() -> void; + +} // namespace teachos::arch::memory::cpu + +#endif // TEACHOS_ARCH_X86_64_KERNEL_CPU_TLB_HPP diff --git a/arch/x86_64/include/arch/memory/cpu/control_register.hpp b/arch/x86_64/include/arch/memory/cpu/control_register.hpp deleted file mode 100644 index e11813d..0000000 --- a/arch/x86_64/include/arch/memory/cpu/control_register.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP - -#include - -namespace teachos::arch::memory::cpu -{ - /** - * @brief Control registers that can be read and written to. - * - * @note CR1 and CR5 - 7 are reserved and will throw an exception if they are accessed, therefore they are not defined - * in the enum. See https://en.wikipedia.org/wiki/Control_register#Control_registers_in_Intel_x86_series for more - * information. - */ - enum struct control_register : uint8_t - { - CR0, ///< Contains various control flags that modify basic operation of the processor, Machine Status World (MSW) - ///< register. - CR2 = 2U, ///< Contains Page Fault Linear Address (PFLA), when page fault occurs address program attended to accces - ///< is stored here. - CR3, ///< Enables process to translate linear addresses into physical addresses using paging, CR0 bit 32 Paging - ///< (PG) needs to be enabled simply contains the register value that represents the physical address of the - ///< level 4 page table used for paging in the system. Therefore reading this value allows to access the level - ///< 4 page table directly. Instead of over the virtual address 0xffffffff'fffff000, which then has to be - ///< first translated into a physical address. - CR4 ///< Used in protected mode to control operations. - }; - - /** - * @brief Control register 0 flags that can be set. - * - * @note Modifies the basic operation of the processor. Only the most important extensions are listed below, the rest - * are excluded for brevity. See https://en.wikipedia.org/wiki/Control_register#CR0 for more information. - */ - enum struct cr0_flags : uint64_t - { - PROTECTED_MODE_ENABLED = 1U << 0U, ///< System is in protected or system is in real mode. - TASK_SWITCHED = 1U << 3U, ///< Allows saving x87 task context upon a task switch only after x87 instruction used. - WRITE_PROTECT = 1U << 16U, ///< When set, the CPU cannot write to read-only pages when privilege level is 0. - PAGING = 1U << 31U, // Enable paging using the CR3 register. - }; - - /** - * @brief Reads the value of the given control register. - * - * @param cr Control register that should be read. - * @return Value of the control register. - */ - auto read_control_register(control_register cr) -> uint64_t; - - /** - * @brief Sets a specific bit in the Extended Feature Enable Register (EFER) Model-Specific Register (MSR) register. - * - * @param cr Control register that should be written. - * @param new_value New value that should be written. - */ - auto write_control_register(control_register cr, uint64_t new_value) -> void; - - /** - * @brief Sets a specific bit in the CR0. - * - * @note This function reads the current value of the CR0 register, ORs the specified - * bit with the current value, and writes the updated value back to the CR0. - * - * @param flag he flag to set in the CR0. - */ - auto set_cr0_bit(cr0_flags flag) -> void; - -} // namespace teachos::arch::memory::cpu - -#endif // TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP diff --git a/arch/x86_64/include/arch/memory/cpu/msr.hpp b/arch/x86_64/include/arch/memory/cpu/msr.hpp deleted file mode 100644 index cda70e2..0000000 --- a/arch/x86_64/include/arch/memory/cpu/msr.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_CPU_NXE_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_CPU_NXE_HPP - -#include -#include - -namespace teachos::arch::memory::cpu -{ - /** - * @brief Important flags that can be writen into the Extended Feature Enable Register (EFER). - * - * @note EFER is a model-specific register allowing to configure CPU extensions. Only the most important extensions - * are listed below, the rest are excluded for brevity. See https://en.wikipedia.org/wiki/Control_register#EFER for - * more information. - */ - enum class efer_flags : uint64_t - { - SCE = 1UL << 0UL, ///< System Call Extensions. - LME = 1UL << 8UL, ///< Long Mode Enabled. - LMA = 1UL << 10UL, ///< Long Mode Active. - NXE = 1UL << 11UL, ///< No-Execute Enable. - SVME = 1UL << 12UL, ///< Secure Virtual Machine Enable. - LMSLE = 1UL << 13UL, ///< Long Mode Segment Limit Enable. - FFXSR = 1UL << 14UL, ///< Fast FXSAVE/FXSTOR. - TCE = 1UL << 15UL, ///< Translation Cache Extension. - }; - - /** - * @brief Reads a 64-bit from the Model-Specific Register (MSR). - * - * @note This function reads the value of an MSR specified by the given address. It combines the lower and upper - * 32-bits of the MSR value read using the 'rdmsr' instruction and returns it as a 64-bit unsigned integer. - * - * @param msr The address of the MSR to read. - * @return The 64-bit value read from the MSR. - */ - auto read_msr(uint32_t msr) -> uint64_t; - - /** - * @brief Writes a 64-bit value to a Model-Specific Register (MSR). - * - * @note This function writes a 64-bit value to the MSR specified by the given address. - * It splits the 64-bit value into two 32-bit parts and writes them using the - * `wrmsr` instruction. - * - * @param msr The address of the MSR to write to. - * @param new_value The 64-bit value to write to the MSR. - */ - auto write_msr(uint32_t msr, uint64_t new_value) -> void; - - /** - * @brief Sets a specific bit in the Extended Feature Enable Register (EFER), which is a Model-Specific Register - * (MSR). - * - * @note This function reads the current value of the EFER register, ORs the specified - * bit with the current value, and writes the updated value back to the EFER register. - * - * @param flag The flag to set in the EFER register. - */ - auto set_efer_bit(efer_flags flag) -> void; - -} // namespace teachos::arch::memory::cpu - -#endif // TEACHOS_ARCH_X86_64_MEMORY_CPU_NXE_HPP \ No newline at end of file diff --git a/arch/x86_64/include/arch/memory/cpu/tlb.hpp b/arch/x86_64/include/arch/memory/cpu/tlb.hpp deleted file mode 100644 index 075d7bb..0000000 --- a/arch/x86_64/include/arch/memory/cpu/tlb.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_CPU_TLB_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_CPU_TLB_HPP - -#include "arch/memory/paging/virtual_page.hpp" - -namespace teachos::arch::memory::cpu -{ - /** - * @brief Invalidates any translation lookaside buffer (TLB) entry for the page table the given address is cotained - * in. See https://www.felixcloutier.com/x86/invlpg for more information on the used x86 instruction. - * - * @param address Memory address, which will be used to determine the contained page and flush the TLB entry for - * that page. - */ - auto tlb_flush(paging::virtual_address address) -> void; - - /** - * @brief Invalidates the translation lookaside buffer (TLB) entry for all page tables. - * - * @note Simply reassigns the CR3 register the value of the CR3 register, causing a flush of the TLB buffer, because - * the system has to assume that the location of the level 4 page table moved. - */ - auto tlb_flush_all() -> void; - -} // namespace teachos::arch::memory::cpu - -#endif // TEACHOS_ARCH_X86_64_MEMORY_CPU_TLB_HPP diff --git a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp index 1b2aaed..9846a21 100644 --- a/arch/x86_64/include/arch/memory/paging/active_page_table.hpp +++ b/arch/x86_64/include/arch/memory/paging/active_page_table.hpp @@ -2,8 +2,8 @@ #define TEACHOS_ARCH_X86_64_MEMORY_PAGING_ACTIVE_PAGE_TABLE_HPP #include "arch/exception_handling/assert.hpp" +#include "arch/kernel/cpu/tlb.hpp" #include "arch/memory/allocator/concept.hpp" -#include "arch/memory/cpu/tlb.hpp" #include "arch/memory/paging/virtual_page.hpp" #include @@ -75,8 +75,8 @@ namespace teachos::arch::memory::paging * @param flags A bitset of flags that configure the page table entry for this mapping. */ template - auto map_page_to_frame(T & allocator, virtual_page page, allocator::physical_frame frame, - std::bitset<64U> flags) -> void + auto map_page_to_frame(T & allocator, virtual_page page, allocator::physical_frame frame, std::bitset<64U> flags) + -> void { auto current_handle = active_handle; diff --git a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp index 74f1c14..b137736 100644 --- a/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp +++ b/arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp @@ -1,7 +1,7 @@ #ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_KERNEL_MAPPER_HPP #define TEACHOS_ARCH_X86_64_MEMORY_PAGING_KERNEL_MAPPER_HPP -#include "arch/memory/cpu/control_register.hpp" +#include "arch/kernel/cpu/control_register.hpp" #include "arch/memory/paging/active_page_table.hpp" #include "arch/memory/paging/inactive_page_table.hpp" #include "arch/memory/paging/temporary_page.hpp" -- cgit v1.2.3