diff options
Diffstat (limited to 'arch/x86_64/src/memory/paging')
| -rw-r--r-- | arch/x86_64/src/memory/paging/page_mapper.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
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<allocator::physical_frame> + { + page_table page_table{}; + bool is_valid = false; + auto huge_page = []() -> std::optional<allocator::physical_frame> { 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> + { + std::size_t offset = virtual_address % allocator::PAGE_FRAME_SIZE; + virtual_page page = virtual_page::containing_address(virtual_address); + std::optional<allocator::physical_frame> 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 *>(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 |
