~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to Core/HLE/sceKernel.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (c) 2012- PPSSPP Project.
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official git repository and contact information can be found at
 
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
 
17
 
 
18
#include "Core/Core.h"
 
19
#include "Core/Config.h"
 
20
#include "Core/CwCheat.h"
 
21
#include "Core/MemMapHelpers.h"
 
22
#include "Core/HLE/HLE.h"
 
23
#include "Core/HLE/FunctionWrappers.h"
 
24
#include "Core/MIPS/MIPS.h"
 
25
#include "Core/MIPS/MIPSCodeUtils.h"
 
26
#include "Core/MIPS/MIPSInt.h"
 
27
#include "Core/MIPS/JitCommon/JitCommon.h"
 
28
 
 
29
#include "Common/LogManager.h"
 
30
#include "Core/FileSystems/FileSystem.h"
 
31
#include "Core/FileSystems/MetaFileSystem.h"
 
32
#include "Core/PSPLoaders.h"
 
33
#include "Core/CoreTiming.h"
 
34
#include "Core/Reporting.h"
 
35
#include "Core/SaveState.h"
 
36
#include "Core/System.h"
 
37
#include "GPU/GPUInterface.h"
 
38
#include "GPU/GPUState.h"
 
39
 
 
40
#include "__sceAudio.h"
 
41
#include "sceAtrac.h"
 
42
#include "sceAudio.h"
 
43
#include "sceAudiocodec.h"
 
44
#include "sceCcc.h"
 
45
#include "sceCtrl.h"
 
46
#include "sceDisplay.h"
 
47
#include "sceFont.h"
 
48
#include "sceGe.h"
 
49
#include "sceIo.h"
 
50
#include "sceJpeg.h"
 
51
#include "sceKernel.h"
 
52
#include "sceKernelAlarm.h"
 
53
#include "sceKernelInterrupt.h"
 
54
#include "sceKernelThread.h"
 
55
#include "sceKernelMemory.h"
 
56
#include "sceKernelModule.h"
 
57
#include "sceKernelMutex.h"
 
58
#include "sceKernelMbx.h"
 
59
#include "sceKernelMsgPipe.h"
 
60
#include "sceKernelInterrupt.h"
 
61
#include "sceKernelSemaphore.h"
 
62
#include "sceKernelEventFlag.h"
 
63
#include "sceKernelVTimer.h"
 
64
#include "sceKernelTime.h"
 
65
#include "sceMp3.h"
 
66
#include "sceMpeg.h"
 
67
#include "sceNet.h"
 
68
#include "sceNetAdhoc.h"
 
69
#include "scePower.h"
 
70
#include "sceUtility.h"
 
71
#include "sceUmd.h"
 
72
#include "sceRtc.h"
 
73
#include "sceSsl.h"
 
74
#include "sceSas.h"
 
75
#include "scePsmf.h"
 
76
#include "sceImpose.h"
 
77
#include "sceUsb.h"
 
78
#include "scePspNpDrm_user.h"
 
79
#include "sceVaudio.h"
 
80
#include "sceHeap.h"
 
81
#include "sceDmac.h"
 
82
#include "sceMp4.h"
 
83
 
 
84
#include "../Util/PPGeDraw.h"
 
85
 
 
86
/*
 
87
17: [MIPS32 R4K 00000000 ]: Loader: Type: 1 Vaddr: 00000000 Filesz: 2856816 Memsz: 2856816 
 
88
18: [MIPS32 R4K 00000000 ]: Loader: Loadable Segment Copied to 0898dab0, size 002b9770
 
89
19: [MIPS32 R4K 00000000 ]: Loader: Type: 1 Vaddr: 002b9770 Filesz: 14964 Memsz: 733156 
 
90
20: [MIPS32 R4K 00000000 ]: Loader: Loadable Segment Copied to 08c47220, size 000b2fe4
 
91
*/
 
92
 
 
93
static bool kernelRunning = false;
 
94
KernelObjectPool kernelObjects;
 
95
KernelStats kernelStats;
 
96
u32 registeredExitCbId;
 
97
 
 
98
void __KernelInit()
 
99
{
 
100
        if (kernelRunning)
 
101
        {
 
102
                ERROR_LOG(SCEKERNEL, "Can't init kernel when kernel is running");
 
103
                return;
 
104
        }
 
105
 
 
106
        __KernelTimeInit();
 
107
        __InterruptsInit();
 
108
        __KernelMemoryInit();
 
109
        __KernelThreadingInit();
 
110
        __KernelAlarmInit();
 
111
        __KernelVTimerInit();
 
112
        __KernelEventFlagInit();
 
113
        __KernelMbxInit();
 
114
        __KernelMutexInit();
 
115
        __KernelSemaInit();
 
116
        __KernelMsgPipeInit();
 
117
        __IoInit();
 
118
        __JpegInit();
 
119
        __AudioInit();
 
120
        __SasInit();
 
121
        __AtracInit();
 
122
        __CccInit();
 
123
        __DisplayInit();
 
124
        __GeInit();
 
125
        __PowerInit();
 
126
        __UtilityInit();
 
127
        __UmdInit();
 
128
        __MpegInit();
 
129
        __PsmfInit();
 
130
        __CtrlInit();
 
131
        __RtcInit();
 
132
        __SslInit();
 
133
        __ImposeInit();
 
134
        __UsbInit();
 
135
        __FontInit();
 
136
        __NetInit();
 
137
        __NetAdhocInit();
 
138
        __VaudioInit();
 
139
        __CheatInit();
 
140
        __HeapInit();
 
141
        __DmacInit();
 
142
        __AudioCodecInit();
 
143
        __VideoPmpInit();
 
144
        
 
145
        SaveState::Init();  // Must be after IO, as it may create a directory
 
146
        Reporting::Init();
 
147
 
 
148
        // "Internal" PSP libraries
 
149
        __PPGeInit();
 
150
 
 
151
        kernelRunning = true;
 
152
        INFO_LOG(SCEKERNEL, "Kernel initialized.");
 
153
}
 
154
 
 
155
void __KernelShutdown()
 
156
{
 
157
        if (!kernelRunning)
 
158
        {
 
159
                ERROR_LOG(SCEKERNEL, "Can't shut down kernel - not running");
 
160
                return;
 
161
        }
 
162
        kernelObjects.List();
 
163
        INFO_LOG(SCEKERNEL, "Shutting down kernel - %i kernel objects alive", kernelObjects.GetCount());
 
164
        hleCurrentThreadName = NULL;
 
165
        kernelObjects.Clear();
 
166
 
 
167
        __AudioCodecShutdown();
 
168
        __VideoPmpShutdown();
 
169
        __AACShutdown();
 
170
        __NetAdhocShutdown();
 
171
        __NetShutdown();
 
172
        __FontShutdown();
 
173
 
 
174
        __Mp3Shutdown();
 
175
        __MpegShutdown();
 
176
        __PsmfShutdown();
 
177
        __PPGeShutdown();
 
178
 
 
179
        __CtrlShutdown();
 
180
        __UtilityShutdown();
 
181
        __GeShutdown();
 
182
        __SasShutdown();
 
183
        __DisplayShutdown();
 
184
        __AtracShutdown();
 
185
        __AudioShutdown();
 
186
        __IoShutdown();
 
187
        __KernelMutexShutdown();
 
188
        __KernelThreadingShutdown();
 
189
        __KernelMemoryShutdown();
 
190
        __InterruptsShutdown();
 
191
        __CheatShutdown();
 
192
        __KernelModuleShutdown();
 
193
 
 
194
        CoreTiming::ClearPendingEvents();
 
195
        CoreTiming::UnregisterAllEvents();
 
196
        Reporting::Shutdown();
 
197
 
 
198
        kernelRunning = false;
 
199
}
 
