aboutsummaryrefslogtreecommitdiff
path: root/kernel/kapi/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kapi/memory.cpp')
-rw-r--r--kernel/kapi/memory.cpp60
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