From a20045fb209edc1e338039c28634c942e3113ea4 Mon Sep 17 00:00:00 2001 From: Lukas Oesch Date: Mon, 16 Mar 2026 21:06:12 +0100 Subject: Protect boot modules in region_allocator --- arch/x86_64/src/memory/region_allocator.cpp | 43 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp index facb1f2..2690a7c 100644 --- a/arch/x86_64/src/memory/region_allocator.cpp +++ b/arch/x86_64/src/memory/region_allocator.cpp @@ -35,7 +35,7 @@ namespace arch::memory , m_kernel_end{kapi::memory::frame::containing(mem_info.image_range.second)} , m_multiboot_start{kapi::memory::frame::containing(mem_info.mbi_range.first)} , m_multiboot_end{kapi::memory::frame::containing(mem_info.mbi_range.second)} - // TODO BA-FS26: Protect MB2 boot modules + , m_multiboot_information{mem_info.mbi} { choose_next_region(); } @@ -76,19 +76,40 @@ namespace arch::memory } } - if (falls_within(m_next_frame, m_kernel_start, m_kernel_end)) + auto advanced = true; + while (advanced) { - m_next_frame = m_kernel_end + 1; - } + advanced = false; - if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end)) - { - m_next_frame = m_multiboot_end + 1; - } + if (falls_within(m_next_frame, m_kernel_start, m_kernel_end)) + { + m_next_frame = m_kernel_end + 1; + advanced = true; + break; + } - if (falls_within(m_next_frame, m_kernel_start, m_kernel_end)) - { - m_next_frame = m_kernel_end + 1; + if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end)) + { + m_next_frame = m_multiboot_end + 1; + advanced = true; + break; + } + + if (m_multiboot_information) + { + for (auto const & module : m_multiboot_information->modules()) + { + auto module_start = kapi::memory::frame::containing(kapi::memory::physical_address{module.start_address}); + auto module_end = kapi::memory::frame::containing(kapi::memory::physical_address{module.end_address}); + + if (falls_within(m_next_frame, module_start, module_end)) + { + m_next_frame = module_end + 1; + advanced = true; + break; + } + } + } } if (m_next_frame > last_frame(*m_current_region)) -- cgit v1.2.3 From 1f8cc6683f4e2ef2e311078f48a1b4477dadaaec Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 17 Mar 2026 22:21:33 +0100 Subject: x86_64/memory: fix region allocator logic --- arch/x86_64/src/memory/region_allocator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp index 2690a7c..4ee3ca4 100644 --- a/arch/x86_64/src/memory/region_allocator.cpp +++ b/arch/x86_64/src/memory/region_allocator.cpp @@ -85,14 +85,14 @@ namespace arch::memory { m_next_frame = m_kernel_end + 1; advanced = true; - break; + continue; } if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end)) { m_next_frame = m_multiboot_end + 1; advanced = true; - break; + continue; } if (m_multiboot_information) -- cgit v1.2.3 From 12c0586ee15cadfa178e6982dc0f76b047cb2df9 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Mar 2026 15:24:26 +0100 Subject: kapi/memory: remove page/frame size macros --- arch/x86_64/src/memory/kernel_mapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/kernel_mapper.cpp b/arch/x86_64/src/memory/kernel_mapper.cpp index 08c32c5..e5bb7f8 100644 --- a/arch/x86_64/src/memory/kernel_mapper.cpp +++ b/arch/x86_64/src/memory/kernel_mapper.cpp @@ -71,7 +71,7 @@ namespace arch::memory auto kernel_mapper::map_section(section_header_type const & section, std::string_view name, kapi::memory::page_mapper & mapper) -> void { - auto number_of_pages = (section.size + (PLATFORM_PAGE_SIZE - 1)) / PLATFORM_PAGE_SIZE; + auto number_of_pages = (section.size + (kapi::memory::page::size - 1)) / kapi::memory::page::size; auto linear_start_address = kapi::memory::linear_address{section.virtual_load_address}; auto physical_start_address = kapi::memory::physical_address{section.virtual_load_address & ~m_kernel_load_base}; -- cgit v1.2.3 From e7ccb96aecae7b231fb05818d7e45a767aebc31d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Mar 2026 17:18:37 +0100 Subject: kstd: introduce strong type for memory amounts --- arch/x86_64/src/memory/kernel_mapper.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/kernel_mapper.cpp b/arch/x86_64/src/memory/kernel_mapper.cpp index e5bb7f8..ced8a14 100644 --- a/arch/x86_64/src/memory/kernel_mapper.cpp +++ b/arch/x86_64/src/memory/kernel_mapper.cpp @@ -6,6 +6,7 @@ #include "arch/boot/ld.hpp" #include +#include #include #include @@ -19,13 +20,14 @@ #include #include +using namespace std::string_view_literals; +using namespace kstd::units_literals; + namespace arch::memory { namespace { - using namespace std::string_view_literals; - constexpr auto static ignored_section_prefixes = std::array{ ".boot_"sv, }; @@ -71,7 +73,8 @@ namespace arch::memory auto kernel_mapper::map_section(section_header_type const & section, std::string_view name, kapi::memory::page_mapper & mapper) -> void { - auto number_of_pages = (section.size + (kapi::memory::page::size - 1)) / kapi::memory::page::size; + auto number_of_pages = + (kstd::units::bytes{section.size} + (kapi::memory::page::size - 1_B)) / kapi::memory::page::size; auto linear_start_address = kapi::memory::linear_address{section.virtual_load_address}; auto physical_start_address = kapi::memory::physical_address{section.virtual_load_address & ~m_kernel_load_base}; -- cgit v1.2.3 From 2d8fed40bd0d0f8144783b6b344dc79944291b72 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 13:31:17 +0200 Subject: chore: organize includes --- arch/x86_64/src/memory/higher_half_mapper.cpp | 6 +++--- arch/x86_64/src/memory/kernel_mapper.cpp | 7 ++++--- arch/x86_64/src/memory/mmu.cpp | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/higher_half_mapper.cpp b/arch/x86_64/src/memory/higher_half_mapper.cpp index abb54a3..b0d1995 100644 --- a/arch/x86_64/src/memory/higher_half_mapper.cpp +++ b/arch/x86_64/src/memory/higher_half_mapper.cpp @@ -1,11 +1,11 @@ #include "arch/memory/higher_half_mapper.hpp" -#include "kapi/memory.hpp" -#include "kapi/system.hpp" - #include "arch/memory/page_table.hpp" #include "arch/memory/page_utilities.hpp" +#include "kapi/memory.hpp" +#include "kapi/system.hpp" + #include #include #include diff --git a/arch/x86_64/src/memory/kernel_mapper.cpp b/arch/x86_64/src/memory/kernel_mapper.cpp index ced8a14..46d4dca 100644 --- a/arch/x86_64/src/memory/kernel_mapper.cpp +++ b/arch/x86_64/src/memory/kernel_mapper.cpp @@ -1,15 +1,16 @@ #include "arch/memory/kernel_mapper.hpp" +#include "arch/boot/ld.hpp" + #include "kapi/memory.hpp" #include "kapi/system.hpp" -#include "arch/boot/ld.hpp" +#include +#include #include #include -#include -#include #include #include diff --git a/arch/x86_64/src/memory/mmu.cpp b/arch/x86_64/src/memory/mmu.cpp index ea23278..6d185a0 100644 --- a/arch/x86_64/src/memory/mmu.cpp +++ b/arch/x86_64/src/memory/mmu.cpp @@ -1,9 +1,9 @@ #include "arch/memory/mmu.hpp" -#include "kapi/memory.hpp" - #include "arch/cpu/registers.hpp" +#include "kapi/memory.hpp" + namespace arch::memory { auto tlb_flush(kapi::memory::linear_address address) -> void -- cgit v1.2.3 From f6f10575f75ac23d06e1d94f7861611503daa7af Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 23 Apr 2026 14:03:28 +0200 Subject: chore: banish relative includes --- arch/x86_64/src/memory/higher_half_mapper.cpp | 10 +++++----- arch/x86_64/src/memory/kernel_mapper.cpp | 8 ++++---- arch/x86_64/src/memory/mmu.cpp | 6 +++--- arch/x86_64/src/memory/page_table.cpp | 4 ++-- arch/x86_64/src/memory/region_allocator.cpp | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) (limited to 'arch/x86_64/src/memory') diff --git a/arch/x86_64/src/memory/higher_half_mapper.cpp b/arch/x86_64/src/memory/higher_half_mapper.cpp index b0d1995..75adb3c 100644 --- a/arch/x86_64/src/memory/higher_half_mapper.cpp +++ b/arch/x86_64/src/memory/higher_half_mapper.cpp @@ -1,10 +1,10 @@ -#include "arch/memory/higher_half_mapper.hpp" +#include -#include "arch/memory/page_table.hpp" -#include "arch/memory/page_utilities.hpp" +#include +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/arch/x86_64/src/memory/kernel_mapper.cpp b/arch/x86_64/src/memory/kernel_mapper.cpp index 46d4dca..74272a0 100644 --- a/arch/x86_64/src/memory/kernel_mapper.cpp +++ b/arch/x86_64/src/memory/kernel_mapper.cpp @@ -1,9 +1,9 @@ -#include "arch/memory/kernel_mapper.hpp" +#include -#include "arch/boot/ld.hpp" +#include -#include "kapi/memory.hpp" -#include "kapi/system.hpp" +#include +#include #include #include diff --git a/arch/x86_64/src/memory/mmu.cpp b/arch/x86_64/src/memory/mmu.cpp index 6d185a0..2b53fa4 100644 --- a/arch/x86_64/src/memory/mmu.cpp +++ b/arch/x86_64/src/memory/mmu.cpp @@ -1,8 +1,8 @@ -#include "arch/memory/mmu.hpp" +#include -#include "arch/cpu/registers.hpp" +#include -#include "kapi/memory.hpp" +#include namespace arch::memory { diff --git a/arch/x86_64/src/memory/page_table.cpp b/arch/x86_64/src/memory/page_table.cpp index 26cdd29..2180420 100644 --- a/arch/x86_64/src/memory/page_table.cpp +++ b/arch/x86_64/src/memory/page_table.cpp @@ -1,6 +1,6 @@ -#include "arch/memory/page_table.hpp" +#include -#include "kapi/memory.hpp" +#include #include #include diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp index 4ee3ca4..4086a10 100644 --- a/arch/x86_64/src/memory/region_allocator.cpp +++ b/arch/x86_64/src/memory/region_allocator.cpp @@ -1,7 +1,7 @@ -#include "arch/memory/region_allocator.hpp" +#include -#include "kapi/memory/address.hpp" -#include "kapi/memory/frame.hpp" +#include +#include #include -- cgit v1.2.3 From 1b964278762dde86b0b737bd9a34fec569339f54 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Thu, 16 Apr 2026 10:29:30 +0200 Subject: x86_64: use p1204 project layout --- arch/x86_64/src/memory/higher_half_mapper.cpp | 119 ------------------- arch/x86_64/src/memory/kernel_mapper.cpp | 117 ------------------ arch/x86_64/src/memory/mmu.cpp | 19 --- arch/x86_64/src/memory/page_table.cpp | 82 ------------- arch/x86_64/src/memory/region_allocator.cpp | 165 -------------------------- 5 files changed, 502 deletions(-) delete mode 100644 arch/x86_64/src/memory/higher_half_mapper.cpp delete mode 100644 arch/x86_64/src/memory/kernel_mapper.cpp delete mode 100644 arch/x86_64/src/memory/mmu.cpp delete mode 100644 arch/x86_64/src/memory/page_table.cpp delete 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/higher_half_mapper.cpp b/arch/x86_64/src/memory/higher_half_mapper.cpp deleted file mode 100644 index 75adb3c..0000000 --- a/arch/x86_64/src/memory/higher_half_mapper.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace arch::memory -{ - - higher_half_mapper::higher_half_mapper(page_table * root) - : m_root{root} - {} - - auto higher_half_mapper::map(kapi::memory::page page, kapi::memory::frame frame, flags flags) -> std::byte * - { - auto table = get_or_create_page_table(page); - if (!table) - { - return nullptr; - } - - auto const index = pml_index(1, page); - auto & entry = (*table)[index]; - - if (entry.present()) - { - kapi::system::panic("[x86_64:MEM] Tried to map a page that is already mapped!"); - } - - entry.frame(frame, to_table_flags(flags) | page_table::entry::flags::present); - - return static_cast(page.start_address()); - } - - auto higher_half_mapper::unmap(kapi::memory::page page) -> void - { - if (!try_unmap(page)) - { - kapi::system::panic("[x86_64:MEM] Tried to unmap a page that is not mapped!"); - } - } - - auto higher_half_mapper::try_unmap(kapi::memory::page page) noexcept -> bool - { - auto table_path = std::array, 4>{}; - table_path[0] = std::pair{m_root, pml_index(4, page)}; - - for (auto level = 4uz; level > 1uz; --level) - { - auto [table, index] = table_path[4 - level]; - auto & entry = (*table)[index]; - - if (!entry.present()) - { - return false; - } - - auto next_table = to_higher_half_pointer(entry.frame()->start_address()); - auto next_index = pml_index(4 - level - 1, page); - table_path[4 - level - 1] = std::pair{next_table, next_index}; - } - - std::ranges::for_each(std::views::reverse(table_path), [previous_was_empty = true](auto & step) mutable { - auto [table, index] = step; - auto & entry = (*table)[index]; - auto frame = entry.frame(); - - if (previous_was_empty) - { - entry.clear(); - previous_was_empty = table->empty(); - kapi::memory::get_frame_allocator().release(*frame); - } - }); - - return true; - } - - auto higher_half_mapper::get_or_create_page_table(kapi::memory::page page) noexcept -> page_table * - { - auto table = m_root; - - for (auto level = 4uz; level > 1uz; --level) - { - auto index = pml_index(level, page); - auto & entry = (*table)[index]; - - if (!entry.present()) - { - auto table_frame = kapi::memory::allocate_frame(); - if (!table_frame) - { - return nullptr; - } - - auto new_table = to_higher_half_pointer(table_frame->start_address()); - std::construct_at(new_table); - - auto const flags = page_table::entry::flags::present | page_table::entry::flags::writable | - page_table::entry::flags::user_accessible; - entry.frame(*table_frame, flags); - } - - table = to_higher_half_pointer(entry.frame()->start_address()); - } - - return table; - } - -} // namespace arch::memory \ No newline at end of file diff --git a/arch/x86_64/src/memory/kernel_mapper.cpp b/arch/x86_64/src/memory/kernel_mapper.cpp deleted file mode 100644 index 74272a0..0000000 --- a/arch/x86_64/src/memory/kernel_mapper.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include - -#include - -#include -#include - -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -using namespace std::string_view_literals; -using namespace kstd::units_literals; - -namespace arch::memory -{ - - namespace - { - constexpr auto static ignored_section_prefixes = std::array{ - ".boot_"sv, - }; - - constexpr auto static user_accessible_prefixes = std::array{ - ".user"sv, - ".stl"sv, - }; - - } // namespace - - kernel_mapper::kernel_mapper(multiboot2::information_view const * mbi) - : m_mbi{std::move(mbi)} - , m_kernel_load_base{std::bit_cast(&arch::boot::TEACHOS_VMA)} - {} - - auto kernel_mapper::remap_kernel(kapi::memory::page_mapper & mapper) -> void - { - auto elf_information = m_mbi->maybe_elf_symbols(); - if (!elf_information) - { - kapi::system::panic("[x86_64:MEM] ELF section information is not available."); - } - - auto sections = *elf_information; - auto allocated_sections = - std::views::all(sections) | std::views::filter(&elf::section_header::allocated) | - std::views::filter([&](auto const & section) -> auto { - auto name = sections.name(section); - return !std::ranges::any_of(ignored_section_prefixes, - [&](auto const & prefix) -> auto { return name.starts_with(prefix); }); - }); - - if (allocated_sections.empty()) - { - kapi::system::panic("[x86_64:MEM] No allocated ELF sections were found."); - } - - std::ranges::for_each(allocated_sections, - [&](auto const & section) -> auto { map_section(section, sections.name(section), mapper); }); - } - - auto kernel_mapper::map_section(section_header_type const & section, std::string_view name, - kapi::memory::page_mapper & mapper) -> void - { - auto number_of_pages = - (kstd::units::bytes{section.size} + (kapi::memory::page::size - 1_B)) / kapi::memory::page::size; - auto linear_start_address = kapi::memory::linear_address{section.virtual_load_address}; - auto physical_start_address = kapi::memory::physical_address{section.virtual_load_address & ~m_kernel_load_base}; - - kstd::println("[x86_64:MEM] mapping {}" - "\n {} bytes -> page count: {}" - "\n {} @ {}", - name, section.size, number_of_pages, linear_start_address, physical_start_address); - - auto first_page = kapi::memory::page::containing(linear_start_address); - auto first_frame = kapi::memory::frame::containing(physical_start_address); - - auto page_flags = kapi::memory::page_mapper::flags::empty; - - if (section.writable()) - { - page_flags |= kapi::memory::page_mapper::flags::writable; - } - - if (section.executable()) - { - page_flags |= kapi::memory::page_mapper::flags::executable; - } - - auto is_prefix_of_name = [=](auto prefix) -> bool { - return name.starts_with(prefix); - }; - - if (!std::ranges::any_of(user_accessible_prefixes, is_prefix_of_name)) - { - page_flags |= kapi::memory::page_mapper::flags::supervisor_only; - } - - for (auto i = 0uz; i < number_of_pages; ++i) - { - mapper.map(first_page + i, first_frame + i, page_flags); - } - } - -} // namespace arch::memory \ No newline at end of file diff --git a/arch/x86_64/src/memory/mmu.cpp b/arch/x86_64/src/memory/mmu.cpp deleted file mode 100644 index 2b53fa4..0000000 --- a/arch/x86_64/src/memory/mmu.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#include - -#include - -namespace arch::memory -{ - auto tlb_flush(kapi::memory::linear_address address) -> void - { - asm volatile("invlpg (%[input])" : /* no output from call */ : [input] "r"(address) : "memory"); - } - - auto tlb_flush_all() -> void - { - auto paging_root = cpu::cr3::read(); - cpu::cr3::write(paging_root); - } -} // namespace arch::memory diff --git a/arch/x86_64/src/memory/page_table.cpp b/arch/x86_64/src/memory/page_table.cpp deleted file mode 100644 index 2180420..0000000 --- a/arch/x86_64/src/memory/page_table.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace arch::memory -{ - - 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(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 - { - if (present()) - { - return kapi::memory::frame::containing(kapi::memory::physical_address{m_raw & frame_number_mask}); - } - return std::nullopt; - } - - auto page_table::entry::frame(kapi::memory::frame frame, flags flags) noexcept -> void - { - m_raw = (frame.start_address().raw() | static_cast(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 arch::memory diff --git a/arch/x86_64/src/memory/region_allocator.cpp b/arch/x86_64/src/memory/region_allocator.cpp deleted file mode 100644 index 4086a10..0000000 --- a/arch/x86_64/src/memory/region_allocator.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include - -namespace arch::memory -{ - namespace - { - constexpr auto last_frame(multiboot2::memory_map::region const & region) - { - return kapi::memory::frame::containing(kapi::memory::physical_address{region.base + region.size_in_B - 1}); - } - - constexpr auto falls_within(kapi::memory::frame const & candidate, kapi::memory::frame const & start, - kapi::memory::frame const & end) - { - return candidate >= start && candidate <= end; - } - } // namespace - - region_allocator::region_allocator(memory_information const & mem_info) - : m_next_frame{} - , m_current_region{} - , m_memory_map{mem_info.memory_map} - , m_kernel_start{kapi::memory::frame::containing(mem_info.image_range.first)} - , m_kernel_end{kapi::memory::frame::containing(mem_info.image_range.second)} - , m_multiboot_start{kapi::memory::frame::containing(mem_info.mbi_range.first)} - , m_multiboot_end{kapi::memory::frame::containing(mem_info.mbi_range.second)} - , m_multiboot_information{mem_info.mbi} - { - choose_next_region(); - } - - auto region_allocator::choose_next_region() -> void - { - m_current_region.reset(); - - auto remaining_regions = - m_memory_map | // - std::views::filter(&multiboot2::memory_map::region::available) | - std::views::filter([this](auto const & region) -> bool { return last_frame(region) >= m_next_frame; }); - - auto lowest_region = - std::ranges::min_element(remaining_regions, [](auto lhs, auto rhs) -> bool { return lhs.base < rhs.base; }); - - if (lowest_region == remaining_regions.end()) - { - return; - } - - m_current_region = *lowest_region; - if (auto start_of_region = kapi::memory::frame::containing(kapi::memory::physical_address{m_current_region->base}); - start_of_region > m_next_frame) - { - m_next_frame = start_of_region; - } - } - - auto region_allocator::find_next_frame() -> std::optional - { - if (!m_current_region || m_next_frame > last_frame(*m_current_region)) - { - choose_next_region(); - if (!m_current_region) - { - return std::nullopt; - } - } - - auto advanced = true; - while (advanced) - { - advanced = false; - - if (falls_within(m_next_frame, m_kernel_start, m_kernel_end)) - { - m_next_frame = m_kernel_end + 1; - advanced = true; - continue; - } - - if (falls_within(m_next_frame, m_multiboot_start, m_multiboot_end)) - { - m_next_frame = m_multiboot_end + 1; - advanced = true; - continue; - } - - if (m_multiboot_information) - { - for (auto const & module : m_multiboot_information->modules()) - { - auto module_start = kapi::memory::frame::containing(kapi::memory::physical_address{module.start_address}); - auto module_end = kapi::memory::frame::containing(kapi::memory::physical_address{module.end_address}); - - if (falls_within(m_next_frame, module_start, module_end)) - { - m_next_frame = module_end + 1; - advanced = true; - break; - } - } - } - } - - if (m_next_frame > last_frame(*m_current_region)) - { - choose_next_region(); - } - - return m_current_region.transform([this](auto) -> auto { return m_next_frame; }); - } - - auto region_allocator::allocate_many(std::size_t count) noexcept - -> std::optional> - { - while (m_current_region) - { - auto result = find_next_frame(); - - if (result) - { - auto region_end = last_frame(*m_current_region); - if ((region_end.number() - result->number()) >= count) - { - m_next_frame = m_next_frame + count; - return std::make_pair(*result, count); - } - else - { - m_next_frame = region_end + 1; - choose_next_region(); - } - } - } - - return std::nullopt; - } - - auto region_allocator::mark_used(kapi::memory::frame frame) -> void - { - if (frame < m_next_frame) - { - m_next_frame = frame; - find_next_frame(); - } - } - - auto region_allocator::release_many(std::pair) -> void {} - - auto region_allocator::next_free_frame() noexcept -> std::optional - { - return find_next_frame(); - } - -} // namespace arch::memory -- cgit v1.2.3