mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-27 06:27:03 +02:00
Use managarm special fastmem fallback
This commit is contained in:
parent
0d736d49d6
commit
b4d55ee1f3
2 changed files with 62 additions and 13 deletions
|
|
@ -32,6 +32,8 @@
|
||||||
#include <mach/mach.h>
|
#include <mach/mach.h>
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
#elif defined(__OPENORBIS__)
|
||||||
|
#include <orbis/libkernel.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FreeBSD
|
// FreeBSD
|
||||||
|
|
@ -391,6 +393,9 @@ private:
|
||||||
ankerl::unordered_dense::map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
|
ankerl::unordered_dense::map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#elif defined(__OPENORBIS__) || defined(__managarm__)
|
||||||
|
// None of the luxuries of POSIX, all of the suffering
|
||||||
|
// For managarm: see https://github.com/managarm/managarm/issues/1370
|
||||||
#else // ^^^ Windows ^^^ vvv POSIX vvv
|
#else // ^^^ Windows ^^^ vvv POSIX vvv
|
||||||
|
|
||||||
#ifdef ARCHITECTURE_arm64
|
#ifdef ARCHITECTURE_arm64
|
||||||
|
|
@ -507,7 +512,7 @@ public:
|
||||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
fd = shm_open(SHM_ANON, O_RDWR, 0600);
|
fd = shm_open(SHM_ANON, O_RDWR, 0600);
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__) || defined(__managarm__)
|
||||||
// macOS doesn't have memfd_create, use anonymous temporary file
|
// macOS doesn't have memfd_create, use anonymous temporary file
|
||||||
char template_path[] = "/tmp/eden_mem_XXXXXX";
|
char template_path[] = "/tmp/eden_mem_XXXXXX";
|
||||||
fd = mkstemp(template_path);
|
fd = mkstemp(template_path);
|
||||||
|
|
@ -669,17 +674,47 @@ private:
|
||||||
|
|
||||||
#endif // ^^^ POSIX ^^^
|
#endif // ^^^ POSIX ^^^
|
||||||
|
|
||||||
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_) : backing_size(backing_size_), virtual_size(virtual_size_) {
|
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
||||||
// Try to allocate a fastmem arena.
|
: backing_size(backing_size_)
|
||||||
// The implementation will fail with std::bad_alloc on errors.
|
, virtual_size(virtual_size_)
|
||||||
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
|
{
|
||||||
backing_base = impl->backing_base;
|
#if defined(__OPENORBIS__) || defined(__managarm__)
|
||||||
virtual_base = impl->virtual_base;
|
LOG_WARNING(HW_Memory, "Platform doesn't support fastmem");
|
||||||
if (virtual_base) {
|
fallback_buffer.emplace(backing_size);
|
||||||
// Ensure the virtual base is aligned to the L2 block size.
|
backing_base = fallback_buffer->data();
|
||||||
virtual_base = reinterpret_cast<u8*>(Common::AlignUp(uintptr_t(virtual_base), HugePageSize));
|
virtual_base = nullptr;
|
||||||
virtual_base_offset = virtual_base - impl->virtual_base;
|
#else
|
||||||
|
bool has_memfd = true; // all platforms support it
|
||||||
|
#ifdef _WIN32
|
||||||
|
// EXCEPT WINDOWS who may not (Windows 8.1, 7, Vista, etc)
|
||||||
|
DynamicLibrary kernelbase_dll("KernelBase");
|
||||||
|
has_memfd = kernelbase_dll.IsOpen();
|
||||||
|
if (has_memfd) {
|
||||||
|
PFN_CreateFileMapping2 p{};
|
||||||
|
GetFuncAddress(kernelbase_dll, "CreateFileMapping2", p);
|
||||||
|
has_memfd = p != nullptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if (has_memfd) {
|
||||||
|
// Try to allocate a fastmem arena.
|
||||||
|
// The implementation will fail with std::bad_alloc on errors.
|
||||||
|
impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment), AlignUp(virtual_size, PageAlignment) + HugePageSize);
|
||||||
|
backing_base = impl->backing_base;
|
||||||
|
virtual_base = impl->virtual_base;
|
||||||
|
if (virtual_base) {
|
||||||
|
// Ensure the virtual base is aligned to the L2 block size.
|
||||||
|
virtual_base = reinterpret_cast<u8*>(Common::AlignUp(uintptr_t(virtual_base), HugePageSize));
|
||||||
|
virtual_base_offset = virtual_base - impl->virtual_base;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG_WARNING(HW_Memory, "Platform doesn't support fastmem");
|
||||||
|
#ifdef _WIN32
|
||||||
|
fallback_buffer.emplace(backing_size);
|
||||||
|
backing_base = fallback_buffer->data();
|
||||||
|
virtual_base = nullptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
HostMemory::~HostMemory() = default;
|
HostMemory::~HostMemory() = default;
|
||||||
|
|
@ -688,8 +723,8 @@ HostMemory::HostMemory(HostMemory&&) noexcept = default;
|
||||||
|
|
||||||
HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default;
|
HostMemory& HostMemory::operator=(HostMemory&&) noexcept = default;
|
||||||
|
|
||||||
void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms, bool separate_heap) {
|
||||||
MemoryPermission perms, bool separate_heap) {
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
ASSERT(virtual_offset % PageAlignment == 0);
|
ASSERT(virtual_offset % PageAlignment == 0);
|
||||||
ASSERT(host_offset % PageAlignment == 0);
|
ASSERT(host_offset % PageAlignment == 0);
|
||||||
ASSERT(length % PageAlignment == 0);
|
ASSERT(length % PageAlignment == 0);
|
||||||
|
|
@ -699,9 +734,11 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
|
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
|
void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap) {
|
||||||
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
ASSERT(virtual_offset % PageAlignment == 0);
|
ASSERT(virtual_offset % PageAlignment == 0);
|
||||||
ASSERT(length % PageAlignment == 0);
|
ASSERT(length % PageAlignment == 0);
|
||||||
ASSERT(virtual_offset + length <= virtual_size);
|
ASSERT(virtual_offset + length <= virtual_size);
|
||||||
|
|
@ -709,9 +746,11 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
impl->Unmap(virtual_offset + virtual_base_offset, length);
|
impl->Unmap(virtual_offset + virtual_base_offset, length);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission perm) {
|
void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission perm) {
|
||||||
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
ASSERT(virtual_offset % PageAlignment == 0);
|
ASSERT(virtual_offset % PageAlignment == 0);
|
||||||
ASSERT(length % PageAlignment == 0);
|
ASSERT(length % PageAlignment == 0);
|
||||||
ASSERT(virtual_offset + length <= virtual_size);
|
ASSERT(virtual_offset + length <= virtual_size);
|
||||||
|
|
@ -722,6 +761,7 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission
|
||||||
const bool write = True(perm & MemoryPermission::Write);
|
const bool write = True(perm & MemoryPermission::Write);
|
||||||
const bool execute = True(perm & MemoryPermission::Execute);
|
const bool execute = True(perm & MemoryPermission::Execute);
|
||||||
impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute);
|
impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) {
|
void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) {
|
||||||
|
|
@ -729,10 +769,12 @@ void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 f
|
||||||
}
|
}
|
||||||
|
|
||||||
void HostMemory::EnableDirectMappedAddress() {
|
void HostMemory::EnableDirectMappedAddress() {
|
||||||
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
if (impl) {
|
if (impl) {
|
||||||
impl->EnableDirectMappedAddress();
|
impl->EnableDirectMappedAddress();
|
||||||
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
|
virtual_size += reinterpret_cast<uintptr_t>(virtual_base);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/virtual_buffer.h"
|
#include "common/virtual_buffer.h"
|
||||||
|
|
@ -76,12 +77,18 @@ private:
|
||||||
size_t backing_size{};
|
size_t backing_size{};
|
||||||
size_t virtual_size{};
|
size_t virtual_size{};
|
||||||
|
|
||||||
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
||||||
// Low level handler for the platform dependent memory routines
|
// Low level handler for the platform dependent memory routines
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
|
#endif
|
||||||
u8* backing_base{};
|
u8* backing_base{};
|
||||||
u8* virtual_base{};
|
u8* virtual_base{};
|
||||||
size_t virtual_base_offset{};
|
size_t virtual_base_offset{};
|
||||||
|
// Windows requires it for kernels whom lack proper support for some functions!
|
||||||
|
#if defined(__OPENORBIS__) || defined(__managarm__) || defined(_WIN32)
|
||||||
|
std::optional<Common::VirtualBuffer<u8>> fallback_buffer;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue