diff options
Diffstat (limited to 'arch/x86_64/include')
| -rw-r--r-- | arch/x86_64/include/arch/memory/cpu/control_register.hpp | 70 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/cpu/cr3.hpp | 27 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/cpu/msr.hpp | 47 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp | 10 |
4 files changed, 102 insertions, 52 deletions
diff --git a/arch/x86_64/include/arch/memory/cpu/control_register.hpp b/arch/x86_64/include/arch/memory/cpu/control_register.hpp new file mode 100644 index 0000000..b48e48c --- /dev/null +++ b/arch/x86_64/include/arch/memory/cpu/control_register.hpp @@ -0,0 +1,70 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP + +#include <cstdint> + +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 2 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 cr2_flags : uint32_t + { + PROTECTED_MODE_ENABLED = 1U << 0U, ///< System is in protected moe else 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. + * + * @note The cr3 register value 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. + * + * @return Physical address the level 4 page table is located at. + */ + + /** + * @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) -> std::size_t; + + /** + * @brief Writes the given value into the given control 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, std::size_t new_value) -> 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/cr3.hpp b/arch/x86_64/include/arch/memory/cpu/cr3.hpp deleted file mode 100644 index 51d5055..0000000 --- a/arch/x86_64/include/arch/memory/cpu/cr3.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP -#define TEACHOS_ARCH_X86_64_MEMORY_CPU_CR3_HPP - -#include "arch/memory/allocator/physical_frame.hpp" - -namespace teachos::arch::memory::cpu -{ - /** - * @brief Reads the value of the cr3 register. - * - * @note The cr3 register value 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. - * - * @return Physical address the level 4 page table is located at. - */ - auto read_cr3_register() -> allocator::physical_address; - - /** - * @brief Writes the given value into the cr3 register. - * - * @param new_p4_table_address Physical address the newly kernel mapped level 4 page table is located at. - */ - auto write_cr3_register(allocator::physical_address new_p4_table_address) -> 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 index 662f3ac..1403995 100644 --- a/arch/x86_64/include/arch/memory/cpu/msr.hpp +++ b/arch/x86_64/include/arch/memory/cpu/msr.hpp @@ -6,63 +6,68 @@ namespace teachos::arch::memory::cpu { - constexpr uint32_t IA32_EFER = 0xC0000080; - - enum class msr_flags : uint64_t + /** + * @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 = 1U << 0ULL, ///< System Call Extensions - LME = 1U << 8ULL, ///< Long Mode Enabled - LMA = 1U << 10ULL, ///< Long Mode Active - NXE = 1U << 11ULL, ///< No-Execute Enable - SVME = 1U << 12ULL, ///< Secure Virtual Machine Enable - LMSLE = 1U << 13ULL, ///< Secure Virtual Machine Enable - FFXSR = 1U << 14ULL, ///< fast FXSAVE/FXSTOR - TCE = 1U << 15ULL, ///< Translation Cache Extension + 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 Model-Specific Register (MSR). * - * This function reads the value of an MSR specified by the given address. It + * @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 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. */ - uint64_t read_msr(uint32_t msr); + auto read_msr(uint32_t msr) -> void; /** * @brief Writes a 64-bit value to a Model-Specific Register (MSR). * - * This function writes a 64-bit value to the MSR specified by the given address. + * @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 value The 64-bit value to write to the MSR. + * @param new_value The 64-bit value to write to the MSR. */ - void write_msr(uint32_t msr, uint64_t value); + auto write_msr(uint32_t msr, uint64_t new_value) -> void; /** - * @brief Sets a specific bit in the MSR register. + * @brief Sets a specific bit in the Extended Feature Enable Register (EFER) Model-Specific Register (MSR) register. * - * This function reads the current value of the EFER register, ORs the specified + * @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. */ - void set_msr_bit(msr_flags flag); + auto set_efer_bit(efer_flags flag) -> void; /** * @brief Enables the No-Execute Enable (NXE) bit in the Extended Feature Enable Register (EFER). * - * This function reads the current value of the EFER register, enables the NXE bit + * @note This function reads the current value of the EFER register, enables the NXE bit * (bit 11), and writes the updated value back to the EFER register. Enabling the NXE * bit allows the processor to support No-Execute memory regions, which are required * for certain memory protection features like Data Execution Prevention (DEP). */ - void enable_nxe_bit(); + auto enable_nxe_bit() -> void; } // namespace teachos::arch::memory::cpu 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 5e51c64..53284b6 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/cr3.hpp" +#include "arch/memory/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" @@ -74,7 +74,8 @@ namespace teachos::arch::memory::paging auto remap_elf_kernel_sections(inactive_page_table inactive_table, temporary_page & temporary_page, active_page_table & active_table) -> void { - auto const backup = allocator::physical_frame::containing_address(cpu::read_cr3_register()); + auto const backup = + allocator::physical_frame::containing_address(cpu::read_control_register(cpu::control_register::CR3)); auto page_table_level4 = temporary_page.map_table_frame(backup, active_table); active_table[511].set_entry(inactive_table.page_table_level_4_frame, entry::PRESENT | entry::WRITABLE); @@ -95,11 +96,12 @@ namespace teachos::arch::memory::paging */ auto switch_active_page_table(inactive_page_table new_table) -> inactive_page_table { - auto const backup = allocator::physical_frame::containing_address(cpu::read_cr3_register()); + auto const backup = + allocator::physical_frame::containing_address(cpu::read_control_register(cpu::control_register::CR3)); auto const old_table = inactive_page_table{backup}; auto const new_address = new_table.page_table_level_4_frame.start_address(); - cpu::write_cr3_register(new_address); + cpu::write_control_register(cpu::control_register::CR3, new_address); return old_table; } |
