diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-10 21:55:42 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-10 21:55:42 +0100 |
| commit | eafbf588760c289b7f54a4771b39af0ccfe8cf59 (patch) | |
| tree | fabf14d8c908a187b0f3247eecac349a56d99b2d /arch/x86_64/src/memory/paging_root.cpp | |
| parent | f0c5ac3c8222d4d89b8e2d2a726427a7ec64e538 (diff) | |
| download | kernel-eafbf588760c289b7f54a4771b39af0ccfe8cf59.tar.xz kernel-eafbf588760c289b7f54a4771b39af0ccfe8cf59.zip | |
kapi: extract page_mapper interface
Diffstat (limited to 'arch/x86_64/src/memory/paging_root.cpp')
| -rw-r--r-- | arch/x86_64/src/memory/paging_root.cpp | 52 |
1 files changed, 43 insertions, 9 deletions
diff --git a/arch/x86_64/src/memory/paging_root.cpp b/arch/x86_64/src/memory/paging_root.cpp index 5ca2bf0..c458093 100644 --- a/arch/x86_64/src/memory/paging_root.cpp +++ b/arch/x86_64/src/memory/paging_root.cpp @@ -27,16 +27,15 @@ namespace teachos::memory::x86_64 //! still enforcing non-writability and non-execution of the affected page. template<std::size_t Level> requires(Level > 1uz && Level < 5uz) - auto do_map(recursive_page_table<Level> * pml, page page, page_table::entry::flags flags, - frame_allocator & allocator) + auto do_map(recursive_page_table<Level> * pml, page page, page_table::entry::flags flags) { auto index = pml_index<Level>(page); flags = flags & ~page_table::entry::flags::no_execute; flags = flags | page_table::entry::flags::writable; if (!(*pml)[index].present()) { - auto new_table_frame = allocator.allocate(); - auto mapping = scoped_mapping{page, allocator}; + auto new_table_frame = active_allocator().allocate(); + auto mapping = scoped_mapping{page}; (*pml)[index].frame(new_table_frame.value(), page_table::entry::flags::present | flags); auto new_table = std::optional{std::construct_at(*pml->next(index))}; return new_table; @@ -114,14 +113,49 @@ namespace teachos::memory::x86_64 .or_else(handle_huge_page); } - auto paging_root::map(page page, frame frame, page_table::entry::flags flags, frame_allocator & allocator) - -> std::optional<std::byte *> + auto paging_root::map(page page, frame frame, page_table::entry::flags flags) -> std::optional<std::byte *> { return std::optional{this} - .and_then([&](auto pml) -> auto { return do_map(pml, page, flags, allocator); }) - .and_then([&](auto pml) -> auto { return do_map(pml, page, flags, allocator); }) - .and_then([&](auto pml) -> auto { return do_map(pml, page, flags, allocator); }) + .and_then([&](auto pml) -> auto { return do_map(pml, page, flags); }) + .and_then([&](auto pml) -> auto { return do_map(pml, page, flags); }) + .and_then([&](auto pml) -> auto { return do_map(pml, page, flags); }) .and_then([&](auto pml) -> auto { return do_map(pml, page, frame, flags); }); } + auto paging_root::unmap(page page) -> void + { + if (!this->translate(page)) + { + system::panic("[x86_64:MEM] Tried to unmap a page that was not mapped."); + } + + auto pml4 = this; + auto pml3 = pml4->next(pml_index<4>(page)).value(); + auto pml2 = pml3->next(pml_index<3>(page)).value(); + auto pml1 = pml2->next(pml_index<2>(page)).value(); + + (*pml1)[pml_index<1>(page)].clear(); + + if (pml1->empty()) + { + auto pml1_frame = (*pml2)[pml_index<2>(page)].frame().value(); + active_allocator().release(pml1_frame); + (*pml2)[pml_index<2>(page)].clear(); + } + + if (pml2->empty()) + { + auto pml2_frame = (*pml3)[pml_index<3>(page)].frame().value(); + active_allocator().release(pml2_frame); + (*pml3)[pml_index<3>(page)].clear(); + } + + if (pml3->empty()) + { + auto pml3_frame = (*pml4)[pml_index<4>(page)].frame().value(); + active_allocator().release(pml3_frame); + (*pml4)[pml_index<4>(page)].clear(); + } + } + } // namespace teachos::memory::x86_64
\ No newline at end of file |
