From 15a0f39fa13218f10a5628bd43713eaec702b52a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 28 Aug 2013 23:15:13 -0700 Subject: [PATCH] Return yet more errors while inside interrupts. --- Core/HLE/sceCtrl.cpp | 21 ++++++++------ Core/HLE/sceIo.cpp | 44 ++++++++++++++++++++++------- Core/HLE/sceKernel.cpp | 4 +-- Core/HLE/sceKernelInterrupt.cpp | 4 +-- Core/HLE/sceKernelModule.cpp | 4 +-- Core/HLE/sceKernelThread.cpp | 4 +++ Core/HLE/scePower.cpp | 4 +-- Core/HLE/sceUmd.cpp | 49 +++++++++++++++++++++------------ GPU/GPUCommon.cpp | 7 +++++ 9 files changed, 96 insertions(+), 45 deletions(-) diff --git a/Core/HLE/sceCtrl.cpp b/Core/HLE/sceCtrl.cpp index d8534b01aa..d01dfd3a31 100644 --- a/Core/HLE/sceCtrl.cpp +++ b/Core/HLE/sceCtrl.cpp @@ -16,15 +16,16 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include -#include "HLE.h" -#include "../MIPS/MIPS.h" -#include "../CoreTiming.h" -#include "ChunkFile.h" -#include "StdMutex.h" -#include "sceCtrl.h" -#include "sceDisplay.h" -#include "sceKernel.h" -#include "sceKernelThread.h" +#include "Core/HLE/HLE.h" +#include "Core/MIPS/MIPS.h" +#include "Core/CoreTiming.h" +#include "Common/ChunkFile.h" +#include "Common/StdMutex.h" +#include "Core/HLE/sceCtrl.h" +#include "Core/HLE/sceDisplay.h" +#include "Core/HLE/sceKernel.h" +#include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernelInterrupt.h" /* Index for the two analog directions */ #define CTRL_ANALOG_X 0 @@ -218,6 +219,8 @@ int __CtrlReadBuffer(u32 ctrlDataPtr, u32 nBufs, bool negative, bool peek) if (!peek && !__KernelIsDispatchEnabled()) return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + if (!peek && __IsInInterrupt()) + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; u32 resetRead = ctrlBufRead; diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 57356e8220..2fa19ffbb6 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -43,6 +43,7 @@ extern "C" { #include "Core/HLE/sceKernel.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernelInterrupt.h" // For headless screenshots. #include "Core/HLE/sceDisplay.h" @@ -646,9 +647,15 @@ bool __IoRead(int &result, int id, u32 data_addr, int size) { u32 sceIoRead(int id, u32 data_addr, int size) { u32 error; FileNode *f = __IoGetFd(id, error); - if (!__KernelIsDispatchEnabled() && id > 2 && f != NULL) { - DEBUG_LOG(HLE, "sceIoRead(%d, %08x, %x): dispatch disabled", id, data_addr, size); - return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + if (id > 2 && f != NULL) { + if (!__KernelIsDispatchEnabled()) { + DEBUG_LOG(HLE, "sceIoRead(%d, %08x, %x): dispatch disabled", id, data_addr, size); + return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + } + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "sceIoRead(%d, %08x, %x): inside interrupt", id, data_addr, size); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } } // TODO: Timing is probably not very accurate, low estimate. @@ -736,9 +743,15 @@ bool __IoWrite(int &result, int id, void *data_ptr, int size) { u32 sceIoWrite(int id, u32 data_addr, int size) { u32 error; FileNode *f = __IoGetFd(id, error); - if (!__KernelIsDispatchEnabled() && id > 2 && f != NULL) { - DEBUG_LOG(HLE, "sceIoWrite(%d, %08x, %x): dispatch disabled", id, data_addr, size); - return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + if (id > 2 && f != NULL) { + if (!__KernelIsDispatchEnabled()) { + DEBUG_LOG(HLE, "sceIoWrite(%d, %08x, %x): dispatch disabled", id, data_addr, size); + return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + } + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "sceIoWrite(%d, %08x, %x): inside interrupt", id, data_addr, size); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } } // TODO: Timing is probably not very accurate, low estimate. @@ -1486,12 +1499,14 @@ u32 sceIoOpenAsync(const char *filename, int flags, int mode) return fd; } -u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) -{ +u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) { u32 error; FileNode *f = __IoGetFd(id, error); - if (f) - { + if (f) { + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "%lli = sceIoGetAsyncStat(%i, %i, %08x): illegal context", f->asyncResult, id, poll, address); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if (f->pendingAsyncResult) { if (poll) { DEBUG_LOG(HLE, "%lli = sceIoGetAsyncStat(%i, %i, %08x): not ready", f->asyncResult, id, poll, address); @@ -1535,6 +1550,10 @@ int sceIoWaitAsync(int id, u32 address) { u32 error; FileNode *f = __IoGetFd(id, error); if (f) { + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x): illegal context", f->asyncResult, id, address); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if (f->pendingAsyncResult) { if (!__KernelIsDispatchEnabled()) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsync(%i, %08x): dispatch disabled", f->asyncResult, id, address); @@ -1570,6 +1589,11 @@ int sceIoWaitAsyncCB(int id, u32 address) { u32 error; FileNode *f = __IoGetFd(id, error); if (f) { + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x): illegal context", f->asyncResult, id, address); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } + hleCheckCurrentCallbacks(); if (f->pendingAsyncResult) { DEBUG_LOG(HLE, "%lli = sceIoWaitAsyncCB(%i, %08x): waiting", f->asyncResult, id, address); diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 359c342b23..131ee1b173 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -686,8 +686,8 @@ const HLEFunction ThreadManForUser[] = //{0xBEED3A47,0, "_sceKernelUnlockLwMutex"}, {0xf8170fbe,WrapI_I, "sceKernelDeleteMutex"}, - {0xB011B11F,WrapI_IIU, "sceKernelLockMutex", HLE_NOT_DISPATCH_SUSPENDED}, - {0x5bf4dd27,WrapI_IIU, "sceKernelLockMutexCB", HLE_NOT_DISPATCH_SUSPENDED}, + {0xB011B11F,WrapI_IIU, "sceKernelLockMutex", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, + {0x5bf4dd27,WrapI_IIU, "sceKernelLockMutexCB", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, {0x6b30100f,WrapI_II, "sceKernelUnlockMutex"}, {0xb7d098c6,WrapI_CUIU, "sceKernelCreateMutex"}, {0x0DDCD2C9,WrapI_II, "sceKernelTryLockMutex"}, diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 6291afcaa6..e9af59d11f 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -575,8 +575,8 @@ const HLEFunction Kernel_Library[] = {0xa089eca4,WrapU_UUU, "sceKernelMemset"}, {0xDC692EE3,WrapI_UI, "sceKernelTryLockLwMutex"}, {0x37431849,WrapI_UI, "sceKernelTryLockLwMutex_600"}, - {0xbea46419,WrapI_UIU, "sceKernelLockLwMutex", HLE_NOT_DISPATCH_SUSPENDED}, - {0x1FC64E09,WrapI_UIU, "sceKernelLockLwMutexCB", HLE_NOT_DISPATCH_SUSPENDED}, + {0xbea46419,WrapI_UIU, "sceKernelLockLwMutex", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, + {0x1FC64E09,WrapI_UIU, "sceKernelLockLwMutexCB", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, {0x15b6446b,WrapI_UI, "sceKernelUnlockLwMutex"}, {0xc1734599,WrapI_UU, "sceKernelReferLwMutexStatus"}, {0x293b45b8,WrapI_V, "sceKernelGetThreadId"}, diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index c8070ca40d..b09c7830ab 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -1512,9 +1512,9 @@ const HLEFunction ModuleMgrForUser[] = { {0x977DE386,&WrapU_CUU,"sceKernelLoadModule"}, {0xb7f46618,&WrapU_UUU,"sceKernelLoadModuleByID"}, - {0x50F0C1EC,&WrapV_UUUUU,"sceKernelStartModule", HLE_NOT_DISPATCH_SUSPENDED}, + {0x50F0C1EC,&WrapV_UUUUU,"sceKernelStartModule", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, {0xD675EBB8,&sceKernelExitGame,"sceKernelSelfStopUnloadModule"}, //HACK - {0xd1ff982a,&WrapU_UUUUU,"sceKernelStopModule", HLE_NOT_DISPATCH_SUSPENDED}, + {0xd1ff982a,&WrapU_UUUUU,"sceKernelStopModule", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, {0x2e0911aa,WrapU_U,"sceKernelUnloadModule"}, {0x710F61B5,0,"sceKernelLoadModuleMs"}, {0xF9275D98,0,"sceKernelLoadModuleBufferUsbWlan"}, ///??? diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 21951602b7..4ec222173d 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -2549,6 +2549,8 @@ int sceKernelWaitThreadEnd(SceUID threadID, u32 timeoutPtr) if (!__KernelIsDispatchEnabled()) return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + if (__IsInInterrupt()) + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; u32 error; Thread *t = kernelObjects.Get(threadID, error); @@ -2578,6 +2580,8 @@ int sceKernelWaitThreadEndCB(SceUID threadID, u32 timeoutPtr) if (!__KernelIsDispatchEnabled()) return SCE_KERNEL_ERROR_CAN_NOT_WAIT; + if (__IsInInterrupt()) + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; u32 error; Thread *t = kernelObjects.Get(threadID, error); diff --git a/Core/HLE/scePower.cpp b/Core/HLE/scePower.cpp index 24873598ac..c619574b23 100644 --- a/Core/HLE/scePower.cpp +++ b/Core/HLE/scePower.cpp @@ -446,7 +446,7 @@ static const HLEFunction scePower[] = { {0xa9d22232,0,"scePowerSetCallbackMode"}, // These seem to be aliases. - {0x23c31ffe,&WrapI_IUU,"scePowerVolatileMemLock", HLE_NOT_DISPATCH_SUSPENDED}, + {0x23c31ffe,&WrapI_IUU,"scePowerVolatileMemLock", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, {0xfa97a599,&WrapI_IUU,"scePowerVolatileMemTryLock"}, {0xb3edd801,&WrapI_I,"scePowerVolatileMemUnlock"}, }; @@ -461,7 +461,7 @@ const HLEFunction sceSuspendForUser[] = { // let you grab it. {0xa14f40b2,&WrapI_IUU,"sceKernelVolatileMemTryLock"}, {0xa569e425,&WrapI_I,"sceKernelVolatileMemUnlock"}, - {0x3e0271d3,&WrapI_IUU,"sceKernelVolatileMemLock", HLE_NOT_DISPATCH_SUSPENDED}, //when "acquiring mem pool" (fired up) + {0x3e0271d3,&WrapI_IUU,"sceKernelVolatileMemLock", HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED}, //when "acquiring mem pool" (fired up) }; diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 1ea32dd36a..a954d57327 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -15,12 +15,13 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -#include "HLE.h" -#include "../MIPS/MIPS.h" +#include "Common/ChunkFile.h" +#include "Core/HLE/HLE.h" +#include "Core/MIPS/MIPS.h" #include "Core/CoreTiming.h" -#include "ChunkFile.h" -#include "sceUmd.h" -#include "sceKernelThread.h" +#include "Core/HLE/sceUmd.h" +#include "Core/HLE/sceKernelThread.h" +#include "Core/HLE/sceKernelInterrupt.h" const u64 MICRO_DELAY_ACTIVATE = 4000; @@ -271,40 +272,48 @@ void __UmdWaitStat(u32 timeout) int sceUmdWaitDriveStat(u32 stat) { if (stat == 0) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x): bad status", stat); + DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): bad status", stat); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x): dispatch disabled", stat); + DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): dispatch disabled", stat); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): inside interrupt", stat); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if ((stat & __KernelUmdGetState()) == 0) { - DEBUG_LOG(HLE,"sceUmdWaitDriveStat(stat = %08x): waiting", stat); + DEBUG_LOG(HLE, "sceUmdWaitDriveStat(stat = %08x): waiting", stat); umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited"); return 0; } - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStat(stat = %08x)", stat); + DEBUG_LOG(HLE, "0=sceUmdWaitDriveStat(stat = %08x)", stat); return 0; } int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) { if (stat == 0) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): bad status", stat, timeout); + DEBUG_LOG(HLE, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): bad status", stat, timeout); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); + DEBUG_LOG(HLE, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): inside interrupt", stat, timeout); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if ((stat & __KernelUmdGetState()) == 0) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): waiting", stat, timeout); + DEBUG_LOG(HLE, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): waiting", stat, timeout); __UmdWaitStat(timeout); umdWaitingThreads.push_back(UmdWaitingThread::Make(__KernelGetCurThread(), stat)); __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited with timer"); @@ -313,25 +322,29 @@ int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) hleReSchedule("umd stat checked"); } - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout); + DEBUG_LOG(HLE, "0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d)", stat, timeout); return 0; } int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) { if (stat == 0) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): bad status", stat, timeout); + DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): bad status", stat, timeout); return SCE_KERNEL_ERROR_ERRNO_INVALID_ARGUMENT; } if (!__KernelIsDispatchEnabled()) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); + DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): dispatch disabled", stat, timeout); return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } + if (__IsInInterrupt()) { + DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): inside interrupt", stat, timeout); + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } hleCheckCurrentCallbacks(); if ((stat & __KernelUmdGetState()) == 0) { - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): waiting", stat, timeout); + DEBUG_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d): waiting", stat, timeout); if (timeout == 0) { timeout = 8000; } @@ -343,13 +356,13 @@ int sceUmdWaitDriveStatCB(u32 stat, u32 timeout) hleReSchedule("umd stat waited"); } - DEBUG_LOG(HLE,"0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); + DEBUG_LOG(HLE, "0=sceUmdWaitDriveStatCB(stat = %08x, timeout = %d)", stat, timeout); return 0; } u32 sceUmdCancelWaitDriveStat() { - DEBUG_LOG(HLE,"0=sceUmdCancelWaitDriveStat()"); + DEBUG_LOG(HLE, "0=sceUmdCancelWaitDriveStat()"); __KernelTriggerWait(WAITTYPE_UMD, 1, SCE_KERNEL_ERROR_WAIT_CANCEL, "umd stat ready", true); // TODO: We should call UnscheduleEvent() event here? diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp index b4d98e88cd..ae81a3fa9a 100644 --- a/GPU/GPUCommon.cpp +++ b/GPU/GPUCommon.cpp @@ -11,6 +11,7 @@ #include "Core/Host.h" #include "Core/Reporting.h" #include "Core/HLE/sceKernelMemory.h" +#include "Core/HLE/sceKernelInterrupt.h" #include "Core/HLE/sceGe.h" GPUCommon::GPUCommon() : @@ -63,6 +64,9 @@ u32 GPUCommon::DrawSync(int mode) { if (!__KernelIsDispatchEnabled()) { return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } + if (__IsInInterrupt()) { + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if (drawCompleteTicks > CoreTiming::GetTicks()) { __GeWaitCurrentThread(WAITTYPE_GEDRAWSYNC, 1, "GeDrawSync"); @@ -143,6 +147,9 @@ int GPUCommon::ListSync(int listid, int mode) { if (!__KernelIsDispatchEnabled()) { return SCE_KERNEL_ERROR_CAN_NOT_WAIT; } + if (__IsInInterrupt()) { + return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT; + } if (dl.waitTicks > CoreTiming::GetTicks()) { __GeWaitCurrentThread(WAITTYPE_GELISTSYNC, listid, "GeListSync");