mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-03-27 22:00:23 -06:00
coreinit: Fix initialization order
Threads were initialized before SDA values were available from RPL loader. Fixes crash in Skylanders Swap Force and some other games
This commit is contained in:
parent
8cd5ce102f
commit
9f58f3a118
@ -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();
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -49,5 +49,6 @@ namespace coreinit
|
||||
|
||||
void alarm_update();
|
||||
|
||||
void MapAlarmExports();
|
||||
void InitializeAlarm();
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -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<void> asyncResultFunc, MEMPTR<void> asyncResultUserParam);
|
||||
|
||||
void MapIPCExports();
|
||||
void InitializeIPC();
|
||||
};
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,7 +503,9 @@ static_assert(sizeof(OSThread_t) == 0x6A0);
|
||||
|
||||
namespace coreinit
|
||||
{
|
||||
void MapThreadExports();
|
||||
void InitializeThread();
|
||||
|
||||
void InitializeConcurrency();
|
||||
|
||||
bool __CemuIsMulticoreMode();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user