diff options
Diffstat (limited to 'kernel/kapi/memory.cpp')
| -rw-r--r-- | kernel/kapi/memory.cpp | 60 |
1 files changed, 52 insertions, 8 deletions
diff --git a/kernel/kapi/memory.cpp b/kernel/kapi/memory.cpp index d8065d4..5ea08b1 100644 --- a/kernel/kapi/memory.cpp +++ b/kernel/kapi/memory.cpp @@ -1,10 +1,12 @@ -#include "kapi/memory.hpp" +#include <kapi/memory.hpp> -#include "kapi/system.hpp" +#include <kernel/memory/bitmap_allocator.hpp> +#include <kernel/memory/mmio_allocator.hpp> -#include "kernel/memory/bitmap_allocator.hpp" +#include <kapi/system.hpp> #include <kstd/print> +#include <kstd/units> #include <algorithm> #include <cstddef> @@ -62,6 +64,7 @@ namespace kapi::memory constinit bad_frame_allocator bad_frame_allocator::instance{}; constinit bad_page_mapper bad_page_mapper::instance{}; auto constinit allocator = std::optional<kernel::memory::bitmap_frame_allocator>{}; + auto constinit mmio_allocator = std::optional<kernel::memory::mmio_allocator>{}; } // namespace constinit auto static active_frame_allocator = static_cast<frame_allocator *>(&bad_frame_allocator::instance); @@ -112,8 +115,10 @@ namespace kapi::memory auto init_pmm(std::size_t frame_count, void (&handoff_handler)(frame_allocator &)) -> void { - auto const bitmap_bytes = (frame_count + 7uz) / 8uz; - auto const bitmap_pages = (bitmap_bytes + page::size - 1uz) / page::size; + using namespace kstd::units_literals; + + auto const bitmap_bytes = kstd::units::bytes{(frame_count + 7uz) / 8uz}; + auto const bitmap_pages = (bitmap_bytes + page::size - 1_B) / page::size; auto const bitmap_frames = allocate_many_frames(bitmap_pages); if (!bitmap_frames) @@ -122,15 +127,20 @@ namespace kapi::memory } auto const flags = page_mapper::flags::writable | page_mapper::flags::supervisor_only | page_mapper::flags::global; + auto bitmap_ptr = static_cast<std::uint64_t *>(nullptr); std::ranges::for_each(std::views::iota(0uz, bitmap_pages), [&](auto index) { auto page = page::containing(pmm_metadata_base + index * page::size); auto frame = memory::frame(bitmap_frames->first.number() + index); - active_page_mapper->map(page, frame, flags); + auto mapped = active_page_mapper->map(page, frame, flags); + if (!bitmap_ptr) + { + bitmap_ptr = reinterpret_cast<std::uint64_t *>(mapped); + } }); - auto bitmap_ptr = static_cast<std::uint64_t *>(pmm_metadata_base); - auto bitmap = std::span{bitmap_ptr, (bitmap_bytes + sizeof(std::uint64_t) - 1uz) / sizeof(std::uint64_t)}; + auto bitmap = + std::span{bitmap_ptr, (bitmap_bytes + kstd::type_size<std::uint64_t> - 1_B) / kstd::type_size<std::uint64_t>}; allocator.emplace(bitmap, frame_count); @@ -139,4 +149,38 @@ namespace kapi::memory kstd::println("[OS:MEM] Physical memory manager initialized."); } + auto init_mmio(linear_address base, std::size_t page_count) -> void + { + mmio_allocator.emplace(base, page_count); + } + + auto allocate_mmio_region(std::size_t page_count) -> mmio_region + { + auto region = mmio_allocator->allocate(page_count); + return {region, page_count}; + } + + auto map_mmio_region(mmio_region region, physical_address hw_base, page_mapper::flags flags) -> std::byte * + { + auto start_page = page::containing(region.first); + auto start_frame = frame::containing(hw_base); + + flags |= page_mapper::flags::uncached; + + auto start = map(start_page, start_frame, flags); + + std::ranges::for_each(std::views::iota(1uz, region.second), [&](auto index) { + auto page = page::containing(region.first + index * page::size); + auto frame = frame::containing(hw_base + index * page::size); + map(page, frame, flags); + }); + + return start; + } + + auto release_mmio_region(mmio_region region) -> void + { + mmio_allocator->release(region.first); + } + } // namespace kapi::memory |