200
 
 
201
void __KernelDoState(PointerWrap &p)
 
202
{
 
203
        {
 
204
                auto s = p.Section("Kernel", 1, 2);
 
205
                if (!s)
 
206
                        return;
 
207
 
 
208
                p.Do(kernelRunning);
 
209
                kernelObjects.DoState(p);
 
210
 
 
211
                if (s >= 2)
 
212
                        p.Do(registeredExitCbId);
 
213
        }
 
214
 
 
215
        {
 
216
                auto s = p.Section("Kernel Modules", 1);
 
217
                if (!s)
 
218
                        return;
 
219
 
 
220
                __InterruptsDoState(p);
 
221
                // Memory needs to be after kernel objects, which may free kernel memory.
 
222
                __KernelMemoryDoState(p);
 
223
                __KernelThreadingDoState(p);
 
224
                __KernelAlarmDoState(p);
 
225
                __KernelVTimerDoState(p);
 
226
                __KernelEventFlagDoState(p);
 
227
                __KernelMbxDoState(p);
 
228
                __KernelModuleDoState(p);
 
229
                __KernelMsgPipeDoState(p);
 
230
                __KernelMutexDoState(p);
 
231
                __KernelSemaDoState(p);
 
232
                __KernelTimeDoState(p);
 
233
        }
 
234
 
 
235
        {
 
236
                auto s = p.Section("HLE Modules", 1);
 
237
                if (!s)
 
238
                        return;
 
239
 
 
240
                __AtracDoState(p);
 
241
                __AudioDoState(p);
 
242
                __CccDoState(p);
 
243
                __CtrlDoState(p);
 
244
                __DisplayDoState(p);
 
245
                __FontDoState(p);
 
246
                __GeDoState(p);
 
247
                __ImposeDoState(p);
 
248
                __IoDoState(p);
 
249
                __JpegDoState(p);
 
250
                __Mp3DoState(p);
 
251
                __MpegDoState(p);
 
252
                __NetDoState(p);
 
253
                __NetAdhocDoState(p);
 
254
                __PowerDoState(p);
 
255
                __PsmfDoState(p);
 
256
                __PsmfPlayerDoState(p);
 
257
                __RtcDoState(p);
 
258
                __SasDoState(p);
 
259
                __SslDoState(p);
 
260
                __UmdDoState(p);
 
261
                __UtilityDoState(p);
 
262
                __UsbDoState(p);
 
263
                __VaudioDoState(p);
 
264
                __HeapDoState(p);
 
265
 
 
266
                __PPGeDoState(p);
 
267
                __CheatDoState(p);
 
268
                __sceAudiocodecDoState(p);
 
269
                __VideoPmpDoState(p);
 
270
                __AACDoState(p);
 
271
        }
 
272
 
 
273
        {
 
274
                auto s = p.Section("Kernel Cleanup", 1);
 
275
                if (!s)
 
276
                        return;
 
277
 
 
278
                __InterruptsDoStateLate(p);
 
279
                __KernelThreadingDoStateLate(p);
 
280
                Reporting::DoState(p);
 
281
        }
 
282
}
 
283
 
 
284
bool __KernelIsRunning() {
 
285
        return kernelRunning;
 
286
}
 
287
 
 
288
void sceKernelExitGame()
 
289
{
 
290
        INFO_LOG(SCEKERNEL, "sceKernelExitGame");
 
291
        __KernelSwitchOffThread("game exited");
 
292
        Core_Stop();
 
293
}
 
294
 
 
295
void sceKernelExitGameWithStatus()
 
296
{
 
297
        INFO_LOG(SCEKERNEL, "sceKernelExitGameWithStatus");
 
298
        __KernelSwitchOffThread("game exited");
 
299
        Core_Stop();
 
300
}
 
301
 
 
302
u32 sceKernelDevkitVersion()
 
303
{
 
304
        int firmwareVersion = g_Config.iFirmwareVersion;
 
305
        int major = firmwareVersion / 100;
 
306
        int minor = (firmwareVersion / 10) % 10;
 
307
        int revision = firmwareVersion % 10;
 
308
        int devkitVersion = (major << 24) | (minor << 16) | (revision << 8) | 0x10;
 
309
 
 
310
        DEBUG_LOG_REPORT_ONCE(devkitVer, SCEKERNEL, "%08x=sceKernelDevkitVersion()", devkitVersion);
 
311
        return devkitVersion;
 
312
}
 
313
 
 
314
u32 sceKernelRegisterKprintfHandler()
 
315
{
 
316
        ERROR_LOG(SCEKERNEL, "UNIMPL sceKernelRegisterKprintfHandler()");
 
317
        return 0;
 
318
}
 
319
 
 
320
int sceKernelRegisterDefaultExceptionHandler()
 
321
{
 
322
        ERROR_LOG(SCEKERNEL, "UNIMPL sceKernelRegisterDefaultExceptionHandler()");
 
323
        return 0;
 
324
}
 
325
 
 
326
void sceKernelSetGPO(u32 ledAddr)
 
327
{
 
328
        // Sets debug LEDs.
 
329
        DEBUG_LOG(SCEKERNEL, "sceKernelSetGPO(%02x)", ledAddr);
 
330
}
 
331
 
 
332
u32 sceKernelGetGPI()
 
333
{
 
334
        // Always returns 0 on production systems.
 
335
        DEBUG_LOG(SCEKERNEL, "0=sceKernelGetGPI()");
 
336
        return 0;
 
337
}
 
338
 
 
339
// #define LOG_CACHE
 
340
 
 
341
// Don't even log these by default, they're spammy and we probably won't
 
342
// need to emulate them. Useful for invalidating cached textures though,
 
343
// and in the future display lists (although hashing takes care of those
 
344
// for now).
 
345
int sceKernelDcacheInvalidateRange(u32 addr, int size)
 
346
{
 
347
#ifdef LOG_CACHE
 
348
        NOTICE_LOG(CPU,"sceKernelDcacheInvalidateRange(%08x, %i)", addr, size);
 
349
#endif
 
350
        if (size < 0 || (int) addr + size < 0)
 
351
                return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
 
352
 
 
353
        if (size > 0)
 
354
        {
 
355
                if ((addr % 64) != 0 || (size % 64) != 0)
 
356
                        return SCE_KERNEL_ERROR_CACHE_ALIGNMENT;
 
357
 
 
358
                if (addr != 0)
 
359
                        gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
 
360
        }
 
361
        hleEatCycles(190);
 
362
        return 0;
 
363
}
 
364
 
 
365
int sceKernelIcacheInvalidateRange(u32 addr, int size) {
 
366
        DEBUG_LOG(CPU, "sceKernelIcacheInvalidateRange(%08x, %i)", addr, size);
 
367
        currentMIPS->InvalidateICache(addr, size);
 
368
        return 0;
 
369
}
 
370
 
 
371
int sceKernelDcacheWritebackAll()
 
372
{
 
373
#ifdef LOG_CACHE
 
374
        NOTICE_LOG(CPU,"sceKernelDcacheWritebackAll()");
 
375
#endif
 
376
        // Some games seem to use this a lot, it doesn't make sense
 
377
        // to zap the whole texture cache.
 
378
        gpu->InvalidateCache(0, -1, GPU_INVALIDATE_ALL);
 
379
        hleEatCycles(3524);
 
380
        hleReSchedule("dcache writeback all");
 
381
        return 0;
 
382
}
 
383
 
 
384
int sceKernelDcacheWritebackRange(u32 addr, int size)
 
