diff --git a/CMakeLists.txt b/CMakeLists.txt index e949f732..d19851e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,9 @@ add_executable(shadps4 src/Core/PS4/Linker.h src/Lib/Threads.cpp src/Lib/Threads.h - "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.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/MemoryManagement.cpp" "src/Core/PS4/HLE/Kernel/MemoryManagement.h" "src/Core/PS4/HLE/Kernel/MemMngCodes.h" "src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp" "src/Util/StringUtil.cpp") + src/Core/PS4/HLE/Kernel/PhysicalMemory.h + src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp + "src/Util/Singleton.h" "src/Util/Disassembler.cpp" "src/Util/Disassembler.h" "src/Util/StringUtil.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/MemoryManagement.cpp" "src/Core/PS4/HLE/Kernel/MemoryManagement.h" "src/Core/PS4/HLE/Kernel/MemMngCodes.h" "src/Util/StringUtil.cpp") find_package(OpenGL REQUIRED) target_link_libraries(shadps4 PUBLIC fmt spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY}) diff --git a/src/Core/PS4/HLE/Kernel/MemoryManagement.cpp b/src/Core/PS4/HLE/Kernel/MemoryManagement.cpp index f58a6dc1..78cd3651 100644 --- a/src/Core/PS4/HLE/Kernel/MemoryManagement.cpp +++ b/src/Core/PS4/HLE/Kernel/MemoryManagement.cpp @@ -5,9 +5,10 @@ #include "../ErrorCodes.h" #include "MemMngCodes.h" #include +#include "PhysicalMemory.h" namespace HLE::Libs::LibKernel::MemoryManagement { - + bool isPowerOfTwo(u64 n) { return std::popcount(n) == 1; } bool is16KBAligned(u64 n) { return ((n % (16ull * 1024) == 0)); } @@ -44,8 +45,14 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u LOG_INFO_IF(true, "alignment = {:#018x}\n", alignment); LOG_INFO_IF(true, "memory_type = {}\n", memoryType); - BREAKPOINT(); - return 0; + u64 physical_addr = 0; + if (!g_physical_memory->Alloc(searchStart, searchEnd, len, alignment, &physical_addr, memoryType)) { + //TODO debug logging + return SCE_KERNEL_ERROR_EAGAIN; + } + *physAddrOut = static_cast(physical_addr); + LOG_INFO_IF(true, "physAddrOut = {:#018x}\n", physical_addr); + return SCE_OK; } } // namespace HLE::Libs::LibKernel::MemoryManagement \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp b/src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp index e69de29b..b998d118 100644 --- a/src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp +++ b/src/Core/PS4/HLE/Kernel/PhysicalMemory.cpp @@ -0,0 +1,44 @@ +#include "PhysicalMemory.h" + +namespace HLE::Libs::LibKernel::MemoryManagement { + + + +void PhysicalMemoryInit() { g_physical_memory = new PhysicalMemory; } + +static u64 align_pos(u64 pos, u64 align) { return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); } + +bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType) { + + u64 find_free_pos = 0; + + //iterate through allocated blocked and find the next free position + if (!m_allocatedBlocks.empty()) { + for (const auto& b : m_allocatedBlocks) { + u64 n = b.start_addr + b.size; + if (n > find_free_pos) { + find_free_pos = n; + } + } + } + + //align free position + find_free_pos = align_pos(find_free_pos, alignment); + + //if the new position is between searchStart - searchEnd , allocate a new block + if (find_free_pos >= searchStart && find_free_pos + len <= searchEnd) { + AllocatedBlock b{}; + b.size = len; + b.start_addr = find_free_pos; + b.memoryType = memoryType; + + m_allocatedBlocks.push_back(b); + + *physAddrOut = find_free_pos; + return true; + } + + return false; +} + +} // namespace HLE::Libs::LibKernel::MemoryManagement \ No newline at end of file diff --git a/src/Core/PS4/HLE/Kernel/PhysicalMemory.h b/src/Core/PS4/HLE/Kernel/PhysicalMemory.h index 07a990d8..bb607d3f 100644 --- a/src/Core/PS4/HLE/Kernel/PhysicalMemory.h +++ b/src/Core/PS4/HLE/Kernel/PhysicalMemory.h @@ -1,15 +1,26 @@ #pragma once +#include +#include "../../../../types.h" namespace HLE::Libs::LibKernel::MemoryManagement { -class PysicalMemory { + +void PhysicalMemoryInit(); + +class PhysicalMemory { + public: struct AllocatedBlock { u64 start_addr; u64 size; + int memoryType; }; - + PhysicalMemory() { } + virtual ~PhysicalMemory() { } + public: + bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType); private: std::vector m_allocatedBlocks; }; +static PhysicalMemory* g_physical_memory = nullptr; } // namespace HLE::Libs::LibKernel::MemoryManagement \ No newline at end of file