diff --git a/CMakeLists.txt b/CMakeLists.txt index 34b07450..79cdc553 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,7 @@ add_executable(shadps4 "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Core/PS4/Util/aerolib.h" "src/Core/PS4/Loader/SymbolsResolver.h" "src/Core/PS4/Loader/SymbolsResolver.cpp" "src/Core/PS4/HLE/Libs.cpp" "src/Core/PS4/HLE/Libs.h" "src/Core/PS4/HLE/LibC.cpp" "src/Core/PS4/HLE/LibC.h" "src/Lib/Timer.cpp" "src/Lib/Timer.h" "src/Core/PS4/HLE/LibKernel.cpp" "src/Core/PS4/HLE/LibKernel.h" "src/Core/PS4/HLE/LibSceVideoOut.cpp" "src/Core/PS4/HLE/LibSceVideoOut.h" "src/Core/PS4/HLE/LibSceGnmDriver.cpp" "src/Core/PS4/HLE/LibSceGnmDriver.h" "src/Core/PS4/HLE/Kernel/ThreadManagement.cpp" "src/Core/PS4/HLE/Kernel/ThreadManagement.h" "src/Core/PS4/HLE/ErrorCodes.h" "src/debug.h" "src/Core/PS4/HLE/Kernel/memory_management.cpp" "src/Core/PS4/HLE/Kernel/memory_management.h") find_package(OpenGL REQUIRED) -target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY}) +target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY}) add_custom_command(TARGET shadps4 POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different diff --git a/src/Core/virtual_memory.cpp b/src/Core/virtual_memory.cpp index a8857057..d96f7c75 100644 --- a/src/Core/virtual_memory.cpp +++ b/src/Core/virtual_memory.cpp @@ -19,6 +19,8 @@ enum PosixPageProtection { }; #endif +#include + #include "../Util/Log.h" namespace VirtualMemory { @@ -117,4 +119,25 @@ bool memory_patch(u64 vaddr, u64 value) { return ret; } +static u64 AlignUp(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); } + +u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) { + // try allocate aligned address inside user area + MEM_ADDRESS_REQUIREMENTS req{}; + MEM_EXTENDED_PARAMETER param{}; + req.LowestStartingAddress = (address == 0 ? reinterpret_cast(USER_MIN) : reinterpret_cast(AlignUp(address, alignment))); + req.HighestEndingAddress = reinterpret_cast(USER_MAX); + req.Alignment = alignment; + param.Type = MemExtendedParameterAddressRequirements; + param.Pointer = &req; + + auto ptr = reinterpret_cast(VirtualAlloc2( + GetCurrentProcess(), nullptr, size, static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), convertMemoryMode(mode), ¶m, 1)); + + if (ptr == 0) { + auto err = static_cast(GetLastError()); + LOG_ERROR_IF(true, "VirtualAlloc2() failed: 0x{:X}\n", err); + } + return ptr; +} } // namespace VirtualMemory diff --git a/src/Core/virtual_memory.h b/src/Core/virtual_memory.h index 25a9dc68..88582b48 100644 --- a/src/Core/virtual_memory.h +++ b/src/Core/virtual_memory.h @@ -3,6 +3,10 @@ constexpr u64 SYSTEM_RESERVED = 0x800000000u; constexpr u64 CODE_BASE_OFFSET = 0x100000000u; +constexpr u64 SYSTEM_MANAGED_MIN = 0x0000040000u; +constexpr u64 SYSTEM_MANAGED_MAX = 0x07FFFFBFFFu; +constexpr u64 USER_MIN = 0x1000000000u; +constexpr u64 USER_MAX = 0xFBFFFFFFFFu; namespace VirtualMemory { enum class MemoryMode : u32 { @@ -16,6 +20,7 @@ enum class MemoryMode : u32 { ExecuteReadWrite = 7, }; u64 memory_alloc(u64 address, u64 size, MemoryMode mode); +u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment); bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode); bool memory_flush(u64 address, u64 size); bool memory_patch(u64 vaddr, u64 value);