385
{
 
386
#ifdef LOG_CACHE
 
387
        NOTICE_LOG(CPU,"sceKernelDcacheWritebackRange(%08x, %i)", addr, size);
 
388
#endif
 
389
        if (size < 0)
 
390
                return SCE_KERNEL_ERROR_INVALID_SIZE;
 
391
 
 
392
        if (size > 0 && addr != 0) {
 
393
                gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
 
394
        }
 
395
        hleEatCycles(165);
 
396
        return 0;
 
397
}
 
398
 
 
399
int sceKernelDcacheWritebackInvalidateRange(u32 addr, int size)
 
400
{
 
401
#ifdef LOG_CACHE
 
402
        NOTICE_LOG(CPU,"sceKernelDcacheInvalidateRange(%08x, %i)", addr, size);
 
403
#endif
 
404
        if (size < 0)
 
405
                return SCE_KERNEL_ERROR_INVALID_SIZE;
 
406
 
 
407
        if (size > 0 && addr != 0) {
 
408
                gpu->InvalidateCache(addr, size, GPU_INVALIDATE_HINT);
 
409
        }
 
410
        hleEatCycles(165);
 
411
        return 0;
 
412
}
 
413
 
 
414
int sceKernelDcacheWritebackInvalidateAll()
 
415
{
 
416
#ifdef LOG_CACHE
 
417
        NOTICE_LOG(CPU,"sceKernelDcacheInvalidateAll()");
 
418
#endif
 
419
        gpu->InvalidateCache(0, -1, GPU_INVALIDATE_ALL);
 
420
        hleEatCycles(1165);
 
421
        hleReSchedule("dcache invalidate all");
 
422
        return 0;
 
423
}
 
424
 
 
425
u32 sceKernelIcacheInvalidateAll()
 
426
{
 
427
#ifdef LOG_CACHE
 
428
        NOTICE_LOG(CPU, "Icache invalidated - should clear JIT someday");
 
429
#endif
 
430
        // Note that this doesn't actually fully invalidate all with such a large range.
 
431
        currentMIPS->InvalidateICache(0, 0x3FFFFFFF);
 
432
        return 0;
 
433
}
 
434
 
 
435
u32 sceKernelIcacheClearAll()
 
436
{
 
437
#ifdef LOG_CACHE
 
438
        NOTICE_LOG(CPU, "Icache cleared - should clear JIT someday");
 
439
#endif
 
440
        DEBUG_LOG(CPU, "Icache cleared - should clear JIT someday");
 
441
        // Note that this doesn't actually fully invalidate all with such a large range.
 
442
        currentMIPS->InvalidateICache(0, 0x3FFFFFFF);
 
443
        return 0;
 
444
}
 
445
 
 
446
void KernelObject::GetQuickInfo(char *ptr, int size)
 
447
{
 
448
        strcpy(ptr, "-");
 
449
}
 
450
 
 
451
KernelObjectPool::KernelObjectPool() {
 
452
        memset(occupied, 0, sizeof(bool)*maxCount);
 
453
        nextID = initialNextID;
 
454
}
 
455
 
 
456
SceUID KernelObjectPool::Create(KernelObject *obj, int rangeBottom, int rangeTop) {
 
457
        if (rangeTop > maxCount)
 
458
                rangeTop = maxCount;
 
459
        if (nextID >= rangeBottom && nextID < rangeTop)
 
460
                rangeBottom = nextID++;
 
461
 
 
462
        for (int i = rangeBottom; i < rangeTop; i++) {
 
463
                if (!occupied[i]) {
 
464
                        occupied[i] = true;
 
465
                        pool[i] = obj;
 
466
                        pool[i]->uid = i + handleOffset;
 
467
                        return i + handleOffset;
 
468
                }
 
469
        }
 
470
 
 
471
        ERROR_LOG_REPORT(SCEKERNEL, "Unable to allocate kernel object, too many objects slots in use.");
 
472
        return 0;
 
473
}
 
474
 
 
475
bool KernelObjectPool::IsValid(SceUID handle) const {
 
476
        int index = handle - handleOffset;
 
477
        if (index < 0 || index >= maxCount)
 
478
                return false;
 
479
        else
 
480
                return occupied[index];
 
481
}
 
482
 
 
483
void KernelObjectPool::Clear() {
 
484
        for (int i = 0; i < maxCount; i++) {
 
485
                // brutally clear everything, no validation
 
486
                if (occupied[i])
 
487
                        delete pool[i];
 
488
                pool[i] = nullptr;
 
489
                occupied[i] = false;
 
490
        }
 
491
        nextID = initialNextID;
 
492
}
 
493
 
 
494
void KernelObjectPool::List() {
 
495
        for (int i = 0; i < maxCount; i++) {
 
496
                if (occupied[i]) {
 
497
                        char buffer[256];
 
498
                        if (pool[i]) {
 
499
                                pool[i]->GetQuickInfo(buffer, 256);
 
500
                                INFO_LOG(SCEKERNEL, "KO %i: %s \"%s\": %s", i + handleOffset, pool[i]->GetTypeName(), pool[i]->GetName(), buffer);
 
501
                        } else {
 
502
                                strcpy(buffer, "WTF? Zero Pointer");
 
503
                        }
 
504
                }
 
505
        }
 
506
}
 
507
 
 
508
int KernelObjectPool::GetCount() const {
 
509
        int count = 0;
 
510
        for (int i = 0; i < maxCount; i++) {
 
511
                if (occupied[i])
 
512
                        count++;
 
513
        }
 
514
        return count;
 
515
}
 
516
 
 
517
void KernelObjectPool::DoState(PointerWrap &p) {
 
518
        auto s = p.Section("KernelObjectPool", 1);
 
519
        if (!s)
 
520
                return;
 
521
 
 
522
        int _maxCount = maxCount;
 
523
        p.Do(_maxCount);
 
524
 
 
525
        if (_maxCount != maxCount) {
 
526
                p.SetError(p.ERROR_FAILURE);
 
527
                ERROR_LOG(SCEKERNEL, "Unable to load state: different kernel object storage.");
 
528
                return;
 
529
        }
 
530
 
 
531
        if (p.mode == p.MODE_READ) {
 
532
                hleCurrentThreadName = nullptr;
 
533
                kernelObjects.Clear();
 
534
        }
 
535
 
 
536
        p.Do(nextID);
 
537
        p.DoArray(occupied, maxCount);
 
538
        for (int i = 0; i < maxCount; ++i) {
 
539
                if (!occupied[i])
 
540
                        continue;
 
541
 
 
542
                int type;
 
543
                if (p.mode == p.MODE_READ) {
 
544
                        p.Do(type);
 
545
                        pool[i] = CreateByIDType(type);
 
546
 
 
547
                        // Already logged an error.
 
548
                        if (pool[i] == nullptr)
 
549
                                return;
 
550
 
 
551
                        pool[i]->uid = i + handleOffset;
 
552
                } else {
 
553
                        type = pool[i]->GetIDType();
 
554
                        p.Do(type);
 
555
                }
 
556
                pool[i]->DoState(p);
 
557
                if (p.error >= p.ERROR_FAILURE)
 
558
                        break;
 
559
        }
 
560
}
 
