void GameThreadEntry(uint32_t argc, void *argv) { auto appModule = internal::getUserModule(); auto userPreinit = appModule->findFuncExport<void, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*>("__preinit_user"); auto start = OSThreadEntryPointFn(appModule->entryPoint); debugger::handlePreLaunch(); if (userPreinit) { ppcutils::StackObject<be_ptr<CommonHeap>> mem1HeapPtr; ppcutils::StackObject<be_ptr<CommonHeap>> fgHeapPtr; ppcutils::StackObject<be_ptr<CommonHeap>> mem2HeapPtr; *mem1HeapPtr = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM1); *fgHeapPtr = MEMGetBaseHeapHandle(MEMBaseHeapType::FG); *mem2HeapPtr = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2); userPreinit(mem1HeapPtr, fgHeapPtr, mem2HeapPtr); MEMSetBaseHeapHandle(MEMBaseHeapType::MEM1, *mem1HeapPtr); MEMSetBaseHeapHandle(MEMBaseHeapType::FG, *fgHeapPtr); MEMSetBaseHeapHandle(MEMBaseHeapType::MEM2, *mem2HeapPtr); } start(argc, argv); }
// TODO: Move to coreinit::internal void CoreInitDefaultHeap() { be_val<uint32_t> addr, size; // Create expanding heap for MEM2 OSGetMemBound(OSMemoryType::MEM2, &addr, &size); auto mem2 = MEMCreateExpHeap(make_virtual_ptr<ExpandedHeap>(addr), size); MEMSetBaseHeapHandle(MEMBaseHeapType::MEM2, reinterpret_cast<CommonHeap*>(mem2)); // Create frame heap for MEM1 OSGetMemBound(OSMemoryType::MEM1, &addr, &size); auto mem1 = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size); MEMSetBaseHeapHandle(MEMBaseHeapType::MEM1, reinterpret_cast<CommonHeap*>(mem1)); // Create frame heap for Foreground OSGetForegroundBucketFreeArea(&addr, &size); auto fg = MEMCreateFrmHeap(make_virtual_ptr<FrameHeap>(addr), size); MEMSetBaseHeapHandle(MEMBaseHeapType::FG, reinterpret_cast<CommonHeap*>(fg)); }
void GameLoaderRun() { auto appModule = gLoader.loadRPL(gGameRpx.c_str()); if (!appModule) { gLog->error("Could not load {}", gGameRpx); return; } gSystem.setUserModule(appModule); gDebugControl.preLaunch(); gLog->debug("Succesfully loaded {}", gGameRpx); // Call the RPX __preinit_user if it is defined auto userPreinit = appModule->findFuncExport<void, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*>("__preinit_user"); if (userPreinit) { struct HeapHandles { be_ptr<CommonHeap> mem1Heap; be_ptr<CommonHeap> fgHeap; be_ptr<CommonHeap> mem2Heap; }; HeapHandles *wiiHandles = OSAllocFromSystem<HeapHandles>(); wiiHandles->mem1Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM1); wiiHandles->fgHeap = MEMGetBaseHeapHandle(BaseHeapType::FG); wiiHandles->mem2Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); userPreinit(&wiiHandles->mem1Heap, &wiiHandles->fgHeap, &wiiHandles->mem2Heap); MEMSetBaseHeapHandle(BaseHeapType::MEM1, wiiHandles->mem1Heap); MEMSetBaseHeapHandle(BaseHeapType::FG, wiiHandles->fgHeap); MEMSetBaseHeapHandle(BaseHeapType::MEM2, wiiHandles->mem2Heap); OSFreeToSystem(wiiHandles); } // Create default threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = appModule->defaultStackSize; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Default Thread %d", i); OSCreateThread(thread, 0u, 0, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, 16, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetDefaultThread(i, thread); OSSetThreadName(thread, name); } // Create interrupt threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = 16 * 1024; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Interrupt Thread %d", i); OSCreateThread(thread, InterruptThreadEntryPoint, i, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, -1, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetInterruptThread(i, thread); OSSetThreadName(thread, name); OSResumeThread(thread); } // Run thread 1 OSRunThread(OSGetDefaultThread(1), appModule->entryPoint, 0, nullptr); }