diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 2b7eda22f7..cb9b9901ca 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -916,6 +916,11 @@ const HLEFunction ThreadManForUser[] = {0x65F54FFB, &WrapI_IUU<_sceKernelAllocateTlspl>, "_sceKernelAllocateTlspl", 'i', "ixp" }, }; +// The type picks one of the kernel's preset stack sizes. This is enough for any of them. +static u32 sceKernelExtendKernelStack(MIPSState *mipsState, int type, u32 cb, u32 arg) { + return sceKernelExtendThreadStack(mipsState, 0x4000, cb, arg); +} + const HLEFunction ThreadManForKernel[] = { {0xCEADEB47, &WrapI_U, "sceKernelDelayThread", 'i', "x", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL }, @@ -970,7 +975,7 @@ const HLEFunction ThreadManForKernel[] = {0xB736E9FF, &WrapI_IU, "sceKernelFreeVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x1D371B8A, &WrapI_IU, "sceKernelCancelVpl", 'i', "ix", HLE_KERNEL_SYSCALL }, {0x39810265, &WrapI_IU, "sceKernelReferVplStatus", 'i', "ip", HLE_KERNEL_SYSCALL }, - {0xBC31C1B9, nullptr, "sceKernelExtendKernelStack"}, + {0xBC31C1B9, &WrapU_IUU, "sceKernelExtendKernelStack", 'x', "ixx", HLE_KERNEL_SYSCALL }, // New entries must go here at the end, not inserted earlier in this table - the funcindex // (this array position) gets baked directly into resolved-import syscall opcodes written // into guest RAM (see GetSyscallOp() in HLE.cpp), which savestates capture verbatim. Inserting diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 1402c716df..b1f5f163a1 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -9,6 +9,7 @@ #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelHeap.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/MemMapHelpers.h" #include "Core/Reporting.h" #include "Core/Util/BlockAllocator.h" @@ -215,6 +216,19 @@ static int sceKernelSetUmdCacheOn(int on) { return hleLogWarning(Log::sceKernel, 0, "UNIMPL"); } +static u32 sceKernelMemset(u32 addr, int value, u32 size) { + if (Memory::IsValidRange(addr, size)) { + Memory::Memset(addr, (u8)value, size, "KernelMemset"); + } + return hleLogDebug(Log::sceKernel, addr); +} + +// The POPS manager uses it to make a file descriptor it opened usable from user mode. Ours +// aren't access-checked, so report no such UID and it skips that. +static int sceKernelGetUIDcontrolBlock(SceUID uid, u32 controlBlockPtr) { + return hleLogDebug(Log::sceKernel, SCE_KERNEL_ERROR_UNKNOWN_UID, "no control blocks"); +} + const HLEFunction SysMemForKernel[] = { { 0X96A3CE2C, &WrapI_U, "sceKernelSetRebootKernel", 'i', "x", HLE_KERNEL_SYSCALL }, { 0X1404C1AA, &WrapI_I, "sceKernelSetUmdCacheOn", 'i', "i", HLE_KERNEL_SYSCALL }, @@ -243,6 +257,8 @@ const HLEFunction SysMemForKernel[] = { { 0xF91FE6AA, &WrapI_V, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL }, { 0xC2460DD5, &WrapI_V, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL }, { 0x807179E7, &WrapI_V, "sceKernelSetParamSfo", 'i', "", HLE_KERNEL_SYSCALL }, + { 0x8AE776AF, &WrapU_UIU, "sceKernelMemset", 'x', "xix", HLE_KERNEL_SYSCALL }, + { 0xC90B0992, &WrapI_IU, "sceKernelGetUIDcontrolBlock", 'i', "ix", HLE_KERNEL_SYSCALL }, }; void Register_SysMemForKernel() { diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 5bf75b07cd..66f60ba855 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -844,6 +844,14 @@ static u32 sysclib_strlen(u32 src) { } } +static u32 sysclib_strnlen(u32 src, u32 maxLen) { + u32 len = 0; + while (len < maxLen && Memory::IsValidAddress(src + len) && Memory::ReadUnchecked_U8(src + len) != 0) { + len++; + } + return hleLogVerbose(Log::sceKernel, len); +} + static int sysclib_memcmp(u32 dst, u32 src, u32 size) { if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) { const int retval = memcmp(Memory::GetCharPointerUnchecked(dst), Memory::GetCharPointerUnchecked(src), size); @@ -1015,6 +1023,7 @@ const HLEFunction SysclibForKernel[] = {0x4C0E0274, &WrapU_UI, "strrchr", 'x', "xx", HLE_KERNEL_SYSCALL }, {0xCE2F7487, &WrapU_U, "toupper", 'x', "x", HLE_KERNEL_SYSCALL }, {0XC2145E80, &WrapI_UIU, "snprintf", 'i', "xx", HLE_KERNEL_SYSCALL }, + {0x90C5573D, &WrapU_UU, "strnlen", 'x', "xx", HLE_KERNEL_SYSCALL }, }; void Register_Kernel_Library() diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 5506d0a0df..4790bc06c6 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -3703,6 +3703,9 @@ const HLEFunction ModuleMgrForKernel[] = { {0x329C89DB, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, {0x8909A807, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, {0xBDFEEC4F, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, + // 6.60 NIDs. + {0x939E4270, &WrapU_CUU, "sceKernelLoadModuleForKernel", 'x', "sxx", HLE_KERNEL_SYSCALL }, + {0x3FF74DF1, &WrapU_UUUUU, "sceKernelStartModule", 'v', "xxxxx", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL }, }; void Register_ModuleMgrForUser() {