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/allocator/area_frame_allocator.hpp6
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_mapper.hpp43
2 files changed, 42 insertions, 7 deletions
diff --git a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
index c9d4e7f..f99b7c8 100644
--- a/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
+++ b/arch/x86_64/include/arch/memory/allocator/area_frame_allocator.hpp
@@ -8,6 +8,12 @@
namespace teachos::arch::memory::allocator
{
+ template<typename T>
+ concept FrameAllocator = requires(T t) {
+ { t.allocate_frame() } -> std::same_as<std::optional<physical_frame>>;
+ { t.deallocate_frame() } -> std::same_as<void>;
+ };
+
/**
* @brief Allocates memory using memory areas read from the multiboot2 information pointer.
*/
diff --git a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp
index 635a848..5bdd82a 100644
--- a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp
@@ -1,6 +1,7 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_MAPPER_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_MAPPER_HPP
+#include "arch/exception_handling/assert.hpp"
#include "arch/memory/allocator/area_frame_allocator.hpp"
#include "arch/memory/paging/virtual_page.hpp"
@@ -34,16 +35,44 @@ namespace teachos::arch::memory::paging
auto translate_address(std::size_t virtual_address) -> std::optional<std::size_t>;
/**
- * @brief Maps a virtual page to a physical frame in the page table with the specified flags.
+ * @brief Maps a virtual page to a physical frame in the page table with the specified flags. Allocates and maps an
+ * entry in every page level if it does not exists yet down to level 1. If the level 1 page table already exists it
+ * halts execution instead.
*
- * @param allocator Reference to the area frame allocator, which is used to allocate frames when a new page table is
- * required.
- * @param page Reference to the virtual page that is being mapped.
- * @param frame The physical frame that the virtual page will be mapped to.
+ * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate entries
+ * when a new page table is required.
+ * @param page Virtual page that is being mapped.
+ * @param frame Physical frame that the virtual page will be mapped to.
* @param flags A bitset of flags that configure the page table entry for this mapping.
*/
- auto map_page_to_frame(allocator::area_frame_allocator & allocator, virtual_page page,
- allocator::physical_frame frame, std::bitset<64U> flags) -> void;
+ template<allocator::FrameAllocator T>
+ auto map_page_to_frame(T & allocator, virtual_page page, allocator::physical_frame frame,
+ std::bitset<64U> flags) -> void
+
+ {
+ page_table page_table{};
+ bool table_exists = false;
+
+ for (auto level = page_table::LEVEL4; level != page_table::LEVEL1; level--)
+ {
+ std::size_t level_index = page.get_level_index(level);
+ table_exists = page_table.next_table(level_index);
+
+ if (!table_exists)
+ {
+ auto allocated_frame = allocator.allocate_frame();
+ exception_handling::assert(!allocated_frame.has_value(), "[Page mapper]: Unable to allocate frame");
+ page_table[level_index].set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
+ page_table.zero_entries();
+ }
+ }
+
+ auto level1_entry = page_table[page.get_level_index(page_table::LEVEL1)];
+ arch::exception_handling::assert(!level1_entry.contains_flags(entry::HUGE_PAGE),
+ "[Page Mapper]: Unable to map huge pages");
+ arch::exception_handling::assert(!level1_entry.is_unused(), "[Page Mapper]: Page table entry is already used");
+ level1_entry.set_entry(frame, flags | std::bitset<64U>{entry::PRESENT});
+ }
} // namespace teachos::arch::memory::paging
#endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_MAPPER_HPP