mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-04 05:51:19 +12:00
Map mem range as needed; save/restore for coreinit; add logging for save states
This commit is contained in:
parent
739b33f733
commit
288c8d9854
41 changed files with 704 additions and 60 deletions
|
@ -981,7 +981,8 @@ namespace CafeSystem
|
|||
{
|
||||
if (!sSystemRunning)
|
||||
return;
|
||||
coreinit::SuspendAllThreads();
|
||||
coreinit::SuspendActiveThreads();
|
||||
iosu::pdm::Stop();
|
||||
sSystemRunning = false;
|
||||
}
|
||||
|
||||
|
@ -989,13 +990,14 @@ namespace CafeSystem
|
|||
{
|
||||
if (sSystemRunning)
|
||||
return;
|
||||
coreinit::ResumeAllThreads();
|
||||
coreinit::ResumeActiveThreads();
|
||||
iosu::pdm::StartTrackingTime(GetForegroundTitleId());
|
||||
sSystemRunning = true;
|
||||
}
|
||||
|
||||
void SaveState(std::string path)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "[SAVESTATE] Saving state...");
|
||||
cemuLog_log(LogType::SaveStates, "Saving state...");
|
||||
MemStreamWriter writer(0);
|
||||
// pause game
|
||||
PauseTitle();
|
||||
|
@ -1006,45 +1008,53 @@ namespace CafeSystem
|
|||
writer.writeData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister));
|
||||
writer.writeData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t));
|
||||
// cpu
|
||||
for (auto& thr : activeThread)
|
||||
{
|
||||
writer.writeBE(thr);
|
||||
}
|
||||
// fs
|
||||
coreinit::FSSave(writer);
|
||||
ci_Save(writer);
|
||||
coreinit::ci_Alarm_Save(writer);
|
||||
ci_Callbacks_Save(writer);
|
||||
coreinit::ci_FS_Save(writer);
|
||||
ci_Init_Save(writer);
|
||||
coreinit::ci_Thread_Save(writer);
|
||||
iosu::fsa::Save(writer);
|
||||
|
||||
FileStream* stream = FileStream::createFile(path);
|
||||
stream->writeData(writer.getResult().data(), writer.getResult().size_bytes());
|
||||
delete stream;
|
||||
cemuLog_log(LogType::Force, "[SAVESTATE] Saved state to {}.", path);
|
||||
cemuLog_log(LogType::SaveStates, "Saved state to {}.", path);
|
||||
|
||||
ResumeTitle(/*isThreadRunning*/);
|
||||
}
|
||||
|
||||
void LoadState(std::string path)
|
||||
{
|
||||
|
||||
PauseTitle();
|
||||
cemuLog_log(LogType::Force, "[SAVESTATE] Loading state...", path);
|
||||
cemuLog_log(LogType::SaveStates, "Loading state...", path);
|
||||
|
||||
auto data = FileStream::LoadIntoMemory(path);
|
||||
assert(data.has_value());
|
||||
MemStreamReader reader(data->data(), data->size());
|
||||
|
||||
bool recreate = false;
|
||||
if (recreate)
|
||||
coreinit::__OSDeleteAllActivePPCThreads();
|
||||
|
||||
// memory
|
||||
DestroyMemorySpace();
|
||||
memory_Deserialize(reader);
|
||||
// gpu
|
||||
reader.readData(LatteGPUState.contextRegister, sizeof(LatteGPUState.contextRegister));
|
||||
reader.readData(LatteGPUState.contextRegisterShadowAddr, sizeof(LatteGPUState.contextRegister));
|
||||
reader.readData(LatteGPUState.sharedArea, sizeof(gx2GPUSharedArea_t));
|
||||
// cpu
|
||||
for (size_t i = 0; i < 256; i++)
|
||||
{
|
||||
activeThread[i] = reader.readBE<uint32>();
|
||||
}
|
||||
// fs
|
||||
coreinit::FSRestore(reader);
|
||||
ci_Restore(reader);
|
||||
coreinit::ci_Alarm_Restore(reader);
|
||||
ci_Callbacks_Restore(reader);
|
||||
coreinit::ci_FS_Restore(reader);
|
||||
ci_Init_Restore(reader);
|
||||
coreinit::ci_Thread_Restore(reader, recreate);
|
||||
iosu::fsa::Restore(reader);
|
||||
|
||||
cemuLog_log(LogType::Force, "[SAVESTATE] Loaded state from {}.", path);
|
||||
cemuLog_log(LogType::SaveStates, "Loaded state from {}.", path);
|
||||
|
||||
ResumeTitle(/*isThreadRunning*/);
|
||||
}
|
||||
|
|
|
@ -110,13 +110,16 @@ void MemStreamWriter::writeBE<MMURange>(const MMURange& v)
|
|||
template <>
|
||||
void MemStreamReader::readBE<MMURange>(MMURange& mmuRange)
|
||||
{
|
||||
mmuRange.m_isMapped = readBE<bool>();
|
||||
bool needsMapped = readBE<bool>();
|
||||
mmuRange.m_isMapped = false;
|
||||
mmuRange.baseAddress = readBE<uint32>();
|
||||
mmuRange.areaId = (MMU_MEM_AREA_ID)readBE<uint8>();
|
||||
mmuRange.flags = (MMURange::MFLAG)readBE<uint8>();
|
||||
mmuRange.name = readBE<std::string>();
|
||||
mmuRange.size = readBE<uint32>();
|
||||
mmuRange.initSize = readBE<uint32>();
|
||||
if (needsMapped)
|
||||
mmuRange.mapMem();
|
||||
}
|
||||
|
||||
bool MMURange::deserializeImpl(MemStreamReader& streamReader)
|
||||
|
@ -470,7 +473,6 @@ void memory_createDump()
|
|||
|
||||
void memory_Serialize(MemStreamWriter& s)
|
||||
{
|
||||
s.writeBE<uint64>(g_mmuRanges.size());
|
||||
for (auto& itr : g_mmuRanges)
|
||||
{
|
||||
s.writeBE(*itr);
|
||||
|
@ -483,7 +485,6 @@ void memory_Serialize(MemStreamWriter& s)
|
|||
|
||||
void memory_Deserialize(MemStreamReader& s)
|
||||
{
|
||||
size_t cnt = s.readBE<uint64>();
|
||||
for (auto& itr : g_mmuRanges)
|
||||
{
|
||||
s.readBE<MMURange>(*itr);
|
||||
|
|
|
@ -992,6 +992,8 @@ namespace iosu::fsa
|
|||
|
||||
void Save(MemStreamWriter& writer)
|
||||
{
|
||||
writer.writeData("iosu_fsa_S", 15);
|
||||
|
||||
writer.writeBE(sFSAIoMsgQueue);
|
||||
for (size_t i = 0; i < 352; i++)
|
||||
{
|
||||
|
@ -1003,6 +1005,10 @@ namespace iosu::fsa
|
|||
|
||||
void Restore(MemStreamReader& reader)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
reader.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "iosu_fsa_S") == 0);
|
||||
|
||||
sFSAIoMsgQueue = reader.readBE<IOSMsgQueueId>();
|
||||
for (size_t i = 0; i < 352; i++)
|
||||
{
|
||||
|
|
|
@ -316,6 +316,56 @@ namespace coreinit
|
|||
}
|
||||
};
|
||||
|
||||
void ci_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_S", 15);
|
||||
|
||||
s.writeData(gCoreinitData, sizeof(coreinitData_t));
|
||||
s.writeBE(placeholderFont);
|
||||
s.writeBE(placeholderFontSize);
|
||||
|
||||
using namespace coreinit;
|
||||
ci_CodeGen_Save(s);
|
||||
ci_DynLoad_Save(s);
|
||||
ci_FG_Save(s);
|
||||
ci_GHS_Save(s);
|
||||
ci_IPC_Save(s);
|
||||
ci_LockedCache_Save(s);
|
||||
ci_MEM_Save(s);
|
||||
ci_MemoryMapping_Save(s);
|
||||
ci_MessageQueue_Save(s);
|
||||
ci_OverlayArena_Save(s);
|
||||
ci_Sync_Save(s);
|
||||
ci_SysHeap_Save(s);
|
||||
ci_SystemInfo_Save(s);
|
||||
}
|
||||
|
||||
void ci_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_S") == 0);
|
||||
|
||||
s.readData(gCoreinitData, sizeof(coreinitData_t));
|
||||
placeholderFont = s.readBE<MPTR>();
|
||||
placeholderFontSize = s.readBE<sint32>();
|
||||
|
||||
using namespace coreinit;
|
||||
ci_CodeGen_Restore(s);
|
||||
ci_DynLoad_Restore(s);
|
||||
ci_FG_Restore(s);
|
||||
ci_GHS_Restore(s);
|
||||
ci_IPC_Restore(s);
|
||||
ci_LockedCache_Restore(s);
|
||||
ci_MEM_Restore(s);
|
||||
ci_MemoryMapping_Restore(s);
|
||||
ci_MessageQueue_Restore(s);
|
||||
ci_OverlayArena_Restore(s);
|
||||
ci_Sync_Restore(s);
|
||||
ci_SysHeap_Restore(s);
|
||||
ci_SystemInfo_Restore(s);
|
||||
}
|
||||
|
||||
void coreinit_load()
|
||||
{
|
||||
coreinit::InitializeCore();
|
||||
|
|
|
@ -11,10 +11,16 @@ void InitializeAsyncCallback();
|
|||
void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0);
|
||||
void coreinitAsyncCallback_addWithLock(MPTR functionMPTR, uint32 numParameters, uint32 r3 = 0, uint32 r4 = 0, uint32 r5 = 0, uint32 r6 = 0, uint32 r7 = 0, uint32 r8 = 0, uint32 r9 = 0, uint32 r10 = 0);
|
||||
|
||||
void ci_Callbacks_Save(MemStreamWriter& s);
|
||||
void ci_Callbacks_Restore(MemStreamReader& s);
|
||||
|
||||
// misc
|
||||
|
||||
void coreinit_load();
|
||||
|
||||
void ci_Save(MemStreamWriter& s);
|
||||
void ci_Restore(MemStreamReader& s);
|
||||
|
||||
// coreinit shared memory
|
||||
|
||||
typedef struct
|
||||
|
@ -35,6 +41,9 @@ extern coreinitData_t* gCoreinitData;
|
|||
// coreinit init
|
||||
void coreinit_start(PPCInterpreter_t* hCPU);
|
||||
|
||||
void ci_Init_Save(MemStreamWriter& s);
|
||||
void ci_Init_Restore(MemStreamReader& s);
|
||||
|
||||
MPTR OSAllocFromSystem(uint32 size, uint32 alignment);
|
||||
void OSFreeToSystem(MPTR mem);
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ namespace coreinit
|
|||
}
|
||||
else
|
||||
{
|
||||
alarm->nextTime = _swapEndianU64(startTime);
|
||||
alarm->nextTime = _swapEndianU64(nextTime);
|
||||
alarm->period = 0;
|
||||
alarm->handler = _swapEndianU32(handlerFunc);
|
||||
}
|
||||
|
@ -305,6 +305,70 @@ namespace coreinit
|
|||
__OSUnlockScheduler();
|
||||
}
|
||||
|
||||
void ci_Alarm_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_A_S", 15);
|
||||
|
||||
s.writeBE(g_alarmEvent.GetMPTR());
|
||||
s.writeBE(g_alarmThread.GetMPTR());
|
||||
s.writeBE(_g_alarmThreadStack.GetMPTR());
|
||||
s.writeBE(_g_alarmThreadName.GetMPTR());
|
||||
|
||||
s.writeBE(coreinit_getOSTime());
|
||||
|
||||
s.writeBE(g_activeAlarms.size());
|
||||
for (auto& itr : g_activeAlarms)
|
||||
{
|
||||
s.writeBE(memory_getVirtualOffsetFromPointer(itr.first));
|
||||
s.writeBE(itr.second->getNextFire());
|
||||
}
|
||||
}
|
||||
|
||||
void ci_Alarm_Restore(MemStreamReader& s)
|
||||
{
|
||||
OSAlarm_Shutdown();
|
||||
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_A_S") == 0);
|
||||
|
||||
g_alarmEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
g_alarmThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_g_alarmThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_g_alarmThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
|
||||
uint64 currentTime = coreinit_getOSTime();
|
||||
uint64_t timeOffset = currentTime - s.readBE<uint64_t>();
|
||||
|
||||
size_t alms = s.readBE<size_t>();
|
||||
for (size_t alm = 0; alm < alms; alm++)
|
||||
{
|
||||
OSAlarm_t* alarm = (OSAlarm_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
|
||||
uint64 startTime = _swapEndianU64(alarm->startTime) + timeOffset;
|
||||
uint64 nextTime = _swapEndianU64(alarm->nextTime) + timeOffset;
|
||||
//uint64 nextTime = startTime;
|
||||
|
||||
uint64 period = _swapEndianU64(alarm->period);
|
||||
|
||||
if (period != 0)
|
||||
{
|
||||
//uint64 ticksSinceStart = currentTime - startTime;
|
||||
//uint64 numPeriods = ticksSinceStart / period;
|
||||
|
||||
//nextTime = startTime + (numPeriods + 1ull) * period;
|
||||
|
||||
alarm->startTime = _swapEndianU64(startTime);
|
||||
}
|
||||
alarm->nextTime = _swapEndianU64(nextTime);
|
||||
|
||||
uint64 nextFire = s.readBE<uint64>() + timeOffset;
|
||||
__OSLockScheduler();
|
||||
g_activeAlarms[alarm] = OSHostAlarmCreate(nextFire, period, __OSHostAlarmTriggered, nullptr);
|
||||
__OSUnlockScheduler();
|
||||
}
|
||||
}
|
||||
|
||||
void _OSAlarmThread(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
while( true )
|
||||
|
|
|
@ -47,6 +47,9 @@ namespace coreinit
|
|||
|
||||
void OSAlarm_Shutdown();
|
||||
|
||||
void ci_Alarm_Save(MemStreamWriter& s);
|
||||
void ci_Alarm_Restore(MemStreamReader& s);
|
||||
|
||||
void alarm_update();
|
||||
|
||||
void InitializeAlarm();
|
||||
|
|
|
@ -31,6 +31,19 @@ struct CoreinitAsyncCallback
|
|||
s_asyncCallbackSpinlock.unlock();
|
||||
}
|
||||
|
||||
static std::vector<struct CoreinitAsyncCallback*>* getPoolPtr()
|
||||
{
|
||||
return &s_asyncCallbackPool;
|
||||
}
|
||||
|
||||
static std::vector<struct CoreinitAsyncCallback*>* getQueuePtr()
|
||||
{
|
||||
return &s_asyncCallbackQueue;
|
||||
}
|
||||
|
||||
friend void ci_Callbacks_Save(MemStreamWriter& s);
|
||||
friend void ci_Callbacks_Restore(MemStreamReader& s);
|
||||
|
||||
private:
|
||||
void doCall()
|
||||
{
|
||||
|
@ -104,6 +117,50 @@ void coreinitAsyncCallback_add(MPTR functionMPTR, uint32 numParameters, uint32 r
|
|||
coreinitAsyncCallback_addWithLock(functionMPTR, numParameters, r3, r4, r5, r6, r7, r8, r9, r10);
|
||||
}
|
||||
|
||||
void ci_Callbacks_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_C_S", 15);
|
||||
|
||||
s.writeBE(g_coreinitCallbackThread.GetMPTR());
|
||||
s.writeBE(_g_coreinitCallbackThreadStack.GetMPTR());
|
||||
s.writeBE(g_asyncCallbackAsync.GetMPTR());
|
||||
s.writeBE(_g_coreinitCBThreadName.GetMPTR());
|
||||
|
||||
std::vector<struct CoreinitAsyncCallback*>* pool = CoreinitAsyncCallback::getPoolPtr();
|
||||
size_t poolSize = pool->size();
|
||||
s.writeBE(poolSize);
|
||||
s.writeData(pool, sizeof(CoreinitAsyncCallback) * poolSize);
|
||||
|
||||
std::vector<struct CoreinitAsyncCallback*>* queue = CoreinitAsyncCallback::getQueuePtr();
|
||||
size_t queueSize = queue->size();
|
||||
s.writeBE(queueSize);
|
||||
s.writeData(queue, sizeof(CoreinitAsyncCallback) * queueSize);
|
||||
}
|
||||
|
||||
void ci_Callbacks_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_C_S") == 0);
|
||||
|
||||
g_coreinitCallbackThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_g_coreinitCallbackThreadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
g_asyncCallbackAsync = (coreinit::OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_g_coreinitCBThreadName = (char*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
|
||||
std::vector<struct CoreinitAsyncCallback*>* pool = CoreinitAsyncCallback::getPoolPtr();
|
||||
size_t poolSize = s.readBE<size_t>();
|
||||
pool->clear();
|
||||
pool->resize(poolSize);
|
||||
s.readData(pool, sizeof(CoreinitAsyncCallback) * poolSize);
|
||||
|
||||
std::vector<struct CoreinitAsyncCallback*>* queue = CoreinitAsyncCallback::getPoolPtr();
|
||||
size_t queueSize = s.readBE<size_t>();
|
||||
queue->clear();
|
||||
queue->resize(queueSize);
|
||||
s.readData(queue, sizeof(CoreinitAsyncCallback) * queueSize);
|
||||
}
|
||||
|
||||
void InitializeAsyncCallback()
|
||||
{
|
||||
coreinit::OSInitSemaphore(g_asyncCallbackAsync.GetPtr(), 0);
|
||||
|
|
|
@ -136,6 +136,21 @@ namespace coreinit
|
|||
return true;
|
||||
}
|
||||
|
||||
void ci_CodeGen_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_CG_S", 15);
|
||||
s.writeData(&coreinitCodeGen, sizeof(coreinitCodeGen));
|
||||
}
|
||||
|
||||
void ci_CodeGen_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_CG_S") == 0);
|
||||
|
||||
s.readData(&coreinitCodeGen, sizeof(coreinitCodeGen));
|
||||
}
|
||||
|
||||
void InitializeCodeGen()
|
||||
{
|
||||
cafeExportRegister("coreinit", OSGetCodegenVirtAddrRange, LogType::Placeholder);
|
||||
|
|
|
@ -6,5 +6,8 @@ namespace coreinit
|
|||
void codeGenHandleICBI(uint32 ea);
|
||||
bool codeGenShouldAvoid();
|
||||
|
||||
void ci_CodeGen_Save(MemStreamWriter& s);
|
||||
void ci_CodeGen_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeCodeGen();
|
||||
}
|
|
@ -129,6 +129,28 @@ namespace coreinit
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ci_DynLoad_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_DL_S", 15);
|
||||
|
||||
s.writeBE(_osDynLoadFuncAlloc);
|
||||
s.writeBE(_osDynLoadFuncFree);
|
||||
s.writeBE(_osDynLoadTLSFuncAlloc);
|
||||
s.writeBE(_osDynLoadTLSFuncFree);
|
||||
}
|
||||
|
||||
void ci_DynLoad_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_DL_S") == 0);
|
||||
|
||||
_osDynLoadFuncAlloc = s.readBE<MPTR>();
|
||||
_osDynLoadFuncFree = s.readBE<MPTR>();
|
||||
_osDynLoadTLSFuncAlloc = s.readBE<MPTR>();
|
||||
_osDynLoadTLSFuncFree = s.readBE<MPTR>();
|
||||
}
|
||||
|
||||
void InitializeDynLoad()
|
||||
{
|
||||
cafeExportRegister("coreinit", OSDynLoad_SetAllocator, LogType::Placeholder);
|
||||
|
|
|
@ -14,5 +14,8 @@ namespace coreinit
|
|||
void OSDynLoad_Release(uint32 moduleHandle);
|
||||
uint32 OSDynLoad_FindExport(uint32 moduleHandle, uint32 isData, const char* exportName, betype<MPTR>* addrOut);
|
||||
|
||||
void ci_DynLoad_Save(MemStreamWriter& s);
|
||||
void ci_DynLoad_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeDynLoad();
|
||||
}
|
|
@ -191,6 +191,26 @@ namespace coreinit
|
|||
osLib_returnFromFunction(hCPU, r ? 1 : 0);
|
||||
}
|
||||
|
||||
void ci_FG_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_FG_S", 15);
|
||||
|
||||
s.writeBE(fgAddr.GetMPTR());
|
||||
s.writeBE(fgSaveAreaAddr.GetMPTR());
|
||||
s.writeData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT);
|
||||
}
|
||||
|
||||
void ci_FG_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_FG_S") == 0);
|
||||
|
||||
fgAddr = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
fgSaveAreaAddr = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s.readData(&fgAreaEntries, sizeof(fgAreaEntries) * FG_BUCKET_AREA_COUNT);
|
||||
}
|
||||
|
||||
void InitializeFG()
|
||||
{
|
||||
osLib_addFunction("coreinit", "OSGetForegroundBucket", coreinitExport_OSGetForegroundBucket);
|
||||
|
|
|
@ -13,5 +13,8 @@ namespace coreinit
|
|||
|
||||
void InitForegroundBucket();
|
||||
|
||||
void ci_FG_Save(MemStreamWriter& s);
|
||||
void ci_FG_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeFG();
|
||||
}
|
|
@ -2638,14 +2638,38 @@ namespace coreinit
|
|||
return FSA_RESULT::OK;
|
||||
}
|
||||
|
||||
void FSSave(MemStreamWriter& s)
|
||||
void ci_FS_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_FS_S", 15);
|
||||
s.writeData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t));
|
||||
s.writeBE(_sdCard01Mounted);
|
||||
s.writeBE(_mlc01Mounted);
|
||||
s.writeBE(_tempFSSpace.GetMPTR());
|
||||
size_t s_fsa_activeClients_size = s_fsa_activeClients.size();
|
||||
s.writeBE(s_fsa_activeClients_size);
|
||||
s.writeData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size);
|
||||
s.writeBE(s_fsaIpcPool.GetMPTR());
|
||||
s.writeBE(s_fsaIpcPoolBuffer.GetMPTR());
|
||||
s.writeBE(s_fsaIpcPoolBufferNumItems.GetMPTR());
|
||||
}
|
||||
|
||||
void FSRestore(MemStreamReader& s)
|
||||
void ci_FS_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_FS_S") == 0);
|
||||
|
||||
s.readData(g_fsRegisteredClientBodies, sizeof(FSClientBody_t));
|
||||
_sdCard01Mounted = s.readBE<bool>();
|
||||
_mlc01Mounted = s.readBE<bool>();
|
||||
_tempFSSpace = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
size_t s_fsa_activeClients_size = s.readBE<size_t>();
|
||||
s_fsa_activeClients.clear();
|
||||
s_fsa_activeClients.resize(s_fsa_activeClients_size);
|
||||
s.readData(&s_fsa_activeClients, sizeof(FSAClientHandle) * s_fsa_activeClients_size);
|
||||
s_fsaIpcPool = (IPCBufPool_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_fsaIpcPoolBuffer = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_fsaIpcPoolBufferNumItems = (uint32be*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void InitializeFS()
|
||||
|
|
|
@ -308,8 +308,8 @@ namespace coreinit
|
|||
|
||||
FS_VOLSTATE FSGetVolumeState(FSClient_t* fsClient);
|
||||
|
||||
void FSSave(MemStreamWriter& s);
|
||||
void FSRestore(MemStreamReader& s);
|
||||
void ci_FS_Save(MemStreamWriter& s);
|
||||
void ci_FS_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeFS();
|
||||
}; // namespace coreinit
|
||||
|
|
|
@ -258,6 +258,26 @@ namespace coreinit
|
|||
return memory_getPointerFromVirtualOffset(_swapEndianU32(tlsBlock->addr) + _swapEndianU32(tlsIndex->ukn04));
|
||||
}
|
||||
|
||||
void ci_GHS_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_GHS_S", 15);
|
||||
|
||||
s.writeBE(g_ghs_data.GetMPTR());
|
||||
s.writeBE(_flockMutexArray.GetMPTR());
|
||||
s.writeData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX);
|
||||
}
|
||||
|
||||
void ci_GHS_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_GHS_S") == 0);
|
||||
|
||||
g_ghs_data = (GHSAccessibleData*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_flockMutexArray = (coreinit::OSMutex*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s.readData(_flockMutexMask, sizeof(bool) * GHS_FOPEN_MAX);
|
||||
}
|
||||
|
||||
void InitializeGHS()
|
||||
{
|
||||
cafeExportRegister("coreinit", __ghs_flock_create, LogType::Placeholder);
|
||||
|
|
|
@ -4,5 +4,8 @@ namespace coreinit
|
|||
{
|
||||
void PrepareGHSRuntime();
|
||||
|
||||
void ci_GHS_Save(MemStreamWriter& s);
|
||||
void ci_GHS_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeGHS();
|
||||
};
|
|
@ -462,6 +462,34 @@ namespace coreinit
|
|||
return r;
|
||||
}
|
||||
|
||||
void ci_IPC_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_IPC_S", 15);
|
||||
|
||||
s.writeBE(s_ipcResourceBuffers.GetMPTR());
|
||||
s.writeBE(s_ipcDriver.GetMPTR());
|
||||
s.writeBE(gIPCThread.GetMPTR());
|
||||
s.writeBE(_gIPCThreadStack.GetMPTR());
|
||||
s.writeBE(_gIPCThreadNameStorage.GetMPTR());
|
||||
s.writeBE(gIPCThreadMsgQueue.GetMPTR());
|
||||
s.writeBE(_gIPCThreadSemaphoreStorage.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_IPC_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_IPC_S") == 0);
|
||||
|
||||
s_ipcResourceBuffers = (IPCResourceBuffer*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_ipcDriver = (IPCDriver*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
gIPCThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_gIPCThreadStack = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_gIPCThreadNameStorage = memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
gIPCThreadMsgQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_gIPCThreadSemaphoreStorage = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void InitializeIPC()
|
||||
{
|
||||
for (uint32 i = 0; i < Espresso::CORE_COUNT; i++)
|
||||
|
@ -478,5 +506,4 @@ namespace coreinit
|
|||
cafeExportRegister("coreinit", IOS_Ioctlv, LogType::PPC_IPC);
|
||||
cafeExportRegister("coreinit", IOS_IoctlvAsync, LogType::PPC_IPC);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -12,5 +12,8 @@ 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 ci_IPC_Save(MemStreamWriter& s);
|
||||
void ci_IPC_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeIPC();
|
||||
};
|
|
@ -215,3 +215,25 @@ void coreinit_start(PPCInterpreter_t* hCPU)
|
|||
hCPU->gpr[3] = _coreinitInfo->argc;
|
||||
hCPU->instructionPointer = _coreinitTitleEntryPoint;
|
||||
}
|
||||
|
||||
void ci_Init_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_Init_S", 15);
|
||||
|
||||
s.writeData(_coreinitInfo, sizeof(coreinitInit_t));
|
||||
s.writeBE(argStorageIndex);
|
||||
s.writeBE(g_preinitUserParam.GetMPTR());
|
||||
s.writeBE(_coreinitTitleEntryPoint);
|
||||
}
|
||||
|
||||
void ci_Init_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_Init_S") == 0);
|
||||
|
||||
s.readData(_coreinitInfo, sizeof(coreinitInit_t));
|
||||
argStorageIndex = s.readBE<sint32>();
|
||||
g_preinitUserParam = (PreinitUserHeapStruct*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_coreinitTitleEntryPoint = s.readBE<sint32>();
|
||||
}
|
|
@ -271,6 +271,26 @@ namespace coreinit
|
|||
osLib_returnFromFunction(hCPU, 0);
|
||||
}
|
||||
|
||||
void ci_LockedCache_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_LC_S", 15);
|
||||
|
||||
s.writeData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY);
|
||||
s.writeData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT);
|
||||
s.writeBE(_lcDisableErrorCounter);
|
||||
}
|
||||
|
||||
void ci_LockedCache_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_LC_S") == 0);
|
||||
|
||||
s.readData(lcCacheMask, sizeof(uint8) * PPC_CORE_COUNT * (LC_LOCKED_CACHE_SIZE + LC_LOCKED_CACHE_GRANULARITY - 1) / LC_LOCKED_CACHE_GRANULARITY);
|
||||
s.readData(lcAllocatedBlocks, sizeof(uint32) * PPC_CORE_COUNT);
|
||||
_lcDisableErrorCounter = s.readBE<sint32>();
|
||||
}
|
||||
|
||||
void InitializeLC()
|
||||
{
|
||||
for (sint32 f = 0; f < PPC_CORE_COUNT; f++)
|
||||
|
|
|
@ -2,5 +2,8 @@
|
|||
|
||||
namespace coreinit
|
||||
{
|
||||
void ci_LockedCache_Save(MemStreamWriter& s);
|
||||
void ci_LockedCache_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeLC();
|
||||
}
|
|
@ -630,6 +630,46 @@ namespace coreinit
|
|||
memset(&g_list3, 0, sizeof(g_list3));
|
||||
}
|
||||
|
||||
void ci_MEM_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_MEM_S", 15);
|
||||
|
||||
s.writeBE(sysAreaAllocatorOffset);
|
||||
s.writeBE(g_heapTableCount);
|
||||
s.writeData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE);
|
||||
s.writeBE(g_slockInitialized);
|
||||
s.writeBE(g_listsInitialized);
|
||||
s.writeData(&g_list1, sizeof(MEMList));
|
||||
s.writeData(&g_list2, sizeof(MEMList));
|
||||
s.writeData(&g_list3, sizeof(MEMList));
|
||||
s.writeData(&gHeapFillValues, sizeof(uint32) * 3);
|
||||
s.writeBE(gHeapGlobalLock.GetMPTR());
|
||||
s.writeData(&gDefaultHeap, sizeof(MEMHeapBase));
|
||||
s.writeData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9);
|
||||
s.writeBE(gDefaultHeapAllocator.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_MEM_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_MEM_S") == 0);
|
||||
|
||||
sysAreaAllocatorOffset = s.readBE<MPTR>();
|
||||
g_heapTableCount = s.readBE<sint32>();
|
||||
s.readData(g_heapTable, sizeof(MEMHeapBase) * MEM_MAX_HEAP_TABLE);
|
||||
g_slockInitialized = s.readBE<bool>();
|
||||
g_listsInitialized = s.readBE<bool>();
|
||||
s.readData(&g_list1, sizeof(MEMList));
|
||||
s.readData(&g_list2, sizeof(MEMList));
|
||||
s.readData(&g_list3, sizeof(MEMList));
|
||||
s.readData(&gHeapFillValues, sizeof(uint32) * 3);
|
||||
gHeapGlobalLock = (OSSpinLock*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s.readData(&gDefaultHeap, sizeof(MEMHeapBase));
|
||||
s.readData(&sHeapBaseHandle, sizeof(MEMHeapBase) * 9);
|
||||
gDefaultHeapAllocator = (MEMAllocatorFunc*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void InitializeMEM()
|
||||
{
|
||||
MEMResetToDefaultState();
|
||||
|
|
|
@ -179,5 +179,8 @@ namespace coreinit
|
|||
|
||||
void InitializeMEMUnitHeap();
|
||||
|
||||
void ci_MEM_Save(MemStreamWriter& s);
|
||||
void ci_MEM_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeMEM();
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace coreinit
|
|||
|
||||
struct OSVirtMemoryEntry
|
||||
{
|
||||
OSVirtMemoryEntry() : virtualAddress(0), size(0), alignment(0) {};
|
||||
|
||||
OSVirtMemoryEntry(MPTR virtualAddress, uint32 size, uint32 alignment) : virtualAddress(virtualAddress), size(size), alignment(alignment) {};
|
||||
|
||||
MPTR virtualAddress;
|
||||
|
@ -151,6 +153,27 @@ namespace coreinit
|
|||
return 1;
|
||||
}
|
||||
|
||||
void ci_MemoryMapping_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_MemMap_S", 15);
|
||||
|
||||
size_t s_allocatedVirtMemorySize = s_allocatedVirtMemory.size();
|
||||
s.writeBE(s_allocatedVirtMemorySize);
|
||||
s.writeData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize);
|
||||
}
|
||||
|
||||
void ci_MemoryMapping_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_MemMap_S") == 0);
|
||||
|
||||
size_t s_allocatedVirtMemorySize = s.readBE<size_t>();
|
||||
s_allocatedVirtMemory.clear();
|
||||
s_allocatedVirtMemory.resize(s_allocatedVirtMemorySize);
|
||||
s.readData(&s_allocatedVirtMemory, sizeof(OSVirtMemoryEntry) * s_allocatedVirtMemorySize);
|
||||
}
|
||||
|
||||
void InitializeMemoryMapping()
|
||||
{
|
||||
s_allocatedVirtMemory.clear();
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
|
||||
namespace coreinit
|
||||
{
|
||||
void ci_MemoryMapping_Save(MemStreamWriter& s);
|
||||
void ci_MemoryMapping_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeMemoryMapping();
|
||||
}
|
||||
|
|
|
@ -117,6 +117,24 @@ namespace coreinit
|
|||
return g_systemMessageQueue.GetPtr();
|
||||
}
|
||||
|
||||
void ci_MessageQueue_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_MessQue_S", 15);
|
||||
|
||||
s.writeBE(g_systemMessageQueue.GetMPTR());
|
||||
s.writeBE(_systemMessageQueueArray.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_MessageQueue_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_MessQue_S") == 0);
|
||||
|
||||
g_systemMessageQueue = (OSMessageQueue*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
_systemMessageQueueArray = (OSMessage*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void InitializeMessageQueue()
|
||||
{
|
||||
OSInitMessageQueue(g_systemMessageQueue.GetPtr(), _systemMessageQueueArray.GetPtr(), _systemMessageQueueArray.GetCount());
|
||||
|
|
|
@ -36,5 +36,8 @@ namespace coreinit
|
|||
bool OSPeekMessage(OSMessageQueue* msgQueue, OSMessage* msg);
|
||||
sint32 OSSendMessage(OSMessageQueue* msgQueue, OSMessage* msg, uint32 flags);
|
||||
|
||||
void ci_MessageQueue_Save(MemStreamWriter& s);
|
||||
void ci_MessageQueue_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeMessageQueue();
|
||||
};
|
|
@ -25,6 +25,21 @@ namespace coreinit
|
|||
*areaSize = MEMORY_OVERLAY_AREA_SIZE;
|
||||
}
|
||||
|
||||
void ci_OverlayArena_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_OverArea_S", 15);
|
||||
|
||||
s.writeData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena));
|
||||
}
|
||||
void ci_OverlayArena_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_OverArea_S") == 0);
|
||||
|
||||
s.readData(&g_coreinitOverlayArena, sizeof(g_coreinitOverlayArena));
|
||||
}
|
||||
|
||||
void InitializeOverlayArena()
|
||||
{
|
||||
cafeExportRegister("coreinit", OSIsEnabledOverlayArena, LogType::Placeholder);
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
namespace coreinit
|
||||
{
|
||||
void ci_OverlayArena_Save(MemStreamWriter& s);
|
||||
void ci_OverlayArena_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeOverlayArena();
|
||||
};
|
|
@ -614,6 +614,22 @@ namespace coreinit
|
|||
OSWakeupThread(&fastCond->threadQueue);
|
||||
}
|
||||
|
||||
void ci_Sync_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_Sync_S", 15);
|
||||
|
||||
s.writeBE(g_rendezvousEvent.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_Sync_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_Sync_S") == 0);
|
||||
|
||||
g_rendezvousEvent = (OSEvent*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
/************* init ************/
|
||||
|
||||
void InitializeConcurrency()
|
||||
|
|
|
@ -32,6 +32,26 @@ namespace coreinit
|
|||
_sysHeapFreeCounter = 0;
|
||||
}
|
||||
|
||||
void ci_SysHeap_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_SysHeap_S", 15);
|
||||
|
||||
s.writeData(_sysHeapHandle, sizeof(MEMHeapBase));
|
||||
s.writeBE(_sysHeapAllocCounter);
|
||||
s.writeBE(_sysHeapFreeCounter);
|
||||
}
|
||||
|
||||
void ci_SysHeap_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_SysHeap_S") == 0);
|
||||
|
||||
s.readData(_sysHeapHandle, sizeof(MEMHeapBase));
|
||||
_sysHeapAllocCounter = s.readBE<sint32>();
|
||||
_sysHeapFreeCounter = s.readBE<sint32>();
|
||||
}
|
||||
|
||||
void InitializeSysHeap()
|
||||
{
|
||||
osLib_addFunction("coreinit", "OSAllocFromSystem", export_OSAllocFromSystem);
|
||||
|
|
|
@ -4,5 +4,8 @@ namespace coreinit
|
|||
{
|
||||
void InitSysHeap();
|
||||
|
||||
void ci_SysHeap_Save(MemStreamWriter& s);
|
||||
void ci_SysHeap_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeSysHeap();
|
||||
}
|
|
@ -10,6 +10,22 @@ namespace coreinit
|
|||
return *g_system_info.GetPtr();
|
||||
}
|
||||
|
||||
void ci_SystemInfo_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_SysInfo_S", 15);
|
||||
|
||||
s.writeBE(g_system_info.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_SystemInfo_Restore(MemStreamReader& s)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section, 15);
|
||||
cemu_assert_debug(strcmp(section, "ci_SysInfo_S") == 0);
|
||||
|
||||
g_system_info = (OSSystemInfo*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void InitializeSystemInfo()
|
||||
{
|
||||
cemu_assert(ppcCyclesSince2000 != 0);
|
||||
|
|
|
@ -16,6 +16,9 @@ namespace coreinit
|
|||
|
||||
const OSSystemInfo& OSGetSystemInfo();
|
||||
|
||||
void ci_SystemInfo_Save(MemStreamWriter& s);
|
||||
void ci_SystemInfo_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeSystemInfo();
|
||||
};
|
||||
|
||||
|
|
|
@ -196,36 +196,6 @@ namespace coreinit
|
|||
return __currentCoreThread[currentInstance->spr.UPIR];
|
||||
}
|
||||
|
||||
void SuspendAllThreads()
|
||||
{
|
||||
for (auto& thr : activeThread)
|
||||
{
|
||||
auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr);
|
||||
if (thr != 0)
|
||||
{
|
||||
OSSuspendThread(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResumeAllThreads()
|
||||
{
|
||||
for (auto& thr : activeThread)
|
||||
{
|
||||
auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr);
|
||||
if (thr != 0)
|
||||
{
|
||||
if (s_threadToFiber.find(ptr) == s_threadToFiber.end())
|
||||
{
|
||||
__OSLockScheduler();
|
||||
__OSCreateHostThread(ptr);
|
||||
__OSUnlockScheduler();
|
||||
}
|
||||
OSResumeThread(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void threadEntry(PPCInterpreter_t* hCPU)
|
||||
{
|
||||
OSThread_t* currentThread = coreinitThread_getCurrentThreadDepr(hCPU);
|
||||
|
@ -1361,6 +1331,104 @@ namespace coreinit
|
|||
}
|
||||
}
|
||||
|
||||
void ci_Thread_Save(MemStreamWriter& s)
|
||||
{
|
||||
s.writeData("ci_T_S", 15);
|
||||
|
||||
s.writeBE(g_activeThreadQueue.GetMPTR());
|
||||
s.writeBE(g_coreRunQueue.GetMPTR());
|
||||
|
||||
s.writeBE(activeThreadCount);
|
||||
for (sint32 i = 0; i < activeThreadCount; i++)
|
||||
{
|
||||
s.writeBE(activeThread[i]);
|
||||
}
|
||||
for (sint32 i = 0; i < PPC_CORE_COUNT; i++)
|
||||
{
|
||||
s.writeBE(memory_getVirtualOffsetFromPointer(__currentCoreThread[i]));
|
||||
s.writeBE(s_lehmer_lcg[i]);
|
||||
s.writeBE(s_terminatorThreads[i].terminatorThread.GetMPTR());
|
||||
s.writeBE(s_terminatorThreads[i].threadStack.GetMPTR());
|
||||
s.writeBE(s_terminatorThreads[i].threadName.GetMPTR());
|
||||
s.writeBE(s_terminatorThreads[i].semaphoreQueuedDeallocators.GetMPTR());
|
||||
}
|
||||
s.writeBE(s_defaultThreads.GetMPTR());
|
||||
s.writeBE(s_stack.GetMPTR());
|
||||
}
|
||||
|
||||
void ci_Thread_Restore(MemStreamReader& s, bool recreate)
|
||||
{
|
||||
char section[16] = { '\0' };
|
||||
s.readData(section,15);
|
||||
cemu_assert_debug(strcmp(section, "ci_T_S") == 0);
|
||||
|
||||
g_activeThreadQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
g_coreRunQueue = (OSThreadQueue*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
|
||||
sint32 prevActiveThreadCount = s.readBE<sint32>();
|
||||
for (sint32 i = 0; i < prevActiveThreadCount; i++)
|
||||
{
|
||||
MPTR threadMPTR = s.readBE<MPTR>();
|
||||
if (recreate)
|
||||
{
|
||||
__OSLockScheduler();
|
||||
__OSActivateThread((OSThread_t*)memory_getPointerFromVirtualOffset(threadMPTR));
|
||||
__OSUnlockScheduler();
|
||||
}
|
||||
else
|
||||
{
|
||||
activeThreadCount = prevActiveThreadCount;
|
||||
activeThread[i] = threadMPTR;
|
||||
}
|
||||
}
|
||||
for (sint32 i = 0; i < PPC_CORE_COUNT; i++)
|
||||
{
|
||||
__currentCoreThread[i] = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_lehmer_lcg[i] = s.readBE<uint32>();
|
||||
s_terminatorThreads[i].terminatorThread = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_terminatorThreads[i].threadStack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_terminatorThreads[i].threadName = (char*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_terminatorThreads[i].semaphoreQueuedDeallocators = (OSSemaphore*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
s_defaultThreads = (OSThread_t*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
s_stack = (uint8*)memory_getPointerFromVirtualOffset(s.readBE<MPTR>());
|
||||
}
|
||||
|
||||
void SuspendActiveThreads()
|
||||
{
|
||||
|
||||
for (auto& thr : activeThread)
|
||||
{
|
||||
if (thr != MPTR_NULL)
|
||||
{
|
||||
auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr);
|
||||
cemuLog_log(LogType::SaveStates, "Before State: {}", ptr->state.value());
|
||||
cemuLog_log(LogType::SaveStates, "Before SusCnt: {}", ptr->suspendCounter);
|
||||
OSSuspendThread(ptr);
|
||||
cemuLog_log(LogType::SaveStates, "After State: {}", ptr->state.value());
|
||||
cemuLog_log(LogType::SaveStates, "After SusCnt: {}", ptr->suspendCounter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ResumeActiveThreads()
|
||||
{
|
||||
for (auto& thr : activeThread)
|
||||
{
|
||||
if (thr != MPTR_NULL)
|
||||
{
|
||||
auto* ptr = (OSThread_t*)memory_getPointerFromVirtualOffset(thr);
|
||||
if (s_threadToFiber.find(ptr) == s_threadToFiber.end())
|
||||
{
|
||||
__OSLockScheduler();
|
||||
__OSCreateHostThread(ptr);
|
||||
__OSUnlockScheduler();
|
||||
}
|
||||
OSResumeThread(ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeThread()
|
||||
{
|
||||
cafeExportRegister("coreinit", OSCreateThreadType, LogType::CoreinitThread);
|
||||
|
|
|
@ -496,7 +496,16 @@ static_assert(sizeof(OSThread_t) == 0x6A0-4); // todo - determine correct size
|
|||
|
||||
namespace coreinit
|
||||
{
|
||||
void ci_Thread_Save(MemStreamWriter& s);
|
||||
void ci_Thread_Restore(MemStreamReader& s, bool recreate);
|
||||
void SuspendActiveThreads();
|
||||
void ResumeActiveThreads();
|
||||
|
||||
void InitializeThread();
|
||||
|
||||
void ci_Sync_Save(MemStreamWriter& s);
|
||||
void ci_Sync_Restore(MemStreamReader& s);
|
||||
|
||||
void InitializeConcurrency();
|
||||
|
||||
bool __CemuIsMulticoreMode();
|
||||
|
@ -524,8 +533,6 @@ namespace coreinit
|
|||
|
||||
sint32 __OSResumeThreadInternal(OSThread_t* thread, sint32 resumeCount);
|
||||
sint32 OSResumeThread(OSThread_t* thread);
|
||||
void SuspendAllThreads();
|
||||
void ResumeAllThreads();
|
||||
void OSContinueThread(OSThread_t* thread);
|
||||
void __OSSuspendThreadInternal(OSThread_t* thread);
|
||||
void __OSSuspendThreadNolock(OSThread_t* thread);
|
||||
|
|
|
@ -35,6 +35,8 @@ enum class LogType : sint32
|
|||
|
||||
ProcUi = 40,
|
||||
|
||||
SaveStates = 50,
|
||||
|
||||
APIErrors = 0, // alias for Force. Logs bad parameters or other API errors in OS libs
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,12 @@ public:
|
|||
m_tempData.insert(m_tempData.begin(), str, str + N);
|
||||
}
|
||||
|
||||
SysAllocator& operator=(T* value)
|
||||
{
|
||||
m_sysMem = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr uint32 GetCount() const
|
||||
{
|
||||
return count;
|
||||
|
@ -165,6 +171,12 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
SysAllocator& operator=(T* value)
|
||||
{
|
||||
m_sysMem = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator T()
|
||||
{
|
||||
return *GetPtr();
|
||||
|
|
|
@ -2250,6 +2250,7 @@ void MainWindow::RecreateMenu()
|
|||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::Patches), _("&Graphic pack patches"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::Patches));
|
||||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::TextureCache), _("&Texture cache warnings"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::TextureCache));
|
||||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::TextureReadback), _("&Texture readback"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::TextureReadback));
|
||||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::SaveStates), _("&Save states"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::SaveStates));
|
||||
debugLoggingMenu->AppendSeparator();
|
||||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::OpenGLLogging), _("&OpenGL debug output"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::OpenGLLogging));
|
||||
debugLoggingMenu->AppendCheckItem(MAINFRAME_MENU_ID_DEBUG_LOGGING0 + stdx::to_underlying(LogType::VulkanValidation), _("&Vulkan validation layer (slow)"), wxEmptyString)->Check(cemuLog_isLoggingEnabled(LogType::VulkanValidation));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue