From bcf0ab205d42d5653215da7b19ece57d74438417 Mon Sep 17 00:00:00 2001 From: PikalaxALT Date: Fri, 20 Aug 2021 18:46:22 -0400 Subject: AllocUsedBlockFromFreeBlock --- arm9/asm/NNS_FND_expheap_s.s | 107 +-------------------------- arm9/lib/libnns/include/NNS_FND_heapcommon.h | 9 +++ arm9/lib/libnns/src/NNS_FND_expheap.c | 73 ++++++++++++++++++ 3 files changed, 83 insertions(+), 106 deletions(-) diff --git a/arm9/asm/NNS_FND_expheap_s.s b/arm9/asm/NNS_FND_expheap_s.s index 48ec1fe4..494e3c21 100644 --- a/arm9/asm/NNS_FND_expheap_s.s +++ b/arm9/asm/NNS_FND_expheap_s.s @@ -7,6 +7,7 @@ .extern InsertMBlock .extern InitMBlock .extern InitExpHeap + .extern AllocUsedBlockFromFreeBlock .text arm_func_start NNS_FndGetSizeForMBlockExpHeap @@ -382,109 +383,3 @@ _020AE270: add sp, sp, #0x4 ldmia sp!, {r4-r9,pc} arm_func_end AllocFromHead - - arm_func_start AllocUsedBlockFromFreeBlock -AllocUsedBlockFromFreeBlock: ; 0x020AE298 - stmdb sp!, {r4-r8,lr} - sub sp, sp, #0x18 - mov r7, r0 - add r0, sp, #0x0 - mov r8, r1 - mov r6, r2 - mov r5, r3 - bl GetRegionOfMBlock - ldr r3, [sp, #0x4] - sub r4, r6, #0x10 - add r2, r5, r6 - mov r0, r7 - mov r1, r8 - str r4, [sp, #0x4] - str r3, [sp, #0xc] - str r2, [sp, #0x8] - bl RemoveMBlock - ldr r2, [sp, #0x0] - ldr r1, [sp, #0x4] - mov r5, r0 - sub r0, r1, r2 - cmp r0, #0x10 - strcc r2, [sp, #0x4] - blo _020AE318 - ldr r1, _020AE418 ; =0x00004652 - add r0, sp, #0x0 - bl InitMBlock - mov r1, r0 - mov r0, r7 - mov r2, r5 - bl InsertMBlock - mov r5, r0 -_020AE318: - ldr r1, [sp, #0xc] - ldr r0, [sp, #0x8] - sub r0, r1, r0 - cmp r0, #0x10 - strcc r1, [sp, #0x8] - blo _020AE34C - ldr r1, _020AE418 ; =0x00004652 - add r0, sp, #0x8 - bl InitMBlock - mov r1, r0 - mov r0, r7 - mov r2, r5 - bl InsertMBlock -_020AE34C: - ldr r0, [r7, #-0x4] - ldr r1, [sp, #0x4] - and r0, r0, #0xff - mov r0, r0, lsl #0x10 - ldr r2, [sp, #0x8] - mov r0, r0, lsr #0x10 - sub r2, r2, r1 - ands r0, r0, #0x1 - beq _020AE378 - mov r0, #0x0 - bl MIi_CpuClear32 -_020AE378: - ldr r2, [sp, #0x8] - ldr r1, _020AE41C ; =0x00005544 - add r0, sp, #0x10 - str r4, [sp, #0x10] - str r2, [sp, #0x14] - bl InitMBlock - mov r1, r0 - ldrh r3, [r1, #0x2] - ldrh r2, [sp, #0x30] - add r0, r7, #0x8 - bic r3, r3, #0x8000 - strh r3, [r1, #0x2] - ldrh r3, [r1, #0x2] - and r2, r2, #0x1 - orr r2, r3, r2, lsl #0xf - strh r2, [r1, #0x2] - ldrh r2, [r1, #0x2] - ldr r3, [sp, #0x4] - bic r2, r2, #0x7f00 - strh r2, [r1, #0x2] - sub r2, r1, r3 - mov r2, r2, lsl #0x10 - mov r2, r2, lsr #0x10 - ldrh r3, [r1, #0x2] - and r2, r2, #0x7f - orr r2, r3, r2, lsl #0x8 - strh r2, [r1, #0x2] - ldrh r2, [r1, #0x2] - ldrh r3, [r7, #0x10] - bic r2, r2, #0xff - strh r2, [r1, #0x2] - ldrh r2, [r1, #0x2] - and r3, r3, #0xff - orr r2, r2, r3 - strh r2, [r1, #0x2] - ldr r2, [r7, #0xc] - bl InsertMBlock - mov r0, r6 - add sp, sp, #0x18 - ldmia sp!, {r4-r8,pc} - .balign 4 -_020AE418: .word 0x00004652 -_020AE41C: .word 0x00005544 - arm_func_end AllocUsedBlockFromFreeBlock diff --git a/arm9/lib/libnns/include/NNS_FND_heapcommon.h b/arm9/lib/libnns/include/NNS_FND_heapcommon.h index 22a6bfdf..77473efe 100644 --- a/arm9/lib/libnns/include/NNS_FND_heapcommon.h +++ b/arm9/lib/libnns/include/NNS_FND_heapcommon.h @@ -2,9 +2,12 @@ #define GUARD_NNS_FND_HEAPCOMMON_H #include "NNS_FND_list.h" +#include "MI_memory.h" #define NNS_FND_HEAP_DEFAULT_ALIGNMENT 4 +#define NNS_FndGetFillValForHeap(type) (0) + typedef struct NNSiFndHeapHead NNSiFndHeapHead; typedef s32 NNSiIntPtr; @@ -87,6 +90,12 @@ static inline void SetOptForHeap( NNSi_FndSetBitValue(pHeapHd->attribute, 0, 8, optFlag); } +static inline void FillAllocMemory(NNSiFndHeapHead* pHeapHd, void* address, u32 size) +{ + if (GetOptForHeap(pHeapHd) & 1) + MI_CpuFill32(address, NNS_FndGetFillValForHeap(0), size); +} + void NNSi_FndInitHeapHead(NNSiFndHeapHead *pHead, u32 signature, void* heapStart, void* heapEnd, u16 optionFlag); #endif //GUARD_NNS_FND_HEAPCOMMON_H diff --git a/arm9/lib/libnns/src/NNS_FND_expheap.c b/arm9/lib/libnns/src/NNS_FND_expheap.c index eee4f9ca..f5a74dc4 100644 --- a/arm9/lib/libnns/src/NNS_FND_expheap.c +++ b/arm9/lib/libnns/src/NNS_FND_expheap.c @@ -11,6 +11,21 @@ static inline u16 GetAlignmentForMBlock(NNSiFndExpHeapMBlockHead* block) return NNSi_FndGetBitValue(block->attribute, 8, 7); } +static inline void SetAllocDirForMBlock(NNSiFndExpHeapMBlockHead* pEHMBHead, u16 direction) +{ + NNSi_FndSetBitValue(pEHMBHead->attribute, 15, 1, direction); +} + +static inline void SetAlignmentForMBlock(NNSiFndExpHeapMBlockHead* pEHMBHead, u16 alignment) +{ + NNSi_FndSetBitValue(pEHMBHead->attribute, 8, 7, alignment); +} + +static inline void SetGroupIDForMBlock(NNSiFndExpHeapMBlockHead* pEHMBHead, u16 groupID) +{ + NNSi_FndSetBitValue(pEHMBHead->attribute, 0, 8, groupID); +} + static inline void* GetMemPtrForMBlock(NNSiFndExpHeapMBlockHead* block) { return AddU32ToPtr(block, sizeof(NNSiFndExpHeapMBlockHead)); @@ -31,6 +46,11 @@ static inline NNSiFndExpHeapHead* GetExpHeapHeadPtrFromHeapHead(NNSiFndHeapHead* return AddU32ToPtr(pHHead, sizeof(NNSiFndHeapHead)); } +static inline NNSiFndHeapHead* GetHeapHeadPtrFromExpHeapHead(NNSiFndExpHeapHead* pEHHead) +{ + return SubU32ToPtr(pEHHead, sizeof(NNSiFndHeapHead)); +} + void GetRegionOfMBlock(NNSiMemRegion* region, NNSiFndExpHeapMBlockHead* block) { region->start = SubU32ToPtr(block, GetAlignmentForMBlock(block)); @@ -129,3 +149,56 @@ NNSiFndHeapHead* InitExpHeap(void* startAddress, void* endAddress, u16 optFlag) return pHeapHd; } + +static inline void AppendMBlock(NNSiFndExpMBlockList* list, NNSiFndExpHeapMBlockHead* block) +{ + (void) InsertMBlock(list, block, list->tail); +} + +void* AllocUsedBlockFromFreeBlock(NNSiFndExpHeapHead* pEHHead, NNSiFndExpHeapMBlockHead* pMBHeadFree, void* mblock, u32 size, u16 direction) +{ + NNSiMemRegion freeRgnT; + NNSiMemRegion freeRgnB; + NNSiFndExpHeapMBlockHead* pMBHeadFreePrev; + + GetRegionOfMBlock(&freeRgnT, pMBHeadFree); + + freeRgnB.end = freeRgnT.end; + freeRgnB.start = AddU32ToPtr(mblock, size); + freeRgnT.end = SubU32ToPtr(mblock, sizeof(NNSiFndExpHeapMBlockHead)); + + pMBHeadFreePrev = RemoveMBlock(&pEHHead->mbFreeList, pMBHeadFree); + + if (GetOffsetFromPtr(freeRgnT.start, freeRgnT.end) < sizeof(NNSiFndExpHeapMBlockHead)) + { + freeRgnT.end = freeRgnT.start; + } + else + { + pMBHeadFreePrev = InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&freeRgnT), pMBHeadFreePrev); + } + if (GetOffsetFromPtr(freeRgnB.start, freeRgnB.end) < sizeof(NNSiFndExpHeapMBlockHead)) + { + freeRgnB.start= freeRgnB.end; + } + else + { + (void)InsertMBlock(&pEHHead->mbFreeList, InitFreeMBlock(&freeRgnB), pMBHeadFreePrev); + } + + FillAllocMemory(GetHeapHeadPtrFromExpHeapHead(pEHHead), freeRgnT.end, GetOffsetFromPtr(freeRgnT.end, freeRgnB.start)); + + NNSiFndExpHeapMBlockHead* pMBHeadNewUsed; + NNSiMemRegion region; + + region.start = SubU32ToPtr(mblock, sizeof(NNSiFndExpHeapMBlockHead)); + region.end = freeRgnB.start; + + pMBHeadNewUsed = InitMBlock(®ion, 0x5544); + SetAllocDirForMBlock(pMBHeadNewUsed, direction); + SetAlignmentForMBlock(pMBHeadNewUsed, (u16)GetOffsetFromPtr(freeRgnT.end, pMBHeadNewUsed)); + SetGroupIDForMBlock(pMBHeadNewUsed, pEHHead->groupID); + AppendMBlock(&pEHHead->mbUsedList, pMBHeadNewUsed); + + return mblock; +} -- cgit v1.2.3