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);
}
Example #2
0
// 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));
}
Example #3
0
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);
}