Compare commits

...

15 Commits

Author SHA1 Message Date
raziel1000 cbf6a62ef5 Added:
- sceSaveDataMount
- Create2 mode (50)
- slight change in error handling (testing for now)
- log to print message when fd = 1 in sceKernelWrite (to avoid crash and move forward, not a file)
- mount savedata at emu start for CUSA00402 - Crimsonland (only case, needs testing)
- sceSaveDataGetMountInfo

- scePthreadGetthreadid
- posix_getpid
- posix_pthread_attr_setdetachstate
- posix_pthread_attr_destroy
- posix_pthread_detach
- scePthreadSetschedparam(partial)
- posix_pthread_setschedparam (partial)
- posix_sched_get_priority_max
2024-05-26 22:12:38 -06:00
raziel1000 5cf24a8be3 Added:
sceKernelGetCpumode
posix_getpagesize
posix_usleep
sceKernelSleep
ps4_clock_getres
posix_pthread_setspecific
posix_pthread_key_create
scePthreadKeyCreate
scePthreadRename
scePthreadJoin

Improved:
sceKernelUsleep
sceKernelNanosleep
2024-05-26 20:06:56 -06:00
georgemoralis 95ea2ce3d1 Merge branch 'kernel_and_rtc' of https://github.com/shadps4-emu/shadPS4 into kernel_and_rtc 2024-05-21 12:23:21 +03:00
georgemoralis d1f6df5d82 improved scePthreadCondTimedwait 2024-05-21 12:22:30 +03:00
raziel1000 e8ecf14f68 posix_pthread_mutexattr_setprotocol
posix_pthread_mutex_trylock
posix_pthread_condattr_init
posix_pthread_condattr_destroy
ps4_gettimeofday (posix)
2024-05-21 02:21:02 -06:00
raziel1000 a34fcc4678 -scePthreadRwlockRdlock
-scePthreadRwlockWrlock
-scePthreadRwlockUnlock
-scePthreadRwlockDestroy
-scePthreadRwlockattrInit
-posix_pthread_rwlock_rdlock
-posix_pthread_rwlock_unlock
2024-05-21 01:22:15 -06:00
raziel1000 b3c77ba835 scePthreadCondDestroy, posix_pthread_mutexattr_settype, pthread_self(posix) 2024-05-21 00:52:36 -06:00
georgemoralis b380a0751e added some posix thread calls 2024-05-21 07:59:36 +03:00
raziel1000 a6bd198d52 - scePthreadCondTimedwait
- gettimeofday
- sceRtcGetCurrentClockLocalTime
- sceRtcGetDayOfWeek
2024-05-20 22:05:21 -06:00
georgemoralis 84467efe51 eventflags enums 2024-05-20 08:37:42 +03:00
georgemoralis 8bae44a90b sceKernelCreateEventFlag , sceKernelWaitEventFlag implementation 2024-05-19 23:28:41 +03:00
georgemoralis ae9a779369 event flags : added function signatures 2024-05-19 12:28:20 +03:00
georgemoralis 4c8719d33d stubbed event_flag functions 2024-05-19 10:58:34 +03:00
georgemoralis edc9543590 added sceRtcGetCurrentTick 2024-05-19 10:03:40 +03:00
georgemoralis c49c2f6c70 added dummy rtc module 2024-05-19 09:50:01 +03:00
20 changed files with 1427 additions and 52 deletions

View File

@ -100,7 +100,12 @@ 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/event_flag/event_flag.cpp
src/core/libraries/kernel/event_flag/event_flag.h
src/core/libraries/kernel/event_flag/event_flag_codes.h
src/core/libraries/kernel/event_flag/event_flag_obj.cpp
src/core/libraries/kernel/event_flag/event_flag_obj.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
@ -147,6 +152,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/system/systemservice.h
src/core/libraries/system/userservice.cpp
src/core/libraries/system/userservice.h
src/core/libraries/rtc/rtc.cpp
src/core/libraries/rtc/rtc.h
)
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h

View File

@ -101,6 +101,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
SUB(Lib, NpTrophy) \
SUB(Lib, Screenshot) \
SUB(Lib, LibCInternal) \
SUB(Lib, Rtc) \
CLS(Frontend) \
CLS(Render) \
SUB(Render, Vulkan) \

View File

