#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::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); void WriteBacking(uint64_t vaddr, const void* data, uint64_t size) noexcept; void PrepareHostWrite(uint64_t vaddr, uint64_t size); 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(uint64_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); void RegisterProgramMemory(uint64_t vaddr, uint64_t size, Common::VirtualMemory::Mode mode, const char* name); void UpdateProgramMemoryProtection(uint64_t vaddr, uint64_t size, Common::VirtualMemory::Mode mode); void UnregisterProgramMemory(uint64_t vaddr, uint64_t size); #if defined(KYTY_VIRTUAL_MEMORY_ALLOCATION_TESTS) void TestFailNextPhysicalMemoryUnmap(); void TestFailPhysicalMemoryUnmapAfter(uint32_t successful_unmaps); void TestFailHostReservationAfter(uint32_t successful_pages); void TestFailNextFixedReserveRangeRegistration(); bool TestPlaceholderRangeIsFree(uint64_t vaddr, uint64_t size); #endif } // namespace Libs::LibKernel::Memory #endif /* EMULATOR_INCLUDE_EMULATOR_KERNEL_MEMORY_H_ */