diff --git a/Core/HLE/HLE.h b/Core/HLE/HLE.h index b4cf7f6874..6d30e298d2 100644 --- a/Core/HLE/HLE.h +++ b/Core/HLE/HLE.h @@ -136,10 +136,12 @@ void hleSplitSyscallOverGe(); // Called after a split syscall from System.cpp void hleFinishSyscallAfterGe(); +[[nodiscard]] inline int hleDelayResult(int result, const char *reason, int usec) { return hleDelayResult((u32) result, reason, usec); } +[[nodiscard]] inline s64 hleDelayResult(s64 result, const char *reason, int usec) { return hleDelayResult((u64) result, reason, usec); } @@ -164,6 +166,7 @@ void *GetQuickSyscallFunc(MIPSOpcode op); void hleDoLogInternal(Log t, LogLevel level, u64 res, const char *file, int line, const char *reportTag, char retmask, const char *reason, const char *formatted_reason); template +[[nodiscard]] T hleDoLog(Log t, LogLevel level, T res, const char *file, int line, const char *reportTag, char retmask, const char *reason, ...) { if ((int)level > MAX_LOGLEVEL || !GenericLogEnabled(level, t)) { return res; @@ -192,6 +195,7 @@ T hleDoLog(Log t, LogLevel level, T res, const char *file, int line, const char } template +[[nodiscard]] T hleDoLog(Log t, LogLevel level, T res, const char *file, int line, const char *reportTag, char retmask) { if (((int)level > MAX_LOGLEVEL || !GenericLogEnabled(level, t)) && !reportTag) { return res; diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index b790a109bf..06d893eb74 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -775,7 +775,7 @@ static u32 sceDisplayIsVblank() { return hleLogSuccessI(Log::sceDisplay, DisplayIsVblank()); } -static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks = false) { +static void __DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks) { const s64 ticksIntoFrame = CoreTiming::GetTicks() - DisplayFrameStartTicks(); const s64 cyclesToNextVblank = msToCycles(frameMs) - ticksIntoFrame; @@ -787,12 +787,6 @@ static int DisplayWaitForVblanks(const char *reason, int vblanks, bool callbacks vblankWaitingThreads.push_back(WaitVBlankInfo(__KernelGetCurThread(), vblanks)); __KernelWaitCurThread(WAITTYPE_VBLANK, 1, 0, 0, callbacks, reason); - - return hleLogSuccessVerboseI(Log::sceDisplay, 0, "waiting for %d vblanks", vblanks); -} - -void __DisplayWaitForVblanks(const char* reason, int vblanks, bool callbacks) { - DisplayWaitForVblanks(reason, vblanks, callbacks); } static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeight) { @@ -811,9 +805,9 @@ static u32 sceDisplaySetMode(int displayMode, int displayWidth, int displayHeigh width = displayWidth; height = displayHeight; - hleLogSuccessI(Log::sceDisplay, 0); // On success, this implicitly waits for a vblank start. - return DisplayWaitForVblanks("display mode", 1); + __DisplayWaitForVblanks("display mode", 1); + return hleLogSuccessI(Log::sceDisplay, 0); } void __DisplaySetFramebuf(u32 topaddr, int linesize, int pixelFormat, int sync) { @@ -951,17 +945,19 @@ static u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelForma return hleLogSuccessI(Log::sceDisplay, 0); } -static int DisplayWaitForVblanksCB(const char *reason, int vblanks) { - return DisplayWaitForVblanks(reason, vblanks, true); +static void __DisplayWaitForVblanksCB(const char *reason, int vblanks) { + __DisplayWaitForVblanks(reason, vblanks, true); } static u32 sceDisplayWaitVblankStart() { - return DisplayWaitForVblanks("vblank start waited", 1); + __DisplayWaitForVblanks("vblank start waited", 1); + return hleLogSuccessI(Log::sceDisplay, 0); } static u32 sceDisplayWaitVblank() { if (!DisplayIsVblank()) { - return DisplayWaitForVblanks("vblank waited", 1); + __DisplayWaitForVblanks("vblank waited", 1); + return hleLogSuccessI(Log::sceDisplay, 0); } else { hleEatCycles(1110); hleReSchedule("vblank wait skipped"); @@ -978,12 +974,14 @@ static u32 sceDisplayWaitVblankStartMulti(int vblanks) { if (__IsInInterrupt()) return hleLogWarning(Log::sceDisplay, SCE_KERNEL_ERROR_ILLEGAL_CONTEXT, "in interrupt"); - return DisplayWaitForVblanks("vblank start multi waited", vblanks); + __DisplayWaitForVblanks("vblank start multi waited", vblanks); + return hleLogSuccessI(Log::sceDisplay, 0); } static u32 sceDisplayWaitVblankCB() { if (!DisplayIsVblank()) { - return DisplayWaitForVblanksCB("vblank waited", 1); + __DisplayWaitForVblanksCB("vblank waited", 1); + return hleLogSuccessI(Log::sceDisplay, 0); } else { hleEatCycles(1110); hleReSchedule("vblank wait skipped"); @@ -992,7 +990,8 @@ static u32 sceDisplayWaitVblankCB() { } static u32 sceDisplayWaitVblankStartCB() { - return DisplayWaitForVblanksCB("vblank start waited", 1); + __DisplayWaitForVblanksCB("vblank start waited", 1); + return hleLogSuccessI(Log::sceDisplay, 0); } static u32 sceDisplayWaitVblankStartMultiCB(int vblanks) { @@ -1004,7 +1003,8 @@ static u32 sceDisplayWaitVblankStartMultiCB(int vblanks) { if (__IsInInterrupt()) return hleLogWarning(Log::sceDisplay, SCE_KERNEL_ERROR_ILLEGAL_CONTEXT, "in interrupt"); - return DisplayWaitForVblanksCB("vblank start multi waited", vblanks); + __DisplayWaitForVblanksCB("vblank start multi waited", vblanks); + return hleLogSuccessI(Log::sceDisplay, 0); } static u32 sceDisplayGetVcount() { diff --git a/Core/HLE/sceFont.cpp b/Core/HLE/sceFont.cpp index 2433e65fac..2d6001eee5 100644 --- a/Core/HLE/sceFont.cpp +++ b/Core/HLE/sceFont.cpp @@ -624,12 +624,12 @@ public: if (foundFontIndex < 0 || fontRefCount_[foundFontIndex] >= MAX_FONT_REFS) { error = ERROR_FONT_TOO_MANY_OPEN_FONTS; - hleLogError(Log::sceFont, 0, "Too many fonts opened in FontLib"); + ERROR_LOG(Log::sceFont, "OpenFont: Too many fonts opened in FontLib"); return nullptr; } if (!font->IsValid()) { error = ERROR_FONT_INVALID_FONT_DATA; - hleLogError(Log::sceFont, 0, "Invalid font data"); + ERROR_LOG(Log::sceFont, "OpenFont: Invalid font data"); return nullptr; } diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 88f2a127e6..285d080484 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2225,6 +2225,7 @@ int __KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnVal // TODO: Why do we skip smoption->attribute here? SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, entryAddr, priority, stacksize, attribute, 0, (module->nm.attribute & 0x1000) != 0); + _dbg_assert_(threadID > 0); __KernelStartThreadValidate(threadID, argsize, argAddr); __KernelSetThreadRA(threadID, NID_MODULERETURN); @@ -2232,13 +2233,12 @@ int __KernelStartModule(SceUID moduleId, u32 argsize, u32 argAddr, u32 returnVal *needsWait = true; } } else if (entryAddr == 0 || entryAddr == (u32)-1) { - INFO_LOG(Log::sceModule, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): no entry address", moduleId, argsize, argAddr, returnValueAddr); + INFO_LOG(Log::sceModule, "__KernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): no entry address", moduleId, argsize, argAddr, returnValueAddr); module->nm.status = MODULE_STATUS_STARTED; } else { - ERROR_LOG(Log::sceModule, "sceKernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): invalid entry address", moduleId, argsize, argAddr, returnValueAddr); + ERROR_LOG(Log::sceModule, "__KernelStartModule(%d,asize=%08x,aptr=%08x,retptr=%08x): invalid entry address", moduleId, argsize, argAddr, returnValueAddr); return -1; } - return moduleId; } @@ -2326,6 +2326,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur if (Memory::IsValidAddress(stopFunc)) { SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0); + _dbg_assert_(threadID > 0); __KernelStartThreadValidate(threadID, argSize, argAddr); __KernelSetThreadRA(threadID, NID_MODULERETURN); __KernelWaitCurThread(WAITTYPE_MODULE, moduleId, 1, 0, false, "stopped module"); @@ -2411,6 +2412,7 @@ u32 hleKernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, if (Memory::IsValidAddress(stopFunc)) { SceUID threadID = __KernelCreateThread(module->nm.name, moduleID, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0); + _dbg_assert_(threadID > 0); __KernelStartThreadValidate(threadID, argSize, argp); __KernelSetThreadRA(threadID, NID_MODULERETURN); __KernelWaitCurThread(WAITTYPE_MODULE, moduleID, 1, 0, false, "unloadstopped module"); diff --git a/Core/HLE/sceKernelSemaphore.cpp b/Core/HLE/sceKernelSemaphore.cpp index 4597a024c9..98c26429d5 100644 --- a/Core/HLE/sceKernelSemaphore.cpp +++ b/Core/HLE/sceKernelSemaphore.cpp @@ -221,16 +221,17 @@ int sceKernelCreateSema(const char* name, u32 attr, int initVal, int maxVal, u32 s->ns.maxCount = maxVal; s->ns.numWaitThreads = 0; + if ((attr & ~PSP_SEMA_ATTR_PRIORITY) != 0) { + WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateSema(%s) unsupported attr parameter: %08x", name, attr); + } + // Many games pass garbage into optionPtr, it doesn't have any options. if (optionPtr != 0) { if (!Memory::IsValidRange(optionPtr, 4)) - hleLogWarning(Log::sceKernel, id, "invalid options parameter"); + return hleLogWarning(Log::sceKernel, id, "invalid options parameter"); else if (Memory::Read_U32(optionPtr) > 4) - hleLogDebug(Log::sceKernel, id, "invalid options parameter size"); + return hleLogDebug(Log::sceKernel, id, "invalid options parameter size"); } - if ((attr & ~PSP_SEMA_ATTR_PRIORITY) != 0) - WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateSema(%s) unsupported attr parameter: %08x", name, attr); - return hleLogSuccessX(Log::sceKernel, id); } diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 6652f02dc3..ba6c3fecd2 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -606,7 +606,7 @@ struct WaitTypeFuncs bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter); -PSPThread *__KernelCreateThread(SceUID &id, SceUID moduleID, const char *name, u32 entryPoint, u32 priority, int stacksize, u32 attr); +PSPThread *__KernelCreateThreadObject(SceUID &id, SceUID moduleID, const char *name, u32 entryPoint, u32 priority, int stacksize, u32 attr); void __KernelResetThread(PSPThread *t, int lowestPriority); void __KernelCancelWakeup(SceUID threadID); void __KernelCancelThreadEndTimeout(SceUID threadID); @@ -943,8 +943,8 @@ void __KernelThreadingInit() // Create the two idle threads, as well. With the absolute minimal possible priority. // 4096 stack size - don't know what the right value is. Hm, if callbacks are ever to run on these threads... - __KernelResetThread(__KernelCreateThread(threadIdleID[0], 0, "idle0", idleThreadHackAddr, 0x7f, 4096, PSP_THREAD_ATTR_KERNEL), 0); - __KernelResetThread(__KernelCreateThread(threadIdleID[1], 0, "idle1", idleThreadHackAddr, 0x7f, 4096, PSP_THREAD_ATTR_KERNEL), 0); + __KernelResetThread(__KernelCreateThreadObject(threadIdleID[0], 0, "idle0", idleThreadHackAddr, 0x7f, 4096, PSP_THREAD_ATTR_KERNEL), 0); + __KernelResetThread(__KernelCreateThreadObject(threadIdleID[1], 0, "idle1", idleThreadHackAddr, 0x7f, 4096, PSP_THREAD_ATTR_KERNEL), 0); // These idle threads are later started in LoadExec, which calls __KernelStartIdleThreads below. __KernelListenThreadEnd(__KernelCancelWakeup); @@ -1858,7 +1858,7 @@ void __KernelResetThread(PSPThread *t, int lowestPriority) { ERROR_LOG_REPORT(Log::sceKernel, "Resetting thread with threads waiting on end?"); } -PSPThread *__KernelCreateThread(SceUID &id, SceUID moduleId, const char *name, u32 entryPoint, u32 priority, int stacksize, u32 attr) { +PSPThread *__KernelCreateThreadObject(SceUID &id, SceUID moduleId, const char *name, u32 entryPoint, u32 priority, int stacksize, u32 attr) { std::lock_guard guard(threadqueueLock); PSPThread *t = new PSPThread(); @@ -1908,7 +1908,7 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int { //grab mips regs SceUID id; - PSPThread *thread = __KernelCreateThread(id, moduleID, "root", currentMIPS->pc, prio, stacksize, attr); + PSPThread *thread = __KernelCreateThreadObject(id, moduleID, "root", currentMIPS->pc, prio, stacksize, attr); if (thread->currentStack.start == 0) ERROR_LOG_REPORT(Log::sceKernel, "Unable to allocate stack for root thread."); __KernelResetThread(thread, 0); @@ -1919,7 +1919,7 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int __SetCurrentThread(thread, id, "root"); thread->nt.status = THREADSTATUS_RUNNING; // do not schedule - strcpy(thread->nt.name, "root"); + truncate_cpy(thread->nt.name, "root"); KernelValidateThreadTarget(thread->context.pc); @@ -1939,32 +1939,44 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr) { SceUID id; - PSPThread *newThread = __KernelCreateThread(id, moduleID, threadName, entry, prio, stacksize, attr); + PSPThread *newThread = __KernelCreateThreadObject(id, moduleID, threadName, entry, prio, stacksize, attr); if (newThread->currentStack.start == 0) return SCE_KERNEL_ERROR_NO_MEMORY; return id; } +// Note: Removed all the uses of hleReport* etc. int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr, bool allowKernel) { - if (threadName == nullptr) - return hleReportError(Log::sceKernel, SCE_KERNEL_ERROR_ERROR, "NULL thread name"); + if (!threadName) { + ERROR_LOG(Log::sceKernel, "__KernelCreateThread: NULL thread name"); + return SCE_KERNEL_ERROR_ERROR; + } - if ((u32)stacksize < 0x200) - return hleReportWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE, "bogus thread stack size %08x", stacksize); + if ((u32)stacksize < 0x200) { + WARN_LOG_REPORT(Log::sceKernel, "bogus thread stack size %08x", stacksize); + return SCE_KERNEL_ERROR_ILLEGAL_STACK_SIZE; + } if (prio < 0x08 || prio > 0x77) { - return hleReportWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "bogus thread priority %08x", prio); + WARN_LOG(Log::sceKernel, "bogus thread priority %08x", prio); + return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY; } if (!Memory::IsValidAddress(entry)) { // The PSP firmware seems to allow NULL...? - if (entry != 0) - return hleReportError(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "invalid thread entry %08x", entry); + if (entry != 0) { + ERROR_LOG(Log::sceKernel, "invalid thread entry %08x", entry); + return SCE_KERNEL_ERROR_ILLEGAL_ADDR; + } } - if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0 && !allowKernel) - return hleReportWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ATTR, "illegal thread attributes %08x", attr); - if ((attr & ~PSP_THREAD_ATTR_SUPPORTED) != 0) - WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateThread(name=%s): unsupported attributes %08x", threadName, attr); + if ((attr & ~PSP_THREAD_ATTR_USER_MASK) != 0 && !allowKernel) { + WARN_LOG(Log::sceKernel, "illegal thread attributes %08x", attr); + return SCE_KERNEL_ERROR_ILLEGAL_ATTR; + } + + if ((attr & ~PSP_THREAD_ATTR_SUPPORTED) != 0) { + WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateThread(name=%s): unsupported attributes %08x, ignoring", threadName, attr & ~PSP_THREAD_ATTR_SUPPORTED); + } // TODO: Not sure what these values are, but they are removed from the attr silently. // Some are USB/VSH specific, probably removes when they are from the wrong module? @@ -1979,11 +1991,14 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 } SceUID id = __KernelCreateThreadInternal(threadName, moduleID, entry, prio, stacksize, attr); - if ((u32)id == SCE_KERNEL_ERROR_NO_MEMORY) - return hleReportError(Log::sceKernel, SCE_KERNEL_ERROR_NO_MEMORY, "out of memory, %08x stack requested", stacksize); + if ((u32)id == SCE_KERNEL_ERROR_NO_MEMORY) { + ERROR_LOG_REPORT(Log::sceKernel, "out of memory, %08x stack requested", stacksize); + return SCE_KERNEL_ERROR_NO_MEMORY; + } - if (optionAddr != 0) + if (optionAddr != 0) { WARN_LOG_REPORT(Log::sceKernel, "sceKernelCreateThread(name=%s): unsupported options parameter %08x", threadName, optionAddr); + } // Creating a thread resumes dispatch automatically. Probably can't create without it. dispatchEnabled = true; @@ -1996,14 +2011,19 @@ int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 // Before triggering, set v0, since we restore on return. RETURN(id); __KernelThreadTriggerEvent((attr & PSP_THREAD_ATTR_KERNEL) != 0, id, THREADEVENT_CREATE); - return hleLogSuccessInfoI(Log::sceKernel, id); + return id; } int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr) { PSPThread *cur = __GetCurrentThread(); SceUID module = __KernelGetCurThreadModuleId(); bool allowKernel = KernelModuleIsKernelMode(module) || hleIsKernelMode() || (cur ? (cur->nt.attr & PSP_THREAD_ATTR_KERNEL) != 0 : false); - return __KernelCreateThread(threadName, module, entry, prio, stacksize, attr, optionAddr, allowKernel); + int retval = __KernelCreateThread(threadName, module, entry, prio, stacksize, attr, optionAddr, allowKernel); + if (retval < 0) { + return hleLogError(Log::sceKernel, retval); + } else { + return hleLogSuccessInfoI(Log::sceKernel, retval); + } } int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs) { diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index 99605448a2..70957565bd 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -166,7 +166,6 @@ std::string __KernelThreadingSummary(); KernelObject *__KernelThreadObject(); KernelObject *__KernelCallbackObject(); -void __KernelScheduleWakeup(int threadnumber, s64 usFromNow); SceUID __KernelGetCurThread(); int KernelCurThreadPriority(); bool KernelChangeThreadPriority(SceUID threadID, int priority); @@ -259,9 +258,8 @@ int __KernelRegisterActionType(ActionCreator creator); void __KernelRestoreActionType(int actionType, ActionCreator creator); struct MipsCall { - MipsCall() - { - doAfter = NULL; + MipsCall() { + doAfter = nullptr; } u32 entryPoint;