@ -68,6 +68,7 @@ enum class Class : u8 {
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
Lib_Screenshot, ///< The LibSceScreenshot implementation
Lib_LibCInternal, ///< The LibCInternal implementation.
Lib_Rtc, ///< The LibSceRtc implementation.
Frontend, ///< Emulator UI
Render, ///< Video Core
Render_Vulkan, ///< Vulkan backend

View File

@ -0,0 +1,141 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <common/assert.h>
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "event_flag.h"
namespace Libraries::Kernel {
int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* pName, u32 attr,
u64 initPattern,
const OrbisKernelEventFlagOptParam* pOptParam) {
LOG_INFO(Kernel_Event, "called name = {} attr = {:#x} initPattern = {:#x}", pName, attr,
initPattern);
if (ef == nullptr || pName == nullptr) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (pOptParam || !pName ||
attr > (ORBIS_KERNEL_EVF_ATTR_MULTI | ORBIS_KERNEL_EVF_ATTR_TH_PRIO)) {
return SCE_KERNEL_ERROR_EINVAL;
}
if (strlen(pName) >= 32) {
return ORBIS_KERNEL_ERROR_ENAMETOOLONG;
}
bool single = true;
bool fifo = true;
switch (attr) {
case 0x10:
case 0x11:
single = true;
fifo = true;
break;
case 0x20:
case 0x21:
single = false;
fifo = true;
break;
case 0x22:
single = false;
fifo = false;
break;
default:
UNREACHABLE();
}
*ef = new EventFlagInternal(std::string(pName), single, fifo, initPattern);
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef) {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelOpenEventFlag() {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelCloseEventFlag() {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
int* pNumWaitThreads) {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern) {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat) {
LOG_ERROR(Kernel_Event, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat, OrbisKernelUseconds* pTimeout) {
LOG_INFO(Kernel_Event, "called bitPattern = {:#x} waitMode = {:#x}", bitPattern, waitMode);
if (ef == nullptr) {
return ORBIS_KERNEL_ERROR_ESRCH;
}
if (bitPattern == 0) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
EventFlagInternal::WaitMode wait = EventFlagInternal::WaitMode::And;
EventFlagInternal::ClearMode clear = EventFlagInternal::ClearMode::None;
switch (waitMode & 0xf) {
case 0x01:
wait = EventFlagInternal::WaitMode::And;
break;
case 0x02:
wait = EventFlagInternal::WaitMode::Or;
break;
default:
UNREACHABLE();
}
switch (waitMode & 0xf0) {
case 0x00:
clear = EventFlagInternal::ClearMode::None;
break;
case 0x10:
clear = EventFlagInternal::ClearMode::All;
break;
case 0x20:
clear = EventFlagInternal::ClearMode::Bits;
break;
default:
UNREACHABLE();
}
auto result = ef->Wait(bitPattern, wait, clear, pResultPat, pTimeout);
if (result != ORBIS_OK) {
LOG_ERROR(Kernel_Event, "returned {}", result);
}
return result;
}
void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("PZku4ZrXJqg", "libkernel", 1, "libkernel", 1, 1, sceKernelCancelEventFlag);
LIB_FUNCTION("7uhBFWRAS60", "libkernel", 1, "libkernel", 1, 1, sceKernelClearEventFlag);
LIB_FUNCTION("s9-RaxukuzQ", "libkernel", 1, "libkernel", 1, 1, sceKernelCloseEventFlag);
LIB_FUNCTION("BpFoboUJoZU", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEventFlag);
LIB_FUNCTION("8mql9OcQnd4", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteEventFlag);
LIB_FUNCTION("1vDaenmJtyA", "libkernel", 1, "libkernel", 1, 1, sceKernelOpenEventFlag);
LIB_FUNCTION("9lvj5DjHZiA", "libkernel", 1, "libkernel", 1, 1, sceKernelPollEventFlag);
LIB_FUNCTION("IOnSvHzqu6A", "libkernel", 1, "libkernel", 1, 1, sceKernelSetEventFlag);
LIB_FUNCTION("JTvBflhYazQ", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEventFlag);
}
} // namespace Libraries::Kernel

View File

@ -0,0 +1,40 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
#include "event_flag_codes.h"
#include "event_flag_obj.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Kernel {
using OrbisKernelUseconds = u32;
using OrbisKernelEventFlag = EventFlagInternal*;
struct OrbisKernelEventFlagOptParam {
size_t size;
};
int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* pName, u32 attr,
u64 initPattern,
const OrbisKernelEventFlagOptParam* pOptParam);
int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef);
int PS4_SYSV_ABI sceKernelOpenEventFlag();
int PS4_SYSV_ABI sceKernelCloseEventFlag();
int PS4_SYSV_ABI sceKernelClearEventFlag(OrbisKernelEventFlag ef, u64 bitPattern);
int PS4_SYSV_ABI sceKernelCancelEventFlag(OrbisKernelEventFlag ef, u64 setPattern,
int* pNumWaitThreads);
int PS4_SYSV_ABI sceKernelSetEventFlag(OrbisKernelEventFlag ef, u64 bitPattern);
int PS4_SYSV_ABI sceKernelPollEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat);
int PS4_SYSV_ABI sceKernelWaitEventFlag(OrbisKernelEventFlag ef, u64 bitPattern, u32 waitMode,
u64* pResultPat, OrbisKernelUseconds* pTimeout);
void RegisterKernelEventFlag(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Kernel

View File

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
constexpr int ORBIS_KERNEL_EVF_ATTR_TH_FIFO = 0x01;
constexpr int ORBIS_KERNEL_EVF_ATTR_TH_PRIO = 0x02;
constexpr int ORBIS_KERNEL_EVF_ATTR_SINGLE = 0x10;
constexpr int ORBIS_KERNEL_EVF_ATTR_MULTI = 0x20;
constexpr int ORBIS_KERNEL_EVF_WAITMODE_AND = 0x01;
constexpr int ORBIS_KERNEL_EVF_WAITMODE_OR = 0x02;
constexpr int ORBIS_KERNEL_EVF_WAITMODE_CLEAR_ALL = 0x10;
constexpr int ORBIS_KERNEL_EVF_WAITMODE_CLEAR_PAT = 0x20;

View File

@ -0,0 +1,73 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <core/libraries/error_codes.h>
#include "event_flag_obj.h"
namespace Libraries::Kernel {
int EventFlagInternal::Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result,
u32* ptr_micros) {
std::unique_lock lock{m_mutex};
uint32_t micros = 0;
bool infinitely = true;
if (ptr_micros != nullptr) {
micros = *ptr_micros;
infinitely = false;
}
if (m_single_thread && m_waiting_threads > 0) {
return ORBIS_KERNEL_ERROR_EPERM;
}
auto const start = std::chrono::system_clock::now();
m_waiting_threads++;
auto waitFunc = [this, wait_mode, bits] {
return (m_status == Status::Canceled || m_status == Status::Deleted ||
(wait_mode == WaitMode::And && (m_bits & bits) == bits) ||
(wait_mode == WaitMode::Or && (m_bits & bits) != 0));
};
if (infinitely) {
m_cond_var.wait(lock, waitFunc);
} else {
if (!m_cond_var.wait_for(lock, std::chrono::microseconds(micros), waitFunc)) {
if (result != nullptr) {
*result = m_bits;
}
*ptr_micros = 0;
--m_waiting_threads;
return ORBIS_KERNEL_ERROR_ETIMEDOUT;
}
}
--m_waiting_threads;
if (result != nullptr) {
*result = m_bits;
}
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now() - start)
.count();
if (result != nullptr) {
*result = m_bits;
}
if (ptr_micros != nullptr) {
*ptr_micros = (elapsed >= micros ? 0 : micros - elapsed);
}
if (m_status == Status::Canceled) {
return ORBIS_KERNEL_ERROR_ECANCELED;
} else if (m_status == Status::Deleted) {
return ORBIS_KERNEL_ERROR_EACCES;
}
if (clear_mode == ClearMode::All) {
m_bits = 0;
} else if (clear_mode == ClearMode::Bits) {
m_bits &= ~bits;
}
return ORBIS_OK;
}
} // namespace Libraries::Kernel

View File

@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <condition_variable>
#include <mutex>
#include "common/types.h"
namespace Libraries::Kernel {
class EventFlagInternal {
public:
enum class ClearMode { None, All, Bits };
enum class WaitMode { And, Or };
EventFlagInternal(const std::string& name, bool single, bool fifo, uint64_t bits)
: m_name(name), m_single_thread(single), m_fifo(fifo), m_bits(bits){};
int Wait(u64 bits, WaitMode wait_mode, ClearMode clear_mode, u64* result, u32* ptr_micros);
private:
enum class Status { Set, Canceled, Deleted };
std::mutex m_mutex;
std::condition_variable m_cond_var;
Status m_status = Status::Set;
int m_waiting_threads = 0;
std::string m_name;
bool m_single_thread = false;
bool m_fifo = false;
u64 m_bits = 0;
};
} // namespace Libraries::Kernel

View File

