kernel: Implement gettimeofday + other misc fixes (#187)
* kernel: Add gettimeofday * kernel: Move sceKernelReleaseDirectMemory where it belongs * savedata: Stub sceSaveDataDialogUpdateStatus to return finished * memory: Add lock to VirtualQuery and remove debug print * clang format * fixed linux build? * special case for sceKernelWrite (stdin,stdout,stderr) * special case for case savedata mount * reduced mutex spamming * added missing default rwlock attributes init * kernel: Add more sleep functions * file_system: Add some functions * memory: Missed adding some functions * kernel: Moved some functions to time * kernel: Fix build error --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
7b1a317b09
commit
8ce58389ad
|
@ -32,7 +32,7 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) {
|
||||||
bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0;
|
bool directory = (flags & ORBIS_KERNEL_O_DIRECTORY) != 0;
|
||||||
|
|
||||||
if (directory) {
|
if (directory) {
|
||||||
UNREACHABLE(); // not supported yet
|
LOG_ERROR(Kernel_Fs, "called on directory");
|
||||||
} else {
|
} else {
|
||||||
u32 handle = h->CreateHandle();
|
u32 handle = h->CreateHandle();
|
||||||
auto* file = h->GetFile(handle);
|
auto* file = h->GetFile(handle);
|
||||||
|
@ -93,6 +93,14 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, void* buf, size_t nbytes) {
|
||||||
if (buf == nullptr) {
|
if (buf == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EFAULT;
|
return SCE_KERNEL_ERROR_EFAULT;
|
||||||
}
|
}
|
||||||
|
if (d <= 2) { // stdin,stdout,stderr
|
||||||
|
char* str = strdup((const char*)buf);
|
||||||
|
if (str[nbytes - 1] == '\n')
|
||||||
|
str[nbytes - 1] = 0;
|
||||||
|
LOG_INFO(Tty, "{}", str);
|
||||||
|
free(str);
|
||||||
|
return nbytes;
|
||||||
|
}
|
||||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||||
auto* file = h->GetFile(d);
|
auto* file = h->GetFile(d);
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
|
@ -215,6 +223,15 @@ int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelCheckReachability(const char* path) {
|
||||||
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
std::string path_name = mnt->GetHostFile(path);
|
||||||
|
if (!std::filesystem::exists(path_name)) {
|
||||||
|
return SCE_KERNEL_ERROR_ENOENT;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset) {
|
s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset) {
|
||||||
if (d < 3) {
|
if (d < 3) {
|
||||||
return ORBIS_KERNEL_ERROR_EPERM;
|
return ORBIS_KERNEL_ERROR_EPERM;
|
||||||
|
@ -281,6 +298,7 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
|
||||||
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat);
|
LIB_FUNCTION("E6ao34wPw+U", "libScePosix", 1, "libkernel", 1, 1, posix_stat);
|
||||||
LIB_FUNCTION("+r3rMFwItV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPread);
|
LIB_FUNCTION("+r3rMFwItV4", "libkernel", 1, "libkernel", 1, 1, sceKernelPread);
|
||||||
|
LIB_FUNCTION("uWyW3v98sU4", "libkernel", 1, "libkernel", 1, 1, sceKernelCheckReachability);
|
||||||
|
|
||||||
// openOrbis (to check if it is valid out of OpenOrbis
|
// openOrbis (to check if it is valid out of OpenOrbis
|
||||||
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "thread_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
class SymbolsResolver;
|
class SymbolsResolver;
|
||||||
|
@ -25,18 +25,18 @@ struct OrbisKernelStat {
|
||||||
u32 st_uid;
|
u32 st_uid;
|
||||||
u32 st_gid;
|
u32 st_gid;
|
||||||
u32 st_rdev;
|
u32 st_rdev;
|
||||||
SceKernelTimespec st_atim;
|
OrbisKernelTimespec st_atim;
|
||||||
SceKernelTimespec st_mtim;
|
OrbisKernelTimespec st_mtim;
|
||||||
SceKernelTimespec st_ctim;
|
OrbisKernelTimespec st_ctim;
|
||||||
s64 st_size;
|
s64 st_size;
|
||||||
s64 st_blocks;
|
s64 st_blocks;
|
||||||
u32 st_blksize;
|
u32 st_blksize;
|
||||||
u32 st_flags;
|
u32 st_flags;
|
||||||
u32 st_gen;
|
u32 st_gen;
|
||||||
s32 st_lspare;
|
s32 st_lspare;
|
||||||
SceKernelTimespec st_birthtim;
|
OrbisKernelTimespec st_birthtim;
|
||||||
unsigned int : (8 / 2) * (16 - static_cast<int>(sizeof(SceKernelTimespec)));
|
unsigned int : (8 / 2) * (16 - static_cast<int>(sizeof(OrbisKernelTimespec)));
|
||||||
unsigned int : (8 / 2) * (16 - static_cast<int>(sizeof(SceKernelTimespec)));
|
unsigned int : (8 / 2) * (16 - static_cast<int>(sizeof(OrbisKernelTimespec)));
|
||||||
};
|
};
|
||||||
|
|
||||||
// flags for Open
|
// flags for Open
|
||||||
|
|
|
@ -36,12 +36,6 @@ static void* PS4_SYSV_ABI sceKernelGetProcParam() {
|
||||||
return reinterpret_cast<void*>(linker->GetProcParam());
|
return reinterpret_cast<void*>(linker->GetProcParam());
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len) {
|
|
||||||
auto* memory = Core::Memory::Instance();
|
|
||||||
memory->Free(start, len);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PS4_SYSV_ABI void stack_chk_fail() {
|
static PS4_SYSV_ABI void stack_chk_fail() {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -53,21 +47,6 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) {
|
||||||
return SCE_OK;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
|
||||||
return SCE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_usleep(u32 microseconds) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
|
||||||
return SCE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelSleep(u32 seconds) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
|
||||||
return SCE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct iovec {
|
struct iovec {
|
||||||
void* iov_base; /* Base address. */
|
void* iov_base; /* Base address. */
|
||||||
size_t iov_len; /* Length. */
|
size_t iov_len; /* Length. */
|
||||||
|
@ -253,6 +232,9 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
|
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
|
||||||
LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1,
|
||||||
sceKernelAllocateMainDirectMemory);
|
sceKernelAllocateMainDirectMemory);
|
||||||
|
LIB_FUNCTION("C0f7TJcbfac", "libkernel", 1, "libkernel", 1, 1,
|
||||||
|
sceKernelAvailableDirectMemorySize);
|
||||||
|
LIB_FUNCTION("rVjRvHJ0X6c", "libkernel", 1, "libkernel", 1, 1, sceKernelVirtualQuery);
|
||||||
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
LIB_FUNCTION("pO96TwzOm5E", "libkernel", 1, "libkernel", 1, 1, sceKernelGetDirectMemorySize);
|
||||||
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
LIB_FUNCTION("NcaWUxfMNIQ", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedDirectMemory);
|
||||||
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, sceKernelMapDirectMemory);
|
||||||
|
@ -281,9 +263,6 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
||||||
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
||||||
LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap);
|
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("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
|
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
|
||||||
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam);
|
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam);
|
||||||
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
||||||
|
|
|
@ -18,7 +18,6 @@ struct OrbisTimesec {
|
||||||
u32 dst_sec;
|
u32 dst_sec;
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len);
|
|
||||||
int* PS4_SYSV_ABI __Error();
|
int* PS4_SYSV_ABI __Error();
|
||||||
|
|
||||||
void LibKernel_Register(Core::Loader::SymbolsResolver* sym);
|
void LibKernel_Register(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
|
@ -62,6 +62,21 @@ s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len) {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceKernelReleaseDirectMemory(u64 start, size_t len) {
|
||||||
|
auto* memory = Core::Memory::Instance();
|
||||||
|
memory->Free(start, len);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchEnd,
|
||||||
|
size_t alignment, u64* physAddrOut,
|
||||||
|
size_t* sizeOut) {
|
||||||
|
LOG_WARNING(Kernel_Vmm, "called searchStart = {:#x}, searchEnd = {:#x}, alignment = {:#x}",
|
||||||
|
searchStart, searchEnd, alignment);
|
||||||
|
auto* memory = Core::Memory::Instance();
|
||||||
|
return memory->DirectQueryAvailable(searchStart, searchEnd, alignment, physAddrOut, sizeOut);
|
||||||
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info,
|
s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info,
|
||||||
size_t infoSize) {
|
size_t infoSize) {
|
||||||
LOG_INFO(Kernel_Vmm, "called addr = {}, flags = {:#x}", fmt::ptr(addr), flags);
|
LOG_INFO(Kernel_Vmm, "called addr = {}, flags = {:#x}", fmt::ptr(addr), flags);
|
||||||
|
|
|
@ -63,7 +63,11 @@ int PS4_SYSV_ABI sceKernelMapDirectMemory(void** addr, u64 len, int prot, int fl
|
||||||
s64 directMemoryStart, u64 alignment);
|
s64 directMemoryStart, u64 alignment);
|
||||||
s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType,
|
s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType,
|
||||||
s64* physAddrOut);
|
s64* physAddrOut);
|
||||||
|
s32 PS4_SYSV_ABI sceKernelReleaseDirectMemory(u64 start, size_t len);
|
||||||
s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len);
|
s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len);
|
||||||
|
s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchEnd,
|
||||||
|
size_t alignment, u64* physAddrOut,
|
||||||
|
size_t* sizeOut);
|
||||||
s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info,
|
s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtualQueryInfo* info,
|
||||||
size_t infoSize);
|
size_t infoSize);
|
||||||
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot,
|
s32 PS4_SYSV_ABI sceKernelMapNamedFlexibleMemory(void** addrInOut, std::size_t len, int prot,
|
||||||
|
|
|
@ -35,6 +35,10 @@ void init_pthreads() {
|
||||||
ScePthreadAttr default_attr = nullptr;
|
ScePthreadAttr default_attr = nullptr;
|
||||||
scePthreadAttrInit(&default_attr);
|
scePthreadAttrInit(&default_attr);
|
||||||
g_pthread_cxt->SetDefaultAttr(default_attr);
|
g_pthread_cxt->SetDefaultAttr(default_attr);
|
||||||
|
// default rw init
|
||||||
|
OrbisPthreadRwlockattr default_rwattr = nullptr;
|
||||||
|
scePthreadRwlockattrInit(&default_rwattr);
|
||||||
|
g_pthread_cxt->setDefaultRwattr(default_rwattr);
|
||||||
|
|
||||||
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
g_pthread_cxt->SetPthreadPool(new PThreadPool);
|
||||||
}
|
}
|
||||||
|
@ -526,7 +530,7 @@ int PS4_SYSV_ABI scePthreadMutexLock(ScePthreadMutex* mutex) {
|
||||||
|
|
||||||
int result = pthread_mutex_lock(&(*mutex)->pth_mutex);
|
int result = pthread_mutex_lock(&(*mutex)->pth_mutex);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
LOG_TRACE(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||||
}
|
}
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -549,7 +553,7 @@ int PS4_SYSV_ABI scePthreadMutexUnlock(ScePthreadMutex* mutex) {
|
||||||
|
|
||||||
int result = pthread_mutex_unlock(&(*mutex)->pth_mutex);
|
int result = pthread_mutex_unlock(&(*mutex)->pth_mutex);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
LOG_TRACE(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||||
}
|
}
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -816,65 +820,6 @@ int PS4_SYSV_ABI posix_pthread_mutexattr_setprotocol(ScePthreadMutexattr* attr,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, SceKernelTimespec* tp) {
|
|
||||||
if (tp == 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_gettime(pclock_id, &t);
|
|
||||||
tp->tv_sec = t.tv_sec;
|
|
||||||
tp->tv_nsec = t.tv_nsec;
|
|
||||||
if (result == 0) {
|
|
||||||
return SCE_OK;
|
|
||||||
}
|
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI clock_gettime(s32 clock_id, SceKernelTimespec* time) {
|
|
||||||
int result = sceKernelClockGettime(clock_id, time);
|
|
||||||
if (result < 0) {
|
|
||||||
UNREACHABLE(); // TODO return posix error code
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
return SCE_OK;
|
|
||||||
}
|
|
||||||
int PS4_SYSV_ABI nanosleep(const SceKernelTimespec* rqtp, SceKernelTimespec* rmtp) {
|
|
||||||
int result = sceKernelNanosleep(rqtp, rmtp);
|
|
||||||
if (result < 0) {
|
|
||||||
UNREACHABLE(); // TODO return posix error code
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
static int pthread_copy_attributes(ScePthreadAttr* dst, const ScePthreadAttr* src) {
|
static int pthread_copy_attributes(ScePthreadAttr* dst, const ScePthreadAttr* src) {
|
||||||
if (dst == nullptr || *dst == nullptr || src == nullptr || *src == nullptr) {
|
if (dst == nullptr || *dst == nullptr || src == nullptr || *src == nullptr) {
|
||||||
return SCE_KERNEL_ERROR_EINVAL;
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
@ -1133,7 +1078,7 @@ int PS4_SYSV_ABI scePthreadMutexTrylock(ScePthreadMutex* mutex) {
|
||||||
|
|
||||||
int result = pthread_mutex_trylock(&(*mutex)->pth_mutex);
|
int result = pthread_mutex_trylock(&(*mutex)->pth_mutex);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
LOG_INFO(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
LOG_TRACE(Kernel_Pthread, "name={}, result={}", (*mutex)->name, result);
|
||||||
}
|
}
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1284,10 +1229,6 @@ void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
posix_pthread_mutexattr_setprotocol);
|
posix_pthread_mutexattr_setprotocol);
|
||||||
LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("HF7lK46xzjY", "libScePosix", 1, "libkernel", 1, 1,
|
||||||
posix_pthread_mutexattr_destroy);
|
posix_pthread_mutexattr_destroy);
|
||||||
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);
|
|
||||||
|
|
||||||
// openorbis weird functions
|
// openorbis weird functions
|
||||||
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
LIB_FUNCTION("7H0iTOciTLo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_mutex_lock);
|
||||||
|
|
|
@ -41,11 +41,6 @@ using OrbisPthreadRwlockattr = PthreadRwLockAttrInernal*;
|
||||||
|
|
||||||
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
using pthreadEntryFunc = PS4_SYSV_ABI void* (*)(void*);
|
||||||
|
|
||||||
struct SceKernelTimespec {
|
|
||||||
int64_t tv_sec;
|
|
||||||
int64_t tv_nsec;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PthreadInternal {
|
struct PthreadInternal {
|
||||||
u8 reserved[4096];
|
u8 reserved[4096];
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/native_clock.h"
|
#include "common/native_clock.h"
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/time_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
#include <pthread_time.h>
|
||||||
|
#else
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
static u64 initial_ptc;
|
static u64 initial_ptc;
|
||||||
|
@ -30,6 +39,101 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() {
|
||||||
return clock->GetUptime();
|
return clock->GetUptime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) {
|
||||||
|
ASSERT(microseconds >= 1000);
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI posix_usleep(u32 microseconds) {
|
||||||
|
ASSERT(microseconds >= 1000);
|
||||||
|
std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(seconds));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) {
|
||||||
|
if (tp == 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_gettime(pclock_id, &t);
|
||||||
|
tp->tv_sec = t.tv_sec;
|
||||||
|
tp->tv_nsec = t.tv_nsec;
|
||||||
|
if (result == 0) {
|
||||||
|
return SCE_OK;
|
||||||
|
}
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI clock_gettime(s32 clock_id, OrbisKernelTimespec* time) {
|
||||||
|
int result = sceKernelClockGettime(clock_id, time);
|
||||||
|
if (result < 0) {
|
||||||
|
UNREACHABLE(); // TODO return posix error code
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI posix_nanosleep(const OrbisKernelTimespec* rqtp, OrbisKernelTimespec* rmtp) {
|
||||||
|
const auto* request = reinterpret_cast<const timespec*>(rqtp);
|
||||||
|
auto* remain = reinterpret_cast<timespec*>(rmtp);
|
||||||
|
return nanosleep(request, remain);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelNanosleep(const OrbisKernelTimespec* rqtp, OrbisKernelTimespec* rmtp) {
|
||||||
|
if (!rqtp || !rmtp) {
|
||||||
|
return SCE_KERNEL_ERROR_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0) {
|
||||||
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return posix_nanosleep(rqtp, rmtp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceKernelGettimeofday(OrbisKernelTimeval* tp) {
|
||||||
|
if (!tp) {
|
||||||
|
return ORBIS_KERNEL_ERROR_EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto now = std::chrono::system_clock::now();
|
||||||
|
auto duration = now.time_since_epoch();
|
||||||
|
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(duration);
|
||||||
|
auto microsecs = std::chrono::duration_cast<std::chrono::microseconds>(duration - seconds);
|
||||||
|
|
||||||
|
tp->tv_sec = seconds.count();
|
||||||
|
tp->tv_usec = microsecs.count();
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI gettimeofday(OrbisKernelTimeval* tp, OrbisKernelTimezone* tz) {
|
||||||
|
// FreeBSD docs mention that the kernel generally does not track these values
|
||||||
|
// and they are usually returned as zero.
|
||||||
|
if (tz) {
|
||||||
|
tz->tz_minuteswest = 0;
|
||||||
|
tz->tz_dsttime = 0;
|
||||||
|
}
|
||||||
|
return sceKernelGettimeofday(tp);
|
||||||
|
}
|
||||||
|
|
||||||
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
clock = std::make_unique<Common::NativeClock>();
|
clock = std::make_unique<Common::NativeClock>();
|
||||||
initial_ptc = clock->GetUptime();
|
initial_ptc = clock->GetUptime();
|
||||||
|
@ -39,6 +143,17 @@ void timeSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
sceKernelGetProcessTimeCounterFrequency);
|
sceKernelGetProcessTimeCounterFrequency);
|
||||||
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
LIB_FUNCTION("-2IRUCO--PM", "libkernel", 1, "libkernel", 1, 1, sceKernelReadTsc);
|
||||||
LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency);
|
LIB_FUNCTION("1j3S3n-tTW4", "libkernel", 1, "libkernel", 1, 1, sceKernelGetTscFrequency);
|
||||||
|
LIB_FUNCTION("ejekcaNQNq0", "libkernel", 1, "libkernel", 1, 1, sceKernelGettimeofday);
|
||||||
|
LIB_FUNCTION("n88vx3C5nW8", "libkernel", 1, "libkernel", 1, 1, gettimeofday);
|
||||||
|
LIB_FUNCTION("n88vx3C5nW8", "libScePosix", 1, "libkernel", 1, 1, gettimeofday);
|
||||||
|
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("yS8U2TGCe1A", "libkernel", 1, "libkernel", 1, 1, posix_nanosleep);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -11,6 +11,21 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
|
struct OrbisKernelTimeval {
|
||||||
|
s64 tv_sec;
|
||||||
|
s64 tv_usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisKernelTimezone {
|
||||||
|
s32 tz_minuteswest;
|
||||||
|
s32 tz_dsttime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrbisKernelTimespec {
|
||||||
|
s64 tv_sec;
|
||||||
|
s64 tv_nsec;
|
||||||
|
};
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
u64 PS4_SYSV_ABI sceKernelGetTscFrequency();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime();
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter();
|
||||||
|
|
|
@ -351,6 +351,7 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode,
|
||||||
mount_result->mount_status = 0;
|
mount_result->mount_status = 0;
|
||||||
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16);
|
||||||
} break;
|
} break;
|
||||||
|
case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY:
|
||||||
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:
|
||||||
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 |
|
||||||
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
|
ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON:
|
||||||
|
|
|
@ -55,7 +55,7 @@ int PS4_SYSV_ABI sceSaveDataDialogTerminate() {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceSaveDataDialogUpdateStatus() {
|
int PS4_SYSV_ABI sceSaveDataDialogUpdateStatus() {
|
||||||
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
LOG_ERROR(Lib_SaveDataDialog, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return 3; // SCE_COMMON_DIALOG_STATUS_FINISHED
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterlibSceSaveDataDialog(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceSaveDataDialog(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
|
|
@ -135,8 +135,6 @@ void MemoryManager::UnmapMemory(VAddr virtual_addr, size_t size) {
|
||||||
"Attempting to unmap partially mapped range");
|
"Attempting to unmap partially mapped range");
|
||||||
|
|
||||||
const auto type = it->second.type;
|
const auto type = it->second.type;
|
||||||
fmt::print("{}\n", u32(type));
|
|
||||||
std::fflush(stdout);
|
|
||||||
const PAddr phys_addr = type == VMAType::Direct ? it->second.phys_base : -1;
|
const PAddr phys_addr = type == VMAType::Direct ? it->second.phys_base : -1;
|
||||||
if (type == VMAType::Direct) {
|
if (type == VMAType::Direct) {
|
||||||
UnmapVulkanMemory(virtual_addr, size);
|
UnmapVulkanMemory(virtual_addr, size);
|
||||||
|
@ -168,6 +166,8 @@ int MemoryManager::QueryProtection(VAddr addr, void** start, void** end, u32* pr
|
||||||
|
|
||||||
int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
int MemoryManager::VirtualQuery(VAddr addr, int flags,
|
||||||
Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
Libraries::Kernel::OrbisVirtualQueryInfo* info) {
|
||||||
|
std::scoped_lock lk{mutex};
|
||||||
|
|
||||||
auto it = FindVMA(addr);
|
auto it = FindVMA(addr);
|
||||||
if (it->second.type == VMAType::Free && flags == 1) {
|
if (it->second.type == VMAType::Free && flags == 1) {
|
||||||
it++;
|
it++;
|
||||||
|
|
Loading…
Reference in New Issue