561
 
 
562
KernelObject *KernelObjectPool::CreateByIDType(int type) {
 
563
        // Used for save states.  This is ugly, but what other way is there?
 
564
        switch (type) {
 
565
        case SCE_KERNEL_TMID_Alarm:
 
566
                return __KernelAlarmObject();
 
567
        case SCE_KERNEL_TMID_EventFlag:
 
568
                return __KernelEventFlagObject();
 
569
        case SCE_KERNEL_TMID_Mbox:
 
570
                return __KernelMbxObject();
 
571
        case SCE_KERNEL_TMID_Fpl:
 
572
                return __KernelMemoryFPLObject();
 
573
        case SCE_KERNEL_TMID_Vpl:
 
574
                return __KernelMemoryVPLObject();
 
575
        case PPSSPP_KERNEL_TMID_PMB:
 
576
                return __KernelMemoryPMBObject();
 
577
        case PPSSPP_KERNEL_TMID_Module:
 
578
                return __KernelModuleObject();
 
579
        case SCE_KERNEL_TMID_Mpipe:
 
580
                return __KernelMsgPipeObject();
 
581
        case SCE_KERNEL_TMID_Mutex:
 
582
                return __KernelMutexObject();
 
583
        case SCE_KERNEL_TMID_LwMutex:
 
584
                return __KernelLwMutexObject();
 
585
        case SCE_KERNEL_TMID_Semaphore:
 
586
                return __KernelSemaphoreObject();
 
587
        case SCE_KERNEL_TMID_Callback:
 
588
                return __KernelCallbackObject();
 
589
        case SCE_KERNEL_TMID_Thread:
 
590
                return __KernelThreadObject();
 
591
        case SCE_KERNEL_TMID_VTimer:
 
592
                return __KernelVTimerObject();
 
593
        case SCE_KERNEL_TMID_Tlspl:
 
594
        case SCE_KERNEL_TMID_Tlspl_v0:
 
595
                return __KernelTlsplObject();
 
596
        case PPSSPP_KERNEL_TMID_File:
 
597
                return __KernelFileNodeObject();
 
598
        case PPSSPP_KERNEL_TMID_DirList:
 
599
                return __KernelDirListingObject();
 
600
        case SCE_KERNEL_TMID_ThreadEventHandler:
 
601
                return __KernelThreadEventHandlerObject();
 
602
 
 
603
        default:
 
604
                ERROR_LOG(COMMON, "Unable to load state: could not find object type %d.", type);
 
605
                return NULL;
 
606
        }
 
607
}
 
608
 
 
609
struct SystemStatus {
 
610
        SceSize_le size;
 
611
        SceUInt_le status;
 
612
        SceUInt_le clockPart1;
 
613
        SceUInt_le clockPart2;
 
614
        SceUInt_le perfcounter1;
 
615
        SceUInt_le perfcounter2;
 
616
        SceUInt_le perfcounter3;
 
617
};
 
618
 
 
619
static int sceKernelReferSystemStatus(u32 statusPtr) {
 
620
        DEBUG_LOG(SCEKERNEL, "sceKernelReferSystemStatus(%08x)", statusPtr);
 
621
        if (Memory::IsValidAddress(statusPtr)) {
 
622
                SystemStatus status;
 
623
                memset(&status, 0, sizeof(SystemStatus));
 
624
                status.size = sizeof(SystemStatus);
 
625
                // TODO: Fill in the struct!
 
626
                Memory::WriteStruct(statusPtr, &status);
 
627
        }
 
628
        return 0;
 
629
}
 
630
 
 
631
struct DebugProfilerRegs {
 
632
        u32 enable;
 
633
        u32 systemck;
 
634
        u32 cpuck;
 
635
        u32 internal;
 
636
        u32 memory;
 
637
        u32 copz;
 
638
        u32 vfpu;
 
639
        u32 sleep;
 
640
        u32 bus_access;
 
641
        u32 uncached_load;
 
642
        u32 uncached_store;
 
643
        u32 cached_load;
 
644
        u32 cached_store;
 
645
        u32 i_miss;
 
646
        u32 d_miss;
 
647
        u32 d_writeback;
 
648
        u32 cop0_inst;
 
649
        u32 fpu_inst;
 
650
        u32 vfpu_inst;
 
651
        u32 local_bus;
 
652
};
 
653
 
 
654
static u32 sceKernelReferThreadProfiler(u32 statusPtr) {
 
655
        ERROR_LOG(SCEKERNEL, "FAKE sceKernelReferThreadProfiler()");
 
656
 
 
657
        // Can we confirm that the struct above is the right struct?
 
658
        // If so, re-enable this code.
 
659
        //DebugProfilerRegs regs;
 
660
        //memset(&regs, 0, sizeof(regs));
 
661
        // TODO: fill the struct.
 
662
        //if (Memory::IsValidAddress(statusPtr)) {
 
663
        //      Memory::WriteStruct(statusPtr, &regs);
 
664
        //}
 
665
        return 0;
 
666
}
 
667
 
 
668
static int sceKernelReferGlobalProfiler(u32 statusPtr) {
 
669
        ERROR_LOG(SCEKERNEL, "UNIMPL sceKernelReferGlobalProfiler(%08x)", statusPtr);
 
670
        // Ignore for now
 
671
        return 0;
 
672
}
 
673
 
 
674
const HLEFunction ThreadManForUser[] =
 