@ -82,6 +82,15 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, void* buf, size_t nbytes) {
if (buf == nullptr) {
return SCE_KERNEL_ERROR_EFAULT;
}
if (d == 1) {
// temp, just to print the message. not a file?
// CUSA00402 - Crimsonland and probably other games.
char* msg = reinterpret_cast<char*>(buf);
size_t length = std::strlen(msg);
LOG_INFO(Kernel_Fs, "sceKernelWrite fd = 1, str = {}, length = {}", msg, length);
return length;
}
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
auto* file = h->GetFile(d);
if (file == nullptr) {
@ -159,7 +168,12 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) {
return SCE_KERNEL_ERROR_EEXIST;
}
if (!std::filesystem::create_directory(dir_name)) {
if (!std::filesystem::create_directories(dir_name)) {
// check me on saveDataMount.
// CUSA02456: calls sceSaveDataMount then mkdir
// CUSA00402: calls mkdir first before sceSaveDataMount
// maybe consider mounting save data at emu start? (added in main)
return SCE_KERNEL_ERROR_EIO;
}

View File

@ -8,6 +8,7 @@
#include "common/singleton.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/kernel/cpu_management.h"
#include "core/libraries/kernel/event_flag/event_flag.h"
#include "core/libraries/kernel/event_queues.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/libkernel.h"
@ -22,6 +23,7 @@
#include <windows.h>
#else
#include <sys/mman.h>
#include <unistd.h>
#endif
#include <core/file_format/psf.h>
@ -50,8 +52,19 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) {
return SCE_OK;
}
void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) {
int PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) {
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
return SCE_OK;
}
int PS4_SYSV_ABI posix_usleep(unsigned int microseconds) {
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
return SCE_OK;
}
u32 PS4_SYSV_ABI sceKernelSleep(unsigned int seconds) {
std::this_thread::sleep_for(std::chrono::seconds(seconds));
return SCE_OK;
}
struct iovec {
@ -197,6 +210,26 @@ s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
strlen(std::fgets(static_cast<char*>(buf), static_cast<int>(nbytes), stdin)));
}
s64 PS4_SYSV_ABI posix_getpagesize() {
return 4096;
}
int PS4_SYSV_ABI sceKernelGetCpumode() {
return SCE_KERNEL_CPUMODE_7CPU_NORMAL;
}
int PS4_SYSV_ABI scePthreadGetthreadid() {
#ifdef _WIN64
return GetCurrentProcessId();
#else
return getpid();
#endif
}
int PS4_SYSV_ABI posix_getpid() {
return scePthreadGetthreadid();
}
void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
// obj
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
@ -220,15 +253,23 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap);
LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep);
LIB_FUNCTION("QcteRwbsnV0", "libScePosix", 1, "libkernel", 1, 1, posix_usleep);
LIB_FUNCTION("-ZR+hG7aDHw", "libkernel", 1, "libkernel", 1, 1, sceKernelSleep);
LIB_FUNCTION("0wu33hunNdE", "libScePosix", 1, "libkernel", 1, 1, sceKernelSleep);
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam);
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
LIB_FUNCTION("VOx8NGmHXTs", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCpumode);
LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, scePthreadGetthreadid);
LIB_FUNCTION("HoLVWNanBBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpid);
Libraries::Kernel::fileSystemSymbolsRegister(sym);
Libraries::Kernel::timeSymbolsRegister(sym);
Libraries::Kernel::pthreadSymbolsRegister(sym);
Libraries::Kernel::RegisterKernelEventFlag(sym);
// temp
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,

View File

@ -12,6 +12,10 @@ class SymbolsResolver;
namespace Libraries::Kernel {
constexpr int SCE_KERNEL_CPUMODE_6CPU = 0;
constexpr int SCE_KERNEL_CPUMODE_7CPU_LOW = 1;
constexpr int SCE_KERNEL_CPUMODE_7CPU_NORMAL = 5;
struct OrbisTimesec {
time_t t;
u64 west_sec;

View File

@ -31,6 +31,10 @@ void init_pthreads() {
ScePthreadAttr default_attr = nullptr;
scePthreadAttrInit(&default_attr);
g_pthread_cxt->SetDefaultAttr(default_attr);
// default rwlock init
ScePthreadRwAttr default_rwattr = nullptr;
scePthreadRwlockattrInit(&default_rwattr);
g_pthread_cxt->setDefaultRwattr(default_rwattr);
g_pthread_cxt->SetPthreadPool(new PThreadPool);
}
@ -173,6 +177,22 @@ int PS4_SYSV_ABI scePthreadAttrSetdetachstate(ScePthreadAttr* attr, int detachst
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
}
int PS4_SYSV_ABI posix_pthread_attr_setdetachstate(ScePthreadAttr* attr, int detachstate) {
int result = scePthreadAttrSetdetachstate(attr, detachstate);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_attr_destroy(ScePthreadAttr* attr) {
int result = scePthreadAttrDestroy(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI scePthreadAttrSetinheritsched(ScePthreadAttr* attr, int inheritSched) {
if (attr == nullptr || *attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -710,7 +730,7 @@ int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, SceKernelTimespec* tp) {
return SCE_KERNEL_ERROR_EINVAL;
}
int PS4_SYSV_ABI clock_gettime(s32 clock_id, SceKernelTimespec* time) {
int PS4_SYSV_ABI ps4_clock_gettime(s32 clock_id, SceKernelTimespec* time) {
int result = sceKernelClockGettime(clock_id, time);
if (result < 0) {
UNREACHABLE(); // TODO return posix error code
@ -719,23 +739,24 @@ int PS4_SYSV_ABI clock_gettime(s32 clock_id, SceKernelTimespec* time) {
}
int PS4_SYSV_ABI sceKernelNanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
if (rqtp == nullptr) {
return SCE_KERNEL_ERROR_EFAULT;
}
if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0) {
return SCE_KERNEL_ERROR_EINVAL;
}
auto start = std::chrono::high_resolution_clock::now();
u64 nanos = rqtp->tv_sec * 1000000000 + rqtp->tv_nsec;
std::this_thread::sleep_for(std::chrono::nanoseconds(nanos));
if (rmtp != nullptr) {
UNREACHABLE(); // not supported yet
auto const end = std::chrono::high_resolution_clock::now();
auto const diff = std::chrono::duration_cast<std::chrono::nanoseconds>(start - end).count();
rmtp->tv_sec = (diff / 1000000000l);
rmtp->tv_nsec = (diff % 1000000000l);
}
return SCE_OK;
}
int PS4_SYSV_ABI nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
int PS4_SYSV_ABI posix_nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
int result = sceKernelNanosleep(rqtp, rmtp);
if (result < 0) {
UNREACHABLE(); // TODO return posix error code
@ -894,7 +915,13 @@ void PS4_SYSV_ABI scePthreadYield() {
}
int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
LOG_INFO(Kernel_Pthread, "thread create name = {}", thread->name);
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
thread->is_detached = true;
return ORBIS_OK;
}
int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) {
LOG_INFO(Kernel_Pthread, "thread detach name = {}", thread->name);
thread->is_detached = true;
return ORBIS_OK;
}
@ -903,6 +930,88 @@ ScePthread PS4_SYSV_ABI pthread_self() {
return g_pthread_self;
}
int PS4_SYSV_ABI scePthreadJoin(ScePthread thread, void** res) {
if (thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_join(thread->pth, res);
LOG_DEBUG(Kernel_Pthread, "scePthreadJoin: result = {}", result);
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
}
int PS4_SYSV_ABI scePthreadRename(ScePthread thread, const char* name) {
LOG_DEBUG(Kernel_Pthread, "scePthreadRename: name = {}", name);
thread->name = std::string(name);
return SCE_OK;
}
int PS4_SYSV_ABI scePthreadKeyCreate(pthread_key_t* key, void (*dest)(void*)) {
int result = pthread_key_create(key, dest); // Does dest really need sysv_abi?
LOG_INFO(Kernel_Pthread, "scePthreadKeyCreate: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case ENOMEM:
return SCE_KERNEL_ERROR_ENOMEM;
case EAGAIN:
return SCE_KERNEL_ERROR_EAGAIN;
case EINVAL:
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI posix_pthread_key_create(pthread_key_t* key, void (*dest)(void*)) {
int result = scePthreadKeyCreate(key, dest);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_setspecific(pthread_key_t key, void* ptr) {
int result = pthread_setspecific(key, ptr);
LOG_DEBUG(Kernel_Pthread, "posix_pthread_setspecific: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case ENOMEM:
return SCE_KERNEL_ERROR_ENOMEM;
case EAGAIN:
return SCE_KERNEL_ERROR_EAGAIN;
case EINVAL:
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadSetschedparam(ScePthread thread, int policy,
const SceKernelSchedParam* param) {
int ppolicy;
if (policy != SCHED_OTHER)
ppolicy = SCHED_OTHER;
int result = pthread_setschedparam(thread->pth, ppolicy, param);
// 0 only on win?
LOG_INFO(Kernel_Pthread, "Todo? scePthreadSetschedparam: policy = {}, result = {}", policy,
result);
return result;
}
int PS4_SYSV_ABI posix_pthread_setschedparam(ScePthread thread, int policy,
const SceKernelSchedParam* param) {
int result = scePthreadSetschedparam(thread, policy, param);
LOG_INFO(Kernel_Pthread, "Todo? posix_pthread_setschedparam: policy = {}, result = {}", policy,
result);
return result;
}
int PS4_SYSV_ABI posix_sched_get_priority_max(int algo) {
LOG_INFO(Kernel_Pthread, "posix_sched_get_priority_max: algo = {}", algo);
return SCE_KERNEL_PRIO_FIFO_HIGHEST;
}
int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
if (cond == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -923,9 +1032,9 @@ int PS4_SYSV_ABI scePthreadCondSignal(ScePthreadCond* cond) {
}
int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex) {
cond = static_cast<ScePthreadCond*>(createCond(cond));
if (cond == nullptr || *cond == nullptr) {
// return SCE_KERNEL_ERROR_EINVAL;
cond = static_cast<ScePthreadCond*>(createCond(cond)); // check this. Kero Blaster.
return SCE_KERNEL_ERROR_EINVAL;
}
if (mutex == nullptr || *mutex == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -946,6 +1055,53 @@ int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex
}
}
int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec) {
cond = static_cast<ScePthreadCond*>(createCond(cond));
if (cond == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
if (mutex == nullptr || *mutex == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
timespec time{};
time.tv_sec = usec / 1000000;
time.tv_nsec = ((usec % 1000000) * 1000);
int result = pthread_cond_timedwait(&(*cond)->cond, &(*mutex)->pth_mutex, &time);
LOG_INFO(Kernel_Pthread, "scePthreadCondTimedwait, result={}", result);
switch (result) {
case 0:
return SCE_OK;
case ETIMEDOUT:
return SCE_KERNEL_ERROR_ETIMEDOUT;
case EINTR:
return SCE_KERNEL_ERROR_EINTR;
case EAGAIN:
return SCE_KERNEL_ERROR_EAGAIN;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond) {
if (cond == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_cond_destroy(&(*cond)->cond);
LOG_INFO(Kernel_Pthread, "scePthreadCondDestroy, result={}", result);
switch (result) {
case 0:
return SCE_OK;
case EBUSY:
return SCE_KERNEL_ERROR_EBUSY;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr) {
if (attr == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
@ -991,26 +1147,307 @@ int PS4_SYSV_ABI scePthreadEqual(ScePthread thread1, ScePthread thread2) {
return (thread1 == thread2 ? 1 : 0);
}
int PS4_SYSV_ABI ps4_gettimeofday(SceKernelTimespec* tp /*, timezone */) {
if (tp == nullptr) {
return -1;
}
LOG_INFO(Kernel_Pthread, "ps4_gettimeofday");
auto now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(duration - seconds);
tp->tv_sec = static_cast<long>(seconds.count());
tp->tv_nsec = static_cast<long>(nanoseconds.count());
return 0;
}
int PS4_SYSV_ABI ps4_clock_getres(u32 clock_id, SceKernelTimespec* res) {
if (res == nullptr) {
return SCE_KERNEL_ERROR_EFAULT;
}
clockid_t pclock_id = CLOCK_REALTIME;
switch (clock_id) {
case 0:
pclock_id = CLOCK_REALTIME;
break;
case 13:
case 4:
pclock_id = CLOCK_MONOTONIC;
break;
default:
UNREACHABLE();
}
timespec t{};
int result = clock_getres(pclock_id, &t);
res->tv_sec = t.tv_sec;
res->tv_nsec = t.tv_nsec;
if (result == 0) {
return SCE_OK;
}
return SCE_KERNEL_ERROR_EINVAL;
}
int PS4_SYSV_ABI posix_pthread_mutexattr_init(ScePthreadMutexattr* attr) {
int result = scePthreadMutexattrInit(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_mutexattr_destroy(ScePthreadMutexattr* attr) {
int result = scePthreadMutexattrDestroy(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_mutexattr_settype(ScePthreadMutexattr* attr, int type) {
int result = scePthreadMutexattrSettype(attr, type);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg) {
int result = scePthreadCreate(thread, attr, start_routine, arg, "");
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_cond_init(ScePthreadCond* cond, const ScePthreadCondattr* attr) {
int result = scePthreadCondInit(cond, attr, "");
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_attr_init(ScePthreadAttr* attr) {
int result = scePthreadAttrInit(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_attr_setstacksize(ScePthreadAttr* attr, size_t stack_size) {
int result = scePthreadAttrSetstacksize(attr, stack_size);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_cond_wait(ScePthreadCond* cond, ScePthreadMutex* mutex) {
int result = scePthreadCondWait(cond, mutex);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(ScePthreadMutexattr* attr, u32 protocol) {
int result = scePthreadMutexattrSetprotocol(attr, protocol);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_mutex_trylock(ScePthreadMutex* mutex) {
int result = scePthreadMutexTrylock(mutex);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_condattr_init(ScePthreadCondattr* attr) {
int result = scePthreadCondattrInit(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_condattr_destroy(ScePthreadCondattr* attr) {
int result = scePthreadCondattrDestroy(attr);
if (result < 0) {
UNREACHABLE();
}
return result;
}
/****
* rwlock
*/
int PS4_SYSV_ABI scePthreadRwlockInit(ScePthreadRw* thread, ScePthreadRwAttr* attr,
const char* name) {
*thread = new PthreadRwInternal{};
if (thread == nullptr || *thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
if (attr == nullptr || *attr == nullptr) {
attr = g_pthread_cxt->getDefaultRwattr();
}
int result = pthread_rwlock_init(&(*thread)->pth_rwlock, &(*attr)->attr_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockInit: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case ENOMEM:
return SCE_KERNEL_ERROR_ENOMEM;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadRwlockRdlock(ScePthreadRw* thread) {
if (thread == nullptr || *thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_rwlock_rdlock(&(*thread)->pth_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockRdlock: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case EBUSY:
return SCE_KERNEL_ERROR_EBUSY;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadRwlockWrlock(ScePthreadRw* thread) {
if (thread == nullptr || *thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_rwlock_wrlock(&(*thread)->pth_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockWrlock: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case EBUSY:
return SCE_KERNEL_ERROR_EBUSY;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadRwlockUnlock(ScePthreadRw* thread) {
if (thread == nullptr || *thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_rwlock_unlock(&(*thread)->pth_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockUnlock: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case EBUSY:
return SCE_KERNEL_ERROR_EBUSY;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
return 0;
}
int PS4_SYSV_ABI scePthreadRwlockDestroy(ScePthreadRw* thread) {
if (thread == nullptr || *thread == nullptr) {
return SCE_KERNEL_ERROR_EINVAL;
}
int result = pthread_rwlock_destroy(&(*thread)->pth_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockDestroy: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case EBUSY:
return SCE_KERNEL_ERROR_EBUSY;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
}
int PS4_SYSV_ABI scePthreadRwlockattrInit(ScePthreadRwAttr* attr) {
*attr = new PthreadRwLockAttrInernal{};
int result = pthread_rwlockattr_init(&(*attr)->attr_rwlock);
LOG_INFO(Kernel_Pthread, "scePthreadRwlockattrInit: result = {}", result);
switch (result) {
case 0:
return SCE_OK;
case ENOMEM:
return SCE_KERNEL_ERROR_ENOMEM;
default:
return SCE_KERNEL_ERROR_EINVAL;
}
return 0;
}
int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(ScePthreadRw* thread) {
int result = scePthreadRwlockRdlock(thread);
if (result < 0) {
UNREACHABLE();
}
return result;
}
int PS4_SYSV_ABI posix_pthread_rwlock_unlock(ScePthreadRw* thread) {
int result = scePthreadRwlockUnlock(thread);
if (result < 0) {
UNREACHABLE();
}
return result;
}
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
// pthreadattr calls
LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedpolicy);
LIB_FUNCTION("-Wreprtu0Qs", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetdetachstate);
LIB_FUNCTION("eXbUSpEaTsA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetinheritsched);
LIB_FUNCTION("DzES9hQF4f4", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetschedparam);
LIB_FUNCTION("nsYoNRywwNg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrInit);
LIB_FUNCTION("62KCwEMmzcM", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrDestroy);
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self);
LIB_FUNCTION("3qxgM4ezETA", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetaffinity);
LIB_FUNCTION("8+s5BzZjxSg", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGetaffinity);
LIB_FUNCTION("x1X76arYMxU", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrGet);
LIB_FUNCTION("UTXzJbWhhTE", "libkernel", 1, "libkernel", 1, 1, scePthreadAttrSetstacksize);
LIB_FUNCTION("E+tyo3lp5Lw", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_attr_setdetachstate);
LIB_FUNCTION("zHchY8ft5pk", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_destroy);
LIB_FUNCTION("4qGrR6eoP9Y", "libkernel", 1, "libkernel", 1, 1, scePthreadDetach);
LIB_FUNCTION("3PtV6p3QNX4", "libkernel", 1, "libkernel", 1, 1, scePthreadEqual);
LIB_FUNCTION("aI+OeCz8xrQ", "libkernel", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("EotR8a3ASf4", "libkernel", 1, "libkernel", 1, 1, pthread_self);
LIB_FUNCTION("EotR8a3ASf4", "libScePosix", 1, "libkernel", 1, 1, scePthreadSelf);
LIB_FUNCTION("bt3CTBKmGyI", "libkernel", 1, "libkernel", 1, 1, scePthreadSetaffinity);
LIB_FUNCTION("6UgtwV+0zb4", "libkernel", 1, "libkernel", 1, 1, scePthreadCreate);
LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, scePthreadYield);
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, scePthreadKeyCreate);
LIB_FUNCTION("oIRFTjoILbg", "libkernel", 1, "libkernel", 1, 1, scePthreadSetschedparam);
LIB_FUNCTION("mqULNdimTn0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_key_create);
LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_key_create);
LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_setspecific);
LIB_FUNCTION("Xs9hdiD7sAA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setschedparam);
LIB_FUNCTION("CBNtXOoef-E", "libScePosix", 1, "libkernel", 1, 1, posix_sched_get_priority_max);
LIB_FUNCTION("+U1R4WtXvoc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_detach);
// mutex calls
LIB_FUNCTION("cmo1RIYva9o", "libkernel", 1, "libkernel", 1, 1, scePthreadMutexInit);
@ -1027,23 +1464,62 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("m5-2bsNfv7s", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrInit);
LIB_FUNCTION("JGgj7Uvrl+A", "libkernel", 1, "libkernel", 1, 1, scePthreadCondBroadcast);
LIB_FUNCTION("WKAXJ4XBPQ4", "libkernel", 1, "libkernel", 1, 1, scePthreadCondWait);
LIB_FUNCTION("BmMjYxmew1w", "libkernel", 1, "libkernel", 1, 1, scePthreadCondTimedwait);
LIB_FUNCTION("waPcxYiR3WA", "libkernel", 1, "libkernel", 1, 1, scePthreadCondattrDestroy);
LIB_FUNCTION("kDh-NfxgMtE", "libkernel", 1, "libkernel", 1, 1, scePthreadCondSignal);
LIB_FUNCTION("g+PZd2hiacg", "libkernel", 1, "libkernel", 1, 1, scePthreadCondDestroy);
// Rwlock funstions
LIB_FUNCTION("6ULAa0fq4jA", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockInit);
LIB_FUNCTION("yOfGg-I1ZII", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockattrInit);
LIB_FUNCTION("Ox9i0c7L5w0", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockRdlock);
LIB_FUNCTION("mqdNorrB+gI", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockWrlock);
LIB_FUNCTION("+L98PIbGttk", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockUnlock);
LIB_FUNCTION("BB+kb08Tl9A", "libkernel", 1, "libkernel", 1, 1, scePthreadRwlockDestroy);
LIB_FUNCTION("iGjsr1WAtI0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_rdlock);
LIB_FUNCTION("EgmLo6EWgso", "libkernel", 1, "libkernel", 1, 1, posix_pthread_rwlock_unlock);
// posix calls
LIB_FUNCTION("ttHNfU+qDBU", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_init);
LIB_FUNCTION("7H0iTOciTLo", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
LIB_FUNCTION("K-jXhbt2gn4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_trylock);
LIB_FUNCTION("2Z+PpY6CaJg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
LIB_FUNCTION("mkx2fVhNMsg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast);
LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime);
LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, clock_gettime);
LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, clock_gettime);
LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, nanosleep);
LIB_FUNCTION("dQHWEsJtoE4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_mutexattr_init);
LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_mutexattr_destroy);
LIB_FUNCTION("mDmgMOGVUqg", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_mutexattr_settype);
LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create);
LIB_FUNCTION("0TyVk4MSLt0", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_init);
LIB_FUNCTION("wtkt-teR1so", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_init);
LIB_FUNCTION("2Q0z6rnBrTE", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_attr_setstacksize);
LIB_FUNCTION("Op8TBGY5KHg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_cond_wait);
LIB_FUNCTION("mKoTx03HRWA", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_condattr_init);
LIB_FUNCTION("dJcuQVn6-Iw", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_condattr_destroy);
LIB_FUNCTION("5txKfcMUAok", "libScePosix", 1, "libkernel", 1, 1,
posix_pthread_mutexattr_setprotocol);
// openorbis weird functions
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
LIB_FUNCTION("2Z+PpY6CaJg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_unlock);
LIB_FUNCTION("mkx2fVhNMsg", "libkernel", 1, "libkernel", 1, 1, posix_pthread_cond_broadcast);
// time
LIB_FUNCTION("QBi7HCK03hw", "libkernel", 1, "libkernel", 1, 1, sceKernelClockGettime);
LIB_FUNCTION("QvsZxomvUHs", "libkernel", 1, "libkernel", 1, 1, sceKernelNanosleep);
LIB_FUNCTION("lLMT9vJAck0", "libkernel", 1, "libkernel", 1, 1, ps4_clock_gettime);
LIB_FUNCTION("lLMT9vJAck0", "libScePosix", 1, "libkernel", 1, 1, ps4_clock_gettime);
LIB_FUNCTION("yS8U2TGCe1A", "libScePosix", 1, "libkernel", 1, 1, posix_nanosleep);
LIB_FUNCTION("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1,
posix_nanosleep); // CUSA18841
LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, ps4_gettimeofday);
LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, ps4_gettimeofday);
LIB_FUNCTION("ejekcaNQNq0", "libkernel", 1, "libkernel", 1, 1,
ps4_gettimeofday); // sceKernelGettimeofday
LIB_FUNCTION("smIj7eqzZE8", "libScePosix", 1, "libkernel", 1, 1, ps4_clock_getres);
}
} // namespace Libraries::Kernel

View File

@ -17,12 +17,21 @@ class SymbolsResolver;
namespace Libraries::Kernel {
/* sceKernelSchedGetPriorityMax/Min */
constexpr int SCE_KERNEL_SCHED_FIFO = SCHED_FIFO;
constexpr int SCE_KERNEL_SCHED_RR = SCHED_RR;
constexpr int SCE_KERNEL_PRIO_FIFO_DEFAULT = 700;
constexpr int SCE_KERNEL_PRIO_FIFO_HIGHEST = 256;
constexpr int SCE_KERNEL_PRIO_FIFO_LOWEST = 767;
struct PthreadInternal;
struct PthreadAttrInternal;
struct PthreadMutexInternal;
struct PthreadMutexattrInternal;
struct PthreadCondInternal;
struct PthreadCondAttrInternal;
struct PthreadRwInternal;
struct PthreadRwLockAttrInernal;
using SceKernelSchedParam = ::sched_param;
using ScePthread = PthreadInternal*;
@ -31,13 +40,12 @@ using ScePthreadMutex = PthreadMutexInternal*;
using ScePthreadMutexattr = PthreadMutexattrInternal*;
using ScePthreadCond = PthreadCondInternal*;
using ScePthreadCondattr = PthreadCondAttrInternal*;
using ScePthreadRw = PthreadRwInternal*;
using ScePthreadRwAttr = PthreadRwLockAttrInernal*;
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
struct SceKernelTimespec {
int64_t tv_sec;
int64_t tv_nsec;
};
typedef struct timespec SceKernelTimespec;
struct PthreadInternal {
u8 reserved[4096];
@ -84,6 +92,19 @@ struct PthreadCondAttrInternal {
pthread_condattr_t cond_attr;
};
struct PthreadRwLockAttrInernal {
u64 initialized = 1;
u8 reserved[64];
pthread_rwlockattr_t attr_rwlock;
int type;
};
struct PthreadRwInternal {
u64 initialized = 1;
pthread_rwlock_t pth_rwlock;
std::string name;
};
class PThreadPool {
public:
ScePthread Create();
@ -113,6 +134,12 @@ public:
void SetDefaultAttr(ScePthreadAttr attr) {
m_default_attr = attr;
}
ScePthreadRwAttr* getDefaultRwattr() {
return &m_default_Rwattr;
}
void setDefaultRwattr(ScePthreadRwAttr attr) {
m_default_Rwattr = attr;
}
PThreadPool* GetPthreadPool() {
return m_pthread_pool;
}
@ -123,6 +150,7 @@ public:
private:
ScePthreadMutexattr m_default_mutexattr = nullptr;
ScePthreadCondattr m_default_condattr = nullptr;
ScePthreadRwAttr m_default_Rwattr = nullptr;
ScePthreadAttr m_default_attr = nullptr;
PThreadPool* m_pthread_pool = nullptr;
};
@ -142,6 +170,13 @@ int PS4_SYSV_ABI scePthreadAttrSetaffinity(ScePthreadAttr* pattr,
int PS4_SYSV_ABI scePthreadSetaffinity(ScePthread thread, const /*SceKernelCpumask*/ u64 mask);
int PS4_SYSV_ABI scePthreadCreate(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg, const char* name);
int PS4_SYSV_ABI scePthreadJoin(ScePthread thread, void** res);
int PS4_SYSV_ABI scePthreadRename(ScePthread thread, const char* name);
int PS4_SYSV_ABI scePthreadKeyCreate(pthread_key_t* key, void (*dest)(void*));
int PS4_SYSV_ABI posix_pthread_create(ScePthread* thread, const ScePthreadAttr* attr,
pthreadEntryFunc start_routine, void* arg);
int PS4_SYSV_ABI posix_pthread_key_create(pthread_key_t* key, void (*dest)(void*));
int PS4_SYSV_ABI posix_pthread_setspecific(pthread_key_t key, void* ptr);
/***
* Mutex calls
@ -160,6 +195,23 @@ int PS4_SYSV_ABI scePthreadCondInit(ScePthreadCond* cond, const ScePthreadCondat
const char* name);
int PS4_SYSV_ABI scePthreadCondattrInit(ScePthreadCondattr* attr);
int PS4_SYSV_ABI scePthreadCondBroadcast(ScePthreadCond* cond);
int PS4_SYSV_ABI scePthreadCondWait(ScePthreadCond* cond, ScePthreadMutex* mutex);
int PS4_SYSV_ABI scePthreadCondTimedwait(ScePthreadCond* cond, ScePthreadMutex* mutex, u64 usec);
int PS4_SYSV_ABI scePthreadCondattrDestroy(ScePthreadCondattr* attr);
int PS4_SYSV_ABI scePthreadCondDestroy(ScePthreadCond* cond);
/****
* rwlock calls
*/
int PS4_SYSV_ABI scePthreadRwlockInit(ScePthreadRw* thread, ScePthreadRwAttr* attr,
const char* name);
int PS4_SYSV_ABI scePthreadRwlockRdlock(ScePthreadRw* thread);
int PS4_SYSV_ABI scePthreadRwlockWrlock(ScePthreadRw* thread);
int PS4_SYSV_ABI scePthreadRwlockUnlock(ScePthreadRw* thread);
int PS4_SYSV_ABI scePthreadRwlockDestroy(ScePthreadRw* thread);
int PS4_SYSV_ABI scePthreadRwlockattrInit(ScePthreadRwAttr* attr);
int PS4_SYSV_ABI posix_pthread_rwlock_rdlock(ScePthreadRw* thread);
int PS4_SYSV_ABI posix_pthread_rwlock_unlock(ScePthreadRw* thread);
/****
* Posix calls
*/

View File

@ -17,6 +17,7 @@
#include "core/libraries/np_score/np_score.h"
#include "core/libraries/np_trophy/np_trophy.h"
#include "core/libraries/pad/pad.h"
#include "core/libraries/rtc/rtc.h"
#include "core/libraries/save_data/savedata.h"
#include "core/libraries/screenshot/screenshot.h"
#include "core/libraries/system/commondialog.h"
@ -59,6 +60,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
Libraries::LibcInternal::RegisterlibSceLibcInternal(sym);
Libraries::Rtc::RegisterlibSceRtc(sym);
}
} // namespace Libraries

View File

@ -0,0 +1,322 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// Generated By moduleGenerator
#include <chrono>
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/libs.h"
#include "rtc.h"
namespace Libraries::Rtc {
int PS4_SYSV_ABI sceRtcCheckValid() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcCompareTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcEnd() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC2822() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC3339() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC3339Precise() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentClock() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime) {
auto now = std::chrono::system_clock::now();
auto now_ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(now);
auto epoch = now_ns.time_since_epoch();
auto micros = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
std::time_t now_time_t = std::chrono::system_clock::to_time_t(now);
std::tm local_tm = *std::localtime(&now_time_t);
pTime->year = local_tm.tm_year + 1900;
pTime->month = local_tm.tm_mon + 1;
pTime->day = local_tm.tm_mday;
pTime->hour = local_tm.tm_hour;
pTime->minute = local_tm.tm_min;
pTime->second = local_tm.tm_sec;
pTime->microsecond = micros.count() % 1000000;
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) {
pTick->tick = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch())
.count();
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) {
std::tm timeinfo = {0};
timeinfo.tm_year = year - 1900;
timeinfo.tm_mon = month - 1;
timeinfo.tm_mday = day;
std::mktime(&timeinfo);
return timeinfo.tm_wday;
}
int PS4_SYSV_ABI sceRtcGetDaysInMonth() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetDosTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetTickResolution() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetTime_t() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcGetWin32FileTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcInit() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcIsLeapYear() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcParseDateTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcParseRFC3339() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetConf() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetCurrentTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetDosTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetTick() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetTime_t() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcSetWin32FileTime() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddDays() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddHours() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddMicroseconds() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddMinutes() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddMonths() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddSeconds() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddTicks() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddWeeks() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceRtcTickAddYears() {
LOG_ERROR(Lib_Rtc, "(STUBBED) called");
return ORBIS_OK;
}
void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("lPEBYdVX0XQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCheckValid);
LIB_FUNCTION("fNaZ4DbzHAE", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcCompareTick);
LIB_FUNCTION("8Yr143yEnRo", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcConvertLocalTimeToUtc);
LIB_FUNCTION("M1TvFst-jrM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcConvertUtcToLocalTime);
LIB_FUNCTION("8SljQx6pDP8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcEnd);
LIB_FUNCTION("eiuobaF-hK4", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC2822);
LIB_FUNCTION("AxHBk3eat04", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC2822LocalTime);
LIB_FUNCTION("WJ3rqFwymew", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339);
LIB_FUNCTION("DwuHIlLGW8I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339LocalTime);
LIB_FUNCTION("lja0nNPWojg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcFormatRFC3339Precise);
LIB_FUNCTION("tOZ6fwwHZOA", "libSceRtc", 1, "libSceRtc", 1, 1,
sceRtcFormatRFC3339PreciseLocalTime);
LIB_FUNCTION("LN3Zcb72Q0c", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentAdNetworkTick);
LIB_FUNCTION("8lfvnRMqwEM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentClock);
LIB_FUNCTION("ZPD1YOKI+Kw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentClockLocalTime);
LIB_FUNCTION("Ot1DE3gif84", "libSceRtc", 1, "libSceRtc", 1, 1,
sceRtcGetCurrentDebugNetworkTick);
LIB_FUNCTION("zO9UL3qIINQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentNetworkTick);
LIB_FUNCTION("HWxHOdbM-Pg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentRawNetworkTick);
LIB_FUNCTION("18B2NS1y9UU", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetCurrentTick);
LIB_FUNCTION("CyIK-i4XdgQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDayOfWeek);
LIB_FUNCTION("3O7Ln8AqJ1o", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDaysInMonth);
LIB_FUNCTION("E7AR4o7Ny7E", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetDosTime);
LIB_FUNCTION("8w-H19ip48I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTick);
LIB_FUNCTION("jMNwqYr4R-k", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTickResolution);
LIB_FUNCTION("BtqmpTRXHgk", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetTime_t);
LIB_FUNCTION("jfRO0uTjtzA", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcGetWin32FileTime);
LIB_FUNCTION("LlodCMDbk3o", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcInit);
LIB_FUNCTION("Ug8pCwQvh0c", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcIsLeapYear);
LIB_FUNCTION("NxEI1KByvCI", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcParseDateTime);
LIB_FUNCTION("99bMGglFW3I", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcParseRFC3339);
LIB_FUNCTION("fFLgmNUpChg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetConf);
LIB_FUNCTION("sV2tK+yOhBU", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentAdNetworkTick);
LIB_FUNCTION("VLDUPKmw5L8", "libSceRtc", 1, "libSceRtc", 1, 1,
sceRtcSetCurrentDebugNetworkTick);
LIB_FUNCTION("qhDBtIo+auw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentNetworkTick);
LIB_FUNCTION("d4fHLCGmY80", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetCurrentTick);
LIB_FUNCTION("aYPCd1cChyg", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetDosTime);
LIB_FUNCTION("ueega6v3GUw", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetTick);
LIB_FUNCTION("bDEVVP4bTjQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetTime_t);
LIB_FUNCTION("n5JiAJXsbcs", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcSetWin32FileTime);
LIB_FUNCTION("NR1J0N7L2xY", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddDays);
LIB_FUNCTION("MDc5cd8HfCA", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddHours);
LIB_FUNCTION("XPIiw58C+GM", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMicroseconds);
LIB_FUNCTION("mn-tf4QiFzk", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMinutes);
LIB_FUNCTION("CL6y9q-XbuQ", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddMonths);
LIB_FUNCTION("07O525HgICs", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddSeconds);
LIB_FUNCTION("AqVMssr52Rc", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddTicks);
LIB_FUNCTION("gI4t194c2W8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddWeeks);
LIB_FUNCTION("-5y2uJ62qS8", "libSceRtc", 1, "libSceRtc", 1, 1, sceRtcTickAddYears);
};
} // namespace Libraries::Rtc

View File

@ -0,0 +1,77 @@
// 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::Rtc {
struct OrbisRtcTick {
u64 tick;
};
struct OrbisRtcDateTime {
u16 year;
u16 month;
u16 day;
u16 hour;
u16 minute;
u16 second;
u16 microsecond;
};
int PS4_SYSV_ABI sceRtcCheckValid();
int PS4_SYSV_ABI sceRtcCompareTick();
int PS4_SYSV_ABI sceRtcConvertLocalTimeToUtc();
int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime();
int PS4_SYSV_ABI sceRtcEnd();
int PS4_SYSV_ABI sceRtcFormatRFC2822();
int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime();
int PS4_SYSV_ABI sceRtcFormatRFC3339();
int PS4_SYSV_ABI sceRtcFormatRFC3339LocalTime();
int PS4_SYSV_ABI sceRtcFormatRFC3339Precise();
int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime();
int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick();
int PS4_SYSV_ABI sceRtcGetCurrentClock();
int PS4_SYSV_ABI sceRtcGetCurrentClockLocalTime(OrbisRtcDateTime* pTime);
int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick();
int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick();
int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick();
int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick);
int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day);
int PS4_SYSV_ABI sceRtcGetDaysInMonth();
int PS4_SYSV_ABI sceRtcGetDosTime();
int PS4_SYSV_ABI sceRtcGetTick();
int PS4_SYSV_ABI sceRtcGetTickResolution();
int PS4_SYSV_ABI sceRtcGetTime_t();
int PS4_SYSV_ABI sceRtcGetWin32FileTime();
int PS4_SYSV_ABI sceRtcInit();
int PS4_SYSV_ABI sceRtcIsLeapYear();
int PS4_SYSV_ABI sceRtcParseDateTime();
int PS4_SYSV_ABI sceRtcParseRFC3339();
int PS4_SYSV_ABI sceRtcSetConf();
int PS4_SYSV_ABI sceRtcSetCurrentAdNetworkTick();
int PS4_SYSV_ABI sceRtcSetCurrentDebugNetworkTick();
int PS4_SYSV_ABI sceRtcSetCurrentNetworkTick();
int PS4_SYSV_ABI sceRtcSetCurrentTick();
int PS4_SYSV_ABI sceRtcSetDosTime();
int PS4_SYSV_ABI sceRtcSetTick();
int PS4_SYSV_ABI sceRtcSetTime_t();
int PS4_SYSV_ABI sceRtcSetWin32FileTime();
int PS4_SYSV_ABI sceRtcTickAddDays();
int PS4_SYSV_ABI sceRtcTickAddHours();
int PS4_SYSV_ABI sceRtcTickAddMicroseconds();
int PS4_SYSV_ABI sceRtcTickAddMinutes();
int PS4_SYSV_ABI sceRtcTickAddMonths();
int PS4_SYSV_ABI sceRtcTickAddSeconds();
int PS4_SYSV_ABI sceRtcTickAddTicks();
int PS4_SYSV_ABI sceRtcTickAddWeeks();
int PS4_SYSV_ABI sceRtcTickAddYears();
void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Rtc

View File

@ -4,5 +4,7 @@
#pragma once
constexpr int ORBIS_SAVE_DATA_ERROR_PARAMETER = 0x809f0000;
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED =
0x809f0001; // save data library not initialized yet
constexpr int ORBIS_SAVE_DATA_ERROR_NOT_FOUND = 0x809f0008; // save data doesn't exist
constexpr int ORBIS_SAVE_DATA_ERROR_EXISTS = 0x809f0007; // save data directory,same name exists

View File

@ -13,7 +13,7 @@
#include "error_codes.h"
namespace Libraries::SaveData {
static bool initialized = false;
static std::string g_mount_point = "/savedata0"; // temp mount point (todo)
int PS4_SYSV_ABI sceSaveDataAbort() {
@ -241,8 +241,11 @@ int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataGetMountInfo() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataMountInfo* info) {
LOG_ERROR(Lib_SaveData, "(STUBBED) called, mount = {}", mountPoint->data);
info->blocks = 100000;
info->freeBlocks = 100000;
return ORBIS_OK;
}
@ -296,17 +299,20 @@ int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize() {
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize2() {
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataInitialize3() {
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam) {
initialized = true; // todo.
LOG_ERROR(Lib_SaveData, "(DUMMY) called");
return ORBIS_OK;
}
@ -331,32 +337,25 @@ int PS4_SYSV_ABI sceSaveDataLoadIcon() {
return ORBIS_OK;
}
int PS4_SYSV_ABI sceSaveDataMount() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
OrbisSaveDataMountResult* mount_result) {
LOG_INFO(Lib_SaveData, "called user_id = {} dir_name = {} blocks = {} mount_mode = {}",
mount->user_id, mount->dir_name->data, mount->blocks, mount->mount_mode);
auto* param_sfo = Common::Singleton<PSF>::Instance();
std::string id(param_sfo->GetString("CONTENT_ID"), 7, 9);
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
std::to_string(mount->user_id) / "savedata" / id /
std::string(mount->dir_name->data);
switch (mount->mount_mode) {
std::to_string(user_id) / "savedata" / id / dir_name;
switch (mount_mode) {
case ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
case ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: {
if (!std::filesystem::exists(mount_dir)) {
return ORBIS_SAVE_DATA_ERROR_NOT_FOUND;
if (!initialized /* !std::filesystem::exists(mount_dir)*/) {
// check this. example: CUSA02456
return ORBIS_SAVE_DATA_ERROR_NOT_INITIALIZED;
}
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point);
mount_result->mount_status = 0;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
LOG_ERROR(Lib_SaveData, "mount = {}", mount_result->mount_point.data);
} break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR:
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
@ -372,6 +371,18 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break;
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR |
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON: {
if (!std::filesystem::exists(mount_dir)) {
std::filesystem::create_directories(mount_dir);
}
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
mnt->Mount(mount_dir, g_mount_point);
mount_result->mount_status = 1;
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
} break;
default:
UNREACHABLE();
}
@ -380,6 +391,28 @@ s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
OrbisSaveDataMountResult* mount_result) {
if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
}
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
mount_result);
}
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
OrbisSaveDataMountResult* mount_result) {
if (mount == nullptr) {
return ORBIS_SAVE_DATA_ERROR_PARAMETER;
}
LOG_INFO(Lib_SaveData, "called: mount = {}, mode = {}, blocks = {}", mount->dir_name->data,
mount->mount_mode, mount->blocks);
return saveDataMount(mount->user_id, std::string(mount->dir_name->data), mount->mount_mode,
mount_result);
}
int PS4_SYSV_ABI sceSaveDataMount5() {
LOG_ERROR(Lib_SaveData, "(STUBBED) called");
return ORBIS_OK;

View File

@ -29,6 +29,30 @@ struct OrbisSaveDataMount2 {
s32 unk2;
};
constexpr int SCE_SAVE_DATA_TITLE_ID_DATA_SIZE = 10;
typedef struct OrbisSaveDataTitleId {
char data[SCE_SAVE_DATA_TITLE_ID_DATA_SIZE];
char padding[6];
} OrbisSaveDataTitleId;
constexpr int SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE = 65;
typedef struct OrbisSaveDataFingerprint {
char data[SCE_SAVE_DATA_FINGERPRINT_DATA_SIZE];
char padding[15];
} OrbisSaveDataFingerprint;
typedef struct OrbisSaveDataMount {
s32 user_id;
s32 pad;
const OrbisSaveDataTitleId* titleId;
const OrbisSaveDataDirName* dir_name;
const OrbisSaveDataFingerprint* fingerprint;
u64 blocks;
u32 mount_mode;
u8 reserved[32];
} OrbisSaveDataMount;
struct OrbisSaveDataMountPoint {
char data[ORBIS_SAVE_DATA_MOUNT_POINT_DATA_MAXSIZE];
};
@ -42,6 +66,14 @@ struct OrbisSaveDataMountResult {
s32 unk1;
};
typedef struct OrbisSaveDataMountInfo {
u64 blocks; // total num of blocks
u64 freeBlocks; // free num of blocks
uint8_t reserved[32];
} OrbisSaveDataMountInfo;
typedef struct _OrbisSaveDataInitParams OrbisSaveDataInitParams;
// savedataMount2 mountModes (ORed values)
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY = 1;
constexpr int ORBIS_SAVE_DATA_MOUNT_MODE_RDWR = 2;
@ -95,7 +127,8 @@ int PS4_SYSV_ABI sceSaveDataGetEventInfo();
int PS4_SYSV_ABI sceSaveDataGetEventResult();
int PS4_SYSV_ABI sceSaveDataGetFormat();
int PS4_SYSV_ABI sceSaveDataGetMountedSaveDataCount();
int PS4_SYSV_ABI sceSaveDataGetMountInfo();
int PS4_SYSV_ABI sceSaveDataGetMountInfo(OrbisSaveDataMountPoint* mountPoint,
OrbisSaveDataMountInfo* info);
int PS4_SYSV_ABI sceSaveDataGetParam();
int PS4_SYSV_ABI sceSaveDataGetProgress();
int PS4_SYSV_ABI sceSaveDataGetSaveDataCount();
@ -106,14 +139,15 @@ int PS4_SYSV_ABI sceSaveDataGetSaveDataRootPath();
int PS4_SYSV_ABI sceSaveDataGetSaveDataRootUsbPath();
int PS4_SYSV_ABI sceSaveDataGetSavePoint();
int PS4_SYSV_ABI sceSaveDataGetUpdatedDataCount();
int PS4_SYSV_ABI sceSaveDataInitialize();
int PS4_SYSV_ABI sceSaveDataInitialize2();
int PS4_SYSV_ABI sceSaveDataInitialize3();
int PS4_SYSV_ABI sceSaveDataInitialize(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitialize2(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitialize3(const OrbisSaveDataInitParams* initParam);
int PS4_SYSV_ABI sceSaveDataInitializeForCdlg();
int PS4_SYSV_ABI sceSaveDataIsDeletingUsbDb();
int PS4_SYSV_ABI sceSaveDataIsMounted();
int PS4_SYSV_ABI sceSaveDataLoadIcon();
int PS4_SYSV_ABI sceSaveDataMount();
int PS4_SYSV_ABI sceSaveDataMount(const OrbisSaveDataMount* mount,
OrbisSaveDataMountResult* mount_result);
s32 PS4_SYSV_ABI sceSaveDataMount2(const OrbisSaveDataMount2* mount,
OrbisSaveDataMountResult* mount_result);
int PS4_SYSV_ABI sceSaveDataMount5();

View File

@ -63,6 +63,13 @@ int main(int argc, char* argv[]) {
u32 fw_version = param_sfo->GetInteger("SYSTEM_VER");
std::string app_version = param_sfo->GetString("APP_VER");
LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version);
// Just testing for now.
// Working fine, one case only so far (CUSA00402 - Crimsonland)
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir) /
"1" / "savedata" / id;
mnt->Mount(mount_dir, "/savedata0");
} else if (entry.path().filename() == "pic0.png" ||
entry.path().filename() == "pic1.png") {
auto* splash = Common::Singleton<Splash>::Instance();