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); }
void memoryRelease(void) { MEMDestroyExpHeap(mem1_heap); MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3); mem1_heap = NULL; MEMDestroyExpHeap(bucket_heap); MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3); bucket_heap = NULL; }
void memoryRelease(void) { MEMDestroyExpHeap(mem1_heap); MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1), MEM_FRAME_HEAP_FREE_ALL); mem1_heap = NULL; MEMDestroyExpHeap(bucket_heap); MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG), MEM_FRAME_HEAP_FREE_ALL); bucket_heap = NULL; }
void memoryInitialize(void) { MEMHeapHandle mem1_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); if(mem1_memory) mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); MEMHeapHandle bucket_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG); unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); if(bucket_memory) bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); }
int MEM_DynLoad_DefaultAlloc(int size, int alignment, be_val<uint32_t> *outPtr) { auto heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); auto memory = MEMAllocFromExpHeapEx(reinterpret_cast<ExpandedHeap*>(heap), size, alignment); *outPtr = gMemory.untranslate(memory); return 0; }
void consoleFree() { OSScreenShutdown(); MEMHeapHandle mem1 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2); MEMFreeToExpHeap(mem1, bufferTV); MEMFreeToExpHeap(mem1, bufferDRC); }
/** * Initialise an Allocator struct for the default heap. */ void MEMInitAllocatorForDefaultHeap(MEMAllocator *allocator) { decaf_check(sDefaultHeapFunctions); allocator->heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2); allocator->align = 0; allocator->funcs = sDefaultHeapFunctions; }
void consoleInit() { MEMHeapHandle mem1; OSScreenInit(); bufferSizeTV = OSScreenGetBufferSizeEx(SCREEN_TV); bufferSizeDRC = OSScreenGetBufferSizeEx(SCREEN_DRC); mem1 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2); bufferTV = MEMAllocFromExpHeapEx(mem1, bufferSizeTV, 4); bufferDRC = MEMAllocFromExpHeapEx(mem1, bufferSizeDRC, 4); OSScreenSetBufferEx(SCREEN_TV, bufferTV); OSScreenSetBufferEx(SCREEN_DRC, bufferDRC); OSScreenEnableEx(SCREEN_TV, 1); OSScreenEnableEx(SCREEN_DRC, 1); }
void MEM2_free(void *ptr) { if (ptr) MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr); }
//!------------------------------------------------------------------------------------------- //! some wrappers //!------------------------------------------------------------------------------------------- void * MEM2_alloc(unsigned int size, unsigned int align) { return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, align); }
void MEM_DynLoad_DefaultFree(void *addr) { auto heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); MEMFreeToExpHeap(reinterpret_cast<ExpandedHeap*>(heap), addr); }
void * defaultAllocFromDefaultHeap(uint32_t size) { auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2); return MEMAllocFromExpHeap(reinterpret_cast<ExpandedHeap*>(heap), size); }
void* _memalign_r(struct _reent *r, size_t alignment, size_t size) { return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), size, alignment); }
static void sMEMFreeToDefaultHeap(p32<void> block) { auto heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); return MEMFreeToExpHeap(reinterpret_cast<ExpandedHeap*>(heap), block); }
static void * sMEMAllocFromDefaultHeapEx(uint32_t size, int alignment) { auto heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); return MEMAllocFromExpHeapEx(reinterpret_cast<ExpandedHeap*>(heap), size, alignment); }
int main(int argc, char **argv) { MEMHeapHandle mem2 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2); test_assert(mem2); test_report("Allocating %d bytes from default heap", HeapSize); void *heapAddr = MEMAllocFromExpHeapEx(mem2, HeapSize, 4); test_assert(heapAddr); // Unalign the frame heap base address void *frameHeapAddr = heapAddr + 1; test_report("Creating frame heap at %p", frameHeapAddr); MEMHeapHandle frameHeap = MEMCreateFrmHeapEx(frameHeapAddr, HeapSize, 0); test_report("Frame heap created at %p", frameHeap); test_assert(frameHeap); test_assert((((uint32_t)frameHeap) % 4) == 0); uint32_t freeSize1 = MEMGetAllocatableSizeForFrmHeapEx(frameHeap, 4); test_report("Free Size before allocation: %d", freeSize1); test_assert((freeSize1 % 4) == 0); { // Allocate an unaligned block from head with an unaligned size void *unalignedBlock = MEMAllocFromFrmHeapEx(frameHeap, 5, 1); uint32_t unalignedBlockAddress = (uint32_t)unalignedBlock; test_report("Unaligned head block allocated at %p", unalignedBlock); test_assert(unalignedBlock); // Allocate an aligned block from head and ensure it is aligned void *alignedBlock = MEMAllocFromFrmHeapEx(frameHeap, 1024, 512); uint32_t alignedBlockAddress = (uint32_t)alignedBlock; test_report("Aligned head block allocated at %p", alignedBlock); test_assert(alignedBlock); test_assert((((uint32_t)alignedBlock) % 512) == 0); test_assert(alignedBlockAddress - unalignedBlockAddress >= 5); } { // Allocate an unaligned block from tail with an unaligned size void *unalignedBlock = MEMAllocFromFrmHeapEx(frameHeap, 5, -1); uint32_t unalignedBlockAddress = (uint32_t)unalignedBlock; test_report("Unaligned tail block allocated at %p", unalignedBlock); test_assert(unalignedBlock); // Allocate an aligned block from tail and ensure it is aligned void *alignedBlock = MEMAllocFromFrmHeapEx(frameHeap, 1024, -512); uint32_t alignedBlockAddress = (uint32_t)alignedBlock; test_report("Aligned tail block allocated at %p", alignedBlock); test_assert(alignedBlock); test_assert((((uint32_t)alignedBlock) % 512) == 0); test_assert(unalignedBlockAddress - alignedBlockAddress >= 512); } // Free all memory MEMFreeToFrmHeap(frameHeap, MEM_FRM_HEAP_FREE_ALL); uint32_t freeSize3 = MEMGetAllocatableSizeForFrmHeapEx(frameHeap, 4); test_report("Free Size after free: %d", freeSize3); test_assert(freeSize1 == freeSize3); MEMDestroyFrmHeap(frameHeap); MEMFreeToExpHeap(mem2, heapAddr); return 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); }
void defaultFreeToDefaultHeap(void *block) { auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2); return MEMFreeToExpHeap(reinterpret_cast<ExpandedHeap*>(heap), block); }
/** * Default implementation for sMemFree */ static void dynloadDefaultFree(void *addr) { auto heap = MEMGetBaseHeapHandle(MEMBaseHeapType::MEM2); MEMFreeToExpHeap(reinterpret_cast<ExpandedHeap*>(heap), addr); }
void __wrap_free(void *ptr) { if (ptr) { MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_2), ptr); } }
void _free_r(struct _reent *r, void *ptr) { if (ptr) { MEMFreeToExpHeap(MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2), ptr); } }
void * __wrap_memalign(size_t alignment, size_t size) { return MEMAllocFromExpHeapEx(MEMGetBaseHeapHandle(MEMORY_ARENA_2), size, alignment); }