diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2021-08-21 11:02:05 -0400 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2021-08-21 11:02:05 -0400 |
commit | 676ebab3d6ad726b3e154c994c4fcfdbb186ed22 (patch) | |
tree | e6faef65beb3337559173f2ce536e6d8a6db3734 | |
parent | cb6f5a1c7ad38e09cb47d402b2b5d78fdd5965cc (diff) |
through NNS_FndAllocFromExpHeapEx
-rw-r--r-- | arm9/asm/NNS_FND_expheap_s.s | 121 | ||||
-rw-r--r-- | arm9/lib/libnns/include/NNS_FND_expheap.h | 4 | ||||
-rw-r--r-- | arm9/lib/libnns/include/NNS_FND_heapcommon.h | 2 | ||||
-rw-r--r-- | arm9/lib/libnns/src/NNS_FND_expheap.c | 116 |
4 files changed, 121 insertions, 122 deletions
diff --git a/arm9/asm/NNS_FND_expheap_s.s b/arm9/asm/NNS_FND_expheap_s.s index d173bef0..d4d958db 100644 --- a/arm9/asm/NNS_FND_expheap_s.s +++ b/arm9/asm/NNS_FND_expheap_s.s @@ -10,6 +10,7 @@ .extern AllocUsedBlockFromFreeBlock .extern AllocFromHead .extern AllocFromTail + .extern RecycleRegion .text arm_func_start NNS_FndGetSizeForMBlockExpHeap @@ -156,123 +157,3 @@ _020ADF90: .balign 4 _020ADF9C: .word 0x00004652 arm_func_end NNS_FndResizeForMBlockExpHeap - - arm_func_start NNS_FndAllocFromExpHeapEx -NNS_FndAllocFromExpHeapEx: ; 0x020ADFA0 - stmdb sp!, {lr} - sub sp, sp, #0x4 - cmp r1, #0x0 - moveq r1, #0x1 - add r1, r1, #0x3 - cmp r2, #0x0 - bic r1, r1, #0x3 - blt _020ADFCC - bl AllocFromHead - add sp, sp, #0x4 - ldmia sp!, {pc} -_020ADFCC: - rsb r2, r2, #0x0 - bl AllocFromTail - add sp, sp, #0x4 - ldmia sp!, {pc} - arm_func_end NNS_FndAllocFromExpHeapEx - - arm_func_start NNS_FndDestroyExpHeap -NNS_FndDestroyExpHeap: ; 0x020ADFDC - ldr ip, _020ADFE4 ; =NNSi_FndFinalizeHeap - bx r12 - .balign 4 -_020ADFE4: .word NNSi_FndFinalizeHeap - arm_func_end NNS_FndDestroyExpHeap - - arm_func_start NNS_FndCreateExpHeapEx -NNS_FndCreateExpHeapEx: ; 0x020ADFE8 - stmdb sp!, {lr} - sub sp, sp, #0x4 - add r1, r1, r0 - add r0, r0, #0x3 - bic r1, r1, #0x3 - bic r0, r0, #0x3 - cmp r0, r1 - bhi _020AE014 - sub r3, r1, r0 - cmp r3, #0x4c - bhs _020AE020 -_020AE014: - add sp, sp, #0x4 - mov r0, #0x0 - ldmia sp!, {pc} -_020AE020: - bl InitExpHeap - add sp, sp, #0x4 - ldmia sp!, {pc} - arm_func_end NNS_FndCreateExpHeapEx - - arm_func_start RecycleRegion -RecycleRegion: - stmdb sp!, {r4-r6,lr} - sub sp, sp, #0x8 - mov r5, r1 - ldr r2, [r5, #0x0] - ldr r1, [r5, #0x4] - mov r6, r0 - str r2, [sp, #0x0] - str r1, [sp, #0x4] - ldr r1, [r6, #0x0] - mov r4, #0x0 - cmp r1, #0x0 - beq _020AE0A0 - ldr r0, [r5, #0x0] -_020AE060: - cmp r1, r0 - movcc r4, r1 - blo _020AE094 - ldr r0, [r5, #0x4] - cmp r1, r0 - bne _020AE0A0 - ldr r2, [r1, #0x4] - add r0, r1, #0x10 - add r2, r2, r0 - mov r0, r6 - str r2, [sp, #0x4] - bl RemoveMBlock - b _020AE0A0 -_020AE094: - ldr r1, [r1, #0xc] - cmp r1, #0x0 - bne _020AE060 -_020AE0A0: - cmp r4, #0x0 - beq _020AE0D4 - ldr r2, [r4, #0x4] - add r1, r4, #0x10 - ldr r0, [r5, #0x0] - add r1, r2, r1 - cmp r1, r0 - bne _020AE0D4 - mov r0, r6 - mov r1, r4 - str r4, [sp, #0x0] - bl RemoveMBlock - mov r4, r0 -_020AE0D4: - ldr r1, [sp, #0x4] - ldr r0, [sp, #0x0] - sub r0, r1, r0 - cmp r0, #0x10 - addcc sp, sp, #0x8 - movcc r0, #0x0 - ldmccia sp!, {r4-r6,pc} - ldr r1, _020AE118 ; =0x00004652 - add r0, sp, #0x0 - bl InitMBlock - mov r1, r0 - mov r0, r6 - mov r2, r4 - bl InsertMBlock - mov r0, #0x1 - add sp, sp, #0x8 - ldmia sp!, {r4-r6,pc} - .balign 4 -_020AE118: .word 0x00004652 - arm_func_end RecycleRegion diff --git a/arm9/lib/libnns/include/NNS_FND_expheap.h b/arm9/lib/libnns/include/NNS_FND_expheap.h index bdc3fcc4..acf33bd4 100644 --- a/arm9/lib/libnns/include/NNS_FND_expheap.h +++ b/arm9/lib/libnns/include/NNS_FND_expheap.h @@ -38,13 +38,13 @@ struct NNSiFndExpHeapHead u16 feature; // Attribute }; -NNSFndHeapHandle NNS_FndCreateExpHeapEx(void *startAddress, u32 size, u32 optFlag); +NNSFndHeapHandle NNS_FndCreateExpHeapEx(void *startAddress, u32 size, u16 optFlag); void *NNS_FndAllocFromExpHeapEx(NNSFndHeapHandle heap, u32 size, int alignment); void NNS_FndDestroyExpHeap(NNSFndHeapHandle heap); void NNS_FndFreeToExpHeap(NNSFndHeapHandle heap, void *memBlock); u32 NNS_FndGetTotalFreeSizeForExpHeap(NNSFndHeapHandle heap); u32 NNS_FndGetSizeForMBlockExpHeap(const void *memBlock); -void NNS_FndResizeForMBlockExpHeap(NNSFndHeapHandle heap, void *memBlock, u32 size); +u32 NNS_FndResizeForMBlockExpHeap(NNSFndHeapHandle heap, void *memBlock, u32 size); #define NNS_FndCreateExpHeap(startAddress, size) \ NNS_FndCreateExpHeapEx(startAddress, size, 0) diff --git a/arm9/lib/libnns/include/NNS_FND_heapcommon.h b/arm9/lib/libnns/include/NNS_FND_heapcommon.h index f35bf097..e3124e81 100644 --- a/arm9/lib/libnns/include/NNS_FND_heapcommon.h +++ b/arm9/lib/libnns/include/NNS_FND_heapcommon.h @@ -98,6 +98,8 @@ static inline void FillAllocMemory(NNSiFndHeapHead* pHeapHd, void* address, u32 void NNSi_FndInitHeapHead(NNSiFndHeapHead *pHead, u32 signature, void* heapStart, void* heapEnd, u16 optionFlag); +void NNSi_FndFinalizeHeap(NNSiFndHeapHead *pHead); + #define NNSi_FndRoundUp(value, alignment) (((value) + (alignment - 1)) & ~(alignment - 1)) #define NNSi_FndRoundUpPtr(ptr, alignment) ((void*)NNSi_FndRoundUp(NNSiGetUIntPtr(ptr), alignment)) diff --git a/arm9/lib/libnns/src/NNS_FND_expheap.c b/arm9/lib/libnns/src/NNS_FND_expheap.c index 31ea5fbe..15657c43 100644 --- a/arm9/lib/libnns/src/NNS_FND_expheap.c +++ b/arm9/lib/libnns/src/NNS_FND_expheap.c @@ -31,6 +31,11 @@ static inline void* GetMemPtrForMBlock(NNSiFndExpHeapMBlockHead* block) return AddU32ToPtr(block, sizeof(NNSiFndExpHeapMBlockHead));
}
+static inline void* GetMBlockHeadPtr(void* block)
+{
+ return SubU32ToPtr(block, sizeof(NNSiFndExpHeapMBlockHead));
+}
+
static inline void* GetMBlockEndAddr(NNSiFndExpHeapMBlockHead* block)
{
return AddU32ToPtr(GetMemPtrForMBlock(block), block->blockSize);
@@ -51,6 +56,11 @@ static inline NNSiFndExpHeapHead* GetExpHeapHeadPtrFromHeapHead(NNSiFndHeapHead* return AddU32ToPtr(pHHead, sizeof(NNSiFndHeapHead));
}
+static inline NNSiFndExpHeapHead* GetExpHeapHeadPtrFromHandle(NNSFndHeapHandle heap)
+{
+ return GetExpHeapHeadPtrFromHeapHead(heap);
+}
+
static inline NNSiFndHeapHead* GetHeapHeadPtrFromExpHeapHead(NNSiFndExpHeapHead* pEHHead)
{
return SubU32ToPtr(pEHHead, sizeof(NNSiFndHeapHead));
@@ -267,3 +277,109 @@ void* AllocFromTail(NNSiFndHeapHead* pHeapHd, u32 size, int alignment) return AllocUsedBlockFromFreeBlock(pExpHeapHd, pMBlkHdFound, foundMBlock, size, 1);
}
+
+BOOL RecycleRegion(NNSiFndExpHeapHead* pEHHead, const NNSiMemRegion* pRegion)
+{
+ NNSiFndExpHeapMBlockHead* pBlkPtrFree = NULL;
+ NNSiMemRegion freeRgn = *pRegion;
+ NNSiFndExpHeapMBlockHead* pBlk;
+ for (pBlk = pEHHead->mbFreeList.head; pBlk; pBlk = pBlk->pMBHeadNext)
+ {
+ if (pBlk < (NNSiFndExpHeapMBlockHead*)pRegion->start)
+ {
+ pBlkPtrFree = pBlk;
+ continue;
+ }
+ if (pBlk == pRegion->end)
+ {
+ freeRgn.end = GetMBlockEndAddr(pBlk);
+ (void)RemoveMBlock(&pEHHead->mbFreeList, pBlk);
+ }
+ break;
+ }
+ if (pBlkPtrFree && GetMBlockEndAddr(pBlkPtrFree) == pRegion->start)
+ {
+ freeRgn.start = pBlkPtrFree;
+ pBlkPtrFree = RemoveMBlock(&pEHHead->mbFreeList, pBlkPtrFree);
+ }
+ if (GetOffsetFromPtr(freeRgn.start, freeRgn.end) < sizeof(NNSiFndExpHeapMBlockHead))
+ return FALSE;
+ InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&freeRgn), pBlkPtrFree);
+ return TRUE;
+}
+
+NNSFndHeapHandle NNS_FndCreateExpHeapEx(void *startAddress, u32 size, u16 optFlag)
+{
+ void* endAddress = NNSi_FndRoundDownPtr(AddU32ToPtr(startAddress, size), 4);
+ startAddress = NNSi_FndRoundUpPtr(startAddress, 4);
+ if (NNSiGetUIntPtr(startAddress) > NNSiGetUIntPtr(endAddress) || GetOffsetFromPtr(startAddress, endAddress) < sizeof(NNSiFndHeapHead) + sizeof(NNSiFndExpHeapHead) + sizeof(NNSiFndExpHeapMBlockHead) + 4)
+ return NULL;
+ return InitExpHeap(startAddress, endAddress, optFlag);
+}
+
+void NNS_FndDestroyExpHeap(NNSFndHeapHandle handle)
+{
+ NNSi_FndFinalizeHeap(handle);
+}
+
+void* NNS_FndAllocFromExpHeapEx(NNSFndHeapHandle handle, u32 size, int alignment)
+{
+ if (size == 0)
+ size = 1;
+ size = NNSi_FndRoundUp(size, 4);
+ if (alignment >= 0)
+ return AllocFromHead(handle, size, alignment);
+ else
+ return AllocFromTail(handle, size, -alignment);
+}
+
+/*
+u32 NNS_FndResizeForMBlockExpHeap(NNSFndHeapHandle heap, void *memBlock, u32 size)
+{
+ NNSiFndExpHeapHead* pEHHead;
+ NNSiFndExpHeapMBlockHead* pMBHead;
+ pEHHead = GetExpHeapHeadPtrFromHandle(heap);
+ pMBHead = GetMBlockHeadPtr(memBlock);
+ size = NNSi_FndRoundUp(size, 4);
+ if (size == pMBHead->blockSize)
+ return size;
+ if (size > pMBHead->blockSize)
+ {
+ void* crUsedEnd = GetMBlockEndAddr(pMBHead);
+ NNSiFndExpHeapMBlockHead* block;
+ for (block = pEHHead->mbFreeList.head; block; block = block->pMBHeadNext)
+ {
+ if (block == crUsedEnd)
+ break;
+ }
+ if (!block || size > pMBHead->blockSize + sizeof(NNSiFndExpHeapMBlockHead) + block->blockSize)
+ return 0;
+
+ NNSiMemRegion rgnNewFree;
+ void* oldFreeStart;
+ NNSiFndExpHeapMBlockHead* nextBlockPrev;
+
+ GetRegionOfMBlock(&rgnNewFree, block);
+ nextBlockPrev = RemoveMBlock(&pEHHead->mbFreeList, block);
+ oldFreeStart = rgnNewFree.start;
+ rgnNewFree.start = AddU32ToPtr(memBlock, size);
+ if (GetOffsetFromPtr(rgnNewFree.start, rgnNewFree.end) < sizeof(NNSiFndExpHeapMBlockHead))
+ rgnNewFree.start = rgnNewFree.end;
+ pMBHead->blockSize = GetOffsetFromPtr(memBlock, rgnNewFree.start);
+ if (GetOffsetFromPtr(rgnNewFree.start, rgnNewFree.end) >= sizeof(NNSiFndExpHeapMBlockHead))
+ (void)InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&rgnNewFree), nextBlockPrev);
+ FillAllocMemory(heap, oldFreeStart, GetOffsetFromPtr(oldFreeStart, rgnNewFree.start));
+ }
+ else
+ {
+ NNSiMemRegion rgnNewFree;
+ const u32 oldBlockSize = pMBHead->blockSize;
+ rgnNewFree.start = AddU32ToPtr(memBlock, size);
+ rgnNewFree.end = GetMBlockEndAddr(pMBHead);
+ pMBHead->blockSize = size;
+ if (!RecycleRegion(pEHHead, &rgnNewFree))
+ pMBHead->blockSize = oldBlockSize;
+ }
+ return pMBHead->blockSize;
+}
+*/
|