675
{
 
676
        {0X55C20A00, &WrapI_CUUU<sceKernelCreateEventFlag>,              "sceKernelCreateEventFlag",                  'i', "sxxx"    },
 
677
        {0X812346E4, &WrapU_IU<sceKernelClearEventFlag>,                 "sceKernelClearEventFlag",                   'x', "ix"      },
 
678
        {0XEF9E4C70, &WrapU_I<sceKernelDeleteEventFlag>,                 "sceKernelDeleteEventFlag",                  'x', "i"       },
 
679
        {0X1FB15A32, &WrapU_IU<sceKernelSetEventFlag>,                   "sceKernelSetEventFlag",                     'x', "ix"      },
 
680
        {0X402FCF22, &WrapI_IUUUU<sceKernelWaitEventFlag>,               "sceKernelWaitEventFlag",                    'i', "ixxpp",  HLE_NOT_IN_INTERRUPT },
 
681
        {0X328C546A, &WrapI_IUUUU<sceKernelWaitEventFlagCB>,             "sceKernelWaitEventFlagCB",                  'i', "ixxpp",  HLE_NOT_IN_INTERRUPT },
 
682
        {0X30FD48F0, &WrapI_IUUU<sceKernelPollEventFlag>,                "sceKernelPollEventFlag",                    'i', "ixxp"    },
 
683
        {0XCD203292, &WrapU_IUU<sceKernelCancelEventFlag>,               "sceKernelCancelEventFlag",                  'x', "ixp"     },
 
684
        {0XA66B0120, &WrapU_IU<sceKernelReferEventFlagStatus>,           "sceKernelReferEventFlagStatus",             'x', "ix"      },
 
685
 
 
686
        {0X8FFDF9A2, &WrapI_IIU<sceKernelCancelSema>,                    "sceKernelCancelSema",                       'i', "iix"     },
 
687
        {0XD6DA4BA1, &WrapI_CUIIU<sceKernelCreateSema>,                  "sceKernelCreateSema",                       'i', "sxiix"   },
 
688
        {0X28B6489C, &WrapI_I<sceKernelDeleteSema>,                      "sceKernelDeleteSema",                       'i', "i"       },
 
689
        {0X58B1F937, &WrapI_II<sceKernelPollSema>,                       "sceKernelPollSema",                         'i', "ii"      },
 
690
        {0XBC6FEBC5, &WrapI_IU<sceKernelReferSemaStatus>,                "sceKernelReferSemaStatus",                  'i', "ix"      },
 
691
        {0X3F53E640, &WrapI_II<sceKernelSignalSema>,                     "sceKernelSignalSema",                       'i', "ii"      },
 
692
        {0X4E3A1105, &WrapI_IIU<sceKernelWaitSema>,                      "sceKernelWaitSema",                         'i', "iix",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
693
        {0X6D212BAC, &WrapI_IIU<sceKernelWaitSemaCB>,                    "sceKernelWaitSemaCB",                       'i', "iix",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
694
 
 
695
        {0X60107536, &WrapI_U<sceKernelDeleteLwMutex>,                   "sceKernelDeleteLwMutex",                    'i', "x"       },
 
696
        {0X19CFF145, &WrapI_UCUIU<sceKernelCreateLwMutex>,               "sceKernelCreateLwMutex",                    'i', "xsxix"   },
 
697
        {0X4C145944, &WrapI_IU<sceKernelReferLwMutexStatusByID>,         "sceKernelReferLwMutexStatusByID",           'i', "ix"      },
 
698
        // NOTE: LockLwMutex, UnlockLwMutex, and ReferLwMutexStatus are in Kernel_Library, see sceKernelInterrupt.cpp.
 
699
        // The below should not be called directly.
 
700
        //{0x71040D5C, nullptr,                                            "_sceKernelTryLockLwMutex",                  '?', ""        },
 
701
        //{0x7CFF8CF3, nullptr,                                            "_sceKernelLockLwMutex",                     '?', ""        },
 
702
        //{0x31327F19, nullptr,                                            "_sceKernelLockLwMutexCB",                   '?', ""        },
 
703
        //{0xBEED3A47, nullptr,                                            "_sceKernelUnlockLwMutex",                   '?', ""        },
 
704
 
 
705
        {0XF8170FBE, &WrapI_I<sceKernelDeleteMutex>,                     "sceKernelDeleteMutex",                      'i', "i"       },
 
706
        {0XB011B11F, &WrapI_IIU<sceKernelLockMutex>,                     "sceKernelLockMutex",                        'i', "iix",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
707
        {0X5BF4DD27, &WrapI_IIU<sceKernelLockMutexCB>,                   "sceKernelLockMutexCB",                      'i', "iix",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
708
        {0X6B30100F, &WrapI_II<sceKernelUnlockMutex>,                    "sceKernelUnlockMutex",                      'i', "ii"      },
 
709
        {0XB7D098C6, &WrapI_CUIU<sceKernelCreateMutex>,                  "sceKernelCreateMutex",                      'i', "sxix"    },
 
710
        {0X0DDCD2C9, &WrapI_II<sceKernelTryLockMutex>,                   "sceKernelTryLockMutex",                     'i', "ii"      },
 
711
        {0XA9C2CB9A, &WrapI_IU<sceKernelReferMutexStatus>,               "sceKernelReferMutexStatus",                 'i', "ix"      },
 
712
        {0X87D9223C, &WrapI_IIU<sceKernelCancelMutex>,                   "sceKernelCancelMutex",                      'i', "iix"     },
 
713
 
 
714
        {0XFCCFAD26, &WrapI_I<sceKernelCancelWakeupThread>,              "sceKernelCancelWakeupThread",               'i', "i"       },
 
715
        {0X1AF94D03, nullptr,                                            "sceKernelDonateWakeupThread",               '?', ""        },
 
716
        {0XEA748E31, &WrapI_UU<sceKernelChangeCurrentThreadAttr>,        "sceKernelChangeCurrentThreadAttr",          'i', "xx"      },
 
717
        {0X71BC9871, &WrapI_II<sceKernelChangeThreadPriority>,           "sceKernelChangeThreadPriority",             'i', "ii"      },
 
718
        {0X446D8DE6, &WrapI_CUUIUU<sceKernelCreateThread>,               "sceKernelCreateThread",                     'i', "sxxixx", HLE_NOT_IN_INTERRUPT },
 
719
        {0X9FA03CD3, &WrapI_I<sceKernelDeleteThread>,                    "sceKernelDeleteThread",                     'i', "i"       },
 
720
        {0XBD123D9E, &WrapI_U<sceKernelDelaySysClockThread>,             "sceKernelDelaySysClockThread",              'i', "P",      HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
721
        {0X1181E963, &WrapI_U<sceKernelDelaySysClockThreadCB>,           "sceKernelDelaySysClockThreadCB",            'i', "P",      HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
722
        {0XCEADEB47, &WrapI_U<sceKernelDelayThread>,                     "sceKernelDelayThread",                      'i', "x",      HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
723
        {0X68DA9E36, &WrapI_U<sceKernelDelayThreadCB>,                   "sceKernelDelayThreadCB",                    'i', "x",      HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
724
        {0XAA73C935, &WrapV_I<sceKernelExitThread>,                      "sceKernelExitThread",                       'v', "i"       },
 
725
        {0X809CE29B, &WrapV_I<sceKernelExitDeleteThread>,                "sceKernelExitDeleteThread",                 'v', "i"       },
 
726
        {0x94aa61ee, &WrapI_V<sceKernelGetThreadCurrentPriority>,        "sceKernelGetThreadCurrentPriority",         'i', ""        },
 
727
        {0X293B45B8, &WrapI_V<sceKernelGetThreadId>,                     "sceKernelGetThreadId",                      'i', "",       HLE_NOT_IN_INTERRUPT },
 
728
        {0X3B183E26, &WrapI_I<sceKernelGetThreadExitStatus>,             "sceKernelGetThreadExitStatus",              'i', "i"       },
 
729
        {0X52089CA1, &WrapI_I<sceKernelGetThreadStackFreeSize>,          "sceKernelGetThreadStackFreeSize",           'i', "i"       },
 
730
        {0XFFC36A14, &WrapU_UU<sceKernelReferThreadRunStatus>,           "sceKernelReferThreadRunStatus",             'x', "xx"      },
 
731
        {0X17C1684E, &WrapU_UU<sceKernelReferThreadStatus>,              "sceKernelReferThreadStatus",                'x', "xx"      },
 
732
        {0X2C34E053, &WrapI_I<sceKernelReleaseWaitThread>,               "sceKernelReleaseWaitThread",                'i', "i"       },
 
733
        {0X75156E8F, &WrapI_I<sceKernelResumeThread>,                    "sceKernelResumeThread",                     'i', "i"       },
 
734
        {0X3AD58B8C, &WrapU_V<sceKernelSuspendDispatchThread>,           "sceKernelSuspendDispatchThread",            'x', "",       HLE_NOT_IN_INTERRUPT },
 
735
        {0X27E22EC2, &WrapU_U<sceKernelResumeDispatchThread>,            "sceKernelResumeDispatchThread",             'x', "x",      HLE_NOT_IN_INTERRUPT },
 
736
        {0X912354A7, &WrapI_I<sceKernelRotateThreadReadyQueue>,          "sceKernelRotateThreadReadyQueue",           'i', "i"       },
 
737
        {0X9ACE131E, &WrapI_V<sceKernelSleepThread>,                     "sceKernelSleepThread",                      'i', "",       HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
738
        {0X82826F70, &WrapI_V<sceKernelSleepThreadCB>,                   "sceKernelSleepThreadCB",                    'i', "",       HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
739
        {0XF475845D, &WrapI_IIU<sceKernelStartThread>,                   "sceKernelStartThread",                      'i', "iix",    HLE_NOT_IN_INTERRUPT },
 
740
        {0X9944F31F, &WrapI_I<sceKernelSuspendThread>,                   "sceKernelSuspendThread",                    'i', "i"       },
 
741
        {0X616403BA, &WrapI_I<sceKernelTerminateThread>,                 "sceKernelTerminateThread",                  'i', "i"       },
 
742
        {0X383F7BCC, &WrapI_I<sceKernelTerminateDeleteThread>,           "sceKernelTerminateDeleteThread",            'i', "i"       },
 
743
        {0X840E8133, &WrapI_IU<sceKernelWaitThreadEndCB>,                "sceKernelWaitThreadEndCB",                  'i', "ix"      },
 
744
        {0XD13BDE95, &WrapI_V<sceKernelCheckThreadStack>,                "sceKernelCheckThreadStack",                 'i', ""        },
 
745
 
 
746
        {0X94416130, &WrapU_UUUU<sceKernelGetThreadmanIdList>,           "sceKernelGetThreadmanIdList",               'x', "xxxx"    },
 
747
        {0X57CF62DD, &WrapU_U<sceKernelGetThreadmanIdType>,              "sceKernelGetThreadmanIdType",               'x', "x"       },
 
748
        {0XBC80EC7C, &WrapU_UUU<sceKernelExtendThreadStack>,             "sceKernelExtendThreadStack",                'x', "xxx"     },
 
749
        // NOTE: Takes a UID from sceKernelMemory's AllocMemoryBlock and seems thread stack related.
 
750
        //{0x28BFD974, nullptr,                                           "ThreadManForUser_28BFD974",                  '?', ""        },
 
751
 
 
752
        {0X82BC5777, &WrapU64_V<sceKernelGetSystemTimeWide>,             "sceKernelGetSystemTimeWide",                'X', ""        },
 
753
        {0XDB738F35, &WrapI_U<sceKernelGetSystemTime>,                   "sceKernelGetSystemTime",                    'i', "x"       },
 
754
        {0X369ED59D, &WrapU_V<sceKernelGetSystemTimeLow>,                "sceKernelGetSystemTimeLow",                 'x', ""        },
 
755
 
 
756
        {0X8218B4DD, &WrapI_U<sceKernelReferGlobalProfiler>,             "sceKernelReferGlobalProfiler",              'i', "x"       },
 
757
        {0X627E6F3A, &WrapI_U<sceKernelReferSystemStatus>,               "sceKernelReferSystemStatus",                'i', "x"       },
 
758
        {0X64D4540E, &WrapU_U<sceKernelReferThreadProfiler>,             "sceKernelReferThreadProfiler",              'x', "x"       },
 
759
 
 
760
        //Fifa Street 2 uses alarms
 
761
        {0X6652B8CA, &WrapI_UUU<sceKernelSetAlarm>,                      "sceKernelSetAlarm",                         'i', "xxx"     },
 
762
        {0XB2C25152, &WrapI_UUU<sceKernelSetSysClockAlarm>,              "sceKernelSetSysClockAlarm",                 'i', "xxx"     },
 
763
        {0X7E65B999, &WrapI_I<sceKernelCancelAlarm>,                     "sceKernelCancelAlarm",                      'i', "i"       },
 
764
        {0XDAA3F564, &WrapI_IU<sceKernelReferAlarmStatus>,               "sceKernelReferAlarmStatus",                 'i', "ix"      },
 
765
 
 
766
        {0XBA6B92E2, &WrapI_UUU<sceKernelSysClock2USec>,                 "sceKernelSysClock2USec",                    'i', "xxx"     },
 
767
        {0X110DEC9A, &WrapI_UU<sceKernelUSec2SysClock>,                  "sceKernelUSec2SysClock",                    'i', "xx"      },
 
768
        {0XC8CD158C, &WrapU64_U<sceKernelUSec2SysClockWide>,             "sceKernelUSec2SysClockWide",                'X', "x"       },
 
769
        {0XE1619D7C, &WrapI_UUUU<sceKernelSysClock2USecWide>,            "sceKernelSysClock2USecWide",                'i', "xxxx"    },
 
770
 
 
771
        {0X278C0DF5, &WrapI_IU<sceKernelWaitThreadEnd>,                  "sceKernelWaitThreadEnd",                    'i', "ix"      },
 
772
        {0XD59EAD2F, &WrapI_I<sceKernelWakeupThread>,                    "sceKernelWakeupThread",                     'i', "i"       }, //AI Go, audio?
 
773
 
 
774
        {0x0C106E53, &WrapI_CIUUU<sceKernelRegisterThreadEventHandler>,  "sceKernelRegisterThreadEventHandler",       'i', "sixxx",  },
 
775
        {0x72F3C145, &WrapI_I<sceKernelReleaseThreadEventHandler>,       "sceKernelReleaseThreadEventHandler",        'i', "i"       },
 
776
        {0x369EEB6B, &WrapI_IU<sceKernelReferThreadEventHandlerStatus>,  "sceKernelReferThreadEventHandlerStatus",    'i', "ip"      },
 
777
 
 
778
        {0x349d6d6c, &sceKernelCheckCallback,                            "sceKernelCheckCallback",                    'i', ""        },
 
779
        {0XE81CAF8F, &WrapI_CUU<sceKernelCreateCallback>,                "sceKernelCreateCallback",                   'i', "sxx"     },
 
780
        {0XEDBA5844, &WrapI_I<sceKernelDeleteCallback>,                  "sceKernelDeleteCallback",                   'i', "i"       },
 
781
        {0XC11BA8C4, &WrapI_II<sceKernelNotifyCallback>,                 "sceKernelNotifyCallback",                   'i', "ii"      },
 
782
        {0XBA4051D6, &WrapI_I<sceKernelCancelCallback>,                  "sceKernelCancelCallback",                   'i', "i"       },
 
783
        {0X2A3D44FF, &WrapI_I<sceKernelGetCallbackCount>,                "sceKernelGetCallbackCount",                 'i', "i"       },
 
784
        {0X730ED8BC, &WrapI_IU<sceKernelReferCallbackStatus>,            "sceKernelReferCallbackStatus",              'i', "ip"      },
 
785
 
 
786
        {0X8125221D, &WrapI_CUU<sceKernelCreateMbx>,                     "sceKernelCreateMbx",                        'i', "sxx"     },
 
787
        {0X86255ADA, &WrapI_I<sceKernelDeleteMbx>,                       "sceKernelDeleteMbx",                        'i', "i"       },
 
788
        {0XE9B3061E, &WrapI_IU<sceKernelSendMbx>,                        "sceKernelSendMbx",                          'i', "ix"      },
 
789
        {0X18260574, &WrapI_IUU<sceKernelReceiveMbx>,                    "sceKernelReceiveMbx",                       'i', "ixx",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
790
        {0XF3986382, &WrapI_IUU<sceKernelReceiveMbxCB>,                  "sceKernelReceiveMbxCB",                     'i', "ixx",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
791
        {0X0D81716A, &WrapI_IU<sceKernelPollMbx>,                        "sceKernelPollMbx",                          'i', "ix"      },
 
792
        {0X87D4DD36, &WrapI_IU<sceKernelCancelReceiveMbx>,               "sceKernelCancelReceiveMbx",                 'i', "ix"      },
 
793
        {0XA8E8C846, &WrapI_IU<sceKernelReferMbxStatus>,                 "sceKernelReferMbxStatus",                   'i', "ix"      },
 
794
 
 
795
        {0X7C0DC2A0, &WrapI_CIUUU<sceKernelCreateMsgPipe>,               "sceKernelCreateMsgPipe",                    'i', "sixxx"   },
 
796
        {0XF0B7DA1C, &WrapI_I<sceKernelDeleteMsgPipe>,                   "sceKernelDeleteMsgPipe",                    'i', "i"       },
 
797
        {0X876DBFAD, &WrapI_IUUUUU<sceKernelSendMsgPipe>,                "sceKernelSendMsgPipe",                      'i', "ixxxxx"  },
 
798
        {0X7C41F2C2, &WrapI_IUUUUU<sceKernelSendMsgPipeCB>,              "sceKernelSendMsgPipeCB",                    'i', "ixxxxx"  },
 
799
        {0X884C9F90, &WrapI_IUUUU<sceKernelTrySendMsgPipe>,              "sceKernelTrySendMsgPipe",                   'i', "ixxxx"   },
 
800
        {0X74829B76, &WrapI_IUUUUU<sceKernelReceiveMsgPipe>,             "sceKernelReceiveMsgPipe",                   'i', "ixxxxx"  },
 
801
        {0XFBFA697D, &WrapI_IUUUUU<sceKernelReceiveMsgPipeCB>,           "sceKernelReceiveMsgPipeCB",                 'i', "ixxxxx"  },
 
802
        {0XDF52098F, &WrapI_IUUUU<sceKernelTryReceiveMsgPipe>,           "sceKernelTryReceiveMsgPipe",                'i', "ixxxx"   },
 
803
        {0X349B864D, &WrapI_IUU<sceKernelCancelMsgPipe>,                 "sceKernelCancelMsgPipe",                    'i', "ixx"     },
 
804
        {0X33BE4024, &WrapI_IU<sceKernelReferMsgPipeStatus>,             "sceKernelReferMsgPipeStatus",               'i', "ix"      },
 
805
 
 
806
        {0X56C039B5, &WrapI_CIUUU<sceKernelCreateVpl>,                   "sceKernelCreateVpl",                        'i', "sixxx"   },
 
807
        {0X89B3D48C, &WrapI_I<sceKernelDeleteVpl>,                       "sceKernelDeleteVpl",                        'i', "i"       },
 
808
        {0XBED27435, &WrapI_IUUU<sceKernelAllocateVpl>,                  "sceKernelAllocateVpl",                      'i', "ixxx",   HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
809
        {0XEC0A693F, &WrapI_IUUU<sceKernelAllocateVplCB>,                "sceKernelAllocateVplCB",                    'i', "ixxx",   HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
810
        {0XAF36D708, &WrapI_IUU<sceKernelTryAllocateVpl>,                "sceKernelTryAllocateVpl",                   'i', "ixx"     },
 
811
        {0XB736E9FF, &WrapI_IU<sceKernelFreeVpl>,                        "sceKernelFreeVpl",                          'i', "ix"      },
 
812
        {0X1D371B8A, &WrapI_IU<sceKernelCancelVpl>,                      "sceKernelCancelVpl",                        'i', "ix"      },
 
813
        {0X39810265, &WrapI_IU<sceKernelReferVplStatus>,                 "sceKernelReferVplStatus",                   'i', "ix"      },
 
814
 
 
815
        {0XC07BB470, &WrapI_CUUUUU<sceKernelCreateFpl>,                  "sceKernelCreateFpl",                        'i', "sxxxxx"  },
 
816
        {0XED1410E0, &WrapI_I<sceKernelDeleteFpl>,                       "sceKernelDeleteFpl",                        'i', "i"       },
 
817
        {0XD979E9BF, &WrapI_IUU<sceKernelAllocateFpl>,                   "sceKernelAllocateFpl",                      'i', "ixx",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
818
        {0XE7282CB6, &WrapI_IUU<sceKernelAllocateFplCB>,                 "sceKernelAllocateFplCB",                    'i', "ixx",    HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED },
 
819
        {0X623AE665, &WrapI_IU<sceKernelTryAllocateFpl>,                 "sceKernelTryAllocateFpl",                   'i', "ix"      },
 
820
        {0XF6414A71, &WrapI_IU<sceKernelFreeFpl>,                        "sceKernelFreeFpl",                          'i', "ix"      },
 
821
        {0XA8AA591F, &WrapI_IU<sceKernelCancelFpl>,                      "sceKernelCancelFpl",                        'i', "ix"      },
 
822
        {0XD8199E4C, &WrapI_IU<sceKernelReferFplStatus>,                 "sceKernelReferFplStatus",                   'i', "ix"      },
 
823
 
 
824
        {0X20FFF560, &WrapU_CU<sceKernelCreateVTimer>,                   "sceKernelCreateVTimer",                     'x', "sx",     HLE_NOT_IN_INTERRUPT },
 
825
        {0X328F9E52, &WrapU_I<sceKernelDeleteVTimer>,                    "sceKernelDeleteVTimer",                     'x', "i",      HLE_NOT_IN_INTERRUPT },
 
826
        {0XC68D9437, &WrapU_I<sceKernelStartVTimer>,                     "sceKernelStartVTimer",                      'x', "i"       },
 
827
        {0XD0AEEE87, &WrapU_I<sceKernelStopVTimer>,                      "sceKernelStopVTimer",                       'x', "i"       },
 
828
        {0XD2D615EF, &WrapU_I<sceKernelCancelVTimerHandler>,             "sceKernelCancelVTimerHandler",              'x', "i"       },
 
829
        {0XB3A59970, &WrapU_IU<sceKernelGetVTimerBase>,                  "sceKernelGetVTimerBase",                    'x', "ix"      },
 
830
        {0XB7C18B77, &WrapU64_I<sceKernelGetVTimerBaseWide>,             "sceKernelGetVTimerBaseWide",                'X', "i"       },
 
831
        {0X034A921F, &WrapU_IU<sceKernelGetVTimerTime>,                  "sceKernelGetVTimerTime",                    'x', "ix"      },
 
832
        {0XC0B3FFD2, &WrapU64_I<sceKernelGetVTimerTimeWide>,             "sceKernelGetVTimerTimeWide",                'X', "i"       },
 
833
        {0X5F32BEAA, &WrapU_IU<sceKernelReferVTimerStatus>,              "sceKernelReferVTimerStatus",                'x', "ix"      },
 
834
        {0X542AD630, &WrapU_IU<sceKernelSetVTimerTime>,                  "sceKernelSetVTimerTime",                    'x', "ix"      },
 
835
        {0XFB6425C3, &WrapU64_IU64<sceKernelSetVTimerTimeWide>,          "sceKernelSetVTimerTimeWide",                'X', "iX"      },
 
836
        {0XD8B299AE, &WrapU_IUUU<sceKernelSetVTimerHandler>,             "sceKernelSetVTimerHandler",                 'x', "ixxx"    },
 
837
        {0X53B00E9A, &WrapU_IU64UU<sceKernelSetVTimerHandlerWide>,       "sceKernelSetVTimerHandlerWide",             'x', "iXxx"    },
 
838
 
 
839
        {0X8DAFF657, &WrapI_CUUUUU<sceKernelCreateTlspl>,                "sceKernelCreateTlspl",                      'i', "sxxxxx"  },
 
840
        {0X32BF938E, &WrapI_I<sceKernelDeleteTlspl>,                     "sceKernelDeleteTlspl",                      'i', "i"       },
 
841
        {0X721067F3, &WrapI_IU<sceKernelReferTlsplStatus>,               "sceKernelReferTlsplStatus",                 'i', "ix"      },
 
842
        // Not completely certain about args.
 
843
        {0X4A719FB2, &WrapI_I<sceKernelFreeTlspl>,                       "sceKernelFreeTlspl",                        'i', "i"       },
 
844
        // Internal.  Takes (uid, &addr) as parameters... probably.
 
845
        //{0x65F54FFB, nullptr,                                            "_sceKernelAllocateTlspl",                   'v', ""        },
 
846
        // NOTE: sceKernelGetTlsAddr is in Kernel_Library, see sceKernelInterrupt.cpp.
 
847
 
 
848
        // Not sure if these should be hooked up. See below.
 
849
        {0x0E927AED, &_sceKernelReturnFromTimerHandler,                  "_sceKernelReturnFromTimerHandler",          'v', ""        },
 
850
        {0X532A522E, &WrapV_I<_sceKernelExitThread>,                     "_sceKernelExitThread",                      'v', "i"       },
 
851
 
 
852
        // Shouldn't hook this up. No games should import this function manually and call it.
 
853
        // {0x6E9EA350, _sceKernelReturnFromCallback,"_sceKernelReturnFromCallback"},
 
854
};
 
855
 
 
856
const HLEFunction ThreadManForKernel[] =
 
857
{
 
858
        {0xCEADEB47, &WrapI_U<sceKernelDelayThread>,                     "sceKernelDelayThread",                      'i', "x",      HLE_NOT_IN_INTERRUPT | HLE_NOT_DISPATCH_SUSPENDED | HLE_KERNEL_SYSCALL },
 
859
        {0x446D8DE6, &WrapI_CUUIUU<sceKernelCreateThread>,               "sceKernelCreateThread",                     'i', "sxxixx", HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL },
 
860
        {0xF475845D, &WrapI_IIU<sceKernelStartThread>,                   "sceKernelStartThread",                      'i', "iix",    HLE_NOT_IN_INTERRUPT | HLE_KERNEL_SYSCALL },
 
861
};
 
862
 
 
863
void Register_ThreadManForUser()
 
864
{
 
865
        RegisterModule("ThreadManForUser", ARRAY_SIZE(ThreadManForUser), ThreadManForUser);
 
866
}
 
867
 
 
868
 
 
869
const HLEFunction LoadExecForUser[] =
 
870
{
 
871
        {0X05572A5F, &WrapV_V<sceKernelExitGame>,                        "sceKernelExitGame",                         'v', ""        },
 
872
        {0X4AC57943, &WrapI_I<sceKernelRegisterExitCallback>,            "sceKernelRegisterExitCallback",             'i', "i"       },
 
873
        {0XBD2F1094, &WrapI_CU<sceKernelLoadExec>,                       "sceKernelLoadExec",                         'i', "sx"      },
 
874
        {0X2AC9954B, &WrapV_V<sceKernelExitGameWithStatus>,              "sceKernelExitGameWithStatus",               'v', ""        },
 
875
        {0X362A956B, &WrapI_V<LoadExecForUser_362A956B>,                 "LoadExecForUser_362A956B",                  'i', ""        },
 
876
        {0X8ADA38D3, nullptr,                                            "LoadExecForUser_8ADA38D3",                  '?', ""        },
 
877
};
 
878
 
 
879
void Register_LoadExecForUser()
 
880
{
 
881
        RegisterModule("LoadExecForUser", ARRAY_SIZE(LoadExecForUser), LoadExecForUser);
 
882
}
 
883
 
 
884
const HLEFunction LoadExecForKernel[] =
 
885
{
 
886
        {0x4AC57943, &WrapI_I<sceKernelRegisterExitCallback>,            "sceKernelRegisterExitCallback",             'i', "i",      HLE_KERNEL_SYSCALL },
 
887
        {0XA3D5E142, nullptr,                                            "LoadExecForKernel_a3d5e142",                '?', ""        },
 
888
};
 
889
 
 
890
void Register_LoadExecForKernel()
 
891
{
 
892
        RegisterModule("LoadExecForKernel", ARRAY_SIZE(LoadExecForKernel), LoadExecForKernel);
 
893
}
 
894
 
 
895
const HLEFunction ExceptionManagerForKernel[] =
 
896
{
 
897
        {0X3FB264FC, nullptr,                                            "sceKernelRegisterExceptionHandler",         '?', ""        },
 
898
        {0X5A837AD4, nullptr,                                            "sceKernelRegisterPriorityExceptionHandler", '?', ""        },
 
899
        {0x565C0B0E, &WrapI_V<sceKernelRegisterDefaultExceptionHandler>, "sceKernelRegisterDefaultExceptionHandler",  'i', "",       HLE_KERNEL_SYSCALL },
 
900
        {0X1AA6CFFA, nullptr,                                            "sceKernelReleaseExceptionHandler",          '?', ""        },
 
901
        {0XDF83875E, nullptr,                                            "sceKernelGetActiveDefaultExceptionHandler", '?', ""        },
 
902
        {0X291FF031, nullptr,                                            "sceKernelReleaseDefaultExceptionHandler",   '?', ""        },
 
903
        {0X15ADC862, nullptr,                                            "sceKernelRegisterNmiHandler",               '?', ""        },
 
904
        {0XB15357C9, nullptr,                                            "sceKernelReleaseNmiHandler",                '?', ""        },
 
905
};
 
906
 
 
907
void Register_ExceptionManagerForKernel()
 
908
{
 
909
        RegisterModule("ExceptionManagerForKernel", ARRAY_SIZE(ExceptionManagerForKernel), ExceptionManagerForKernel);
 
910
}
 
911
 
 
912
// Seen in some homebrew
 
913
const HLEFunction UtilsForKernel[] = {
 
914
        {0xC2DF770E, WrapI_UI<sceKernelIcacheInvalidateRange>,           "sceKernelIcacheInvalidateRange",            '?', "",       HLE_KERNEL_SYSCALL },
 
915
        {0X78934841, nullptr,                                            "sceKernelGzipDecompress",                   '?', ""        },
 
916
        {0XE8DB3CE6, nullptr,                                            "sceKernelDeflateDecompress",                '?', ""        },
 
917
        {0X840259F1, nullptr,                                            "sceKernelUtilsSha1Digest",                  '?', ""        },
 
918
        {0X9E5C5086, nullptr,                                            "sceKernelUtilsMd5BlockInit",                '?', ""        },
 
919
        {0X61E1E525, nullptr,                                            "sceKernelUtilsMd5BlockUpdate",              '?', ""        },
 
920
        {0XB8D24E78, nullptr,                                            "sceKernelUtilsMd5BlockResult",              '?', ""        },
 
921
        {0XC8186A58, nullptr,                                            "sceKernelUtilsMd5Digest",                   '?', ""        },
 
922
        {0X6C6887EE, nullptr,                                            "UtilsForKernel_6C6887EE",                   '?', ""        },
 
923
        {0X91E4F6A7, nullptr,                                            "sceKernelLibcClock",                        '?', ""        },
 
924
        {0X27CC57F0, nullptr,                                            "sceKernelLibcTime",                         '?', ""        },
 
925
        {0X79D1C3FA, nullptr,                                            "sceKernelDcacheWritebackAll",               '?', ""        },
 
926
        {0X3EE30821, nullptr,                                            "sceKernelDcacheWritebackRange",             '?', ""        },
 
927
        {0X34B9FA9E, nullptr,                                            "sceKernelDcacheWritebackInvalidateRange",   '?', ""        },
 
928
        {0XB435DEC5, nullptr,                                            "sceKernelDcacheWritebackInvalidateAll",     '?', ""        },
 
929
        {0XBFA98062, nullptr,                                            "sceKernelDcacheInvalidateRange",            '?', ""        },
 
930
        {0X920F104A, nullptr,                                            "sceKernelIcacheInvalidateAll",              '?', ""        },
 
931
        {0XE860E75E, nullptr,                                            "sceKernelUtilsMt19937Init",                 '?', ""        },
 
932
        {0X06FB8A63, nullptr,                                            "sceKernelUtilsMt19937UInt",                 '?', ""        },
 
933
};
 
934
 
 
935
 
 
936
void Register_UtilsForKernel()
 
937
{
 
938
        RegisterModule("UtilsForKernel", ARRAY_SIZE(UtilsForKernel), UtilsForKernel);
 
939
}
 
940
 
 
941
void Register_ThreadManForKernel()
 
942
{
 
943
        RegisterModule("ThreadManForKernel", ARRAY_SIZE(ThreadManForKernel), ThreadManForKernel);               
 
944
}