diff options
Diffstat (limited to 'arch/x86_64/src/memory/page_table.cpp')
| -rw-r--r-- | arch/x86_64/src/memory/page_table.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/arch/x86_64/src/memory/page_table.cpp b/arch/x86_64/src/memory/page_table.cpp new file mode 100644 index 0000000..2de099d --- /dev/null +++ b/arch/x86_64/src/memory/page_table.cpp @@ -0,0 +1,82 @@ +#include "x86_64/memory/page_table.hpp" + +#include "kapi/memory.hpp" + +#include <algorithm> +#include <bit> +#include <cstddef> +#include <cstdint> +#include <optional> +#include <utility> + +namespace teachos::memory::x86_64 +{ + + auto page_table::entry::clear() noexcept -> void + { + m_raw = 0; + } + + auto page_table::entry::present() const noexcept -> bool + { + return (all_flags() & flags::present) != flags::empty; + } + + auto page_table::entry::huge() const noexcept -> bool + { + return (all_flags() & flags::huge_page) != flags::empty; + } + + auto page_table::entry::all_flags() const noexcept -> flags + { + return std::bit_cast<flags>(m_raw & ~frame_number_mask); + } + + auto page_table::entry::all_flags(flags flags) noexcept -> void + { + m_raw = (m_raw & ~frame_number_mask) | std::to_underlying(flags); + } + + auto page_table::entry::operator|=(flags rhs) noexcept -> page_table::entry & + { + auto raw_flags = std::to_underlying(rhs) & ~frame_number_mask; + m_raw |= raw_flags; + return *this; + } + + auto page_table::entry::frame() const noexcept -> std::optional<struct frame> + { + if (present()) + { + return frame::containing(physical_address{m_raw & frame_number_mask}); + } + return std::nullopt; + } + + auto page_table::entry::frame(struct frame frame, flags flags) noexcept -> void + { + m_raw = (frame.start_address().raw() | static_cast<std::uint64_t>(flags)); + }; + + auto page_table::operator[](std::size_t index) -> entry & + { + return m_entries.at(index); + } + + auto page_table::operator[](std::size_t index) const -> entry const & + { + return m_entries.at(index); + } + + auto page_table::clear() noexcept -> void + { + std::ranges::for_each(m_entries, &page_table::entry::clear); + } + + auto page_table::empty() const noexcept -> bool + { + return std::ranges::all_of(m_entries, + [](auto const & entry) -> auto { return entry.all_flags() == entry::flags::empty; }); + } + +} // namespace teachos::memory::x86_64 |
