2012-11-01 16:19:01 +01:00
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
2012-11-04 23:01:49 +01:00
// the Free Software Foundation, version 2.0 or later versions.
2012-11-01 16:19:01 +01:00
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
# pragma once
2013-12-30 10:49:05 +01:00
# include <string>
2013-12-30 10:17:11 +01:00
# include <vector>
2012-11-01 16:19:01 +01:00
2014-03-15 11:44:02 -07:00
# include "Common/CommonTypes.h"
# include "Core/HLE/sceKernel.h"
2012-11-01 16:19:01 +01:00
// There's a good description of the thread scheduling rules in:
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/ThreadManForUser.java
2020-03-15 08:33:40 -07:00
class PSPThread ;
2018-05-09 17:51:27 -07:00
class DebugInterface ;
2014-08-01 01:54:13 +07:00
2013-06-05 23:04:42 -07:00
int sceKernelChangeThreadPriority ( SceUID threadID , int priority ) ;
2014-05-22 23:38:21 -07:00
SceUID __KernelCreateThreadInternal ( const char * threadName , SceUID moduleID , u32 entry , u32 prio , int stacksize , u32 attr ) ;
2019-03-23 12:05:06 -07:00
int __KernelCreateThread ( const char * threadName , SceUID moduleID , u32 entry , u32 prio , int stacksize , u32 attr , u32 optionAddr , bool allowKernel ) ;
2012-12-09 00:29:10 -08:00
int sceKernelCreateThread ( const char * threadName , u32 entry , u32 prio , int stacksize , u32 attr , u32 optionAddr ) ;
2013-03-06 07:40:34 -08:00
int sceKernelDelayThread ( u32 usec ) ;
int sceKernelDelayThreadCB ( u32 usec ) ;
2013-08-27 23:02:18 -07:00
int sceKernelDelaySysClockThread ( u32 sysclockAddr ) ;
int sceKernelDelaySysClockThreadCB ( u32 sysclockAddr ) ;
2014-05-22 23:38:21 -07:00
void __KernelStopThread ( SceUID threadID , int exitStatus , const char * reason ) ;
u32 __KernelDeleteThread ( SceUID threadID , int exitStatus , const char * reason ) ;
2012-12-09 00:29:10 -08:00
int sceKernelDeleteThread ( int threadHandle ) ;
2020-08-18 21:03:45 +08:00
int sceKernelExitDeleteThread ( int exitStatus ) ;
2020-08-17 23:16:15 +08:00
int sceKernelExitThread ( int exitStatus ) ;
2013-04-09 23:16:23 -07:00
void _sceKernelExitThread ( int exitStatus ) ;
SceUID sceKernelGetThreadId ( ) ;
2015-03-22 16:57:56 -07:00
int sceKernelGetThreadCurrentPriority ( ) ;
2016-05-28 21:14:19 -07:00
// Warning: will alter v0 in current MIPS state.
2014-05-22 23:38:21 -07:00
int __KernelStartThread ( SceUID threadToStartID , int argSize , u32 argBlockPtr , bool forceArgs = false ) ;
2015-03-28 14:46:09 -07:00
int __KernelStartThreadValidate ( SceUID threadToStartID , int argSize , u32 argBlockPtr , bool forceArgs = false ) ;
2013-04-27 21:26:50 -07:00
int sceKernelStartThread ( SceUID threadToStartID , int argSize , u32 argBlockPtr ) ;
2012-11-06 19:22:14 +01:00
u32 sceKernelSuspendDispatchThread ( ) ;
u32 sceKernelResumeDispatchThread ( u32 suspended ) ;
2013-01-07 10:02:11 -08:00
int sceKernelWaitThreadEnd ( SceUID threadID , u32 timeoutPtr ) ;
2013-01-05 23:06:28 +01:00
u32 sceKernelReferThreadStatus ( u32 uid , u32 statusPtr ) ;
u32 sceKernelReferThreadRunStatus ( u32 uid , u32 statusPtr ) ;
2013-01-07 19:44:39 -08:00
int sceKernelReleaseWaitThread ( SceUID threadID ) ;
2013-06-06 00:08:24 -07:00
int sceKernelChangeCurrentThreadAttr ( u32 clearAttr , u32 setAttr ) ;
2013-02-09 02:17:19 -08:00
int sceKernelRotateThreadReadyQueue ( int priority ) ;
2020-08-28 01:05:02 -07:00
int KernelRotateThreadReadyQueue ( int priority ) ;
2013-03-23 14:41:13 +01:00
int sceKernelCheckThreadStack ( ) ;
2013-05-26 00:54:30 -07:00
int sceKernelSuspendThread ( SceUID threadID ) ;
int sceKernelResumeThread ( SceUID threadID ) ;
2013-05-25 20:43:19 -07:00
int sceKernelWakeupThread ( SceUID threadID ) ;
int sceKernelCancelWakeupThread ( SceUID threadID ) ;
int sceKernelSleepThread ( ) ;
int sceKernelSleepThreadCB ( ) ;
2012-12-09 00:29:10 -08:00
int sceKernelTerminateDeleteThread ( int threadno ) ;
2013-03-02 14:58:58 -08:00
int sceKernelTerminateThread ( SceUID threadID ) ;
2013-01-07 10:02:11 -08:00
int sceKernelWaitThreadEndCB ( SceUID threadID , u32 timeoutPtr ) ;
2013-05-26 10:17:59 -07:00
int sceKernelGetThreadExitStatus ( SceUID threadID ) ;
2012-12-17 22:20:32 +01:00
u32 sceKernelGetThreadmanIdType ( u32 ) ;
u32 sceKernelGetThreadmanIdList ( u32 type , u32 readBufPtr , u32 readBufSize , u32 idCountPtr ) ;
2013-04-19 22:22:35 +08:00
u32 sceKernelExtendThreadStack ( u32 size , u32 entryAddr , u32 entryParameter ) ;
2012-11-01 16:19:01 +01:00
2012-12-30 21:30:33 +01:00
struct SceKernelSysClock {
2013-07-24 23:58:45 -07:00
u32_le lo ;
u32_le hi ;
2012-12-30 21:30:33 +01:00
} ;
2012-11-01 16:19:01 +01:00
2013-08-26 01:04:37 -07:00
// TODO: Map these to PSP wait types. Most of these are wrong.
2013-07-06 21:40:41 +02:00
// remember to update the waitTypeNames array in sceKernelThread.cpp when changing these
2020-01-03 13:09:58 -08:00
enum WaitType : int
2012-11-01 16:19:01 +01:00
{
2014-03-03 11:16:53 -05:00
WAITTYPE_NONE = 0 ,
WAITTYPE_SLEEP = 1 ,
WAITTYPE_DELAY = 2 ,
WAITTYPE_SEMA = 3 ,
WAITTYPE_EVENTFLAG = 4 ,
WAITTYPE_MBX = 5 ,
WAITTYPE_VPL = 6 ,
WAITTYPE_FPL = 7 ,
WAITTYPE_MSGPIPE = 8 , // fake
WAITTYPE_THREADEND = 9 ,
2012-11-01 16:19:01 +01:00
WAITTYPE_AUDIOCHANNEL = 10 , // this is fake, should be replaced with 8 eventflags ( ?? )
2014-03-03 11:16:53 -05:00
WAITTYPE_UMD = 11 , // this is fake, should be replaced with 1 eventflag ( ?? )
WAITTYPE_VBLANK = 12 , // fake
WAITTYPE_MUTEX = 13 ,
WAITTYPE_LWMUTEX = 14 ,
WAITTYPE_CTRL = 15 ,
WAITTYPE_IO = 16 ,
WAITTYPE_GEDRAWSYNC = 17 ,
WAITTYPE_GELISTSYNC = 18 ,
WAITTYPE_MODULE = 19 ,
WAITTYPE_HLEDELAY = 20 ,
WAITTYPE_TLSPL = 21 ,
WAITTYPE_VMEM = 22 ,
WAITTYPE_ASYNCIO = 23 ,
2020-07-31 10:24:17 +08:00
WAITTYPE_MICINPUT = 24 , // fake
2020-08-18 02:01:30 +07:00
WAITTYPE_NET = 25 , // fake
2013-03-27 00:51:46 -07:00
NUM_WAITTYPES
2012-11-01 16:19:01 +01:00
} ;
2013-07-06 23:06:16 -07:00
const char * getWaitTypeName ( WaitType type ) ;
2013-07-06 21:40:41 +02:00
2013-03-27 00:51:46 -07:00
// Suspend wait and timeout while a thread enters a callback.
typedef void ( * WaitBeginCallbackFunc ) ( SceUID threadID , SceUID prevCallbackId ) ;
// Resume wait and timeout as a thread exits a callback.
2013-09-02 16:29:00 -07:00
typedef void ( * WaitEndCallbackFunc ) ( SceUID threadID , SceUID prevCallbackId ) ;
2013-03-27 00:51:46 -07:00
void __KernelRegisterWaitTypeFuncs ( WaitType type , WaitBeginCallbackFunc beginFunc , WaitEndCallbackFunc endFunc ) ;
2012-11-01 16:19:01 +01:00
2020-03-15 08:33:40 -07:00
struct PSPThreadContext {
2012-12-30 21:30:33 +01:00
void reset ( ) ;
2013-08-15 01:26:16 -07:00
// r must be followed by f.
2012-12-30 21:30:33 +01:00
u32 r [ 32 ] ;
2013-10-29 21:39:24 -07:00
union {
float f [ 32 ] ;
u32 fi [ 32 ] ;
int fs [ 32 ] ;
} ;
union {
float v [ 128 ] ;
u32 vi [ 128 ] ;
} ;
2012-12-30 21:30:33 +01:00
u32 vfpuCtrl [ 16 ] ;
2013-08-15 01:26:16 -07:00
union {
struct {
u32 pc ;
2013-01-26 11:27:06 -08:00
2013-08-15 01:26:16 -07:00
u32 lo ;
2015-06-28 10:42:19 -07:00
u32 hi ;
2012-12-30 21:30:33 +01:00
2013-08-15 01:26:16 -07:00
u32 fcr31 ;
u32 fpcond ;
} ;
u32 other [ 6 ] ;
} ;
2012-11-01 16:19:01 +01:00
} ;
// Internal API, used by implementations of kernel functions
void __KernelThreadingInit ( ) ;
2012-12-27 19:30:36 -08:00
void __KernelThreadingDoState ( PointerWrap & p ) ;
void __KernelThreadingDoStateLate ( PointerWrap & p ) ;
2012-11-01 16:19:01 +01:00
void __KernelThreadingShutdown ( ) ;
2020-07-12 16:47:53 +02:00
std : : string __KernelThreadingSummary ( ) ;
2012-12-26 22:45:19 -08:00
KernelObject * __KernelThreadObject ( ) ;
KernelObject * __KernelCallbackObject ( ) ;
2012-11-01 16:19:01 +01:00
2013-01-05 23:24:05 +01:00
void __KernelScheduleWakeup ( int threadnumber , s64 usFromNow ) ;
2012-11-01 16:19:01 +01:00
SceUID __KernelGetCurThread ( ) ;
2019-07-28 14:55:21 -07:00
int KernelCurThreadPriority ( ) ;
2019-10-20 10:26:37 -07:00
bool KernelChangeThreadPriority ( SceUID threadID , int priority ) ;
2013-03-23 14:26:54 +01:00
u32 __KernelGetCurThreadStack ( ) ;
2015-03-02 01:03:12 +01:00
u32 __KernelGetCurThreadStackStart ( ) ;
2013-03-10 22:25:03 -07:00
const char * __KernelGetThreadName ( SceUID threadID ) ;
2019-07-28 14:55:21 -07:00
bool KernelIsThreadDormant ( SceUID threadID ) ;
2012-11-01 16:19:01 +01:00
2020-03-15 08:33:40 -07:00
void __KernelSaveContext ( PSPThreadContext * ctx , bool vfpuEnabled ) ;
void __KernelLoadContext ( PSPThreadContext * ctx , bool vfpuEnabled ) ;
2012-11-01 16:19:01 +01:00
2013-09-08 12:02:18 -07:00
u32 __KernelResumeThreadFromWait ( SceUID threadID , u32 retval ) ; // can return an error value
2013-03-10 10:59:59 -07:00
u32 __KernelResumeThreadFromWait ( SceUID threadID , u64 retval ) ;
inline u32 __KernelResumeThreadFromWait ( SceUID threadID , int retval )
{
return __KernelResumeThreadFromWait ( threadID , ( u32 ) retval ) ;
}
inline u32 __KernelResumeThreadFromWait ( SceUID threadID , s64 retval )
{
return __KernelResumeThreadFromWait ( threadID , ( u64 ) retval ) ;
}
2012-11-01 16:19:01 +01:00
u32 __KernelGetWaitValue ( SceUID threadID , u32 & error ) ;
2012-11-18 19:13:39 -08:00
u32 __KernelGetWaitTimeoutPtr ( SceUID threadID , u32 & error ) ;
2012-11-20 00:18:11 -08:00
SceUID __KernelGetWaitID ( SceUID threadID , WaitType type , u32 & error ) ;
2013-03-27 00:51:46 -07:00
SceUID __KernelGetCurrentCallbackID ( SceUID threadID , u32 & error ) ;
2013-01-26 10:44:04 -08:00
void __KernelWaitCurThread ( WaitType type , SceUID waitId , u32 waitValue , u32 timeoutPtr , bool processCallbacks , const char * reason ) ;
2013-03-30 13:48:29 -07:00
void __KernelWaitCallbacksCurThread ( WaitType type , SceUID waitID , u32 waitValue , u32 timeoutPtr ) ;
2012-11-01 16:19:01 +01:00
void __KernelReSchedule ( const char * reason = " no reason " ) ;
2012-11-07 15:44:48 +01:00
void __KernelReSchedule ( bool doCallbacks , const char * reason ) ;
2012-11-06 15:46:21 +01:00
2012-11-01 16:19:01 +01:00
SceUID __KernelGetCurThread ( ) ;
2012-11-17 14:20:04 +01:00
SceUID __KernelGetCurThreadModuleId ( ) ;
2013-05-26 10:28:08 -07:00
SceUID __KernelSetupRootThread ( SceUID moduleId , int args , const char * argp , int prio , int stacksize , int attr ) ; //represents the real PSP elf loader, run before execution
2013-04-10 21:16:31 -07:00
void __KernelStartIdleThreads ( SceUID moduleId ) ;
2012-11-07 15:44:48 +01:00
void __KernelReturnFromThread ( ) ; // Called as HLE function
2012-11-08 14:24:51 +01:00
u32 __KernelGetThreadPrio ( SceUID id ) ;
2013-01-17 00:45:13 -08:00
bool __KernelThreadSortPriority ( SceUID thread1 , SceUID thread2 ) ;
2013-03-24 23:30:32 -07:00
bool __KernelIsDispatchEnabled ( ) ;
2013-05-18 20:16:01 -07:00
void __KernelReturnFromExtendStack ( ) ;
2012-11-01 16:19:01 +01:00
2012-11-17 14:20:04 +01:00
void __KernelIdle ( ) ;
2012-11-01 16:19:01 +01:00
2020-03-21 16:09:23 -07:00
u32 HLEMipsCallReturnAddress ( ) ;
u32 __KernelCallbackReturnAddress ( ) ;
2012-11-07 15:44:48 +01:00
u32 __KernelInterruptReturnAddress ( ) ; // TODO: remove
2012-11-06 15:46:21 +01:00
2013-04-14 23:45:46 -07:00
SceUID sceKernelCreateCallback ( const char * name , u32 entrypoint , u32 signalArg ) ;
int sceKernelDeleteCallback ( SceUID cbId ) ;
int sceKernelNotifyCallback ( SceUID cbId , int notifyArg ) ;
int sceKernelCancelCallback ( SceUID cbId ) ;
int sceKernelGetCallbackCount ( SceUID cbId ) ;
2012-11-07 15:44:48 +01:00
void sceKernelCheckCallback ( ) ;
2013-04-14 23:45:46 -07:00
int sceKernelReferCallbackStatus ( SceUID cbId , u32 statusAddr ) ;
2012-11-13 18:05:26 +01:00
2020-03-15 08:33:40 -07:00
class PSPAction ;
2012-11-13 18:05:26 +01:00
// Not an official Callback object, just calls a mips function on the current thread.
2020-07-12 10:16:42 +02:00
// Takes ownership of afterAction.
2020-03-15 08:33:40 -07:00
void __KernelDirectMipsCall ( u32 entryPoint , PSPAction * afterAction , u32 args [ ] , int numargs , bool reschedAfter ) ;
2012-11-13 18:05:26 +01:00
2012-11-07 15:44:48 +01:00
void __KernelReturnFromMipsCall ( ) ; // Called as HLE function
2012-11-06 15:46:21 +01:00
bool __KernelInCallback ( ) ;
// Should be called by (nearly) all ...CB functions.
bool __KernelCheckCallbacks ( ) ;
2012-12-01 18:43:45 -08:00
bool __KernelForceCallbacks ( ) ;
2013-03-29 00:27:33 -07:00
bool __KernelCurHasReadyCallbacks ( ) ;
2020-03-15 08:33:40 -07:00
void __KernelSwitchContext ( PSPThread * target , const char * reason ) ;
bool __KernelExecutePendingMipsCalls ( PSPThread * currentThread , bool reschedAfter ) ;
2013-09-02 01:25:41 -07:00
void __KernelNotifyCallback ( SceUID cbId , int notifyArg ) ;
2012-11-07 15:44:48 +01:00
2012-12-18 00:58:46 -08:00
// Switch to an idle / non-user thread, if not already on one.
// Returns whether a switch occurred.
bool __KernelSwitchOffThread ( const char * reason ) ;
2013-04-06 17:03:39 -07:00
bool __KernelSwitchToThread ( SceUID threadID , const char * reason ) ;
2012-12-18 00:58:46 -08:00
2013-05-26 10:28:08 -07:00
// Set a thread's return address to a specific FakeSyscall nid.
// Discards old RA. Only useful for special threads that do special things on exit.
2013-05-26 19:02:40 -07:00
u32 __KernelSetThreadRA ( SceUID threadID , u32 nid ) ;
2013-05-26 10:28:08 -07:00
2012-11-07 15:44:48 +01:00
// A call into game code. These can be pending on a thread.
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
2020-03-15 08:33:40 -07:00
typedef PSPAction * ( * ActionCreator ) ( ) ;
PSPAction * __KernelCreateAction ( int actionType ) ;
2012-12-27 19:30:36 -08:00
int __KernelRegisterActionType ( ActionCreator creator ) ;
void __KernelRestoreActionType ( int actionType , ActionCreator creator ) ;
2012-12-28 22:32:56 -08:00
2012-11-07 15:44:48 +01:00
struct MipsCall {
2013-02-02 18:46:23 -08:00
MipsCall ( )
{
doAfter = NULL ;
}
2012-11-07 15:44:48 +01:00
u32 entryPoint ;
u32 cbId ;
u32 args [ 6 ] ;
int numArgs ;
2020-03-15 08:33:40 -07:00
PSPAction * doAfter ;
2012-11-07 15:44:48 +01:00
u32 savedPc ;
u32 savedV0 ;
u32 savedV1 ;
2012-12-27 19:30:36 -08:00
std : : string tag ;
2012-12-08 11:23:20 -08:00
u32 savedId ;
2012-12-08 20:09:20 -08:00
bool reschedAfter ;
2012-12-27 19:30:36 -08:00
void DoState ( PointerWrap & p ) ;
2013-01-06 15:53:44 -08:00
void setReturnValue ( u32 value ) ;
2013-03-10 10:59:59 -07:00
void setReturnValue ( u64 value ) ;
inline void setReturnValue ( int value )
{
setReturnValue ( ( u32 ) value ) ;
}
inline void setReturnValue ( s64 value )
{
setReturnValue ( ( u64 ) value ) ;
}
2013-01-06 15:53:44 -08:00
} ;
2020-03-15 08:33:40 -07:00
class PSPAction
2013-01-06 15:53:44 -08:00
{
public :
2020-03-15 08:33:40 -07:00
virtual ~ PSPAction ( ) { }
2013-01-06 15:53:44 -08:00
virtual void run ( MipsCall & call ) = 0 ;
virtual void DoState ( PointerWrap & p ) = 0 ;
int actionTypeID ;
2012-11-07 15:44:48 +01:00
} ;
2012-12-30 21:30:33 +01:00
2012-11-07 15:44:48 +01:00
enum ThreadStatus
{
THREADSTATUS_RUNNING = 1 ,
2014-03-03 11:16:53 -05:00
THREADSTATUS_READY = 2 ,
THREADSTATUS_WAIT = 4 ,
2012-11-07 15:44:48 +01:00
THREADSTATUS_SUSPEND = 8 ,
THREADSTATUS_DORMANT = 16 ,
2014-03-03 11:16:53 -05:00
THREADSTATUS_DEAD = 32 ,
2012-11-07 15:44:48 +01:00
THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
} ;
2020-03-15 08:33:40 -07:00
void __KernelChangeThreadState ( PSPThread * thread , ThreadStatus newStatus ) ;
2012-11-20 00:18:11 -08:00
typedef void ( * ThreadCallback ) ( SceUID threadID ) ;
void __KernelListenThreadEnd ( ThreadCallback callback ) ;
2013-02-10 16:36:06 +01:00
struct DebugThreadInfo
{
SceUID id ;
char name [ KERNELOBJECT_MAX_NAME_LENGTH + 1 ] ;
u32 status ;
2013-08-12 01:54:14 -07:00
u32 curPC ;
u32 entrypoint ;
u32 initialStack ;
int stackSize ;
2013-07-06 21:40:41 +02:00
int priority ;
WaitType waitType ;
2013-02-10 16:36:06 +01:00
bool isCurrent ;
} ;
std : : vector < DebugThreadInfo > GetThreadsInfo ( ) ;
2018-05-09 17:51:27 -07:00
DebugInterface * KernelDebugThread ( SceUID threadID ) ;
2013-02-10 16:36:06 +01:00
void __KernelChangeThreadState ( SceUID threadId , ThreadStatus newStatus ) ;
2013-09-29 01:10:07 -07:00
2013-09-29 00:19:54 -07:00
int LoadExecForUser_362A956B ( ) ;
2013-09-29 01:10:07 -07:00
int sceKernelRegisterExitCallback ( SceUID cbId ) ;
2014-01-04 22:41:37 -08:00
KernelObject * __KernelThreadEventHandlerObject ( ) ;
SceUID sceKernelRegisterThreadEventHandler ( const char * name , SceUID threadID , u32 mask , u32 handlerPtr , u32 commonArg ) ;
int sceKernelReleaseThreadEventHandler ( SceUID uid ) ;
int sceKernelReferThreadEventHandlerStatus ( SceUID uid , u32 infoPtr ) ;