diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | asm/SDK/OS/OSAlloc_asm.s | 116 | ||||
-rw-r--r-- | asm/sbss.s | 4 | ||||
-rw-r--r-- | include/SDK/OS/OSAlloc.h | 23 | ||||
-rw-r--r-- | obj_files.mk | 1 | ||||
-rw-r--r-- | src/SDK/OS/OSAlloc.c | 186 |
7 files changed, 214 insertions, 121 deletions
@@ -17,4 +17,5 @@ *.map
*.exe
build
-.idea
\ No newline at end of file +.idea
+.dump
@@ -71,7 +71,7 @@ INCLUDES := -i . -I- -i include -i include/SDK ASFLAGS := -mgekko -I include LDFLAGS := -map $(MAP) -fp hard -nodefaults -CFLAGS := -Cpp_exceptions off -proc gekko -fp hard -O4,s -nodefaults -msgstyle gcc $(INCLUDES) +CFLAGS := -Cpp_exceptions off -proc gekko -fp hard -O4,p -nodefaults -msgstyle gcc $(INCLUDES) # for postprocess.py PROCFLAGS := -fprologue-fixup=old_stack diff --git a/asm/SDK/OS/OSAlloc_asm.s b/asm/SDK/OS/OSAlloc_asm.s deleted file mode 100644 index 2826b5c..0000000 --- a/asm/SDK/OS/OSAlloc_asm.s +++ /dev/null @@ -1,116 +0,0 @@ -.include "macros.inc" - -.section .text, "ax" # 0x80006980 - 0x803E1E60 - -.global OSAllocFromHeap -OSAllocFromHeap: -/* 80269F5C 00265BBC 1C 63 00 0C */ mulli r3, r3, 0xc -/* 80269F60 00265BC0 80 AD A7 B8 */ lwz r5, lbl_8063FA78-_SDA_BASE_(r13) -/* 80269F64 00265BC4 38 04 00 3F */ addi r0, r4, 0x3f -/* 80269F68 00265BC8 7C A5 1A 14 */ add r5, r5, r3 -/* 80269F6C 00265BCC 54 04 00 34 */ rlwinm r4, r0, 0, 0, 0x1a -/* 80269F70 00265BD0 80 65 00 04 */ lwz r3, 4(r5) -/* 80269F74 00265BD4 7C 66 1B 78 */ mr r6, r3 -/* 80269F78 00265BD8 48 00 00 14 */ b lbl_80269F8C -lbl_80269F7C: -/* 80269F7C 00265BDC 80 06 00 08 */ lwz r0, 8(r6) -/* 80269F80 00265BE0 7C 04 00 00 */ cmpw r4, r0 -/* 80269F84 00265BE4 40 81 00 10 */ ble lbl_80269F94 -/* 80269F88 00265BE8 80 C6 00 04 */ lwz r6, 4(r6) -lbl_80269F8C: -/* 80269F8C 00265BEC 2C 06 00 00 */ cmpwi r6, 0 -/* 80269F90 00265BF0 40 82 FF EC */ bne lbl_80269F7C -lbl_80269F94: -/* 80269F94 00265BF4 2C 06 00 00 */ cmpwi r6, 0 -/* 80269F98 00265BF8 40 82 00 0C */ bne lbl_80269FA4 -/* 80269F9C 00265BFC 38 60 00 00 */ li r3, 0 -/* 80269FA0 00265C00 4E 80 00 20 */ blr -lbl_80269FA4: -/* 80269FA4 00265C04 80 06 00 08 */ lwz r0, 8(r6) -/* 80269FA8 00265C08 7C 04 00 50 */ subf r0, r4, r0 -/* 80269FAC 00265C0C 28 00 00 40 */ cmplwi r0, 0x40 -/* 80269FB0 00265C10 40 80 00 3C */ bge lbl_80269FEC -/* 80269FB4 00265C14 80 86 00 04 */ lwz r4, 4(r6) -/* 80269FB8 00265C18 2C 04 00 00 */ cmpwi r4, 0 -/* 80269FBC 00265C1C 41 82 00 0C */ beq lbl_80269FC8 -/* 80269FC0 00265C20 80 06 00 00 */ lwz r0, 0(r6) -/* 80269FC4 00265C24 90 04 00 00 */ stw r0, 0(r4) -lbl_80269FC8: -/* 80269FC8 00265C28 80 86 00 00 */ lwz r4, 0(r6) -/* 80269FCC 00265C2C 2C 04 00 00 */ cmpwi r4, 0 -/* 80269FD0 00265C30 40 82 00 0C */ bne lbl_80269FDC -/* 80269FD4 00265C34 80 66 00 04 */ lwz r3, 4(r6) -/* 80269FD8 00265C38 48 00 00 0C */ b lbl_80269FE4 -lbl_80269FDC: -/* 80269FDC 00265C3C 80 06 00 04 */ lwz r0, 4(r6) -/* 80269FE0 00265C40 90 04 00 04 */ stw r0, 4(r4) -lbl_80269FE4: -/* 80269FE4 00265C44 90 65 00 04 */ stw r3, 4(r5) -/* 80269FE8 00265C48 48 00 00 44 */ b lbl_8026A02C -lbl_80269FEC: -/* 80269FEC 00265C4C 90 86 00 08 */ stw r4, 8(r6) -/* 80269FF0 00265C50 7C 86 22 14 */ add r4, r6, r4 -/* 80269FF4 00265C54 90 04 00 08 */ stw r0, 8(r4) -/* 80269FF8 00265C58 80 06 00 00 */ lwz r0, 0(r6) -/* 80269FFC 00265C5C 90 04 00 00 */ stw r0, 0(r4) -/* 8026A000 00265C60 80 66 00 04 */ lwz r3, 4(r6) -/* 8026A004 00265C64 2C 03 00 00 */ cmpwi r3, 0 -/* 8026A008 00265C68 90 64 00 04 */ stw r3, 4(r4) -/* 8026A00C 00265C6C 41 82 00 08 */ beq lbl_8026A014 -/* 8026A010 00265C70 90 83 00 00 */ stw r4, 0(r3) -lbl_8026A014: -/* 8026A014 00265C74 80 64 00 00 */ lwz r3, 0(r4) -/* 8026A018 00265C78 2C 03 00 00 */ cmpwi r3, 0 -/* 8026A01C 00265C7C 41 82 00 0C */ beq lbl_8026A028 -/* 8026A020 00265C80 90 83 00 04 */ stw r4, 4(r3) -/* 8026A024 00265C84 48 00 00 08 */ b lbl_8026A02C -lbl_8026A028: -/* 8026A028 00265C88 90 85 00 04 */ stw r4, 4(r5) -lbl_8026A02C: -/* 8026A02C 00265C8C 80 65 00 08 */ lwz r3, 8(r5) -/* 8026A030 00265C90 38 00 00 00 */ li r0, 0 -/* 8026A034 00265C94 90 66 00 04 */ stw r3, 4(r6) -/* 8026A038 00265C98 2C 03 00 00 */ cmpwi r3, 0 -/* 8026A03C 00265C9C 90 06 00 00 */ stw r0, 0(r6) -/* 8026A040 00265CA0 41 82 00 08 */ beq lbl_8026A048 -/* 8026A044 00265CA4 90 C3 00 00 */ stw r6, 0(r3) -lbl_8026A048: -/* 8026A048 00265CA8 90 C5 00 08 */ stw r6, 8(r5) -/* 8026A04C 00265CAC 38 66 00 20 */ addi r3, r6, 0x20 -/* 8026A050 00265CB0 4E 80 00 20 */ blr - -.global OSFreeToHeap -OSFreeToHeap: -/* 8026A054 00265CB4 94 21 FF F0 */ stwu r1, -0x10(r1) -/* 8026A058 00265CB8 7C 08 02 A6 */ mflr r0 -/* 8026A05C 00265CBC 38 84 FF E0 */ addi r4, r4, -32 -/* 8026A060 00265CC0 90 01 00 14 */ stw r0, 0x14(r1) -/* 8026A064 00265CC4 1C 03 00 0C */ mulli r0, r3, 0xc -/* 8026A068 00265CC8 93 E1 00 0C */ stw r31, 0xc(r1) -/* 8026A06C 00265CCC 80 AD A7 B8 */ lwz r5, lbl_8063FA78-_SDA_BASE_(r13) -/* 8026A070 00265CD0 80 C4 00 04 */ lwz r6, 4(r4) -/* 8026A074 00265CD4 7F E5 02 14 */ add r31, r5, r0 -/* 8026A078 00265CD8 2C 06 00 00 */ cmpwi r6, 0 -/* 8026A07C 00265CDC 80 7F 00 08 */ lwz r3, 8(r31) -/* 8026A080 00265CE0 41 82 00 0C */ beq lbl_8026A08C -/* 8026A084 00265CE4 80 04 00 00 */ lwz r0, 0(r4) -/* 8026A088 00265CE8 90 06 00 00 */ stw r0, 0(r6) -lbl_8026A08C: -/* 8026A08C 00265CEC 80 A4 00 00 */ lwz r5, 0(r4) -/* 8026A090 00265CF0 2C 05 00 00 */ cmpwi r5, 0 -/* 8026A094 00265CF4 40 82 00 0C */ bne lbl_8026A0A0 -/* 8026A098 00265CF8 80 64 00 04 */ lwz r3, 4(r4) -/* 8026A09C 00265CFC 48 00 00 0C */ b lbl_8026A0A8 -lbl_8026A0A0: -/* 8026A0A0 00265D00 80 04 00 04 */ lwz r0, 4(r4) -/* 8026A0A4 00265D04 90 05 00 04 */ stw r0, 4(r5) -lbl_8026A0A8: -/* 8026A0A8 00265D08 90 7F 00 08 */ stw r3, 8(r31) -/* 8026A0AC 00265D0C 80 7F 00 04 */ lwz r3, 4(r31) -/* 8026A0B0 00265D10 4B FF FE 01 */ bl DLInsert -/* 8026A0B4 00265D14 90 7F 00 04 */ stw r3, 4(r31) -/* 8026A0B8 00265D18 83 E1 00 0C */ lwz r31, 0xc(r1) -/* 8026A0BC 00265D1C 80 01 00 14 */ lwz r0, 0x14(r1) -/* 8026A0C0 00265D20 7C 08 03 A6 */ mtlr r0 -/* 8026A0C4 00265D24 38 21 00 10 */ addi r1, r1, 0x10 -/* 8026A0C8 00265D28 4E 80 00 20 */ blr @@ -2529,8 +2529,8 @@ lbl_8063FA6C: .global lbl_8063FA70 lbl_8063FA70: .skip 0x8 -.global lbl_8063FA78 -lbl_8063FA78: +.global HeapArray +HeapArray: .skip 0x8 .global lbl_8063FA80 lbl_8063FA80: diff --git a/include/SDK/OS/OSAlloc.h b/include/SDK/OS/OSAlloc.h index 150a5f8..a8714eb 100644 --- a/include/SDK/OS/OSAlloc.h +++ b/include/SDK/OS/OSAlloc.h @@ -5,6 +5,13 @@ extern "C" { #endif + +#if 0 +extern volatile OSHeapHandle __OSCurrHeap; // used in OSInitAlloc +#endif + +typedef s32 OSHeapHandle; + typedef struct Cell Cell; struct Cell { @@ -13,7 +20,23 @@ struct Cell { long size; }; +typedef struct { + long size; + Cell *free; + Cell *allocated; +} HeapDesc; + +typedef struct { + volatile OSHeapHandle currentHeap; + int numHeaps; + void* arenaStart; + void* arenaEnd; + HeapDesc* heapArray; +} OSHeapInfo; + Cell *DLInsert(Cell *original, Cell *inserted); +void *OSAllocFromHeap(OSHeapHandle heap, u32 size); +void OSFreeToHeap(OSHeapHandle heap, void *ptr); #ifdef __cplusplus } diff --git a/obj_files.mk b/obj_files.mk index 51feafd..69ffa82 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -18,7 +18,6 @@ TEXT_O_FILES := \ $(BUILD_DIR)/asm/SDK/OS/OS.o \ $(BUILD_DIR)/asm/SDK/OS/OSAlarm.o \ $(BUILD_DIR)/src/SDK/OS/OSAlloc.o \ - $(BUILD_DIR)/asm/SDK/OS/OSAlloc_asm.o \ $(BUILD_DIR)/asm/SDK/OS/OSArena.o \ $(BUILD_DIR)/asm/SDK/OS/OSAudioSystem.o \ $(BUILD_DIR)/asm/SDK/OS/OSCache.o \ diff --git a/src/SDK/OS/OSAlloc.c b/src/SDK/OS/OSAlloc.c index 090233e..a60f3c0 100644 --- a/src/SDK/OS/OSAlloc.c +++ b/src/SDK/OS/OSAlloc.c @@ -1,6 +1,48 @@ #include "types.h" #include "OS/OSAlloc.h" +// TODO: move to header +typedef enum { + OS_ARENA_MAIN = 0, + OS_ARENA_MAIN_SUBPRIV = 1, + OS_ARENA_MAINEX = 2, + OS_ARENA_ITCM = 3, + OS_ARENA_DTCM = 4, + OS_ARENA_SHARED = 5, + OS_ARENA_WRAM_MAIN = 6, + OS_ARENA_WRAM_SUB = 7, + OS_ARENA_WRAM_SUBPRIV = 8, + OS_ARENA_MAX = 9 +} OSArenaId; + +#define OSi_ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1)) + +// NOTE: there is just one HeapInfo pointer in PBR, not an array +// void* OSiHeapInfo[OS_ARENA_MAX]; + +inline Cell* DLAddFront(Cell* list, Cell* cell) +{ + cell->next = list; + cell->prev = NULL; + + if (list != NULL) + list->prev = cell; + return cell; +} + +inline Cell* DLExtract(Cell* list, Cell* cell) +{ + if (cell->next) { + cell->next->prev = cell->prev; + } + if (cell->prev == NULL) { + list = cell->next; + } else { + cell->prev->next = cell->next; + } + return list; +} + Cell *DLInsert(Cell *original, Cell *inserted) { Cell *prevCell = NULL; @@ -47,3 +89,147 @@ Cell *DLInsert(Cell *original, Cell *inserted) return inserted; } + +#if 0 // not found in DOL +static u32 gUnk8063fa6c; // aligned arenaEnd, 680 + +// returned by OSInitAlloc, "base address of the new arena," +// pointer to the beginning of the real data after the heap array header, 684 +static void *gUnk8063fa70; + +// Table of heaps +static int gUnk8063fa74; // maxHeaps param of OSInitAlloc, 688 + +volatile OSHeapHandle __OSCurrHeap = -1; + +void *OSInitAlloc(void *arenaStart, void *arenaEnd, int maxHeaps) +{ + HeapArray = (HeapDesc *)arenaStart; + gUnk8063fa74 = maxHeaps; + for (int i = 0; i < gUnk8063fa74; i++) { + HeapArray[i].heapSize = -1; // -1 indicates this heap is unused + HeapArray[i].start = NULL; + HeapArray[i].freeList = NULL; + } + gUnk8063fa6c = (u32)arenaEnd & ~0x1f; + __OSCurrHeap = -1; + gUnk8063fa70 = (void *)(((u32)&HeapArray[maxHeaps] + 0x1f) & ~0x1f); + return gUnk8063fa70; +} + +OSHeapHandle OSCreateHeap(void *start, void *end) +{ + start = (void *)((u32)start + 0x1f & ~0x1f); + end = (void *)((u32)end & ~0x1f); + for (int i = 0; i < gUnk8063fa74; i++) { + if (HeapArray[i].heapSize < 0) { + HeapArray[i].heapSize = end - start; + ((Cell *)start)->prev = NULL; + ((Cell *)start)->next = NULL; + ((Cell *)start)->size = HeapArray[i].heapSize; + HeapArray[i].start = (Cell *)start; + HeapArray[i].freeList = NULL; + return i; + } + } + return -1; +} + +#endif + +// arenaStart param of OSInitAlloc, points to array of +// maxHeap HeapDescs, 68c +extern HeapDesc *HeapArray; + +#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32) +#define MINOBJSIZE (HEADERSIZE+32) + +void* OSAllocFromHeap(/*OSArenaId id,*/ OSHeapHandle heap, u32 size) { + // OSHeapInfo* heapInfo; + HeapDesc* hd; + Cell* cell; + Cell* newCell; + long leftoverSize; + + /* + OSIntrMode enabled = OS_DisableInterrupts(); + heapInfo = OSiHeapInfo[id]; + if (!heapInfo) { + (void)OS_RestoreInterrupts(enabled); + return NULL; + } + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + */ + + //hd = &heapInfo->heapArray[heap]; + hd = &HeapArray[heap]; + + size += HEADERSIZE; + size = OSi_ROUND(size, 32); + + for (cell = hd->free; cell != NULL; cell = cell->next) { + if ((long)size <= cell->size) { + break; + } + } + + if (cell == NULL) { + //(void)OS_RestoreInterrupts(enabled); + return NULL; + } + + leftoverSize = cell->size - (long)size; + if (leftoverSize < MINOBJSIZE) { + hd->free = DLExtract(hd->free, cell); + } else { + cell->size = (long)size; + + newCell = (Cell *) ((char *)cell + size); + newCell->size = leftoverSize; + + newCell->prev = cell->prev; + newCell->next = cell->next; + + if (newCell->next != NULL) { + newCell->next->prev = newCell; + } + + if (newCell->prev != NULL) { + newCell->prev->next = newCell; + } else { + hd->free = newCell; + } + } + + hd->allocated = DLAddFront(hd->allocated, cell); + + //(void)OS_RestoreInterrupts(enabled); + return (void *)((char *)cell + HEADERSIZE); +} + +void OSFreeToHeap(/*OSArenaId id,*/ OSHeapHandle heap, void* ptr) { + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + + /* + OSIntrMode enabled = OS_DisableInterrupts(); + heapInfo = OSiHeapInfo[id]; + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + */ + + cell = (Cell *) ((char *)ptr - HEADERSIZE); + //hd = &heapInfo->heapArray[heap]; + hd = &HeapArray[heap]; + + hd->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); + + //(void)OS_RestoreInterrupts(enabled); +} |