diff options
| author | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-23 13:28:07 +0000 |
|---|---|---|
| committer | Matteo Gmür <matteo.gmuer1@ost.ch> | 2024-10-23 13:28:07 +0000 |
| commit | 61db7fa6097a9e3784f8fb18a8d3de47d7d7c007 (patch) | |
| tree | 47ece442b393f2c895623c4cc01ad9fb7da002c8 /arch/x86_64 | |
| parent | ef22c9394534014dbda3e2a070df3d02a9fd041e (diff) | |
| download | teachos-61db7fa6097a9e3784f8fb18a8d3de47d7d7c007.tar.xz teachos-61db7fa6097a9e3784f8fb18a8d3de47d7d7c007.zip | |
Extract next_table_or_create into page_table
Diffstat (limited to 'arch/x86_64')
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging/page_mapper.hpp | 19 | ||||
| -rw-r--r-- | arch/x86_64/include/arch/memory/paging/page_table.hpp | 32 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging/page_table.cpp | 2 |
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 { /** |
