rpcsx/kernel/orbis/src/fmem.cpp

87 lines
2.4 KiB
C++
Raw Normal View History

#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 <cassert>
#include <rx/Mappable.hpp>
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<FlexibleMemoryAllocation, orbis::kallocator>;
static auto g_fmemInstance = orbis::createGlobalObject<
kernel::LockableKernelObject<FlexibleMemoryResource>>();
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<rx::AddressRange, orbis::ErrorCode>
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{}) {
2025-11-30 18:38:19 +01:00
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);
}