mirror of
https://github.com/cemu-project/Cemu.git
synced 2026-06-06 06:35:00 -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 -------");
|
cemuLog_log(LogType::Force, "------- Run title -------");
|
||||||
// wait till GPU thread is initialized
|
// wait till GPU thread is initialized
|
||||||
while (g_isGPUInitFinished == false) std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
while (g_isGPUInitFinished == false) std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
// init initial thread
|
// run coreinit rpl_entry
|
||||||
OSThread_t* initialThread = coreinit::OSGetDefaultThread(1);
|
RPLLoader_CallCoreinitEntrypoint();
|
||||||
coreinit::OSSetThreadPriority(initialThread, 16);
|
|
||||||
coreinit::OSRunThread(initialThread, PPCInterpreter_makeCallableExportDepr(coreinit_start), 0, nullptr);
|
|
||||||
// init AX and start AX I/O thread
|
// init AX and start AX I/O thread
|
||||||
snd_core::AXOut_init();
|
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()
|
void RPLLoader_NotifyControlPassedToApplication()
|
||||||
{
|
{
|
||||||
rplLoader_applicationHasMemoryControl = true;
|
rplLoader_applicationHasMemoryControl = true;
|
||||||
@ -2350,11 +2369,13 @@ uint32 RPLLoader_FindModuleOrHLEExport(uint32 moduleHandle, bool isData, const c
|
|||||||
|
|
||||||
uint32 RPLLoader_GetSDA1Base()
|
uint32 RPLLoader_GetSDA1Base()
|
||||||
{
|
{
|
||||||
|
cemu_assert_debug(rplModuleCount > 0); // this should not be called before the main executable was loaded
|
||||||
return rplLoader_sdataAddr;
|
return rplLoader_sdataAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 RPLLoader_GetSDA2Base()
|
uint32 RPLLoader_GetSDA2Base()
|
||||||
{
|
{
|
||||||
|
cemu_assert_debug(rplModuleCount > 0);
|
||||||
return rplLoader_sdata2Addr;
|
return rplLoader_sdata2Addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ void RPLLoader_SetMainModule(RPLModule* rplLoaderContext);
|
|||||||
uint32 RPLLoader_GetMainModuleHandle();
|
uint32 RPLLoader_GetMainModuleHandle();
|
||||||
|
|
||||||
void RPLLoader_CallEntrypoints();
|
void RPLLoader_CallEntrypoints();
|
||||||
|
void RPLLoader_CallCoreinitEntrypoint();
|
||||||
void RPLLoader_NotifyControlPassedToApplication();
|
void RPLLoader_NotifyControlPassedToApplication();
|
||||||
|
|
||||||
void RPLLoader_AddDependency(std::string_view name);
|
void RPLLoader_AddDependency(std::string_view name);
|
||||||
|
|||||||
@ -331,7 +331,7 @@ namespace coreinit
|
|||||||
|
|
||||||
// init GHS and threads
|
// init GHS and threads
|
||||||
coreinit::PrepareGHSRuntime();
|
coreinit::PrepareGHSRuntime();
|
||||||
coreinit::InitializeThread();
|
coreinit::MapThreadExports();
|
||||||
|
|
||||||
// reset threads
|
// reset threads
|
||||||
activeThreadCount = 0;
|
activeThreadCount = 0;
|
||||||
@ -353,13 +353,13 @@ namespace coreinit
|
|||||||
coreinit::InitializeLC();
|
coreinit::InitializeLC();
|
||||||
coreinit::InitializeMP();
|
coreinit::InitializeMP();
|
||||||
coreinit::InitializeTimeAndCalendar();
|
coreinit::InitializeTimeAndCalendar();
|
||||||
coreinit::InitializeAlarm();
|
coreinit::MapAlarmExports();
|
||||||
coreinit::InitializeFS();
|
coreinit::InitializeFS();
|
||||||
coreinit::InitializeSystemInfo();
|
coreinit::InitializeSystemInfo();
|
||||||
coreinit::InitializeConcurrency();
|
coreinit::InitializeConcurrency();
|
||||||
coreinit::InitializeSpinlock();
|
coreinit::InitializeSpinlock();
|
||||||
coreinit::InitializeMessageQueue();
|
coreinit::InitializeMessageQueue();
|
||||||
coreinit::InitializeIPC();
|
coreinit::MapIPCExports();
|
||||||
coreinit::InitializeIPCBuf();
|
coreinit::InitializeIPCBuf();
|
||||||
coreinit::InitializeMemoryMapping();
|
coreinit::InitializeMemoryMapping();
|
||||||
coreinit::InitializeCodeGen();
|
coreinit::InitializeCodeGen();
|
||||||
@ -373,16 +373,20 @@ namespace coreinit
|
|||||||
coreinit::miscInit();
|
coreinit::miscInit();
|
||||||
osLib_addFunction("coreinit", "OSGetSharedData", coreinitExport_OSGetSharedData);
|
osLib_addFunction("coreinit", "OSGetSharedData", coreinitExport_OSGetSharedData);
|
||||||
osLib_addFunction("coreinit", "UCReadSysConfig", coreinitExport_UCReadSysConfig);
|
osLib_addFunction("coreinit", "UCReadSysConfig", coreinitExport_UCReadSysConfig);
|
||||||
|
|
||||||
// async callbacks
|
|
||||||
InitializeAsyncCallback();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override
|
void rpl_entry(uint32 moduleHandle, coreinit::RplEntryReason reason) override
|
||||||
{
|
{
|
||||||
if (reason == coreinit::RplEntryReason::Loaded)
|
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)
|
else if (reason == coreinit::RplEntryReason::Unloaded)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -349,7 +349,7 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeAlarm()
|
void MapAlarmExports()
|
||||||
{
|
{
|
||||||
cafeExportRegister("coreinit", OSCreateAlarm, LogType::CoreinitAlarm);
|
cafeExportRegister("coreinit", OSCreateAlarm, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSCreateAlarmEx, LogType::CoreinitAlarm);
|
cafeExportRegister("coreinit", OSCreateAlarmEx, LogType::CoreinitAlarm);
|
||||||
@ -358,7 +358,10 @@ namespace coreinit
|
|||||||
cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::CoreinitAlarm);
|
cafeExportRegister("coreinit", OSSetPeriodicAlarm, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::CoreinitAlarm);
|
cafeExportRegister("coreinit", OSSetAlarmUserData, LogType::CoreinitAlarm);
|
||||||
cafeExportRegister("coreinit", OSGetAlarmUserData, LogType::CoreinitAlarm);
|
cafeExportRegister("coreinit", OSGetAlarmUserData, LogType::CoreinitAlarm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeAlarm()
|
||||||
|
{
|
||||||
// init event
|
// init event
|
||||||
OSInitEvent(g_alarmEvent.GetPtr(), OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, OSEvent::EVENT_MODE::MODE_AUTO);
|
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 alarm_update();
|
||||||
|
|
||||||
|
void MapAlarmExports();
|
||||||
void InitializeAlarm();
|
void InitializeAlarm();
|
||||||
}
|
}
|
||||||
@ -445,15 +445,8 @@ namespace coreinit
|
|||||||
return r;
|
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_Open, LogType::PPC_IPC);
|
||||||
cafeExportRegister("coreinit", IOS_Close, LogType::PPC_IPC);
|
cafeExportRegister("coreinit", IOS_Close, LogType::PPC_IPC);
|
||||||
cafeExportRegister("coreinit", IOS_Ioctl, LogType::PPC_IPC);
|
cafeExportRegister("coreinit", IOS_Ioctl, LogType::PPC_IPC);
|
||||||
@ -462,4 +455,13 @@ namespace coreinit
|
|||||||
cafeExportRegister("coreinit", IOS_IoctlvAsync, LogType::PPC_IPC);
|
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_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);
|
IOS_ERROR IOS_IoctlvAsync(IOSDevHandle devHandle, uint32 requestId, uint32 numIn, uint32 numOut, IPCIoctlVector* vec, MEMPTR<void> asyncResultFunc, MEMPTR<void> asyncResultUserParam);
|
||||||
|
|
||||||
|
void MapIPCExports();
|
||||||
void InitializeIPC();
|
void InitializeIPC();
|
||||||
};
|
};
|
||||||
@ -1588,7 +1588,7 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeThread()
|
void MapThreadExports()
|
||||||
{
|
{
|
||||||
cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread);
|
cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread);
|
||||||
cafeExportRegister("coreinit", OSCreateThread, LogType::CoreinitThread);
|
cafeExportRegister("coreinit", OSCreateThread, LogType::CoreinitThread);
|
||||||
@ -1632,16 +1632,16 @@ namespace coreinit
|
|||||||
// OSThreadQueue
|
// OSThreadQueue
|
||||||
cafeExportRegister("coreinit", OSInitThreadQueue, LogType::CoreinitThread);
|
cafeExportRegister("coreinit", OSInitThreadQueue, LogType::CoreinitThread);
|
||||||
cafeExportRegister("coreinit", OSInitThreadQueueEx, 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
|
namespace coreinit
|
||||||
{
|
{
|
||||||
|
void MapThreadExports();
|
||||||
void InitializeThread();
|
void InitializeThread();
|
||||||
|
|
||||||
void InitializeConcurrency();
|
void InitializeConcurrency();
|
||||||
|
|
||||||
bool __CemuIsMulticoreMode();
|
bool __CemuIsMulticoreMode();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user