diff --git a/src/core/devices/gc_device.cpp b/src/core/devices/gc_device.cpp index 866a72675..94a4a585a 100644 --- a/src/core/devices/gc_device.cpp +++ b/src/core/devices/gc_device.cpp @@ -2,7 +2,11 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" -#include "gc_device.h" +#include "core/devices/gc_device.h" +#include "core/libraries/kernel/posix_error.h" +#include "core/libraries/gnmdriver/gnmdriver.h" +#include "core/memory.h" +#include "common/assert.h" namespace Core::Devices { @@ -11,27 +15,93 @@ std::shared_ptr GcDevice::Create(u32 handle, const char*, int, u16) reinterpret_cast(new GcDevice(handle))); } + + +s32* submits_addr = 0; + s32 GcDevice::ioctl(u64 cmd, Common::VaCtx* args) { auto command = GcCommands(cmd); switch(command) { - case GcCommands::AreSubmitsAllowed: { - LOG_ERROR(Lib_GnmDriver, "unhandled ioctl sceGnmAreSubmitsAllowed", cmd); - break; - } - case GcCommands::GetCuMask: { - LOG_ERROR(Lib_GnmDriver, "unhandled ioctl get cu mask", cmd); - break; - } case GcCommands::GetNumTcaUnits: { - LOG_ERROR(Lib_GnmDriver, "unhandled ioctl sceGnmGetNumTcaUnits", cmd); + auto data = vaArgPtr(&args->va_list); + *data = 0; break; } - case GcCommands::MipStatsReport: { - LOG_ERROR(Lib_GnmDriver, "unhandled ioctl sceGnmMipStatsReport", cmd); + case GcCommands::AreSubmitsAllowed: { + LOG_INFO(Lib_GnmDriver, "ioctl AreSubmitsAllowed"); + if (submits_addr == nullptr) { + auto* memory = Core::Memory::Instance(); + s32* out_addr; + VAddr in_addr{0xfe0100000}; + auto prot = Core::MemoryProt::CpuRead; + auto flags = Core::MemoryMapFlags::Shared | Core::MemoryMapFlags::Anon | Core::MemoryMapFlags::System; + auto type = Core::VMAType::Direct; + s32 result = memory->MapMemory(reinterpret_cast(&out_addr), in_addr, 0x4000, prot, flags, type); + if (result != 0) { + return POSIX_ENOMEM; + } + submits_addr = out_addr; + } + auto data = vaArgPtr(&args->va_list); + *data = submits_addr; + + *submits_addr = 0; break; } case GcCommands::SetGsRingSizes: { - LOG_ERROR(Lib_GnmDriver, "unhandled ioctl sceGnmSetGsRingSizes", cmd); + auto data = vaArgPtr(&args->va_list); + LOG_ERROR(Lib_GnmDriver, "unhandled ioctl SetGsRingSizes, esgs size = {:#x}, gsvs size = {:#x}", data->esgs_ring_size, data->gsvs_ring_size); + break; + } + case GcCommands::Submit: { + ASSERT(true); + LOG_ERROR(Lib_GnmDriver, "ioctl Submit"); + auto data = vaArgPtr(&args->va_list); + auto commands = std::span{data->cmds, data->count}; + // Submit ioctl receives an indirect buffer packet + break; + } + case GcCommands::GetCuMask: { + auto data = vaArgPtr(&args->va_list); + data[0] = 0x10; + data[1] = 0x10; + data[2] = 0; + data[3] = 0; + break; + } + case GcCommands::SubmitEop: { + ASSERT(true); + LOG_ERROR(Lib_GnmDriver, "ioctl SubmitEop"); + auto data = vaArgPtr(&args->va_list); + auto commands = std::span{data->cmds, data->count}; + // Submit ioctl receives an indirect buffer packet + break; + } + case GcCommands::MapComputeQueue: { + ASSERT(true); + auto data = vaArgPtr(&args->va_list); + auto pipe_id = data->pipe_lo - 1; + auto ring_size = pow(2, data->ring_size_dw); + LOG_ERROR(Lib_GnmDriver, "ioctl MapComputeQueue, pipe_id = {}", pipe_id); + Libraries::GnmDriver::sceGnmMapComputeQueueWithPriority(pipe_id, data->queue_id, data->ring_base_addr, ring_size, data->read_ptr_addr, data->pipe_priority); + break; + } + case GcCommands::SetWaveLimitMultipliers: { + LOG_ERROR(Lib_GnmDriver, "ioctl SetWaveLimitMultipliers"); + auto data = vaArgPtr(&args->va_list); + break; + } + case GcCommands::MipStatsReport: { + auto data = vaArgPtr(&args->va_list); + switch(data->type) { + case 0x10001: + case 0x18001: { + break; + } + default: { + return POSIX_EINVAL; + } + } break; } default: { diff --git a/src/core/devices/gc_device.h b/src/core/devices/gc_device.h index 2541b7c45..9e7e01490 100644 --- a/src/core/devices/gc_device.h +++ b/src/core/devices/gc_device.h @@ -31,10 +31,61 @@ public: private: enum class GcCommands : u64 { GetNumTcaUnits = 0xc004811f, - SetGsRingSizes = 0xc00c8110, - MipStatsReport = 0xc0848119, AreSubmitsAllowed = 0xc008811b, + SetGsRingSizes = 0xc00c8110, + Submit = 0xc0108102, GetCuMask = 0xc010810b, + SubmitEop = 0xc020810c, + MapComputeQueue = 0xc030810d, + SetWaveLimitMultipliers = 0xc030811e, + MipStatsReport = 0xc0848119, + }; + + struct SetGsRingSizesArgs { + u32 esgs_ring_size; + u32 gsvs_ring_size; + u32 unk; + }; + + struct SubmitArgs { + u32 pid; + u32 count; + u64* cmds; + }; + + struct SubmitEopArgs { + u32 pid; + u32 count; + u64* cmds; + u64 eop_v; + s32 wait; + }; + + struct MapComputeQueueArgs { + u32 pipe_hi; + u32 pipe_lo; + u32 queue_id; + u32 g_queue_id; + VAddr ring_base_addr; + u32* read_ptr_addr; + VAddr ding_dong_ptr; + u32 ring_size_dw; + u32 pipe_priority; + }; + + struct SetWaveLimitMultipliersArgs { + s32 bitset; + s32 values[8]; + s32 unk0; + s32 unk1; + s32 unk2; + }; + + struct SetMipStatsReportArgs { + u32 type; + u32 unk0; + u32 unk1; + u32 unk2; }; }; diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 02d888bd1..108b48186 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -2817,10 +2817,35 @@ void InitializePresenter() { nullptr); } -void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { - LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent); +void RegisterRequiredGnmDriver(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("29oKvKXzEZo", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmMapComputeQueue); + LIB_FUNCTION("A+uGq+3KFtQ", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmMapComputeQueueWithPriority); + LIB_FUNCTION("gObODli-OH8", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmRequestFlipAndSubmitDone); + LIB_FUNCTION("6YRHhh5mHCs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmRequestFlipAndSubmitDoneForWorkload); + LIB_FUNCTION("xbxNatawohc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmSubmitAndFlipCommandBuffers); + LIB_FUNCTION("Ga6r7H6Y0RI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmSubmitAndFlipCommandBuffersForWorkload); + LIB_FUNCTION("zwY0YV91TTI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmSubmitCommandBuffers); + LIB_FUNCTION("jRcI8VcgTz4", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmSubmitCommandBuffersForWorkload); + LIB_FUNCTION("yvZ73uQUqrk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitDone); + LIB_FUNCTION("ArSg-TGinhk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmUnmapComputeQueue); + LIB_FUNCTION("bX5IbRvECXk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDingDong); + LIB_FUNCTION("byXlqupd8cE", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, + sceGnmDingDongForWorkload); LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAreSubmitsAllowed); +} + +void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent); LIB_FUNCTION("ihxrbsoSKWc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmBeginWorkload); LIB_FUNCTION("ffrNQOshows", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmComputeWaitOnAddress); @@ -2851,9 +2876,6 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("PVT+fuoS9gU", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDeleteEqEvent); LIB_FUNCTION("UtObDRQiGbs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDestroyWorkloadStream); - LIB_FUNCTION("bX5IbRvECXk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDingDong); - LIB_FUNCTION("byXlqupd8cE", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmDingDongForWorkload); LIB_FUNCTION("HHo1BAljZO8", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmDisableMipStatsReport); LIB_FUNCTION("0BzLGljcwBo", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, @@ -2998,10 +3020,6 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { sceGnmLogicalCuMaskToPhysicalCuMask); LIB_FUNCTION("Kl0Z3LH07QI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmLogicalTcaUnitToPhysical); - LIB_FUNCTION("29oKvKXzEZo", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmMapComputeQueue); - LIB_FUNCTION("A+uGq+3KFtQ", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmMapComputeQueueWithPriority); LIB_FUNCTION("+N+wrSYBLIw", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmPaDisableFlipCallbacks); LIB_FUNCTION("8WDA9RiXLaw", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, @@ -3018,10 +3036,6 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("ZFqKFl23aMc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRegisterOwner); LIB_FUNCTION("nvEwfYAImTs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRegisterResource); - LIB_FUNCTION("gObODli-OH8", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmRequestFlipAndSubmitDone); - LIB_FUNCTION("6YRHhh5mHCs", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmRequestFlipAndSubmitDoneForWorkload); LIB_FUNCTION("f85orjx7qts", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmRequestMipStatsReportAndReset); LIB_FUNCTION("MYRtYhojKdA", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, @@ -3131,17 +3145,6 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) { sceGnmSqttSwitchTraceBuffer2); LIB_FUNCTION("QLzOwOF0t+A", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSqttWaitForEvent); - LIB_FUNCTION("xbxNatawohc", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmSubmitAndFlipCommandBuffers); - LIB_FUNCTION("Ga6r7H6Y0RI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmSubmitAndFlipCommandBuffersForWorkload); - LIB_FUNCTION("zwY0YV91TTI", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmSubmitCommandBuffers); - LIB_FUNCTION("jRcI8VcgTz4", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmSubmitCommandBuffersForWorkload); - LIB_FUNCTION("yvZ73uQUqrk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmSubmitDone); - LIB_FUNCTION("ArSg-TGinhk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, - sceGnmUnmapComputeQueue); LIB_FUNCTION("yhFCnaz5daw", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmUnregisterAllResourcesForOwner); LIB_FUNCTION("fhKwCVVj9nk", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, diff --git a/src/core/libraries/gnmdriver/gnmdriver.h b/src/core/libraries/gnmdriver/gnmdriver.h index 94f1392d8..94167cef1 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.h +++ b/src/core/libraries/gnmdriver/gnmdriver.h @@ -297,5 +297,6 @@ int PS4_SYSV_ABI Func_BFB41C057478F0BF(); int PS4_SYSV_ABI Func_E51D44DB8151238C(); int PS4_SYSV_ABI Func_F916890425496553(); +void RegisterRequiredGnmDriver(Core::Loader::SymbolsResolver* sym); void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::GnmDriver diff --git a/src/core/libraries/kernel/memory.h b/src/core/libraries/kernel/memory.h index 400b6c3fc..2a86f3843 100644 --- a/src/core/libraries/kernel/memory.h +++ b/src/core/libraries/kernel/memory.h @@ -129,6 +129,8 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolReserve(void* addrIn, size_t len, size_t ali s32 PS4_SYSV_ABI sceKernelMemoryPoolCommit(void* addr, size_t len, int type, int prot, int flags); s32 PS4_SYSV_ABI sceKernelMemoryPoolDecommit(void* addr, size_t len, int flags); +int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset, void** res); + int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len); void RegisterMemory(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 658e36bad..8d8d755cf 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -67,6 +67,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { LOG_INFO(Lib_Kernel, "Initializing HLE libraries"); Libraries::Kernel::RegisterKernel(sym); Libraries::GnmDriver::InitializePresenter(); + Libraries::GnmDriver::RegisterRequiredGnmDriver(sym); Libraries::VideoOut::RegisterLib(sym); Libraries::UserService::RegisterlibSceUserService(sym); Libraries::SystemService::RegisterlibSceSystemService(sym); diff --git a/src/core/memory.h b/src/core/memory.h index f8ab7efd7..13dfb8d3d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -41,8 +41,10 @@ enum class MemoryMapFlags : u32 { Shared = 1, Private = 2, Fixed = 0x10, - NoOverwrite = 0x0080, + NoOverwrite = 0x80, NoSync = 0x800, + Anon = 0x1000, + System = 0x2000, NoCore = 0x20000, NoCoalesce = 0x400000, };