aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/include
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-12 14:07:28 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-12 14:07:28 +0100
commit50c9c9a1d963e66f7658ab31e9ecd65bf227cfff (patch)
tree7b16e1cbf5aafaa1f5a5d814cac96bb283009e0c /arch/x86_64/include
parent8fc5f9e3cc28b07b1f120eb1ffedc042fa6662b8 (diff)
downloadteachos-50c9c9a1d963e66f7658ab31e9ecd65bf227cfff.tar.xz
teachos-50c9c9a1d963e66f7658ab31e9ecd65bf227cfff.zip
x86_64/memory: clean up dependencies
Diffstat (limited to 'arch/x86_64/include')
-rw-r--r--arch/x86_64/include/x86_64/memory/kernel_mapper.hpp6
-rw-r--r--arch/x86_64/include/x86_64/memory/page_table.hpp54
-rw-r--r--arch/x86_64/include/x86_64/memory/paging_root.hpp22
-rw-r--r--arch/x86_64/include/x86_64/memory/scoped_mapping.hpp4
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;
};