#include "fmem.hpp" #include "KernelAllocator.hpp" #include "KernelObject.hpp" #include "error.hpp" #include "kernel/KernelObject.hpp" #include "kernel/MemoryResource.hpp" #include "pmem.hpp" #include "rx/AddressRange.hpp" #include "rx/debug.hpp" #include "rx/print.hpp" #include "vmem.hpp" #include #include struct FlexibleMemoryAllocation { bool allocated = false; [[nodiscard]] bool isAllocated() const { return allocated; } [[nodiscard]] bool isRelated(const FlexibleMemoryAllocation &, rx::AddressRange, rx::AddressRange) const { return true; } [[nodiscard]] FlexibleMemoryAllocation merge(const FlexibleMemoryAllocation &other, rx::AddressRange, rx::AddressRange) const { return other; } bool operator==(const FlexibleMemoryAllocation &) const = default; }; using FlexibleMemoryResource = kernel::AllocableResource; static auto g_fmemInstance = orbis::createGlobalObject< kernel::LockableKernelObject>(); orbis::ErrorCode orbis::fmem::initialize(std::uint64_t size) { auto [range, errc] = pmem::allocate(0, size, kernel::AllocationFlags::Stack, vmem::kPageSize); if (errc != ErrorCode{}) { return errc; } rx::println("fmem: {:x}-{:x}", range.beginAddress(), range.endAddress()); std::lock_guard lock(*g_fmemInstance); return toErrorCode(g_fmemInstance->create(range)); } void orbis::fmem::destroy() { std::lock_guard lock(*g_fmemInstance); for (auto allocation : g_fmemInstance->allocations) { pmem::deallocate(allocation); } g_fmemInstance->destroy(); } std::pair orbis::fmem::allocate(std::uint64_t size) { std::lock_guard lock(*g_fmemInstance); FlexibleMemoryAllocation allocation{.allocated = true}; auto [it, errc, range] = g_fmemInstance->map( 0, size, allocation, kernel::AllocationFlags::NoMerge, vmem::kPageSize); if (errc != std::errc{}) { rx::println(stderr, "fmem: failed to allocate {:#x} bytes", size); return {{}, toErrorCode(errc)}; } return {range, {}}; } orbis::ErrorCode orbis::fmem::deallocate(rx::AddressRange range) { FlexibleMemoryAllocation allocation{}; std::lock_guard lock(*g_fmemInstance); auto [it, errc, _] = g_fmemInstance->map(range.beginAddress(), range.size(), allocation, AllocationFlags::Fixed, 1); return toErrorCode(errc); }