From 14ed096fc5de6844cb116f3319c0d03043d26ea2 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 17 Jul 2025 21:09:02 +0000 Subject: x86-64: prepare new architecture --- .../x86_64/src/memory/allocator/physical_frame.cpp | 24 ------ arch/x86_64/src/memory/region_allocator.cpp | 95 ++++++++++++++++++++++ 2 files changed, 95 insertions(+), 24 deletions(-) delete mode 100644 arch/x86_64/src/memory/allocator/physical_frame.cpp create mode 100644 arch/x86_64/src/memory/region_allocator.cpp (limited to 'arch/x86_64/src/memory') 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 +// #include +// #include + +#include "x86_64/memory/region_allocator.hpp" + +#include "x86_64/memory/address.hpp" +#include "x86_64/memory/frame.hpp" + +#include + +#include +#include + +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 + { + 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 -- cgit v1.2.3