aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory/paging_root.cpp
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-10 21:55:42 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-10 21:55:42 +0100
commiteafbf588760c289b7f54a4771b39af0ccfe8cf59 (patch)
treefabf14d8c908a187b0f3247eecac349a56d99b2d /arch/x86_64/src/memory/paging_root.cpp
parentf0c5ac3c8222d4d89b8e2d2a726427a7ec64e538 (diff)
downloadkernel-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.cpp52
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