aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMatteo Gmür <matteo.gmuer1@ost.ch>2024-10-23 13:28:07 +0000
committerMatteo Gmür <matteo.gmuer1@ost.ch>2024-10-23 13:28:07 +0000
commit61db7fa6097a9e3784f8fb18a8d3de47d7d7c007 (patch)
tree47ece442b393f2c895623c4cc01ad9fb7da002c8 /arch
parentef22c9394534014dbda3e2a070df3d02a9fd041e (diff)
downloadteachos-61db7fa6097a9e3784f8fb18a8d3de47d7d7c007.tar.xz
teachos-61db7fa6097a9e3784f8fb18a8d3de47d7d7c007.zip
Extract next_table_or_create into page_table
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_mapper.hpp19
-rw-r--r--arch/x86_64/include/arch/memory/paging/page_table.hpp32
-rw-r--r--arch/x86_64/src/memory/paging/page_table.cpp2
3 files changed, 33 insertions, 20 deletions
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 80f6eb4..3590dda 100644
--- a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp
@@ -65,24 +65,7 @@ namespace teachos::arch::memory::paging
for (auto level = page_table_handle::LEVEL4; level != page_table_handle::LEVEL1; --level)
{
- auto level_index = page.get_level_index(level);
- auto next_handle = current_handle.next_table(level_index);
- // If the next table method failed then it means that the page level of the frame we want allocate has not yet
- // been created itself. So we have to do that before we are able to allocate the wanted frame. This has to be done
- // for every level, meaning we potenitally create a level 4, level 3 and level 2 page entry, each pointing to a
- // page table one level below.
- if (!next_handle)
- {
- auto allocated_frame = allocator.allocate_frame();
- exception_handling::assert(allocated_frame.has_value(), "[Page mapper] Unable to allocate frame");
- current_handle[level_index].set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
- // There should now be an entry at the previously not existent index, therefore we can simply access it again.
- next_handle = current_handle.next_table(level_index);
- exception_handling::assert(next_handle.has_value(), "[Page mapper] Unable to create new entry into page table");
- // TODO: Crashes when trying to access underlying entries array.
- next_handle.value().zero_entries();
- }
- current_handle = next_handle.value();
+ current_handle = current_handle.next_table_or_create(allocator, page.get_level_index(level));
}
auto level1_entry = current_handle[page.get_level_index(page_table_handle::LEVEL1)];
diff --git a/arch/x86_64/include/arch/memory/paging/page_table.hpp b/arch/x86_64/include/arch/memory/paging/page_table.hpp
index eb0b984..8250e30 100644
--- a/arch/x86_64/include/arch/memory/paging/page_table.hpp
+++ b/arch/x86_64/include/arch/memory/paging/page_table.hpp
@@ -1,6 +1,8 @@
#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_TABLE_HPP
#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_TABLE_HPP
+#include "arch/exception_handling/assert.hpp"
+#include "arch/memory/allocator/area_frame_allocator.hpp"
#include "arch/memory/paging/page_entry.hpp"
namespace teachos::arch::memory::paging
@@ -61,6 +63,36 @@ namespace teachos::arch::memory::paging
auto next_table(std::size_t table_index) -> std::optional<page_table_handle>;
/**
+ * @brief Call next_table and then checks if the table already exists, if it does not it will use the given
+ * allocator to get the next free frame and set the entry to that instead.
+ *
+ * @param allocator Reference to an allocator following the FrameAllocator concept, which is used to allocate
+ * entries when a new page table is required.
+ * @param table_index Index of this page table in the page table one level lower.
+ */
+ template<allocator::FrameAllocator T>
+ auto next_table_or_create(T & allocator, std::size_t table_index) -> page_table_handle
+ {
+ auto next_handle = next_table(table_index);
+ // If the next table method failed then it means that the page level of the frame we want allocate has not yet
+ // been created itself. So we have to do that before we are able to allocate the wanted frame. This has to be done
+ // for every level, meaning we potenitally create a level 4, level 3 and level 2 page entry, each pointing to a
+ // page table one level below.
+ if (!next_handle)
+ {
+ auto allocated_frame = allocator.allocate_frame();
+ exception_handling::assert(allocated_frame.has_value(), "[Page mapper] Unable to allocate frame");
+ this->operator[](table_index).set_entry(allocated_frame.value(), entry::PRESENT | entry::WRITABLE);
+ // There should now be an entry at the previously not existent index, therefore we can simply access it again.
+ next_handle = next_table(table_index);
+ exception_handling::assert(next_handle.has_value(), "[Page mapper] Unable to create new entry into page table");
+ // TODO: Crashes when trying to access underlying entries array.
+ next_handle.value().zero_entries();
+ }
+ return next_handle.value();
+ }
+
+ /**
* @brief Index operator overload to access specific immutable entry directy.
*
* @param index Index of the entry we want to access and only read.
diff --git a/arch/x86_64/src/memory/paging/page_table.cpp b/arch/x86_64/src/memory/paging/page_table.cpp
index 33d0b75..40662e3 100644
--- a/arch/x86_64/src/memory/paging/page_table.cpp
+++ b/arch/x86_64/src/memory/paging/page_table.cpp
@@ -1,7 +1,5 @@
#include "arch/memory/paging/page_table.hpp"
-#include "arch/exception_handling/assert.hpp"
-
namespace teachos::arch::memory::paging
{
/**