aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/src')
-rw-r--r--arch/x86_64/src/kapi/memory.cpp10
-rw-r--r--arch/x86_64/src/memory/page_table.cpp57
-rw-r--r--arch/x86_64/src/memory/paging_root.cpp19
3 files changed, 82 insertions, 4 deletions
diff --git a/arch/x86_64/src/kapi/memory.cpp b/arch/x86_64/src/kapi/memory.cpp
index 3848fb8..99dcb5c 100644
--- a/arch/x86_64/src/kapi/memory.cpp
+++ b/arch/x86_64/src/kapi/memory.cpp
@@ -12,6 +12,7 @@
#include <multiboot2/information.hpp>
#include <atomic>
+#include <span>
namespace teachos::memory
{
@@ -25,11 +26,12 @@ namespace teachos::memory
auto create_memory_information() -> x86_64::region_allocator::memory_information
{
auto const & mbi = boot::bootstrap_information.mbi;
+ auto mbi_span = std::span{std::bit_cast<std::byte *>(mbi), mbi->size_bytes()};
+ auto image_span = std::span{&boot::x86_64::_start_physical, &boot::x86_64::_end_physical};
- return {.image_range = std::make_pair(physical_address{&boot::x86_64::_start_physical},
- physical_address{&boot::x86_64::_end_physical}),
- .mbi_range = std::make_pair(physical_address{std::bit_cast<std::byte *>(mbi)},
- physical_address{std::bit_cast<std::byte *>(mbi) + mbi->size_bytes()}),
+ return {.image_range =
+ std::make_pair(physical_address{&image_span.front()}, physical_address{&image_span.back()}),
+ .mbi_range = std::make_pair(physical_address{&mbi_span.front()}, physical_address{&mbi_span.back()}),
.memory_map = mbi->memory_map()};
};
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..c716c5c
--- /dev/null
+++ b/arch/x86_64/src/memory/page_table.cpp
@@ -0,0 +1,57 @@
+#include "x86_64/memory/page_table.hpp"
+
+#include <algorithm>
+
+namespace teachos::memory::x86_64
+{
+
+ auto page_table::entry::clear() -> void
+ {
+ m_raw = 0;
+ }
+
+ auto page_table::entry::present() const -> bool
+ {
+ return (flags() & flags::present) != flags::empty;
+ }
+
+ auto page_table::entry::huge() const -> bool
+ {
+ return (flags() & flags::huge_page) != flags::empty;
+ }
+
+ auto page_table::entry::all_flags() const -> flags
+ {
+ return std::bit_cast<flags>(m_raw & ~frame_number_mask);
+ }
+
+ auto page_table::entry::frame() const -> 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) -> 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() -> void
+ {
+ std::ranges::for_each(m_entries, &page_table::entry::clear);
+ }
+
+} // namespace teachos::memory::x86_64
diff --git a/arch/x86_64/src/memory/paging_root.cpp b/arch/x86_64/src/memory/paging_root.cpp
new file mode 100644
index 0000000..1234308
--- /dev/null
+++ b/arch/x86_64/src/memory/paging_root.cpp
@@ -0,0 +1,19 @@
+#include "x86_64/memory/paging_root.hpp"
+
+#include <cstdint>
+
+namespace teachos::memory::x86_64
+{
+
+ namespace
+ {
+ constexpr auto PML_RECURSIVE_BASE = std::uintptr_t{0177777'776'776'776'776'0000uz};
+ }
+
+ auto paging_root::get() -> paging_root &
+ {
+ auto pml4_address = std::bit_cast<paging_root *>(PML_RECURSIVE_BASE);
+ return *pml4_address;
+ }
+
+} // namespace teachos::memory::x86_64 \ No newline at end of file