mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-03 11:23:49 +00:00
* Rework guest memory tracking * add unknwon flag * Fix macOS guest address-space reservation
195 lines
8.8 KiB
C++
195 lines
8.8 KiB
C++
#ifndef EMULATOR_INCLUDE_EMULATOR_KERNEL_MEMORY_H_
|
|
#define EMULATOR_INCLUDE_EMULATOR_KERNEL_MEMORY_H_
|
|
|
|
#include "common/abi.h"
|
|
#include "common/common.h"
|
|
#include "common/subsystems.h"
|
|
#include "common/virtualMemory.h"
|
|
|
|
namespace Libs::Graphics {
|
|
class GpuResourceManager;
|
|
enum class PageFaultAccess;
|
|
} // namespace Libs::Graphics
|
|
|
|
namespace Libs::LibKernel::Memory {
|
|
|
|
KYTY_SUBSYSTEM_DEFINE(Memory);
|
|
|
|
using callback_func_t = void (*)(uintptr_t addr, size_t size);
|
|
|
|
constexpr uint32_t KERNEL_MAXIMUM_NAME_LENGTH = 32;
|
|
|
|
struct VirtualQueryInfo {
|
|
uintptr_t start;
|
|
uintptr_t end;
|
|
uint64_t offset;
|
|
int32_t protection;
|
|
int32_t memory_type;
|
|
uint32_t is_flexible : 1;
|
|
uint32_t is_direct : 1;
|
|
uint32_t is_stack : 1;
|
|
uint32_t is_pooled : 1;
|
|
uint32_t is_committed : 1;
|
|
uint32_t is_gpu_prt : 1;
|
|
uint32_t amm_usage : 1;
|
|
uint32_t reserved : 1;
|
|
char name[KERNEL_MAXIMUM_NAME_LENGTH];
|
|
uint8_t gpu_mask_id;
|
|
uint8_t reserved2;
|
|
};
|
|
|
|
static_assert(sizeof(VirtualQueryInfo) == 72, "VirtualQueryInfo struct size is incorrect");
|
|
|
|
struct KernelBatchMapEntry {
|
|
void* start;
|
|
uint64_t offset;
|
|
uint64_t length;
|
|
char protection;
|
|
char type;
|
|
int16_t reserved;
|
|
int32_t operation;
|
|
};
|
|
|
|
static_assert(sizeof(KernelBatchMapEntry) == 32, "KernelBatchMapEntry struct size is incorrect");
|
|
|
|
struct KernelMemoryPoolBatchEntry {
|
|
uint32_t op;
|
|
uint32_t flags;
|
|
union {
|
|
struct {
|
|
void* addr;
|
|
uint64_t len;
|
|
uint8_t prot;
|
|
uint8_t type;
|
|
} commit;
|
|
struct {
|
|
void* addr;
|
|
uint64_t len;
|
|
} decommit;
|
|
struct {
|
|
void* addr;
|
|
uint64_t len;
|
|
uint8_t prot;
|
|
} protect;
|
|
struct {
|
|
void* addr;
|
|
uint64_t len;
|
|
uint8_t prot;
|
|
uint8_t type;
|
|
} type_protect;
|
|
struct {
|
|
void* dst;
|
|
void* src;
|
|
uint64_t len;
|
|
} move;
|
|
uintptr_t padding[3];
|
|
};
|
|
};
|
|
|
|
static_assert(sizeof(KernelMemoryPoolBatchEntry) == 32,
|
|
"KernelMemoryPoolBatchEntry struct size is incorrect");
|
|
|
|
struct KernelMemoryPoolBlockStats {
|
|
int32_t available_flushed_blocks;
|
|
int32_t available_cached_blocks;
|
|
int32_t allocated_flushed_blocks;
|
|
int32_t allocated_cached_blocks;
|
|
};
|
|
|
|
static_assert(sizeof(KernelMemoryPoolBlockStats) == 16,
|
|
"KernelMemoryPoolBlockStats struct size is incorrect");
|
|
|
|
void RegisterCallbacks(callback_func_t alloc_func, callback_func_t free_func);
|
|
void SetFlexibleMemorySize(uint64_t size);
|
|
bool TryWriteBacking(uint64_t vaddr, const void* data, uint64_t size);
|
|
bool TryReadBacking(uint64_t vaddr, void* data, uint64_t size);
|
|
[[nodiscard]] uint64_t ClampRangeSize(uint64_t vaddr, uint64_t size);
|
|
void WriteBacking(uint64_t vaddr, const void* data, uint64_t size) noexcept;
|
|
void InvalidateMemory(uint64_t vaddr, uint64_t size);
|
|
void InstallGpuResources(Graphics::GpuResourceManager* resources) noexcept;
|
|
[[nodiscard]] bool HandleGpuFault(Graphics::PageFaultAccess access, uint64_t fault_vaddr) noexcept;
|
|
|
|
int KYTY_SYSV_ABI KernelMapNamedFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags,
|
|
const char* name);
|
|
int KYTY_SYSV_ABI KernelMapFlexibleMemory(void** addr_in_out, size_t len, int prot, int flags);
|
|
int KYTY_SYSV_ABI KernelSetVirtualRangeName(const void* addr, uint64_t len, const char* name);
|
|
int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len);
|
|
size_t KYTY_SYSV_ABI KernelGetDirectMemorySize();
|
|
int KYTY_SYSV_ABI KernelAvailableDirectMemorySize(int64_t search_start, int64_t search_end,
|
|
size_t alignment, int64_t* phys_addr_out,
|
|
size_t* size_out);
|
|
int KYTY_SYSV_ABI KernelGetPageTableStats(int* cpu_total, int* cpu_available, int* gpu_total,
|
|
int* gpu_available);
|
|
int KYTY_SYSV_ABI KernelAllocateDirectMemory(int64_t search_start, int64_t search_end, size_t len,
|
|
size_t alignment, int memory_type,
|
|
int64_t* phys_addr_out);
|
|
int KYTY_SYSV_ABI KernelAllocateMainDirectMemory(size_t len, size_t alignment, int memory_type,
|
|
int64_t* phys_addr_out);
|
|
int KYTY_SYSV_ABI KernelCheckedReleaseDirectMemory(int64_t start, size_t len);
|
|
int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len);
|
|
int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int flags,
|
|
int64_t direct_memory_start, size_t alignment);
|
|
int KYTY_SYSV_ABI KernelMapDirectMemory2(void** addr, size_t len, int type, int prot, int flags,
|
|
int64_t direct_memory_start, size_t alignment);
|
|
int KYTY_SYSV_ABI KernelMapNamedDirectMemory(void** addr, size_t len, int prot, int flags,
|
|
int64_t direct_memory_start, size_t alignment,
|
|
const char* name);
|
|
int KYTY_SYSV_ABI KernelSetPrtAperture(int index, void* addr, size_t len);
|
|
int KYTY_SYSV_ABI KernelGetPrtAperture(int index, void** addr, size_t* len);
|
|
int KYTY_SYSV_ABI KernelIsAddressSanitizerEnabled();
|
|
int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** end, int* prot);
|
|
int KYTY_SYSV_ABI KernelDirectMemoryQuery(int64_t offset, int flags, void* info, size_t info_size);
|
|
int KYTY_SYSV_ABI KernelVirtualQuery(const void* addr, int flags, VirtualQueryInfo* info,
|
|
uint64_t info_size);
|
|
int KYTY_SYSV_ABI KernelIsStack(void* addr, void** start, void** end);
|
|
int KYTY_SYSV_ABI KernelReserveVirtualRange(void** addr, size_t len, int flags, size_t alignment);
|
|
bool KernelHandleReservedRangeAccessViolation(uint64_t vaddr);
|
|
int KYTY_SYSV_ABI KernelAvailableFlexibleMemorySize(size_t* size);
|
|
int KYTY_SYSV_ABI KernelConfiguredFlexibleMemorySize(size_t* size);
|
|
int KYTY_SYSV_ABI KernelMprotect(const void* addr, size_t len, int prot);
|
|
int KYTY_SYSV_ABI KernelMtypeprotect(const void* addr, size_t len, int type, int prot);
|
|
int KYTY_SYSV_ABI KernelBatchMap(KernelBatchMapEntry* entries, int num_entries,
|
|
int* num_entries_out);
|
|
int KYTY_SYSV_ABI KernelBatchMap2(KernelBatchMapEntry* entries, int num_entries,
|
|
int* num_entries_out, int flags);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolExpand(int64_t search_start, int64_t search_end, size_t len,
|
|
size_t alignment, int64_t* phys_addr_out);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolReserve(void* addr_in, size_t len, size_t alignment, int flags,
|
|
void** addr_out);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolCommit(void* addr, size_t len, int type, int prot, int flags);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolDecommit(void* addr, size_t len, int flags);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolBatch(const KernelMemoryPoolBatchEntry* entries, int num_entries,
|
|
int* num_entries_out, int flags);
|
|
int KYTY_SYSV_ABI KernelMemoryPoolGetBlockStats(KernelMemoryPoolBlockStats* output,
|
|
size_t output_size);
|
|
|
|
uint64_t AllocateProgramMemory(uint64_t search_addr, uint64_t size,
|
|
Common::VirtualMemory::Mode mode, const char* name);
|
|
void SetProgramMemoryProtection(uint64_t vaddr, uint64_t size, Common::VirtualMemory::Mode mode);
|
|
uint64_t AllocateRuntimeMemory(uint64_t search_addr, uint64_t size,
|
|
Common::VirtualMemory::Mode mode, const char* name,
|
|
bool fixed = false);
|
|
uint64_t AllocateGuestStackMemory(uint64_t search_addr, uint64_t size,
|
|
Common::VirtualMemory::Mode mode, const char* name);
|
|
bool ProtectGuestMemory(uint64_t vaddr, uint64_t size, Common::VirtualMemory::Mode mode,
|
|
Common::VirtualMemory::Mode* old_mode = nullptr);
|
|
// Transient PageManager watch state; does not change the guest mapping's semantic protection.
|
|
bool ProtectGuestHostMemory(uint64_t vaddr, uint64_t size, Common::VirtualMemory::Mode mode);
|
|
bool FreeGuestMemory(uint64_t vaddr, uint64_t size);
|
|
|
|
#if defined(KYTY_VIRTUAL_MEMORY_ALLOCATION_TESTS)
|
|
void TestFailNextPhysicalMemoryUnmap();
|
|
void TestFailPhysicalMemoryUnmapAfter(uint32_t successful_unmaps);
|
|
void TestFailGuestBackingStoreUnmapAfter(uint32_t successful_unmaps);
|
|
void TestFailNextFixedReserveRangeRegistration();
|
|
bool TestPlaceholderRangeIsFree(uint64_t vaddr, uint64_t size);
|
|
bool TestGuestAddressRangeIsOwned(uint64_t vaddr, uint64_t size);
|
|
bool TestGuestBackingOutsideAddressSpace();
|
|
uint64_t TestGuestBackingSize();
|
|
bool TestGuestFreeRangeBounds();
|
|
#endif
|
|
|
|
} // namespace Libs::LibKernel::Memory
|
|
|
|
#endif /* EMULATOR_INCLUDE_EMULATOR_KERNEL_MEMORY_H_ */
|