From 6d949f4d0b8fabbacb4e50b31bc0991fc4e2d71b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 9 Sep 2013 23:49:06 -0700 Subject: [PATCH] Improve volatile mem locking w/ suspended intr. --- Core/HLE/scePower.cpp | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/Core/HLE/scePower.cpp b/Core/HLE/scePower.cpp index 7465b7b4ef..d16d354633 100644 --- a/Core/HLE/scePower.cpp +++ b/Core/HLE/scePower.cpp @@ -24,6 +24,7 @@ #include "Core/HLE/scePower.h" #include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernelInterrupt.h" struct VolatileWaitingThread { SceUID threadID; @@ -275,12 +276,24 @@ int sceKernelVolatileMemUnlock(int type) { } } else { ERROR_LOG_REPORT(HLE, "sceKernelVolatileMemUnlock(%i) FAILED - not locked", type); + // I guess it must use a sema. + return SCE_KERNEL_ERROR_SEMA_OVF; } return 0; } int sceKernelVolatileMemLock(int type, u32 paddr, u32 psize) { - u32 error = __KernelVolatileMemLock(type, paddr, psize); + u32 error = 0; + + // If dispatch is disabled or in an interrupt, don't check, just return an error. + // But still write the addr and size (some games require this to work, and it's testably true.) + if (!__KernelIsDispatchEnabled()) { + error = SCE_KERNEL_ERROR_CAN_NOT_WAIT; + } else if (__IsInInterrupt()) { + error = SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } else { + error = __KernelVolatileMemLock(type, paddr, psize); + } switch (error) { case 0: @@ -296,6 +309,22 @@ int sceKernelVolatileMemLock(int type, u32 paddr, u32 psize) { } break; + case SCE_KERNEL_ERROR_CAN_NOT_WAIT: + { + WARN_LOG(HLE, "sceKernelVolatileMemLock(%i, %08x, %08x): dispatch disabled", type, paddr, psize); + Memory::Write_U32(0x08400000, paddr); + Memory::Write_U32(0x00400000, psize); + } + break; + + case SCE_KERNEL_ERROR_ILLEGAL_CONTEXT: + { + WARN_LOG(HLE, "sceKernelVolatileMemLock(%i, %08x, %08x): dispatch disabled", type, paddr, psize); + Memory::Write_U32(0x08400000, paddr); + Memory::Write_U32(0x00400000, psize); + } + break; + default: ERROR_LOG_REPORT(HLE, "%08x=sceKernelVolatileMemLock(%i, %08x, %08x) - error", type, paddr, psize, error); break; @@ -443,7 +472,7 @@ static const HLEFunction scePower[] = { {0xa9d22232,0,"scePowerSetCallbackMode"}, // These seem to be aliases. - {0x23c31ffe,&WrapI_IUU,"scePowerVolatileMemLock", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, + {0x23c31ffe,&WrapI_IUU,"scePowerVolatileMemLock"}, {0xfa97a599,&WrapI_IUU,"scePowerVolatileMemTryLock"}, {0xb3edd801,&WrapI_I,"scePowerVolatileMemUnlock"}, }; @@ -458,7 +487,7 @@ const HLEFunction sceSuspendForUser[] = { // let you grab it. {0xa14f40b2,&WrapI_IUU,"sceKernelVolatileMemTryLock"}, {0xa569e425,&WrapI_I,"sceKernelVolatileMemUnlock"}, - {0x3e0271d3,&WrapI_IUU,"sceKernelVolatileMemLock", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, //when "acquiring mem pool" (fired up) + {0x3e0271d3,&WrapI_IUU,"sceKernelVolatileMemLock"}, //when "acquiring mem pool" (fired up) };