From 1d157101eb550f99dac9ec943053f85bbf6c7644 Mon Sep 17 00:00:00 2001 From: Fabian Imhof Date: Sun, 20 Oct 2024 09:03:30 +0000 Subject: create page_mapper --- arch/x86_64/CMakeLists.txt | 1 + .../include/arch/memory/paging/page_mapper.hpp | 30 ++++++++++++ .../include/arch/memory/paging/virtual_page.hpp | 51 ------------------- arch/x86_64/src/memory/paging/page_mapper.cpp | 57 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 51 deletions(-) create mode 100644 arch/x86_64/include/arch/memory/paging/page_mapper.hpp create mode 100644 arch/x86_64/src/memory/paging/page_mapper.cpp diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index fe83548..018fe61 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -49,6 +49,7 @@ target_sources("_memory" PRIVATE "src/memory/paging/page_entry.cpp" "src/memory/paging/page_table.cpp" "src/memory/paging/virtual_page.cpp" + "src/memory/paging/page_mapper.cpp" ) #[============================================================================[ diff --git a/arch/x86_64/include/arch/memory/paging/page_mapper.hpp b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp new file mode 100644 index 0000000..b151a7f --- /dev/null +++ b/arch/x86_64/include/arch/memory/paging/page_mapper.hpp @@ -0,0 +1,30 @@ +#ifndef TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_MAPPER_HPP +#define TEACHOS_ARCH_X86_64_MEMORY_PAGING_PAGE_MAPPER_HPP + +#include "arch/memory/paging/virtual_page.hpp" + +#include + +namespace teachos::arch::memory::paging +{ + /** + * @brief Translate page into physical_frame + * + * @param page Page to translate into physical_frame + * @return Physical frame corresponding to the provided page_table + */ + auto translate_page(virtual_page page) -> std::optional; + + /** + * @brief Translate virtual into phyical address + * + * @param virtual_address Address to translate into physical + * @return Physical address + */ + auto translate_address(std::size_t virtual_address) -> std::optional; + + auto map_page_to_frame(memory::allocator::area_frame_allocator & allocator, const Page & page, const Frame & frame, + EntryFlags flags) -> void; +} // namespace teachos::arch::memory::paging + +#endif \ No newline at end of file diff --git a/arch/x86_64/include/arch/memory/paging/virtual_page.hpp b/arch/x86_64/include/arch/memory/paging/virtual_page.hpp index 705de29..6b9a641 100644 --- a/arch/x86_64/include/arch/memory/paging/virtual_page.hpp +++ b/arch/x86_64/include/arch/memory/paging/virtual_page.hpp @@ -58,57 +58,6 @@ namespace teachos::arch::memory::paging std::size_t page_number; ///< Index number of the current virtual page, used to distinguish it from other pages. }; - /** - * @brief Translate page into physical_frame - * - * @param page Page to translate into physical_frame - * @return Physical frame corresponding to the provided page_table - */ - auto translate_page(virtual_page page) -> std::optional - { - page_table page_table{}; - bool is_valid = false; - auto huge_page = []() -> std::optional { return std::nullopt; }; - - for (auto level = page_table::LEVEL4; level != page_table::LEVEL1; level--) - { - is_valid = page_table.next_table(page.get_level_index(level)); - if (!is_valid) - { - break; - } - } - - if (is_valid) - { - auto level1_index = page.get_level_index(page_table::LEVEL1); - auto frame = page_table[level1_index].calculate_pointed_to_frame(); - return frame; - } - - return huge_page(); - } - - /** - * @brief Translate virtual into phyical address - * - * @param virtual_address Address to translate into physical - * @return Physical address - */ - auto translate_address(std::size_t virtual_address) -> std::optional - { - std::size_t offset = virtual_address % allocator::PAGE_FRAME_SIZE; - virtual_page page = virtual_page::containing_address(virtual_address); - std::optional frame = translate_page(page); - - if (frame.has_value()) - { - return frame.value().frame_number * allocator::PAGE_FRAME_SIZE + offset; - } - - return std::nullopt; - } - } // namespace teachos::arch::memory::paging #endif // TEACHOS_ARCH_X86_64_MEMORY_PAGING_VIRTUAL_PAGE_HPP diff --git a/arch/x86_64/src/memory/paging/page_mapper.cpp b/arch/x86_64/src/memory/paging/page_mapper.cpp new file mode 100644 index 0000000..5372561 --- /dev/null +++ b/arch/x86_64/src/memory/paging/page_mapper.cpp @@ -0,0 +1,57 @@ +#include "arch/exception_handling/assert.hpp" +#include "arch/memory/allocator/area_frame_allocator.hpp" +#include "arch/memory/paging/virtual_page.hpp" + +namespace teachos::arch::memory::paging +{ + auto translate_page(virtual_page page) -> std::optional + { + page_table page_table{}; + bool is_valid = false; + auto huge_page = []() -> std::optional { return std::nullopt; }; + + for (auto level = page_table::LEVEL4; level != page_table::LEVEL1; level--) + { + is_valid = page_table.next_table(page.get_level_index(level)); + if (!is_valid) + { + break; + } + } + + if (is_valid) + { + auto level1_index = page.get_level_index(page_table::LEVEL1); + auto frame = page_table[level1_index].calculate_pointed_to_frame(); + return frame; + } + + return huge_page(); + } + + auto translate_address(std::size_t virtual_address) -> std::optional + { + std::size_t offset = virtual_address % allocator::PAGE_FRAME_SIZE; + virtual_page page = virtual_page::containing_address(virtual_address); + std::optional frame = translate_page(page); + + if (frame.has_value()) + { + return frame.value().frame_number * allocator::PAGE_FRAME_SIZE + offset; + } + + return std::nullopt; + } + + auto map_page_to_frame(memory::allocator::area_frame_allocator & allocator, const virtual_page & page, + const memory::allocator::physical_frame & frame, entry::bitset flags) -> void + { + auto p4 = reinterpret_cast(P4); // Assuming P4 is defined somewhere + auto p3 = p4->next_table_create(page.p4_index(), allocator); + auto p2 = p3->next_table_create(page.p3_index(), allocator); + auto p1 = p2->next_table_create(page.p2_index(), allocator); + + assert(p1[page.p1_index()].is_unused()); + p1[page.p1_index()].set(frame, flags | PRESENT); + } +} // namespace teachos::arch::memory::paging \ No newline at end of file -- cgit v1.2.3