implemented sceKernelMapDirectMemory
This commit is contained in:
parent
c412a5cb0b
commit
25e1095c7e
|
@ -41,7 +41,7 @@ add_executable(shadps4
|
||||||
src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp
|
src/Core/PS4/HLE/Kernel/Objects/physical_memory.cpp
|
||||||
src/Util/string_util.cpp
|
src/Util/string_util.cpp
|
||||||
src/Util/string_util.cpp
|
src/Util/string_util.cpp
|
||||||
"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")
|
"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" "src/Core/PS4/GPU/gpu_memory.cpp" "src/Core/PS4/GPU/gpu_memory.h")
|
||||||
|
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY})
|
target_link_libraries(shadps4 PUBLIC fmt mincore spdlog IMGUI SDL3-shared ${OPENGL_LIBRARY})
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include "gpu_memory.h"
|
||||||
|
|
||||||
|
namespace GPU {
|
||||||
|
void GpuMemorySetAllocArea(u64 virtual_addr, u64 size) {}
|
||||||
|
} // namespace GPU
|
|
@ -0,0 +1,9 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
namespace GPU {
|
||||||
|
enum class GPUMemoryMode : u32 { NoAccess = 0, Read = 1, Write = 2, ReadWrite = 3 };
|
||||||
|
|
||||||
|
void GpuMemorySetAllocArea(u64 virtual_addr, u64 size);
|
||||||
|
}
|
|
@ -24,6 +24,11 @@ bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignmen
|
||||||
block.size = len;
|
block.size = len;
|
||||||
block.start_addr = find_free_pos;
|
block.start_addr = find_free_pos;
|
||||||
block.memoryType = memoryType;
|
block.memoryType = memoryType;
|
||||||
|
block.gpu_mode = GPU::GPUMemoryMode::NoAccess;
|
||||||
|
block.map_size = 0;
|
||||||
|
block.map_virtual_addr = 0;
|
||||||
|
block.prot = 0;
|
||||||
|
block.cpu_mode = VirtualMemory::MemoryMode::NoAccess;
|
||||||
|
|
||||||
m_allocatedBlocks.push_back(block);
|
m_allocatedBlocks.push_back(block);
|
||||||
|
|
||||||
|
@ -33,4 +38,23 @@ bool PhysicalMemory::Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignmen
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool PhysicalMemory::Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, GPU::GPUMemoryMode gpu_mode) {
|
||||||
|
for (auto& b : m_allocatedBlocks) {
|
||||||
|
if (phys_addr >= b.start_addr && phys_addr < b.start_addr + b.size) {
|
||||||
|
if (b.map_virtual_addr != 0 || b.map_size != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
b.map_virtual_addr = virtual_addr;
|
||||||
|
b.map_size = len;
|
||||||
|
b.prot = prot;
|
||||||
|
b.cpu_mode = cpu_mode;
|
||||||
|
b.gpu_mode = gpu_mode;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} // namespace HLE::Kernel::Objects
|
} // namespace HLE::Kernel::Objects
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
#include <Core/virtual_memory.h>
|
||||||
|
#include <Core/PS4/GPU/gpu_memory.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace HLE::Kernel::Objects {
|
namespace HLE::Kernel::Objects {
|
||||||
|
@ -11,12 +12,18 @@ class PhysicalMemory {
|
||||||
u64 start_addr;
|
u64 start_addr;
|
||||||
u64 size;
|
u64 size;
|
||||||
int memoryType;
|
int memoryType;
|
||||||
|
u64 map_virtual_addr;
|
||||||
|
u64 map_size;
|
||||||
|
int prot;
|
||||||
|
VirtualMemory::MemoryMode cpu_mode;
|
||||||
|
GPU::GPUMemoryMode gpu_mode;
|
||||||
};
|
};
|
||||||
PhysicalMemory() {}
|
PhysicalMemory() {}
|
||||||
virtual ~PhysicalMemory() {}
|
virtual ~PhysicalMemory() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType);
|
bool Alloc(u64 searchStart, u64 searchEnd, u64 len, u64 alignment, u64* physAddrOut, int memoryType);
|
||||||
|
bool Map(u64 virtual_addr, u64 phys_addr, u64 len, int prot, VirtualMemory::MemoryMode cpu_mode, GPU::GPUMemoryMode gpu_mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<AllocatedBlock> m_allocatedBlocks;
|
std::vector<AllocatedBlock> m_allocatedBlocks;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "memory_management.h"
|
#include "memory_management.h"
|
||||||
|
|
||||||
|
#include <Core/PS4/GPU/gpu_memory.h>
|
||||||
|
#include <Core/virtual_memory.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
@ -65,14 +67,63 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment) {
|
int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int flags, s64 directMemoryStart, u64 alignment) {
|
||||||
PRINT_FUNCTION_NAME();
|
PRINT_FUNCTION_NAME();
|
||||||
|
if (len == 0 || !is16KBAligned(len))
|
||||||
|
{
|
||||||
|
LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL len invalid\n");
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
if (!is16KBAligned(directMemoryStart))
|
||||||
|
{
|
||||||
|
LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL directMemoryStart invalid\n");
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
if (alignment != 0 || (!isPowerOfTwo(alignment) && !is16KBAligned(alignment)))
|
||||||
|
{
|
||||||
|
LOG_TRACE_IF(log_file_memory, "sceKernelMapDirectMemory returned SCE_KERNEL_ERROR_EINVAL alignment invalid\n");
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
auto* physical_memory = Singleton<HLE::Kernel::Objects::PhysicalMemory>::Instance();
|
auto* physical_memory = Singleton<HLE::Kernel::Objects::PhysicalMemory>::Instance();
|
||||||
|
|
||||||
LOG_INFO_IF(log_file_memory, "len = {}\n", log_hex_full(len));
|
LOG_INFO_IF(log_file_memory, "len = {}\n", log_hex_full(len));
|
||||||
LOG_INFO_IF(log_file_memory, "prot = {}\n", log_hex_full(prot));
|
LOG_INFO_IF(log_file_memory, "prot = {}\n", log_hex_full(prot));
|
||||||
LOG_INFO_IF(log_file_memory, "flags = {}\n", log_hex_full(flags));
|
LOG_INFO_IF(log_file_memory, "flags = {}\n", log_hex_full(flags));
|
||||||
LOG_INFO_IF(log_file_memory, "directMemoryStart = {}\n", log_hex_full(directMemoryStart));
|
LOG_INFO_IF(log_file_memory, "directMemoryStart = {}\n", log_hex_full(directMemoryStart));
|
||||||
LOG_INFO_IF(log_file_memory, "alignment = {}\n", log_hex_full(alignment));
|
LOG_INFO_IF(log_file_memory, "alignment = {}\n", log_hex_full(alignment));
|
||||||
|
|
||||||
|
VirtualMemory::MemoryMode cpu_mode = VirtualMemory::MemoryMode::NoAccess;
|
||||||
|
GPU::GPUMemoryMode gpu_mode = GPU::GPUMemoryMode::NoAccess;
|
||||||
|
|
||||||
|
switch (prot) {
|
||||||
|
case 0x33://SCE_KERNEL_PROT_CPU_READ|SCE_KERNEL_PROT_CPU_WRITE|SCE_KERNEL_PROT_GPU_READ|SCE_KERNEL_PROT_GPU_ALL
|
||||||
|
cpu_mode = VirtualMemory::MemoryMode::ReadWrite;
|
||||||
|
gpu_mode = GPU::GPUMemoryMode::ReadWrite;
|
||||||
|
break;
|
||||||
|
default: BREAKPOINT();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto in_addr = reinterpret_cast<u64>(*addr);
|
||||||
|
u64 out_addr = 0;
|
||||||
|
|
||||||
|
if (flags == 0) {
|
||||||
|
out_addr = VirtualMemory::memory_alloc_aligned(in_addr, len, cpu_mode, alignment);
|
||||||
|
}
|
||||||
|
LOG_INFO_IF(log_file_memory, "in_addr = {}\n", log_hex_full(in_addr));
|
||||||
|
LOG_INFO_IF(log_file_memory, "out_addr = {}\n", log_hex_full(out_addr));
|
||||||
|
|
||||||
|
*addr = reinterpret_cast<void*>(out_addr); // return out_addr to first functions parameter
|
||||||
|
|
||||||
|
if (out_addr == 0) {
|
||||||
|
return SCE_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!physical_memory->Map(out_addr, directMemoryStart, len, prot, cpu_mode, gpu_mode)) {
|
||||||
BREAKPOINT();
|
BREAKPOINT();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gpu_mode != GPU::GPUMemoryMode::NoAccess) {
|
||||||
|
GPU::GpuMemorySetAllocArea(out_addr, len);
|
||||||
|
}
|
||||||
|
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5376_MB; // ~ 6GB
|
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5376_MB; // ~ 6GB
|
||||||
|
|
||||||
|
namespace HLE::Libs::LibKernel::MemoryManagement {
|
||||||
|
|
||||||
// memory types
|
// memory types
|
||||||
|
|
||||||
enum MemoryTypes : u32 {
|
enum MemoryTypes : u32 {
|
||||||
|
@ -15,7 +17,6 @@ enum MemoryTypes : u32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemoryFlags : u32 {
|
enum MemoryFlags : u32 {
|
||||||
NOT_SPECIFIED = 0, // not in SCE but it is a possible value (aligned memory)
|
|
||||||
SCE_KERNEL_MAP_FIXED = 0x0010, // Fixed
|
SCE_KERNEL_MAP_FIXED = 0x0010, // Fixed
|
||||||
SCE_KERNEL_MAP_NO_OVERWRITE = 0x0080,
|
SCE_KERNEL_MAP_NO_OVERWRITE = 0x0080,
|
||||||
SCE_KERNEL_MAP_NO_COALESCE = 0x400000
|
SCE_KERNEL_MAP_NO_COALESCE = 0x400000
|
||||||
|
@ -28,7 +29,6 @@ enum MemoryProtection : u32 {
|
||||||
SCE_KERNEL_PROT_GPU_WRITE = 0x20, // Permit writes from the GPU
|
SCE_KERNEL_PROT_GPU_WRITE = 0x20, // Permit writes from the GPU
|
||||||
SCE_KERNEL_PROT_GPU_RW = 0x30 // Permit reads/writes from the GPU
|
SCE_KERNEL_PROT_GPU_RW = 0x30 // Permit reads/writes from the GPU
|
||||||
};
|
};
|
||||||
namespace HLE::Libs::LibKernel::MemoryManagement {
|
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize();
|
||||||
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, u64 alignment, int memoryType, s64* physAddrOut);
|
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len, u64 alignment, int memoryType, s64* physAddrOut);
|
||||||
|
|
Loading…
Reference in New Issue