diff --git a/include/usersystemlib_kernel.h b/include/usersystemlib_kernel.h index 30648f7..1d4f655 100644 --- a/include/usersystemlib_kernel.h +++ b/include/usersystemlib_kernel.h @@ -4,12 +4,27 @@ #include "common_header.h" +#define SCE_KERNEL_LWMUTEX_RECURSIVE 0x200 + +typedef struct { + u32 lockCount; // 0 + u32 owner; // 4 + u32 flags; // 8 + u32 unk3; // 12 + u32 id; // 16 +} SceLwMutex; + s32 sceKernelCpuSuspendIntr(void); void sceKernelCpuResumeIntr(s32 intr); void sceKernelCpuResumeIntrWithSync(s32 intr); s32 sceKernelIsCpuIntrSuspended(s32 intr); s32 sceKernelIsCpuIntrEnable(void); -void *sceKernelMemcpy(void *dst, const void *src, u32 n); -void *sceKernelMemset(void *s, s32 c, u32 n); +s32 sceKernelGetThreadId(void); +s32 sceKernelCheckThreadStack(void); +s32 sceKernelTryLockLwMutex(SceLwMutex *mutex, u32 count); +s32 sceKernelTryLockLwMutex_600(SceLwMutex *mutex, u32 count); + +void *sceKernelMemcpy(void *dst, const void *src, u32 size); +void *sceKernelMemset(void *dst, s32 val, u32 size); diff --git a/src/usersystemlib/Makefile b/src/usersystemlib/Makefile new file mode 100644 index 0000000..16f3489 --- /dev/null +++ b/src/usersystemlib/Makefile @@ -0,0 +1,11 @@ +# Copyright (C) 2011, 2012 The uOFW team +# See the file COPYING for copying permission. + +TARGET = usersystemlib +OBJS = kernel_library.o ge_lazy.o intr.o + +#DEBUG = 1 + +LIBS = + +include ../../lib/build.mak diff --git a/src/usersystemlib/exports.exp b/src/usersystemlib/exports.exp index 8269fd0..7691a85 100644 --- a/src/usersystemlib/exports.exp +++ b/src/usersystemlib/exports.exp @@ -2,29 +2,29 @@ PSP_BEGIN_EXPORTS PSP_EXPORT_START(syslib, 0x0000, 0x8000) -PSP_EXPORT_FUNC_HASH(module_start) +PSP_EXPORT_FUNC_HASH(module_start) # ok PSP_EXPORT_VAR_HASH(module_info) PSP_EXPORT_VAR_HASH(module_sdk_version) PSP_EXPORT_VAR_HASH(module_start_thread_parameter) PSP_EXPORT_END PSP_EXPORT_START(Kernel_Library, 0x0011, 0x0001) -PSP_EXPORT_FUNC_HASH(sceKernelCpuSuspendIntr) +PSP_EXPORT_FUNC_HASH(sceKernelCpuSuspendIntr) # ok PSP_EXPORT_FUNC_HASH(sceKernelUnlockLwMutex) PSP_EXPORT_FUNC_HASH(sceKernelMemcpy) PSP_EXPORT_FUNC_HASH(sceKernelLockLwMutexCB) -PSP_EXPORT_FUNC_HASH(sceKernelGetThreadId) +PSP_EXPORT_FUNC_HASH(sceKernelGetThreadId) # ok PSP_EXPORT_FUNC_HASH(sceKernelTryLockLwMutex_600) PSP_EXPORT_FUNC_NID(Kernel_Library_3AD10D4D, 0x3AD10D4D) -PSP_EXPORT_FUNC_HASH(sceKernelCpuResumeIntrWithSync) -PSP_EXPORT_FUNC_HASH(sceKernelIsCpuIntrSuspended) -PSP_EXPORT_FUNC_HASH(sceKernelCpuResumeIntr) +PSP_EXPORT_FUNC_HASH(sceKernelCpuResumeIntrWithSync) # ok +PSP_EXPORT_FUNC_HASH(sceKernelIsCpuIntrSuspended) # ok +PSP_EXPORT_FUNC_HASH(sceKernelCpuResumeIntr) # ok PSP_EXPORT_FUNC_HASH(sceKernelMemset) -PSP_EXPORT_FUNC_HASH(sceKernelIsCpuIntrEnable) +PSP_EXPORT_FUNC_HASH(sceKernelIsCpuIntrEnable) # ok PSP_EXPORT_FUNC_HASH(sceKernelLockLwMutex) PSP_EXPORT_FUNC_HASH(sceKernelReferLwMutexStatus) -PSP_EXPORT_FUNC_HASH(sceKernelCheckThreadStack) -PSP_EXPORT_FUNC_HASH(sceKernelTryLockLwMutex) +PSP_EXPORT_FUNC_HASH(sceKernelCheckThreadStack) # ok +PSP_EXPORT_FUNC_HASH(sceKernelTryLockLwMutex) # ok PSP_EXPORT_FUNC_NID(Kernel_Library_FA835CDE, 0xFA835CDE) PSP_EXPORT_END diff --git a/src/usersystemlib/ge_lazy.c b/src/usersystemlib/ge_lazy.c new file mode 100644 index 0000000..5f83ae5 --- /dev/null +++ b/src/usersystemlib/ge_lazy.c @@ -0,0 +1,7 @@ +/* Copyright (C) 2011, 2012, 2013 The uOFW team + See the file COPYING for copying permission. +*/ + +void sceGe_lazy_31129B95(s32 arg0, s32 arg1) +{ +} \ No newline at end of file diff --git a/src/usersystemlib/intr.S b/src/usersystemlib/intr.S new file mode 100644 index 0000000..7a63d61 --- /dev/null +++ b/src/usersystemlib/intr.S @@ -0,0 +1,123 @@ +# Copyright (C) 2011, 2012, 2013 The uOFW team +# See the file COPYING for copying permission. + + .text + .set noat + .set noreorder + + .global sceKernelCpuSuspendIntr + .global sceKernelCpuResumeIntr + .global sceKernelCpuResumeIntrWithSync + .global sceKernelIsCpuIntrSuspended + .global sceKernelIsCpuIntrEnable + .global sub_00000208 + +## +# Kernel_Library_092968F4 +## + + .ent sceKernelCpuSuspendIntr +sceKernelCpuSuspendIntr: + mfic $v0, $0 + mtic $0, $0 + nop + nop + nop + nop + nop + nop + nop + jr $ra + nop + .end sceKernelCpuSuspendIntr + +## +# Kernel_Library_5F10D406 +## + + .ent sceKernelCpuResumeIntr +sceKernelCpuResumeIntr: + mtic $a0, $0 + nop + nop + nop + nop + nop + nop + nop + jr $ra + nop + .end sceKernelCpuResumeIntr + +## +# Kernel_Library_3B84732D +## + + .ent sceKernelCpuResumeIntrWithSync +sceKernelCpuResumeIntrWithSync: + sync + nop + sync + nop + mtic $a0, $0 + nop + nop + nop + nop + nop + nop + nop + jr $ra + nop + .end sceKernelCpuResumeIntrWithSync + +## +# Kernel_Library_47A0B729 +## + + .ent sceKernelIsCpuIntrSuspended +sceKernelIsCpuIntrSuspended: + jr $ra + sltiu $v0, $a0, 1 + .end sceKernelIsCpuIntrSuspended + +## +# Kernel_Library_B55249D2 +## + + .ent sceKernelIsCpuIntrEnable +sceKernelIsCpuIntrEnable: + mfic $v0, $0 + jr $ra + nop + nop + nop + nop + nop + nop + nop + nop + nop + .end sceKernelIsCpuIntrEnable + +## +# sub_00000208 +## + + .ent sub_00000208 +sub_00000208: + jr $ra + syscall 0x0 + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + .end sub_00000208 \ No newline at end of file diff --git a/src/usersystemlib/kernel_library.c b/src/usersystemlib/kernel_library.c new file mode 100644 index 0000000..2761ab3 --- /dev/null +++ b/src/usersystemlib/kernel_library.c @@ -0,0 +1,208 @@ +/* Copyright (C) 2011, 2012, 2013 The uOFW team + See the file COPYING for copying permission. +*/ + +#include "usersystemlib_kernel.h" + +#include +#include + +SCE_MODULE_INFO("sceKernelLibrary", + SCE_MODULE_KERNEL | SCE_MODULE_ATTR_CANT_STOP | + SCE_MODULE_ATTR_EXCLUSIVE_LOAD | SCE_MODULE_ATTR_EXCLUSIVE_START, 1, 1); +SCE_MODULE_BOOTSTART("_UserSystemLibInit"); + +// .rodata +static const s32 g_userSpaceIntrStackSize = 0x2000; // b68 + +// .data +static s32 g_b80 = -1; // b80 + +// .bss +static u8 g_userSpaceIntrStack[0x2000]; // bc0 +static s32 *g_2bc0; // 2bc0 +static u8 g_unk_2bc4[0x3C]; // 2bc4 +static u8 g_2c00[0x80]; // 2c00 +static s32 g_thid; // 2c80 +static u8 g_unk_2c84[4]; // 2c84 +static void *g_sp; // 2c88 + +// module_start +s32 _UserSystemLibInit(SceSize argc __attribute__((unused)), void *argp) +{ + // InterruptManager_EEE43F47 + sceKernelRegisterUserSpaceIntrStack( + (s32)g_userSpaceIntrStack, // 0xBC0 + g_userSpaceIntrStackSize, // 0x2000 + (s32)&g_2bc0 // 0x2BC0 + ); + + // SysMemUserForUser_A6848DF8 + sceKernelSetUsersystemLibWork( + g_2c00, // 0x2C00 + 0x140, + &g_b80 // 0xB80 + ); + + return SCE_ERROR_OK; +} + +// Kernel_Library_293B45B8 +s32 sceKernelGetThreadId(void) +{ + if (g_2bc0 == NULL) { // 0x2BC0 + // 0x80020064 + return SCE_ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT; + } + + return g_thid; // 0x2BC0 + 192 +} + +// Kernel_Library_D13BDE95 +s32 sceKernelCheckThreadStack(void) +{ + u32 size; + + size = pspGetSp() - g_sp; // 0x2BC0 + 200 + + if (g_2bc0 == NULL || size < 64) { // 0x2BC0 + // ThreadManForUser_D13BDE95 + return sceKernelCheckThreadStack(); + } + + return size; +} + +// Kernel_Library_DC692EE3 +s32 sceKernelTryLockLwMutex(SceLwMutex *mutex, u32 count) +{ + // Kernel_Library_37431849 + if (sceKernelTryLockLwMutex_600(mutex, count) != SCE_ERROR_OK) { + // 0x800201C4 + return SCE_ERROR_KERNEL_MUTEX_LOCKED; + } + + return SCE_ERROR_OK; +} + +// Kernel_Library_37431849 +// reference: http://linux.die.net/man/3/pthread_mutex_trylock +s32 sceKernelTryLockLwMutex_600(SceLwMutex *mutex, u32 count) +{ + u32 tmpCount; + u32 tmpOwner; + + if (g_2bc0 == NULL) { + // 0x80020064 + return SCE_ERROR_KERNEL_CANNOT_BE_CALLED_FROM_INTERRUPT; + } + + if (count <= 0) { + // 0x800201BD + return SCE_ERROR_KERNEL_ILLEGAL_COUNT; + } + + if (mutex->id < 0) { + // 0x800201CA + return SCE_ERROR_KERNEL_LWMUTEX_NOT_FOUND; + } + + if (mutex->owner == g_2bc0[48]) { // loc_00000340 + if (!(mutex->flags & SCE_KERNEL_LWMUTEX_RECURSIVE) { + // 0x800201CF + return SCE_ERROR_KERNEL_LWMUTEX_RECURSIVE_NOT_ALLOWED; + } + + if (mutex->lockCount + count < 0) { + // 0x800201CD + return SCE_ERROR_KERNEL_LWMUTEX_LOCK_OVERFLOW; + } + + mutex->lockCount += count; + + return SCE_ERROR_OK; + } + + if (mutex->owner != 0) { + // 0x800201CB + return SCE_ERROR_KERNEL_LWMUTEX_LOCKED; + } + + if (mutex->flags & SCE_KERNEL_LWMUTEX_RECURSIVE) { + tmpCount = 0; + } else { + tmpCount = count ^ 1; + } + + if (tmpCount != 0) { + // 0x800201BD + return SCE_ERROR_KERNEL_ILLEGAL_COUNT; + } + + do { // loc_00000320 + /* begin atomic RMW */ + asm __volatile__( + "ll %0, (%1)" + : "=r" (tmpOwner) + : "r" (&mutex->owner) + ); + + if (tmpOwner != 0) { + // 0x800201CB + return SCE_ERROR_KERNEL_LWMUTEX_LOCKED; + } + + tmpOwner = g_2bc0[48]; + + /* end atomic RMW */ + /* if an atomic update as occured, %0 will be set to 1 */ + "sc %0, (%1)" + : "=r" (tmpOwner) + : "r" (&mutex->owner) + ); + } while (tmpOwner == 0); + + mutex->lockCount = count; + + return SCE_ERROR_OK; +} + +s32 sceKernelLockLwMutexCB(void) +{ + return SCE_ERROR_OK; +} + +s32 sceKernelLockLwMutex(void) +{ + return SCE_ERROR_OK; +} + +s32 sceKernelUnlockLwMutex(void) +{ + return SCE_ERROR_OK; +} + +s32 Kernel_Library_3AD10D4D(void) +{ + return SCE_ERROR_OK; +} + +s32 sceKernelReferLwMutexStatus(void) +{ + return SCE_ERROR_OK; +} + +s32 Kernel_Library_F1835CDE(void) +{ + return SCE_ERROR_OK; +} + +void *sceKernelMemcpy(void *dst, const void *src, u32 size) +{ + return NULL; +} + +void *sceKernelMemset(void *dst, s32 val, u32 size) +{ + return NULL; +} \ No newline at end of file