diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 14:07:28 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2025-12-12 14:07:28 +0100 |
| commit | 50c9c9a1d963e66f7658ab31e9ecd65bf227cfff (patch) | |
| tree | 7b16e1cbf5aafaa1f5a5d814cac96bb283009e0c /arch/x86_64/include | |
| parent | 8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8 (diff) | |
| download | teachos-50c9c9a1d963e66f7658ab31e9ecd65bf227cfff.tar.xz teachos-50c9c9a1d963e66f7658ab31e9ecd65bf227cfff.zip | |
x86_64/memory: clean up dependencies
Diffstat (limited to 'arch/x86_64/include')
4 files changed, 62 insertions, 24 deletions
diff --git a/arch/x86_64/include/x86_64/memory/kernel_mapper.hpp b/arch/x86_64/include/x86_64/memory/kernel_mapper.hpp index 1f217ae..5b9c2fd 100644 --- a/arch/x86_64/include/x86_64/memory/kernel_mapper.hpp +++ b/arch/x86_64/include/x86_64/memory/kernel_mapper.hpp @@ -1,6 +1,8 @@ #ifndef TEACHOS_X86_64_KERNEL_MAPPER_HPP #define TEACHOS_X86_64_KERNEL_MAPPER_HPP +#include "kapi/memory.hpp" + #include <elf/format.hpp> #include <elf/section_header.hpp> #include <multiboot2/information.hpp> @@ -16,10 +18,10 @@ namespace teachos::memory::x86_64 explicit kernel_mapper(multiboot2::information_view const * mbi); - auto remap_kernel() -> void; + auto remap_kernel(page_mapper & mapper) -> void; private: - auto map_section(section_header_type const & section, std::string_view name) -> void; + auto map_section(section_header_type const & section, std::string_view name, page_mapper & mapper) -> void; multiboot2::information_view const * m_mbi; std::uintptr_t m_kernel_load_base; diff --git a/arch/x86_64/include/x86_64/memory/page_table.hpp b/arch/x86_64/include/x86_64/memory/page_table.hpp index 3bc2a2b..71ba5b7 100644 --- a/arch/x86_64/include/x86_64/memory/page_table.hpp +++ b/arch/x86_64/include/x86_64/memory/page_table.hpp @@ -3,6 +3,8 @@ #include "kapi/memory.hpp" +#include "x86_64/memory/page_utilities.hpp" + #include <kstd/ext/bitfield_enum> #include <array> @@ -183,6 +185,58 @@ namespace teachos::memory::x86_64 }); } + [[nodiscard]] auto translate(linear_address address) const -> std::optional<physical_address> + requires(Level == 4) + { + auto offset = address.raw() % page::size; + return translate(page::containing(address)).transform([offset](auto frame) -> auto { + return physical_address{frame.start_address().raw() + offset}; + }); + } + + [[nodiscard]] auto translate(page page) const -> std::optional<frame> + requires(Level == 4) + { + 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) + { + return std::nullopt; + } + else if (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 pml2 = (*pml3)->next(pml_index<3>(page)); + auto pml2_entry = pml2.transform([&](auto pml2) -> auto { return (*pml2)[pml_index<2>(page)]; }); + if (!pml2_entry) + { + return std::nullopt; + } + else if (pml2_entry->huge()) + { + auto pml2_entry_frame = *pml2_entry->frame(); + return frame{pml2_entry_frame.number() + pml_index<1>(page)}; + } + + 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); + } + private: //! The number of address bits used to represent the page index per level. constexpr auto static level_bits = 9; diff --git a/arch/x86_64/include/x86_64/memory/paging_root.hpp b/arch/x86_64/include/x86_64/memory/paging_root.hpp index 75ba120..47ee2f9 100644 --- a/arch/x86_64/include/x86_64/memory/paging_root.hpp +++ b/arch/x86_64/include/x86_64/memory/paging_root.hpp @@ -1,19 +1,15 @@ #ifndef TEACHOS_X86_64_PAGING_ROOT_HPP #define TEACHOS_X86_64_PAGING_ROOT_HPP -#include "kapi/memory.hpp" - #include "x86_64/memory/page_table.hpp" -#include <optional> - namespace teachos::memory::x86_64 { //! The active, recursively mapped, root map (e.g. PML4) struct paging_root : recursive_page_table<4> { - auto static get() -> paging_root &; + auto static get() -> paging_root *; paging_root(paging_root const &) = delete; paging_root(paging_root &&) = delete; @@ -22,22 +18,6 @@ namespace teachos::memory::x86_64 ~paging_root() = delete; - [[nodiscard]] auto translate(linear_address address) const -> std::optional<physical_address>; - [[nodiscard]] auto translate(page page) const -> std::optional<frame>; - - //! Map the given page into the given frame using the given flags. - //! - //! @param page A page to map. - //! @param frame The frame into which to map the page. - //! @param flags The flags to apply to the mapping. - auto map(page page, frame frame, entry::flags flags) -> std::optional<std::byte *>; - - //! Unmap the given page from virtual memory. - //! - //! @warning If the page has not previously been mapped, this function will panic. - //! @param page The page to unmap - auto unmap(page page) -> void; - private: paging_root() = default; }; diff --git a/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp index 415ea8e..835e2df 100644 --- a/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp +++ b/arch/x86_64/include/x86_64/memory/scoped_mapping.hpp @@ -22,7 +22,8 @@ namespace teachos::memory::x86_64 //! Construct a new scoped mapping, which can be used to map a frame to the given unused page. //! @param page An unused page. If the page is already mapped, this constructor will panic. - explicit scoped_mapping(page page); + //! @param mapper The page mapper to use for mapping and unmapping of the page. + explicit scoped_mapping(page page, page_mapper & mapper); //! Unmap the mapped frame if one was mapped. //! @note Any page tables that were allocated to support the mapping will be released. @@ -56,6 +57,7 @@ namespace teachos::memory::x86_64 private: page m_page; + page_mapper * m_mapper; bool m_mapped; }; |
