1
// Copyright (c) 2012- PPSSPP Project.
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
23
#include "Common/CommonTypes.h"
24
#include "Core/HLE/sceKernel.h"
26
// There's a good description of the thread scheduling rules in:
27
// http://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/HLE/modules150/ThreadManForUser.java
31
int sceKernelChangeThreadPriority(SceUID threadID, int priority);
32
SceUID __KernelCreateThreadInternal(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr);
33
int __KernelCreateThread(const char *threadName, SceUID moduleID, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
34
int sceKernelCreateThread(const char *threadName, u32 entry, u32 prio, int stacksize, u32 attr, u32 optionAddr);
35
int sceKernelDelayThread(u32 usec);
36
int sceKernelDelayThreadCB(u32 usec);
37
int sceKernelDelaySysClockThread(u32 sysclockAddr);
38
int sceKernelDelaySysClockThreadCB(u32 sysclockAddr);
39
void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason);
40
u32 __KernelDeleteThread(SceUID threadID, int exitStatus, const char *reason);
41
int sceKernelDeleteThread(int threadHandle);
42
void sceKernelExitDeleteThread(int exitStatus);
43
void sceKernelExitThread(int exitStatus);
44
void _sceKernelExitThread(int exitStatus);
45
SceUID sceKernelGetThreadId();
46
int sceKernelGetThreadCurrentPriority();
47
int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
48
int __KernelStartThreadValidate(SceUID threadToStartID, int argSize, u32 argBlockPtr, bool forceArgs = false);
49
int sceKernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr);
50
u32 sceKernelSuspendDispatchThread();
51
u32 sceKernelResumeDispatchThread(u32 suspended);
52
int sceKernelWaitThreadEnd(SceUID threadID, u32 timeoutPtr);
53
u32 sceKernelReferThreadStatus(u32 uid, u32 statusPtr);
54
u32 sceKernelReferThreadRunStatus(u32 uid, u32 statusPtr);
55
int sceKernelReleaseWaitThread(SceUID threadID);
56
int sceKernelChangeCurrentThreadAttr(u32 clearAttr, u32 setAttr);
57
int sceKernelRotateThreadReadyQueue(int priority);
58
int sceKernelCheckThreadStack();
59
int sceKernelSuspendThread(SceUID threadID);
60
int sceKernelResumeThread(SceUID threadID);
61
int sceKernelWakeupThread(SceUID threadID);
62
int sceKernelCancelWakeupThread(SceUID threadID);
63
int sceKernelSleepThread();
64
int sceKernelSleepThreadCB();
65
int sceKernelTerminateDeleteThread(int threadno);
66
int sceKernelTerminateThread(SceUID threadID);
67
int sceKernelWaitThreadEndCB(SceUID threadID, u32 timeoutPtr);
68
int sceKernelGetThreadExitStatus(SceUID threadID);
69
u32 sceKernelGetThreadmanIdType(u32);
70
u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 idCountPtr);
71
u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter);
73
struct SceKernelSysClock {
79
// TODO: Map these to PSP wait types. Most of these are wrong.
80
// remember to update the waitTypeNames array in sceKernelThread.cpp when changing these
87
WAITTYPE_EVENTFLAG = 4,
91
WAITTYPE_MSGPIPE = 8, // fake
92
WAITTYPE_THREADEND = 9,
93
WAITTYPE_AUDIOCHANNEL = 10, // this is fake, should be replaced with 8 eventflags ( ?? )
94
WAITTYPE_UMD = 11, // this is fake, should be replaced with 1 eventflag ( ?? )
95
WAITTYPE_VBLANK = 12, // fake
97
WAITTYPE_LWMUTEX = 14,
100
WAITTYPE_GEDRAWSYNC = 17,
101
WAITTYPE_GELISTSYNC = 18,
102
WAITTYPE_MODULE = 19,
103
WAITTYPE_HLEDELAY = 20,
106
WAITTYPE_ASYNCIO = 23,
111
const char *getWaitTypeName(WaitType type);
113
// Suspend wait and timeout while a thread enters a callback.
114
typedef void (* WaitBeginCallbackFunc)(SceUID threadID, SceUID prevCallbackId);
115
// Resume wait and timeout as a thread exits a callback.
116
typedef void (* WaitEndCallbackFunc)(SceUID threadID, SceUID prevCallbackId);
118
void __KernelRegisterWaitTypeFuncs(WaitType type, WaitBeginCallbackFunc beginFunc, WaitEndCallbackFunc endFunc);
124
// r must be followed by f.
151
// Internal API, used by implementations of kernel functions
153
void __KernelThreadingInit();
154
void __KernelThreadingDoState(PointerWrap &p);
155
void __KernelThreadingDoStateLate(PointerWrap &p);
156
void __KernelThreadingShutdown();
157
KernelObject *__KernelThreadObject();
158
KernelObject *__KernelCallbackObject();
160
void __KernelScheduleWakeup(int threadnumber, s64 usFromNow);
161
SceUID __KernelGetCurThread();
162
u32 __KernelGetCurThreadStack();
163
u32 __KernelGetCurThreadStackStart();
164
const char *__KernelGetThreadName(SceUID threadID);
166
void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled);
167
void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled);
169
u32 __KernelResumeThreadFromWait(SceUID threadID, u32 retval); // can return an error value
170
u32 __KernelResumeThreadFromWait(SceUID threadID, u64 retval);
172
inline u32 __KernelResumeThreadFromWait(SceUID threadID, int retval)
174
return __KernelResumeThreadFromWait(threadID, (u32)retval);
177
inline u32 __KernelResumeThreadFromWait(SceUID threadID, s64 retval)
179
return __KernelResumeThreadFromWait(threadID, (u64)retval);
182
u32 __KernelGetWaitValue(SceUID threadID, u32 &error);
183
u32 __KernelGetWaitTimeoutPtr(SceUID threadID, u32 &error);
184
SceUID __KernelGetWaitID(SceUID threadID, WaitType type, u32 &error);
185
SceUID __KernelGetCurrentCallbackID(SceUID threadID, u32 &error);
186
void __KernelWaitCurThread(WaitType type, SceUID waitId, u32 waitValue, u32 timeoutPtr, bool processCallbacks, const char *reason);
187
void __KernelWaitCallbacksCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 timeoutPtr);
188
void __KernelReSchedule(const char *reason = "no reason");
189
void __KernelReSchedule(bool doCallbacks, const char *reason);
191
SceUID __KernelGetCurThread();
192
SceUID __KernelGetCurThreadModuleId();
193
SceUID __KernelSetupRootThread(SceUID moduleId, int args, const char *argp, int prio, int stacksize, int attr); //represents the real PSP elf loader, run before execution
194
void __KernelStartIdleThreads(SceUID moduleId);
195
void __KernelReturnFromThread(); // Called as HLE function
196
u32 __KernelGetThreadPrio(SceUID id);
197
bool __KernelThreadSortPriority(SceUID thread1, SceUID thread2);
198
bool __KernelIsDispatchEnabled();
199
void __KernelReturnFromExtendStack();
203
u32 __KernelMipsCallReturnAddress();
204
u32 __KernelInterruptReturnAddress(); // TODO: remove
206
SceUID sceKernelCreateCallback(const char *name, u32 entrypoint, u32 signalArg);
207
int sceKernelDeleteCallback(SceUID cbId);
208
int sceKernelNotifyCallback(SceUID cbId, int notifyArg);
209
int sceKernelCancelCallback(SceUID cbId);
210
int sceKernelGetCallbackCount(SceUID cbId);
211
void sceKernelCheckCallback();
212
int sceKernelReferCallbackStatus(SceUID cbId, u32 statusAddr);
216
// Not an official Callback object, just calls a mips function on the current thread.
217
void __KernelDirectMipsCall(u32 entryPoint, Action *afterAction, u32 args[], int numargs, bool reschedAfter);
219
void __KernelReturnFromMipsCall(); // Called as HLE function
220
bool __KernelInCallback();
222
// Should be called by (nearly) all ...CB functions.
223
bool __KernelCheckCallbacks();
224
bool __KernelForceCallbacks();
225
bool __KernelCurHasReadyCallbacks();
226
void __KernelSwitchContext(Thread *target, const char *reason);
227
bool __KernelExecutePendingMipsCalls(Thread *currentThread, bool reschedAfter);
228
void __KernelNotifyCallback(SceUID cbId, int notifyArg);
230
// Switch to an idle / non-user thread, if not already on one.
231
// Returns whether a switch occurred.
232
bool __KernelSwitchOffThread(const char *reason);
233
bool __KernelSwitchToThread(SceUID threadID, const char *reason);
235
// Set a thread's return address to a specific FakeSyscall nid.
236
// Discards old RA. Only useful for special threads that do special things on exit.
237
u32 __KernelSetThreadRA(SceUID threadID, u32 nid);
239
// A call into game code. These can be pending on a thread.
240
// Similar to Callback-s (NOT CallbackInfos) in JPCSP.
241
typedef Action *(*ActionCreator)();
242
Action *__KernelCreateAction(int actionType);
243
int __KernelRegisterActionType(ActionCreator creator);
244
void __KernelRestoreActionType(int actionType, ActionCreator creator);
265
void DoState(PointerWrap &p);
266
void setReturnValue(u32 value);
267
void setReturnValue(u64 value);
268
inline void setReturnValue(int value)
270
setReturnValue((u32)value);
272
inline void setReturnValue(s64 value)
274
setReturnValue((u64)value);
282
virtual void run(MipsCall &call) = 0;
283
virtual void DoState(PointerWrap &p) = 0;
289
THREADSTATUS_RUNNING = 1,
290
THREADSTATUS_READY = 2,
291
THREADSTATUS_WAIT = 4,
292
THREADSTATUS_SUSPEND = 8,
293
THREADSTATUS_DORMANT = 16,
294
THREADSTATUS_DEAD = 32,
296
THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
299
void __KernelChangeThreadState(Thread *thread, ThreadStatus newStatus);
301
typedef void (*ThreadCallback)(SceUID threadID);
302
void __KernelListenThreadEnd(ThreadCallback callback);
304
struct DebugThreadInfo
307
char name[KERNELOBJECT_MAX_NAME_LENGTH+1];
318
std::vector<DebugThreadInfo> GetThreadsInfo();
319
void __KernelChangeThreadState(SceUID threadId, ThreadStatus newStatus);
321
int LoadExecForUser_362A956B();
322
int sceKernelRegisterExitCallback(SceUID cbId);