aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory/paging
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src/memory/paging')
-rw-r--r--arch/x86_64/src/memory/paging/page_mapper.cpp57
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