aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/arch/memory/cpu/control_register.hpp70
-rw-r--r--arch/x86_64/include/arch/memory/cpu/cr3.hpp27
-rw-r--r--arch/x86_64/include/arch/memory/cpu/msr.hpp47
-rw-r--r--arch/x86_64/include/arch/memory/paging/kernel_mapper.hpp10
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;
}