diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index d31a4a88..879085b9 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -427,10 +427,8 @@ void cemu_initForGame() cemuLog_log(LogType::Force, "------- Run title -------"); // wait till GPU thread is initialized while (g_isGPUInitFinished == false) std::this_thread::sleep_for(std::chrono::milliseconds(50)); - // init initial thread - OSThread_t* initialThread = coreinit::OSGetDefaultThread(1); - coreinit::OSSetThreadPriority(initialThread, 16); - coreinit::OSRunThread(initialThread, PPCInterpreter_makeCallableExportDepr(coreinit_start), 0, nullptr); + // run coreinit rpl_entry + RPLLoader_CallCoreinitEntrypoint(); // init AX and start AX I/O thread snd_core::AXOut_init(); } diff --git a/src/Cafe/OS/RPL/rpl.cpp b/src/Cafe/OS/RPL/rpl.cpp index d39ea95e..b906b6b1 100644 --- a/src/Cafe/OS/RPL/rpl.cpp +++ b/src/Cafe/OS/RPL/rpl.cpp @@ -2305,6 +2305,25 @@ void RPLLoader_CallEntrypoints() } } +// calls the entrypoint of coreinit and marks it as called so that RPLLoader_CallEntrypoints() wont call it again later +void RPLLoader_CallCoreinitEntrypoint() +{ + // for HLE modules we need to check the dependency list + for (auto& dependency : rplDependencyList) + { + if (strcmp(dependency->modulename, "coreinit") != 0) + continue; + if (!dependency->rplHLEModule) + continue; + if (dependency->hleEntrypointCalled) + continue; + dependency->rplHLEModule->rpl_entry(dependency->coreinitHandle, coreinit::RplEntryReason::Loaded); + dependency->hleEntrypointCalled = true; + return; + } + cemu_assert_unimplemented(); // coreinit.rpl present in cafelibs? We currently do not support native coreinit and no thread context exists yet to do a PPC call +} + void RPLLoader_NotifyControlPassedToApplication() { rplLoader_applicationHasMemoryControl = true; @@ -2350,11 +2369,13 @@ uint32 RPLLoader_FindModuleOrHLEExport(uint32 moduleHandle, bool isData, const c uint32 RPLLoader_GetSDA1Base() { + cemu_assert_debug(rplModuleCount > 0); // this should not be called before the main executable was loaded return rplLoader_sdataAddr; } uint32 RPLLoader_GetSDA2Base() { + cemu_assert_debug(rplModuleCount > 0); return rplLoader_sdata2Addr; } diff --git a/src/Cafe/OS/RPL/rpl.h b/src/Cafe/OS/RPL/rpl.h index b56411c4..6d161d2b 100644 --- a/src/Cafe/OS/RPL/rpl.h +++ b/src/Cafe/OS/RPL/rpl.h @@ -25,6 +25,7 @@ void RPLLoader_SetMainModule(RPLModule* rplLoaderContext); uint32 RPLLoader_GetMainModuleHandle(); void RPLLoader_CallEntrypoints(); +void RPLLoader_CallCoreinitEntrypoint(); void RPLLoader_NotifyControlPassedToApplication(); void RPLLoader_AddDependency(std::string_view name); diff --git a/src/Cafe/OS/libs/coreinit/coreinit.cpp b/src/Cafe/OS/libs/coreinit/coreinit.cpp index 8f783164..9ec370c3 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit.cpp @@ -331,7 +331,7 @@ namespace coreinit // init GHS and threads coreinit::PrepareGHSRuntime(); - coreinit::InitializeThread(); + coreinit::MapThreadExports(); // reset threads activeThreadCount = 0; @@ -353,13 +353,13 @@ namespace coreinit coreinit::InitializeLC(); coreinit::InitializeMP(); coreinit::InitializeTimeAndCalendar(); - coreinit::InitializeAlarm(); + coreinit::MapAlarmExports(); coreinit::InitializeFS(); coreinit::InitializeSystemInfo(); coreinit::InitializeConcurrency(); coreinit::InitializeSpinlock(); coreinit::InitializeMessageQueue(); - coreinit::InitializeIPC(); + coreinit::MapIPCExports(); coreinit::InitializeIPCBuf(); coreinit::InitializeMemoryMapping(); coreinit::InitializeCodeGen(); @@ -373,16 +373,20 @@ namespace coreinit coreinit::miscInit(); osLib_addFunction("coreinit", "OSGetSharedData", coreinitExport_OSGetSharedData); osLib_addFunction("coreinit", "UCReadSysConfig", coreinitExport_UCReadSysConfig); - - // async callbacks - InitializeAsyncCallback(); }; void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override { if (reason == coreinit::RplEntryReason::Loaded) { - // todo + coreinit::InitializeThread(); + coreinit::InitializeAlarm(); + coreinit::InitializeIPC(); + InitializeAsyncCallback(); + // remaining coreinit initialization happens in coreinit_start and requires a valid PPC context + OSThread_t* initialThread = coreinit::OSGetDefaultThread(1); + coreinit::OSSetThreadPriority(initialThread, 16); + coreinit::OSRunThread(initialThread, PPCInterpreter_makeCallableExportDepr(coreinit_start), 0, nullptr); } else if (reason == coreinit::RplEntryReason::Unloaded) { diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp index ae2d1e63..be5e9a7f 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.cpp @@ -349,7 +349,7 @@ namespace coreinit } } - void InitializeAlarm() + void MapAlarmExports() { cafeExportRegister("coreinit", OSCreateAlarm, LogType::CoreinitAlarm); cafeExportRegister("coreinit", OSCreateAlarmEx, LogType::CoreinitAlarm); @@ -358,7 +358,10 @@ namespace coreinit cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::CoreinitAlarm); cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::CoreinitAlarm); cafeExportRegister("coreinit", OSGetAlarmUserData, LogType::CoreinitAlarm); + } + void InitializeAlarm() + { // init event OSInitEvent(g_alarmEvent.GetPtr(), OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, OSEvent::EVENT_MODE::MODE_AUTO); diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h index 472d4f21..6f4964f1 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Alarm.h @@ -49,5 +49,6 @@ namespace coreinit void alarm_update(); + void MapAlarmExports(); void InitializeAlarm(); } \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp index 12d83afc..19a3b69c 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.cpp @@ -445,15 +445,8 @@ namespace coreinit return r; } - void InitializeIPC() + void MapIPCExports() { - for (uint32 i = 0; i < Espresso::CORE_COUNT; i++) - { - IPCDriver_InitForCore(i); - IPCDriver_InitIPCThread(i); - } - - // register API cafeExportRegister("coreinit", IOS_Open, LogType::PPC_IPC); cafeExportRegister("coreinit", IOS_Close, LogType::PPC_IPC); cafeExportRegister("coreinit", IOS_Ioctl, LogType::PPC_IPC); @@ -462,4 +455,13 @@ namespace coreinit cafeExportRegister("coreinit", IOS_IoctlvAsync, LogType::PPC_IPC); } + void InitializeIPC() + { + for (uint32 i = 0; i < Espresso::CORE_COUNT; i++) + { + IPCDriver_InitForCore(i); + IPCDriver_InitIPCThread(i); + } + } + }; diff --git a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h index 362c4725..2915ddc5 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_IPC.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_IPC.h @@ -12,5 +12,6 @@ namespace coreinit IOS_ERROR IOS_Ioctlv(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec); IOS_ERROR IOS_IoctlvAsync(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec, MEMPTR asyncResultFunc, MEMPTR asyncResultUserParam); + void MapIPCExports(); void InitializeIPC(); }; \ No newline at end of file diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp index 19391bbd..8f3b9e0a 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.cpp @@ -1588,7 +1588,7 @@ namespace coreinit } } - void InitializeThread() + void MapThreadExports() { cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread); cafeExportRegister("coreinit", OSCreateThread, LogType::CoreinitThread); @@ -1632,16 +1632,16 @@ namespace coreinit // OSThreadQueue cafeExportRegister("coreinit", OSInitThreadQueue, LogType::CoreinitThread); cafeExportRegister("coreinit", OSInitThreadQueueEx, LogType::CoreinitThread); - - OSInitThreadQueue(g_activeThreadQueue.GetPtr()); - for (sint32 i = 0; i < PPC_CORE_COUNT; i++) - OSInitThreadQueue(g_coreRunQueue.GetPtr() + i); - - for (sint32 i = 0; i < PPC_CORE_COUNT; i++) - __currentCoreThread[i] = nullptr; - - __OSInitDefaultThreads(); - __OSInitTerminatorThreads(); - } + + void InitializeThread() + { + OSInitThreadQueue(g_activeThreadQueue.GetPtr()); + for (sint32 i = 0; i < Espresso::CORE_COUNT; i++) + OSInitThreadQueue(g_coreRunQueue.GetPtr() + i); + for (sint32 i = 0; i < Espresso::CORE_COUNT; i++) + __currentCoreThread[i] = nullptr; + __OSInitDefaultThreads(); + __OSInitTerminatorThreads(); + } } diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h index 1a93022b..a0517d9a 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Thread.h +++ b/src/Cafe/OS/libs/coreinit/coreinit_Thread.h @@ -503,7 +503,9 @@ static_assert(sizeof(OSThread_t) == 0x6A0); namespace coreinit { + void MapThreadExports(); void InitializeThread(); + void InitializeConcurrency(); bool __CemuIsMulticoreMode();