2025-11-09 19:38:23 +01:00
|
|
|
#include "fmem.hpp"
|
|
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
#include "KernelAllocator.hpp"
|
2025-11-09 19:38:23 +01:00
|
|
|
#include "KernelObject.hpp"
|
|
|
|
|
#include "error.hpp"
|
|
|
|
|
#include "kernel/KernelObject.hpp"
|
|
|
|
|
#include "kernel/MemoryResource.hpp"
|
|
|
|
|
#include "pmem.hpp"
|
|
|
|
|
#include "rx/AddressRange.hpp"
|
2025-11-30 13:46:37 +01:00
|
|
|
#include "rx/debug.hpp"
|
|
|
|
|
#include "rx/print.hpp"
|
2025-11-09 19:38:23 +01:00
|
|
|
#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 =
|
2025-11-30 13:46:37 +01:00
|
|
|
kernel::AllocableResource<FlexibleMemoryAllocation, orbis::kallocator>;
|
2025-11-09 19:38:23 +01:00
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
static auto g_fmemInstance = orbis::createGlobalObject<
|
2025-11-09 19:38:23 +01:00
|
|
|
kernel::LockableKernelObject<FlexibleMemoryResource>>();
|
|
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
orbis::ErrorCode orbis::fmem::initialize(std::uint64_t size) {
|
2025-11-09 19:38:23 +01:00
|
|
|
auto [range, errc] =
|
2025-11-30 13:46:37 +01:00
|
|
|
pmem::allocate(0, size, kernel::AllocationFlags::Stack, vmem::kPageSize);
|
2025-11-09 19:38:23 +01:00
|
|
|
if (errc != ErrorCode{}) {
|
|
|
|
|
return errc;
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
rx::println("fmem: {:x}-{:x}", range.beginAddress(), range.endAddress());
|
2025-11-09 19:38:23 +01:00
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
std::lock_guard lock(*g_fmemInstance);
|
|
|
|
|
return toErrorCode(g_fmemInstance->create(range));
|
|
|
|
|
}
|
2025-11-09 19:38:23 +01:00
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
void orbis::fmem::destroy() {
|
|
|
|
|
std::lock_guard lock(*g_fmemInstance);
|
2025-11-09 19:38:23 +01:00
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
for (auto allocation : g_fmemInstance->allocations) {
|
2025-11-09 19:38:23 +01:00
|
|
|
pmem::deallocate(allocation);
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
g_fmemInstance->destroy();
|
2025-11-09 19:38:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<rx::AddressRange, orbis::ErrorCode>
|
2025-11-30 13:46:37 +01:00
|
|
|
orbis::fmem::allocate(std::uint64_t size) {
|
|
|
|
|
std::lock_guard lock(*g_fmemInstance);
|
2025-11-09 19:38:23 +01:00
|
|
|
FlexibleMemoryAllocation allocation{.allocated = true};
|
2025-11-30 13:46:37 +01:00
|
|
|
auto [it, errc, range] = g_fmemInstance->map(
|
2025-11-09 19:38:23 +01:00
|
|
|
0, size, allocation, kernel::AllocationFlags::NoMerge, vmem::kPageSize);
|
|
|
|
|
|
|
|
|
|
if (errc != std::errc{}) {
|
|
|
|
|
return {{}, toErrorCode(errc)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {range, {}};
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-30 13:46:37 +01:00
|
|
|
orbis::ErrorCode orbis::fmem::deallocate(rx::AddressRange range) {
|
2025-11-09 19:38:23 +01:00
|
|
|
FlexibleMemoryAllocation allocation{};
|
2025-11-30 13:46:37 +01:00
|
|
|
std::lock_guard lock(*g_fmemInstance);
|
|
|
|
|
auto [it, errc, _] =
|
|
|
|
|
g_fmemInstance->map(range.beginAddress(), range.size(), allocation,
|
|
|
|
|
AllocationFlags::Fixed, 1);
|
2025-11-09 19:38:23 +01:00
|
|
|
|
|
|
|
|
return toErrorCode(errc);
|
|
|
|
|
}
|