diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-02 12:31:53 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-02 12:31:53 +0100 |
| commit | be86be1facfce8fe3f376153b9c582f2c5c026aa (patch) | |
| tree | 6d05b8ed07fa6afdbbf980fdfdf584e818c1cd61 | |
| parent | 203355e51690073e571d4906d53f2494c3dad41b (diff) | |
| download | teachos-be86be1facfce8fe3f376153b9c582f2c5c026aa.tar.xz teachos-be86be1facfce8fe3f376153b9c582f2c5c026aa.zip | |
x86_64/memory: extend scoped_mapping
| -rw-r--r-- | arch/x86_64/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | arch/x86_64/include/x86_64/memory/page_utilities.hpp | 22 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/paging_root.cpp | 41 | ||||
| -rw-r--r-- | arch/x86_64/src/memory/scoped_mapping.cpp | 8 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/frame.hpp | 5 | ||||
| -rw-r--r-- | kapi/include/kapi/memory/page.hpp | 5 |
6 files changed, 81 insertions, 1 deletions
diff --git a/arch/x86_64/CMakeLists.txt b/arch/x86_64/CMakeLists.txt index 4d32f76..f010dcf 100644 --- a/arch/x86_64/CMakeLists.txt +++ b/arch/x86_64/CMakeLists.txt @@ -52,6 +52,7 @@ target_sources("x86_64" PRIVATE # Memory management "include/x86_64/memory/mmu.hpp" "include/x86_64/memory/page_table.hpp" + "include/x86_64/memory/page_utilities.hpp" "include/x86_64/memory/paging_root.hpp" "include/x86_64/memory/region_allocator.hpp" "include/x86_64/memory/scoped_mapping.hpp" diff --git a/arch/x86_64/include/x86_64/memory/page_utilities.hpp b/arch/x86_64/include/x86_64/memory/page_utilities.hpp new file mode 100644 index 0000000..efd1b80 --- /dev/null +++ b/arch/x86_64/include/x86_64/memory/page_utilities.hpp @@ -0,0 +1,22 @@ +#ifndef TEACHOS_X86_64_PAGE_UTILITIES_HPP +#define TEACHOS_X86_64_PAGE_UTILITIES_HPP + +#include "kapi/memory.hpp" + +#include <cstddef> + +namespace teachos::memory::x86_64 +{ + + template<std::size_t Level> + requires(Level > 0uz && Level < 5uz) + constexpr auto pml_index(page page) noexcept -> std::size_t + { + constexpr auto shift_width = (Level - 1) * 9; + constexpr auto index_mask = 0x1ffuz; + return page.number() >> shift_width & index_mask; + } + +} // namespace teachos::memory::x86_64 + +#endif
\ No newline at end of file diff --git a/arch/x86_64/src/memory/paging_root.cpp b/arch/x86_64/src/memory/paging_root.cpp index 1234308..6b65f60 100644 --- a/arch/x86_64/src/memory/paging_root.cpp +++ b/arch/x86_64/src/memory/paging_root.cpp @@ -1,6 +1,11 @@ #include "x86_64/memory/paging_root.hpp" +#include "kapi/memory.hpp" + +#include "x86_64/memory/page_utilities.hpp" + #include <cstdint> +#include <optional> namespace teachos::memory::x86_64 { @@ -16,4 +21,40 @@ namespace teachos::memory::x86_64 return *pml4_address; } + auto paging_root::translate(linear_address address) const -> std::optional<physical_address> + { + auto offset = address.raw() % PLATFORM_PAGE_SIZE; + return translate(page::containing(address)).transform([offset](auto frame) -> auto { + return physical_address{frame.start_address().raw() + offset}; + }); + } + + auto paging_root::translate(page page) const -> std::optional<frame> + { + auto pml3 = next(pml_index<4>(page)); + + if (!pml3) + { + return std::nullopt; + } + + auto handle_huge_page = [&] -> std::optional<frame> { + auto pml3_entry = pml3.transform([&](auto pml3) -> auto { return (*pml3)[pml_index<3>(page)]; }); + if (pml3_entry && pml3_entry->huge()) + { + auto pml3_entry_frame = *pml3_entry->frame(); + return frame{pml3_entry_frame.number() + pml_index<2>(page) * entry_count + pml_index<1>(page)}; + } + + // auto pml3_entry = (**pml3)[page.start_address().raw() >> 39 & 0x1ff]; + + return std::nullopt; + }; + + return pml3.and_then([&](auto pml3) -> auto { return pml3->next(pml_index<3>(page)); }) + .and_then([&](auto pml2) -> auto { return pml2->next(pml_index<2>(page)); }) + .and_then([&](auto pml1) -> auto { return (*pml1)[pml_index<1>(page)].frame(); }) + .or_else(handle_huge_page); + } + } // namespace teachos::memory::x86_64
\ No newline at end of file diff --git a/arch/x86_64/src/memory/scoped_mapping.cpp b/arch/x86_64/src/memory/scoped_mapping.cpp index c436ee5..27c4785 100644 --- a/arch/x86_64/src/memory/scoped_mapping.cpp +++ b/arch/x86_64/src/memory/scoped_mapping.cpp @@ -4,6 +4,7 @@ #include "kapi/system.hpp" #include "x86_64/memory/mmu.hpp" +#include "x86_64/memory/paging_root.hpp" #include <utility> @@ -20,7 +21,12 @@ namespace teachos::memory::x86_64 : m_address{address} , m_allocator{&allocator} , m_mapped{false} - {} + { + if (paging_root::get().translate(address)) + { + system::panic("[MEM] Tried to map a page that is already mapped!"); + } + } scoped_mapping::~scoped_mapping() { diff --git a/kapi/include/kapi/memory/frame.hpp b/kapi/include/kapi/memory/frame.hpp index 095a3df..5793b8b 100644 --- a/kapi/include/kapi/memory/frame.hpp +++ b/kapi/include/kapi/memory/frame.hpp @@ -42,6 +42,11 @@ namespace teachos::memory return physical_address{m_number * PLATFORM_FRAME_SIZE}; } + [[nodiscard]] constexpr auto number() const noexcept -> std::size_t + { + return m_number; + } + /** * @brief Get the nth next frame. * diff --git a/kapi/include/kapi/memory/page.hpp b/kapi/include/kapi/memory/page.hpp index b84094f..473a8b8 100644 --- a/kapi/include/kapi/memory/page.hpp +++ b/kapi/include/kapi/memory/page.hpp @@ -42,6 +42,11 @@ namespace teachos::memory return linear_address{m_number * PLATFORM_PAGE_SIZE}; } + [[nodiscard]] constexpr auto number() const noexcept -> std::size_t + { + return m_number; + } + /** * @brief Check if this page refers to the same page as @p other. */ |
