From 90e3e47c4df525a5f9db3debca7a7cb53c5e52a2 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 2 May 2024 17:13:51 +0300 Subject: [PATCH 1/3] added stubbed mostly version of flexible memory - it allows sonic mania to go further --- CMakeLists.txt | 6 +- src/core/libraries/kernel/libkernel.cpp | 2 + .../kernel/memory/flexible_memory.cpp | 22 ++++++ .../libraries/kernel/memory/flexible_memory.h | 33 ++++++++ .../libraries/kernel/memory/kernel_memory.cpp | 78 +++++++++++++++++++ .../libraries/kernel/memory/kernel_memory.h | 18 +++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 src/core/libraries/kernel/memory/flexible_memory.cpp create mode 100644 src/core/libraries/kernel/memory/flexible_memory.h create mode 100644 src/core/libraries/kernel/memory/kernel_memory.cpp create mode 100644 src/core/libraries/kernel/memory/kernel_memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 498051ad..5cd33d94 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,7 +101,11 @@ set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp src/core/libraries/gnmdriver/gnmdriver.h ) -set(KERNEL_LIB src/core/libraries/kernel/cpu_management.cpp +set(KERNEL_LIB src/core/libraries/kernel/memory/flexible_memory.cpp + src/core/libraries/kernel/memory/flexible_memory.h + src/core/libraries/kernel/memory/kernel_memory.cpp + src/core/libraries/kernel/memory/kernel_memory.h + src/core/libraries/kernel/cpu_management.cpp src/core/libraries/kernel/cpu_management.h src/core/libraries/kernel/event_queue.cpp src/core/libraries/kernel/event_queue.h diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index 226137db..cda68433 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -10,6 +10,7 @@ #include "core/libraries/kernel/event_queues.h" #include "core/libraries/kernel/file_system.h" #include "core/libraries/kernel/libkernel.h" +#include "core/libraries/kernel/memory/kernel_memory.h" #include "core/libraries/kernel/memory_management.h" #include "core/libraries/kernel/thread_management.h" #include "core/libraries/kernel/time_management.h" @@ -180,6 +181,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) { Libraries::Kernel::fileSystemSymbolsRegister(sym); Libraries::Kernel::timeSymbolsRegister(sym); Libraries::Kernel::pthreadSymbolsRegister(sym); + Libraries::Kernel::RegisterKernelMemory(sym); // temp LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1, diff --git a/src/core/libraries/kernel/memory/flexible_memory.cpp b/src/core/libraries/kernel/memory/flexible_memory.cpp new file mode 100644 index 00000000..690990e3 --- /dev/null +++ b/src/core/libraries/kernel/memory/flexible_memory.cpp @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "flexible_memory.h" + +namespace Libraries::Kernel { +bool FlexibleMemory::Map(u64 virtual_addr, std::size_t len, int prot, + VirtualMemory::MemoryMode cpu_mode) { + std::scoped_lock lock{mutex}; + + AllocatedBlock block{}; + block.map_virtual_addr = virtual_addr; + block.map_size = len; + block.prot = prot; + block.cpu_mode = cpu_mode; + + allocated_blocks.push_back(block); + allocated_total += len; + + return true; +} +} // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/memory/flexible_memory.h b/src/core/libraries/kernel/memory/flexible_memory.h new file mode 100644 index 00000000..a33ed6f2 --- /dev/null +++ b/src/core/libraries/kernel/memory/flexible_memory.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "common/types.h" +#include "core/virtual_memory.h" + +namespace Libraries::Kernel { + +class FlexibleMemory { +public: + struct AllocatedBlock { + u64 map_virtual_addr; + u64 map_size; + int prot; + VirtualMemory::MemoryMode cpu_mode; + }; + + FlexibleMemory(){}; + virtual ~FlexibleMemory(){}; + +public: + bool Map(u64 virtual_addr, std::size_t len, int prot, VirtualMemory::MemoryMode cpu_mode); + +private: + std::vector allocated_blocks; + u64 allocated_total = 0; + std::mutex mutex; +}; +} // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/memory/kernel_memory.cpp b/src/core/libraries/kernel/memory/kernel_memory.cpp new file mode 100644 index 00000000..33536ea5 --- /dev/null +++ b/src/core/libraries/kernel/memory/kernel_memory.cpp @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include +#include +#include "flexible_memory.h" +#include "kernel_memory.h" + +namespace Libraries::Kernel { + +bool Is16KBMultiple(u64 n) { + return ((n % (16ull * 1024) == 0)); +} +s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addr_in_out, std::size_t len, int prot, + int flags, const char* name) { + + LOG_INFO(Kernel_Vmm, "len = {:#x}, prot = {:#x}, flags = {:#x}, name = {}", len, prot, flags, + name); + + if (len == 0 || !Is16KBMultiple(len)) { + LOG_ERROR(Kernel_Vmm, "len is 0 or not 16kb multiple"); + return ORBIS_KERNEL_ERROR_EINVAL; + } + + static constexpr size_t MaxNameSize = 32; + if (std::strlen(name) > MaxNameSize) { + LOG_ERROR(Kernel_Vmm, "name exceeds 32 bytes!"); + return ORBIS_KERNEL_ERROR_ENAMETOOLONG; + } + + if (name == nullptr) { + LOG_ERROR(Kernel_Vmm, "name is invalid!"); + return ORBIS_KERNEL_ERROR_EFAULT; + } + + VirtualMemory::MemoryMode cpu_mode = VirtualMemory::MemoryMode::NoAccess; + + switch (prot) { + case 0x3: + cpu_mode = VirtualMemory::MemoryMode::ReadWrite; + break; + default: + UNREACHABLE(); + } + + auto in_addr = reinterpret_cast(*addr_in_out); + auto out_addr = VirtualMemory::memory_alloc(in_addr, len, cpu_mode); + *addr_in_out = reinterpret_cast(out_addr); + + auto* flexible_memory = Common::Singleton::Instance(); + + if (!flexible_memory->Map(out_addr, len, prot, cpu_mode)) { + UNREACHABLE(); + } + + if (out_addr == 0) { + LOG_ERROR(Kernel_Vmm, "Can't allocate address"); + return ORBIS_KERNEL_ERROR_ENOMEM; + } + LOG_INFO(Kernel_Vmm, "in_addr = {:#x} out_addr = {:#x}", in_addr, out_addr); + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int prot, + int flags) { + return sceKernelMapNamedFlexibleMemory(addr_in_out, len, prot, flags, ""); +} + +void RegisterKernelMemory(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedFlexibleMemory); + LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory); +} + +} // namespace Libraries::Kernel \ No newline at end of file diff --git a/src/core/libraries/kernel/memory/kernel_memory.h b/src/core/libraries/kernel/memory/kernel_memory.h new file mode 100644 index 00000000..9b4ee288 --- /dev/null +++ b/src/core/libraries/kernel/memory/kernel_memory.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::Kernel { +s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot, + int flags, const char* name); +s32 PS4_SYSV_ABI sceKernelMapFlexibleMemory(void** addr_in_out, std::size_t len, int prot, + int flags); +void RegisterKernelMemory(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::Kernel \ No newline at end of file From d2cc256b28e101087022a924c8d10a5304cb51b5 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 2 May 2024 17:14:30 +0300 Subject: [PATCH 2/3] create_thread : sometime thread name is null --- src/core/libraries/kernel/thread_management.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/libraries/kernel/thread_management.cpp b/src/core/libraries/kernel/thread_management.cpp index a2d7d7ee..b4422679 100644 --- a/src/core/libraries/kernel/thread_management.cpp +++ b/src/core/libraries/kernel/thread_management.cpp @@ -827,7 +827,11 @@ int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr int result = pthread_copy_attributes(&(*thread)->attr, attr); if (result == 0) { - (*thread)->name = name; + if (name != NULL) { + (*thread)->name = name; + } else { + (*thread)->name = "no-name"; + } (*thread)->entry = start_routine; (*thread)->arg = arg; (*thread)->is_almost_done = false; From 150854c583e17fd9a3c6329cd4a2453ba1060394 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 2 May 2024 17:14:55 +0300 Subject: [PATCH 3/3] added a login event in sceUserServiceGetEvent --- src/core/libraries/system/userservice.cpp | 16 +++++++++++++--- src/core/libraries/system/userservice.h | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/core/libraries/system/userservice.cpp b/src/core/libraries/system/userservice.cpp index e385e425..16e5295c 100644 --- a/src/core/libraries/system/userservice.cpp +++ b/src/core/libraries/system/userservice.cpp @@ -103,9 +103,19 @@ int PS4_SYSV_ABI sceUserServiceGetDiscPlayerFlag() { return ORBIS_OK; } -int PS4_SYSV_ABI sceUserServiceGetEvent() { - LOG_ERROR(Lib_UserService, "(STUBBED) called"); - return ORBIS_OK; +s32 PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event) { + LOG_INFO(Lib_UserService, "(DUMMY) called"); + // fake a loggin event + static bool logged_in = false; + + if (!logged_in) { + logged_in = true; + event->event = SCE_USER_SERVICE_EVENT_TYPE_LOGIN; + event->userId = 1; + return ORBIS_OK; + } + + return ORBIS_USER_SERVICE_ERROR_NO_EVENT; } int PS4_SYSV_ABI sceUserServiceGetEventCalendarType() { diff --git a/src/core/libraries/system/userservice.h b/src/core/libraries/system/userservice.h index 5abadf96..5bb1fd04 100644 --- a/src/core/libraries/system/userservice.h +++ b/src/core/libraries/system/userservice.h @@ -76,7 +76,7 @@ int PS4_SYSV_ABI sceUserServiceGetCurrentUserGroupIndex(); int PS4_SYSV_ABI sceUserServiceGetDefaultNewUserGroupName(); int PS4_SYSV_ABI sceUserServiceGetDeletedUserInfo(); int PS4_SYSV_ABI sceUserServiceGetDiscPlayerFlag(); -int PS4_SYSV_ABI sceUserServiceGetEvent(); +int PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event); int PS4_SYSV_ABI sceUserServiceGetEventCalendarType(); int PS4_SYSV_ABI sceUserServiceGetEventFilterTeamEvent(); int PS4_SYSV_ABI sceUserServiceGetEventSortEvent();