aboutsummaryrefslogtreecommitdiff
path: root/arch/x86_64/src/memory
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-07-17 21:09:02 +0000
committerFelix Morgner <felix.morgner@ost.ch>2025-07-18 13:02:34 +0200
commit14ed096fc5de6844cb116f3319c0d03043d26ea2 (patch)
treee78cc753b2d6dcabd703aebc4b9bea1783cc2e6d /arch/x86_64/src/memory
parent891ca8834122e55638d33a129baab7292b8ed6d0 (diff)
downloadteachos-14ed096fc5de6844cb116f3319c0d03043d26ea2.tar.xz
teachos-14ed096fc5de6844cb116f3319c0d03043d26ea2.zip
x86-64: prepare new architecture
Diffstat (limited to 'arch/x86_64/src/memory')
-rw-r--r--arch/x86_64/src/memory/allocator/physical_frame.cpp24
-rw-r--r--arch/x86_64/src/memory/region_allocator.cpp95
2 files changed, 95 insertions, 24 deletions
diff --git a/arch/x86_64/src/memory/allocator/physical_frame.cpp b/arch/x86_64/src/memory/allocator/physical_frame.cpp
deleted file mode 100644
index ec387a1..0000000
--- a/arch/x86_64/src/memory/allocator/physical_frame.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "arch/memory/allocator/physical_frame.hpp"
-
-namespace teachos::arch::memory::allocator
-{
- auto physical_frame::containing_address(physical_address address) -> physical_frame
- {
- return physical_frame{address / PAGE_FRAME_SIZE};
- }
-
- auto physical_frame::start_address() const -> physical_address { return frame_number * PAGE_FRAME_SIZE; }
-
- auto physical_frame::operator++(int) -> physical_frame
- {
- physical_frame const old_value = *this;
- ++frame_number;
- return old_value;
- }
-
- auto physical_frame::operator++() -> physical_frame &
- {
- ++frame_number;
- return *this;
- }
-} // namespace teachos::arch::memory::allocator
diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp
new file mode 100644
index 0000000..c9a98b4
--- /dev/null
+++ b/arch/x86_64/src/memory/region_allocator.cpp
@@ -0,0 +1,95 @@
+// #include "arch/memory/allocator/region_allocator.hpp"
+
+// #include "arch/exception_handling/assert.hpp"
+
+// #include <algorithm>
+// #include <array>
+// #include <ranges>
+
+#include "x86_64/memory/region_allocator.hpp"
+
+#include "x86_64/memory/address.hpp"
+#include "x86_64/memory/frame.hpp"
+
+#include <multiboot2/information.hpp>
+
+#include <algorithm>
+#include <ranges>
+
+namespace teachos::x86_64::memory
+{
+ namespace
+ {
+ auto constexpr last_frame(multiboot2::memory_map::region const & region)
+ {
+ return frame::containing(physical_address{region.base + region.size_in_B - 1});
+ }
+ } // namespace
+
+ region_allocator::region_allocator(memory_information const & mem_info)
+ : m_next_frame{}
+ , m_current_region{}
+ , m_memory_map{}
+ , m_kernel_start(frame::containing(mem_info.image_range.first))
+ , m_kernel_end(frame::containing(mem_info.image_range.second))
+ , m_multiboot_start(frame::containing(mem_info.mbi_range.first))
+ , m_multiboot_end(frame::containing(mem_info.mbi_range.second))
+ {
+ choose_next_area();
+ }
+
+ auto region_allocator::choose_next_area() -> void
+ {
+ m_current_region.reset();
+ auto next_area_with_free_frames =
+ m_memory_map | std::views::filter(&multiboot2::memory_map::region::available) |
+ std::views::filter([next = m_next_frame](auto const & region) { return last_frame(region) >= next; });
+
+ auto lowest_region_with_free_frames =
+ std::ranges::min_element(next_area_with_free_frames, [](auto lhs, auto rhs) { return lhs.base < rhs.base; });
+
+ if (lowest_region_with_free_frames != next_area_with_free_frames.end())
+ {
+ m_current_region = *lowest_region_with_free_frames;
+ auto start_frame = frame::containing(physical_address{m_current_region->base});
+ if (m_next_frame < start_frame)
+ {
+ m_next_frame = start_frame;
+ }
+ }
+ }
+
+ auto region_allocator::allocate_frame() -> std::optional<frame>
+ {
+ if (!m_current_region)
+ {
+ return {};
+ }
+
+ auto const end_address = physical_address{m_current_region->base + m_current_region->size_in_B - 1};
+ auto end_frame = frame::containing(end_address);
+
+ if (m_next_frame > end_frame)
+ {
+ choose_next_area();
+ }
+ else if (m_next_frame >= m_kernel_start && m_next_frame <= m_kernel_end)
+ {
+ m_next_frame = m_kernel_end + 1;
+ }
+ else if (m_next_frame >= m_multiboot_start && m_next_frame <= m_multiboot_end)
+ {
+ m_next_frame = m_multiboot_end + 1;
+ }
+ else
+ {
+ auto allocated = m_next_frame;
+ ++m_next_frame;
+ return allocated;
+ }
+
+ return allocate_frame();
+ }
+
+ auto region_allocator::deallocate_frame(frame const &) -> void {}
+} // namespace teachos::x86_64::memory