diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/nitro/consts.h | 45 | ||||
-rw-r--r-- | include/nitro/mmap.h | 45 | ||||
-rw-r--r-- | include/nitro/nitro.h | 6 | ||||
-rw-r--r-- | include/nitro/os.c | 33 | ||||
-rw-r--r-- | include/nitro/os.h | 9 | ||||
-rw-r--r-- | include/nitro/os_alloc.c | 257 | ||||
-rw-r--r-- | include/nitro/os_alloc.h | 38 | ||||
-rw-r--r-- | include/nitro/os_arena.c | 539 | ||||
-rw-r--r-- | include/nitro/os_arena.h | 41 | ||||
-rw-r--r-- | include/nitro/os_asm.h | 12 | ||||
-rw-r--r-- | include/nitro/os_asm.s | 7 | ||||
-rw-r--r-- | include/nitro/os_protectionRegion.c | 17 | ||||
-rw-r--r-- | include/nitro/os_protectionRegion.h | 47 | ||||
-rw-r--r-- | include/nitro/os_system.c | 28 | ||||
-rw-r--r-- | include/nitro/os_system.h | 44 | ||||
-rw-r--r-- | include/nitro/types.h | 10 |
16 files changed, 1144 insertions, 34 deletions
diff --git a/include/nitro/consts.h b/include/nitro/consts.h new file mode 100644 index 00000000..6fc71be2 --- /dev/null +++ b/include/nitro/consts.h @@ -0,0 +1,45 @@ +// +// Created by mart on 4/15/20. +// + +#ifndef POKEDIAMOND_CONSTS_H +#define POKEDIAMOND_CONSTS_H + +#include "mmap.h" + +#define HW_PSR_CPU_MODE_MASK 0x1f // CPU mode + +#define HW_PSR_FIQ_DISABLE 0x40 // Disable FIQ +#define HW_PSR_IRQ_DISABLE 0x80 // Disable IRQ +#define HW_PSR_IRQ_FIQ_DISABLE 0xc0 // Disable FIQ and IRQ + +#define HW_C6_PR_4KB 0x16 +#define HW_C6_PR_8KB 0x18 +#define HW_C6_PR_16KB 0x1a +#define HW_C6_PR_32KB 0x1c +#define HW_C6_PR_64KB 0x1e +#define HW_C6_PR_128KB 0x20 +#define HW_C6_PR_256KB 0x22 +#define HW_C6_PR_512KB 0x24 +#define HW_C6_PR_1MB 0x26 +#define HW_C6_PR_2MB 0x28 +#define HW_C6_PR_4MB 0x2a +#define HW_C6_PR_8MB 0x2c +#define HW_C6_PR_16MB 0x2e +#define HW_C6_PR_32MB 0x30 +#define HW_C6_PR_64MB 0x32 +#define HW_C6_PR_128MB 0x34 +#define HW_C6_PR_256MB 0x36 +#define HW_C6_PR_512MB 0x38 +#define HW_C6_PR_1GB 0x3a +#define HW_C6_PR_2GB 0x3c +#define HW_C6_PR_4GB 0x3e + +#define OS_CONSOLE_SIZE_MASK 0x00000003 +#define OS_CONSOLE_SIZE_4MB 0x00000001 + +#define OSi_GetArenaInfo() (*(OSArenaInfo*)HW_ARENA_INFO_BUF) +#define OSi_TRUNC(n, a) (((u32) (n)) & ~((a) - 1)) +#define OSi_ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1)) + +#endif //POKEDIAMOND_CONSTS_H diff --git a/include/nitro/mmap.h b/include/nitro/mmap.h new file mode 100644 index 00000000..14820c39 --- /dev/null +++ b/include/nitro/mmap.h @@ -0,0 +1,45 @@ +#ifndef NITRO_MMAP_H +#define NITRO_MMAP_H + +#include "types.h" + +extern u32 SDK_AUTOLOAD_DTCM_START[]; + +#define HW_MAIN_MEM 0x02000000 +#define HW_MAIN_MEM_SIZE 0x00400000 +#define HW_MAIN_MEM_EX_SIZE 0x00800000 +#define HW_MAIN_MEM_MAIN_SIZE 0x003E0000 +#define HW_MAIN_MEM_SHARED_SIZE 0x00001000 +#define HW_MAIN_MEM_DEBUGGER_OFFSET 0x00700000 + +#define HW_ITCM 0x01FF8000 +#define HW_ITCM_SIZE 0x00008000 + +#define HW_WRAM 0x037F8000 + +#define HW_DTCM ((u32)SDK_AUTOLOAD_DTCM_START) +#define HW_DTCM_SIZE 0x00004000 + +#define HW_CARD_ROM_HEADER_SIZE 0x00000160 +#define HW_DOWNLOAD_PARAMETER_SIZE 0x00000020 + +#define HW_ARENA_INFO_BUF (HW_MAIN_MEM + 0x007ffda0) // Arena data structure +#define HW_ROM_HEADER_BUF (HW_MAIN_MEM + 0x007ffe00) // ROM registration area data buffer +#define HW_RED_RESERVED (HW_MAIN_MEM + 0x007ff800) // Some kind of reserved data for shared memory +#define HW_MAIN_MEM_MAIN_END (HW_MAIN_MEM + HW_MAIN_MEM_MAIN_SIZE) +#define HW_MAIN_MEM_EX_END (HW_MAIN_MEM + HW_MAIN_MEM_EX_SIZE) +#define HW_MAIN_MEM_SHARED (HW_MAIN_MEM_EX_END - HW_MAIN_MEM_SHARED_SIZE) +#define HW_DTCM_SVC_STACK_END (HW_DTCM + 0x00003fc0) +#define HW_SVC_STACK_SIZE 0x00000040 +#define HW_DTCM_SVC_STACK (HW_DTCM_SVC_STACK_END - HW_SVC_STACK_SIZE) +#define HW_DTCM_IRQ_STACK_END (HW_DTCM_SVC_STACK) + +#define OSi_MAIN_ARENA_HI_DEFAULT (HW_MAIN_MEM_MAIN_END) +#define OSi_MAINEX_ARENA_HI_DEFAULT (HW_MAIN_MEM + HW_MAIN_MEM_DEBUGGER_OFFSET) +#define HW_ITCM_ARENA_HI_DEFAULT (HW_ITCM + HW_ITCM_SIZE) +#define HW_SHARED_ARENA_HI_DEFAULT (HW_RED_RESERVED - HW_CARD_ROM_HEADER_SIZE - HW_DOWNLOAD_PARAMETER_SIZE) +#define HW_SHARED_ARENA_LO_DEFAULT (HW_MAIN_MEM_SHARED) +#define OSi_WRAM_MAIN_ARENA_HI_DEFAULT (HW_WRAM) +#define OSi_WRAM_MAIN_ARENA_LO_DEFAULT (HW_WRAM) + +#endif
\ No newline at end of file diff --git a/include/nitro/nitro.h b/include/nitro/nitro.h index 017f3708..8cf603f5 100644 --- a/include/nitro/nitro.h +++ b/include/nitro/nitro.h @@ -6,8 +6,10 @@ extern "C" { #endif // Include all nitro files -#include "nitro/types.h" -#include "nitro/os.h" +#include "types.h" +#include "consts.h" +#include "os.h" +#include "mmap.h" #ifdef __cplusplus }; diff --git a/include/nitro/os.c b/include/nitro/os.c index a531740d..2531a636 100644 --- a/include/nitro/os.c +++ b/include/nitro/os.c @@ -4,6 +4,35 @@ #include "os.h" -asm void OS_GetProcMode() { +extern void PXI_Init(); +extern void OS_InitLock(); +extern void OS_InitIrqTable(); +extern void OS_SetIrqStackChecker(); +extern void OS_InitException(); +extern void MI_Init(); +extern void OS_InitVAlarm(); +extern void OSi_InitVramExclusive(); +extern void OS_InitThread(); +extern void OS_InitReset(); +extern void CTRDG_Init(); +extern void CARD_Init(); +extern void PM_Init(); + +void OS_Init(void) { + OS_InitArena(); + PXI_Init(); + OS_InitLock(); + OS_InitArenaEx(); + OS_InitIrqTable(); + OS_SetIrqStackChecker(); + OS_InitException(); + MI_Init(); + OS_InitVAlarm(); + OSi_InitVramExclusive(); + OS_InitThread(); + OS_InitReset(); + CTRDG_Init(); + CARD_Init(); + PM_Init(); +} -}
\ No newline at end of file diff --git a/include/nitro/os.h b/include/nitro/os.h index c14b2891..591d8db0 100644 --- a/include/nitro/os.h +++ b/include/nitro/os.h @@ -5,6 +5,13 @@ #ifndef POKEDIAMOND_OS_H #define POKEDIAMOND_OS_H -#include "nitro/os_asm.h" +#include "types.h" +#include "consts.h" +#include "os_protectionRegion.h" +#include "os_arena.h" +#include "os_alloc.h" +#include "os_system.h" + +void OS_Init(); #endif //POKEDIAMOND_OS_H diff --git a/include/nitro/os_alloc.c b/include/nitro/os_alloc.c new file mode 100644 index 00000000..9ba92e18 --- /dev/null +++ b/include/nitro/os_alloc.c @@ -0,0 +1,257 @@ +// +// Created by mart on 4/23/20. +// + +#include "os_alloc.h" +#include "consts.h" +#include "os_system.h" + +extern Cell* DLInsert(Cell* list, Cell* cell); +extern Cell* DLAddFront(Cell* list, Cell* cell); + +void* OSiHeapInfo[OS_ARENA_MAX] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +#ifdef MATCH_ASM +asm static Cell* DLExtract(Cell* list, Cell* cell) +{ + ldr r3, [r1, #0x4] + cmp r3, #0x0 + ldrne r2, [r1, #0x0] + strne r2, [r3, #0x0] + ldr r2, [r1, #0x0] + cmp r2, #0x0 + ldreq r0, [r1, #0x4] + ldrne r1, [r1, #0x4] + strne r1, [r2, #0x4] + bx lr +} +#else +static Cell* DLExtract(Cell* list, Cell* cell) +{ + if (cell->next) { + cell->prev = cell->next->prev; + } + if (cell->prev) { + cell->prev->next = cell->next; + return list; + } + else { + return cell->next; + } +} +#endif + +#define HEADERSIZE OSi_ROUND(sizeof(Cell), 32) +#define MINOBJSIZE (HEADERSIZE+32) + +#ifdef MATCH_ASM +asm void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void* ptr) { + stmdb sp!, {r4-r7, lr} + sub sp,sp,#0x4 + mov r7,r0 + mov r5,r1 + mov r4,r2 + bl OS_DisableInterrupts + ldr r1,=OSiHeapInfo + mov r6,r0 + ldr r0,[r1,r7,lsl #0x2] + cmp r5,#0x0 + ldrlt r5,[r0,#0x0] + ldr r1,[r0,#0x10] + mov r0,#0xc + mla r7,r5,r0,r1 + sub r4,r4,#0x20 + ldr r0,[r7,#0x8] + mov r1,r4 + bl DLExtract + str r0,[r7,#0x8] + ldr r0,[r7,#0x4] + mov r1,r4 + bl DLInsert + str r0,[r7,#0x4] + mov r0,r6 + bl OS_RestoreInterrupts + add sp,sp,#0x4 + ldmia sp!,{ r4-r7, lr } + bx lr +} +#else +void OS_FreeToHeap(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->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); + + OS_RestoreInterrupts(enabled); +} +#endif + +#ifdef MATCH_ASM +asm void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size) { + stmdb sp!, {r4-r7,lr} + sub sp, sp, #0x4 + mov r6, r0 + mov r5, r1 + mov r7, r2 + bl OS_DisableInterrupts + ldr r1, =OSiHeapInfo + mov r4, r0 + ldr r1, [r1, r6, lsl #0x2] + cmp r1, #0x0 + bne _020CC7AC + bl OS_RestoreInterrupts + add sp, sp, #0x4 + mov r0, #0x0 + ldmia sp!, {r4-r7,lr} + bx lr +_020CC7AC: + cmp r5, #0x0 + ldrlt r5, [r1, #0x0] + ldr r1, [r1, #0x10] + mov r0, #0xc + mla r6, r5, r0, r1 + ldr r0, [r6, #0x4] + add r1, r7, #0x20 + add r1, r1, #0x1f + mov r5, r0 + cmp r0, #0x0 + bic r7, r1, #0x1f + beq _020CC7F4 +_020CC7DC: + ldr r1, [r5, #0x8] + cmp r7, r1 + ble _020CC7F4 + ldr r5, [r5, #0x4] + cmp r5, #0x0 + bne _020CC7DC +_020CC7F4: + cmp r5, #0x0 + bne _020CC814 + mov r0, r4 + bl OS_RestoreInterrupts + add sp, sp, #0x4 + mov r0, #0x0 + ldmia sp!, {r4-r7,lr} + bx lr +_020CC814: + ldr r1, [r5, #0x8] + sub r1, r1, r7 + cmp r1, #0x40 + bhs _020CC834 + mov r1, r5 + bl DLExtract + str r0, [r6, #0x4] + b _020CC86C +_020CC834: + str r7, [r5, #0x8] + add r2, r5, r7 + str r1, [r2, #0x8] + ldr r0, [r5, #0x0] + str r0, [r5, r7] + ldr r0, [r5, #0x4] + str r0, [r2, #0x4] + ldr r0, [r2, #0x4] + cmp r0, #0x0 + strne r2, [r0, #0x0] + ldr r0, [r2, #0x0] + cmp r0, #0x0 + strne r2, [r0, #0x4] + streq r2, [r6, #0x4] +_020CC86C: + ldr r0, [r6, #0x8] + mov r1, r5 + bl DLAddFront + str r0, [r6, #0x8] + mov r0, r4 + bl OS_RestoreInterrupts + add r0, r5, #0x20 + add sp, sp, #0x4 + ldmia sp!, {r4-r7,lr} + bx lr +} +#else +void* OS_AllocFromHeap(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) { + OS_RestoreInterrupts(enabled); + return NULL; + } + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + hd = &heapInfo->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) { + 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); + + OS_RestoreInterrupts(enabled); + return (void *)((char *)cell + HEADERSIZE); +} +#endif
\ No newline at end of file diff --git a/include/nitro/os_alloc.h b/include/nitro/os_alloc.h new file mode 100644 index 00000000..1c4b6122 --- /dev/null +++ b/include/nitro/os_alloc.h @@ -0,0 +1,38 @@ +// +// Created by mart on 4/23/20. +// + +#ifndef POKEDIAMOND_OS_ALLOC_H +#define POKEDIAMOND_OS_ALLOC_H + +#include "types.h" +#include "os_arena.h" + +typedef int OSHeapHandle; + +typedef struct Cell Cell; + +struct Cell { + Cell* prev; + Cell* next; + 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; + +void OS_FreeToHeap(OSArenaId id, OSHeapHandle heap, void *ptr); +void* OS_AllocFromHeap(OSArenaId id, OSHeapHandle heap, u32 size); + +#endif //POKEDIAMOND_OS_ALLOC_H diff --git a/include/nitro/os_arena.c b/include/nitro/os_arena.c new file mode 100644 index 00000000..31d66289 --- /dev/null +++ b/include/nitro/os_arena.c @@ -0,0 +1,539 @@ +// +// Created by red031000 on 2020-04-27. +// + +#include "consts.h" +#include "os_arena.h" +#include "os_protectionRegion.h" + +extern u32 OS_GetConsoleType(); +extern BOOL OSi_MainExArenaEnabled; +extern BOOL OSi_Initialized; // TODO: located at 0x021d36f0 +void SDK_MAIN_ARENA_LO(); // TODO: technically this should be defined in the lcf +extern void SDK_SECTION_ARENA_EX_START(); // TODO: technically this should be defined in the lcf +extern void SDK_SECTION_ARENA_ITCM_START(); // TODO: technically this should be defined in the lcf +extern void SDK_SECTION_ARENA_DTCM_START(); // TODO: technically this should be defined in the lcf +extern void SDK_IRQ_STACKSIZE(); // TODO: technically this should be defined in the lcf +extern void SDK_SYS_STACKSIZE(); // TODO: technically this should be defined in the lcf + +#ifdef MATCH_ASM +asm void OS_InitArena() { + stmdb sp!,{ lr } + sub sp,sp,#0x4 + ldr r1, =OSi_Initialized + ldr r0,[r1,#0x0] + cmp r0,#0x0 + addne sp,sp,#0x4 + ldmneia sp!,{ lr } + bxne lr + mov r2,#0x1 + mov r0,#0x0 + str r2,[r1,#0x0] + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x0 + bl OS_SetArenaHi + mov r0,#0x0 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x0 + bl OS_SetArenaLo + mov r0,#0x2 + mov r1,#0x0 + bl OS_SetArenaLo + mov r0,#0x2 + mov r1,#0x0 + bl OS_SetArenaHi + mov r0,#0x3 + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x3 + bl OS_SetArenaHi + mov r0,#0x3 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x3 + bl OS_SetArenaLo + mov r0,#0x4 + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x4 + bl OS_SetArenaHi + mov r0,#0x4 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x4 + bl OS_SetArenaLo + mov r0,#0x5 + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x5 + bl OS_SetArenaHi + mov r0,#0x5 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x5 + bl OS_SetArenaLo + mov r0,#0x6 + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x6 + bl OS_SetArenaHi + mov r0,#0x6 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x6 + bl OS_SetArenaLo + add sp,sp,#0x4 + ldmia sp!,{ lr } + bx lr +} +#else +void OS_InitArena() { + if (OSi_Initialized) { + return; + } + OSi_Initialized = TRUE; + + OS_SetArenaHi(OS_ARENA_MAIN, OS_GetInitArenaHi(OS_ARENA_MAIN)); + OS_SetArenaLo(OS_ARENA_MAIN, OS_GetInitArenaLo(OS_ARENA_MAIN)); + + OS_SetArenaLo(OS_ARENA_MAINEX, (void *)0); + OS_SetArenaHi(OS_ARENA_MAINEX, (void *)0); + + OS_SetArenaHi(OS_ARENA_ITCM, OS_GetInitArenaHi(OS_ARENA_ITCM)); + OS_SetArenaLo(OS_ARENA_ITCM, OS_GetInitArenaLo(OS_ARENA_ITCM)); + + OS_SetArenaHi(OS_ARENA_DTCM, OS_GetInitArenaHi(OS_ARENA_DTCM)); + OS_SetArenaLo(OS_ARENA_DTCM, OS_GetInitArenaLo(OS_ARENA_DTCM)); + + OS_SetArenaHi(OS_ARENA_SHARED, OS_GetInitArenaHi(OS_ARENA_SHARED)); + OS_SetArenaLo(OS_ARENA_SHARED, OS_GetInitArenaLo(OS_ARENA_SHARED)); + + OS_SetArenaHi(OS_ARENA_WRAM_MAIN, OS_GetInitArenaHi(OS_ARENA_WRAM_MAIN)); + OS_SetArenaLo(OS_ARENA_WRAM_MAIN, OS_GetInitArenaLo(OS_ARENA_WRAM_MAIN)); +} +#endif + +#ifdef MATCH_ASM +asm void OS_InitArenaEx() { + stmdb sp!,{ lr } + sub sp,sp,#0x4 + mov r0,#0x2 + bl OS_GetInitArenaHi + mov r1,r0 + mov r0,#0x2 + bl OS_SetArenaHi + mov r0,#0x2 + bl OS_GetInitArenaLo + mov r1,r0 + mov r0,#0x2 + bl OS_SetArenaLo + ldr r0, =OSi_MainExArenaEnabled + ldr r0,[r0,#0x0] + cmp r0,#0x0 + beq _020CC5B8 + bl OS_GetConsoleType + and r0,r0,#0x3 + cmp r0,#0x1 + addne sp,sp,#0x4 + ldmneia sp!,{ lr } + bxne lr +_020CC5B8: + ldr r0, =0x0200002b + bl OS_SetProtectionRegion1 + ldr r0, =0x023e0021 + bl OS_SetProtectionRegion2 + add sp,sp,#0x4 + ldmia sp!,{ lr } + bx lr +} +#else +void OS_InitArenaEx() { + OS_SetArenaHi(2, OS_GetInitArenaHi(OS_ARENA_MAINEX)); + OS_SetArenaLo(2, OS_GetInitArenaLo(OS_ARENA_MAINEX)); + + if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) { + OS_SetProtectionRegion(1, HW_MAIN_MEM, 4MB); + OS_SetProtectionRegion(2, HW_MAIN_MEM_MAIN_END, 128KB); + } +} +#endif + +#ifdef MATCH_ASM +asm void* OS_GetArenaHi(OSArenaId id) { + mov r0,r0, lsl #0x2 + add r0,r0,#0x2700000 + add r0,r0,#0xff000 + ldr r0,[r0,#0xdc4] + bx lr +} +#else +void* OS_GetArenaHi(OSArenaId id) { + return OSi_GetArenaInfo().hi[id]; +} +#endif + +#ifdef MATCH_ASM +asm void* OS_GetArenaLo(OSArenaId id) { + mov r0,r0, lsl #0x2 + add r0,r0,#0x2700000 + add r0,r0,#0xff000 + ldr r0,[r0,#0xda0] + bx lr +} +#else +void* OS_GetArenaLo(OSArenaId id) { + return OSi_GetArenaInfo().lo[id]; +} +#endif + +#ifdef MATCH_ASM +asm void* OS_GetInitArenaHi(OSArenaId id) { + stmdb sp!, {lr} + sub sp, sp, #0x4 + cmp r0, #0x6 + addls pc, pc, r0, lsl #0x2 + b _020CC508 +_020CC41C: + b _020CC438 + b _020CC508 + b _020CC448 + b _020CC488 + b _020CC498 + b _020CC4E8 + b _020CC4F8 +_020CC438: + add sp, sp, #0x4 + ldr r0, =OSi_MAIN_ARENA_HI_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC448: + ldr r0, =OSi_MainExArenaEnabled + ldr r0, [r0] + cmp r0, #0x0 + beq _020CC468 + bl OS_GetConsoleType + and r0, r0, #0x3 + cmp r0, #0x1 + bne _020CC478 +_020CC468: + add sp, sp, #0x4 + mov r0, #0x0 + ldmfd sp!, {lr} + bx lr +_020CC478: + add sp, sp, #0x4 + mov r0, #OSi_MAINEX_ARENA_HI_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC488: + add sp, sp, #0x4 + mov r0, #HW_ITCM_ARENA_HI_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC498: + ldr r0, =0x027E0000 + ldr r1, =0x00000000 + ldr r2, =0x00000400 + add r3, r0, #0x3f80 + cmp r1, #0x0 + sub r2, r3, r2 + bne _020CC4CC + ldr r1, =0x027E0080 + add sp, sp, #0x4 + cmp r0, r1 + movcc r0, r1 + ldmfd sp!, {lr} + bx lr +_020CC4CC: + cmp r1, #0x0 + ldrlt r0, =0x027E0080 + add sp, sp, #0x4 + sublt r0, r0, r1 + subge r0, r2, r1 + ldmfd sp!, {lr} + bx lr +_020CC4E8: + add sp, sp, #0x4 + ldr r0, =HW_SHARED_ARENA_HI_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC4F8: + add sp, sp, #0x4 + ldr r0, =OSi_WRAM_MAIN_ARENA_HI_DEFAULT; + ldmfd sp!, {lr} + bx lr +_020CC508: + mov r0, #0x0 + add sp, sp, #0x4 + ldmia sp!, {lr} + bx lr +} +#else +void* OS_GetInitArenaHi(OSArenaId id) { + switch (id) { + case OS_ARENA_MAIN: + return (void *)OSi_MAIN_ARENA_HI_DEFAULT; + case OS_ARENA_MAINEX: + if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) { + return (void *)0; + } else { + return (void *)OSi_MAINEX_ARENA_HI_DEFAULT; + } + case OS_ARENA_ITCM: + return (void *)HW_ITCM_ARENA_HI_DEFAULT; + case OS_ARENA_DTCM: + u32 irqStackLo = (u32)HW_DTCM_IRQ_STACK_END - (s32)SDK_IRQ_STACKSIZE; + u32 sysStackLo; + + if (!(s32)SDK_SYS_STACKSIZE) { + sysStackLo = HW_DTCM; + if (sysStackLo < (u32)SDK_SECTION_ARENA_DTCM_START) { + sysStackLo = (u32)SDK_SECTION_ARENA_DTCM_START; + } + } + else if ((s32)SDK_SYS_STACKSIZE < 0) { + sysStackLo = (u32)SDK_SECTION_ARENA_DTCM_START - (s32)SDK_SYS_STACKSIZE; + } + else { + sysStackLo = irqStackLo - (s32)SDK_SYS_STACKSIZE; + } + return (void*)sysStackLo; + case OS_ARENA_SHARED: + return (void *)HW_SHARED_ARENA_HI_DEFAULT; + case OS_ARENA_WRAM_MAIN: + return (void *)OSi_WRAM_MAIN_ARENA_HI_DEFAULT; + default: + return NULL; + } +} +#endif + +#ifdef MATCH_ASM +asm void* OS_GetInitArenaLo(OSArenaId id) { + stmdb sp!, {lr} + sub sp, sp, #0x4 + cmp r0, #0x6 + addls pc, pc, r0, lsl #0x2 + b _020CC3DC +_020CC330: + b _020CC34C + b _020CC3DC + b _020CC35C + b _020CC39C + b _020CC3AC + b _020CC3BC + b _020CC3CC +_020CC34C: + add sp, sp, #0x4 + ldr r0, =SDK_MAIN_ARENA_LO + ldmfd sp!, {lr} + bx lr +_020CC35C: + ldr r0, =OSi_MainExArenaEnabled + ldr r0, [r0] + cmp r0, #0x0 + beq _020CC37C + bl OS_GetConsoleType + and r0, r0, #0x3 + cmp r0, #0x1 + bne _020CC38C +_020CC37C: + add sp, sp, #0x4 + mov r0, #0x0 + ldmfd sp!, {lr} + bx lr +_020CC38C: + add sp, sp, #0x4 + ldr r0, =SDK_SECTION_ARENA_EX_START + ldmfd sp!, {lr} + bx lr +_020CC39C: + add sp, sp, #0x4 + ldr r0, =SDK_SECTION_ARENA_ITCM_START + ldmfd sp!, {lr} + bx lr +_020CC3AC: + add sp, sp, #0x4 + ldr r0, =SDK_SECTION_ARENA_DTCM_START + ldmfd sp!, {lr} + bx lr +_020CC3BC: + add sp, sp, #0x4 + ldr r0, =HW_SHARED_ARENA_LO_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC3CC: + add sp, sp, #0x4 + ldr r0, =OSi_WRAM_MAIN_ARENA_LO_DEFAULT + ldmfd sp!, {lr} + bx lr +_020CC3DC: + mov r0, #0x0 + add sp, sp, #0x4 + ldmia sp!, {lr} + bx lr +} +#else +void* OS_GetInitArenaLo(OSArenaId id) { + switch (id) { + case OS_ARENA_MAIN: + return (void *)SDK_MAIN_ARENA_LO; + case OS_ARENA_MAINEX: + if (!OSi_MainExArenaEnabled || (OS_GetConsoleType() & OS_CONSOLE_SIZE_MASK) == OS_CONSOLE_SIZE_4MB) { + return NULL; + } else { + return (void *)SDK_SECTION_ARENA_EX_START; + } + case OS_ARENA_ITCM: + return (void *)SDK_SECTION_ARENA_ITCM_START; + case OS_ARENA_DTCM: + return (void *)SDK_SECTION_ARENA_DTCM_START; + case OS_ARENA_SHARED: + return (void *)HW_SHARED_ARENA_LO_DEFAULT; + case OS_ARENA_WRAM_MAIN: + return (void *)OSi_WRAM_MAIN_ARENA_LO_DEFAULT; + default: + return NULL; + } +} +#endif + +#ifdef MATCH_ASM +asm void OS_SetArenaHi(OSArenaId id, void* newHi) { + mov r0,r0, lsl #0x2 + add r0,r0,#0x2700000 + add r0,r0,#0xff000 + str r1,[r0,#0xdc4] + bx lr +} +#else +void OS_SetArenaHi(OSArenaId id, void* newHi) { + OSi_GetArenaInfo().hi[id] = newHi; +} +#endif + +#ifdef MATCH_ASM +asm void OS_SetArenaLo(OSArenaId id, void* newLo) { + mov r0,r0, lsl #0x2 + add r0,r0,#0x2700000 + add r0,r0,#0xff000 + str r1,[r0,#0xda0] + bx lr +} +#else +void OS_SetArenaLo(OSArenaId id, void* newLo) { + OSi_GetArenaInfo().lo[id] = newLo; +} +#endif + +#ifdef MATCH_ASM +asm void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) { + stmdb sp!,{ r4-r7, lr } + sub sp,sp,#0x4 + mov r7,r0 + mov r6,r1 + mov r5,r2 + bl OS_GetArenaLo + cmp r0,#0x0 + addeq sp,sp,#0x4 + moveq r0,#0x0 + ldmeqia sp!,{ r4-r7, lr } + bxeq lr + add r0,r0,r5 + sub r1,r5,#0x1 + mvn r2,r1 + sub r0,r0,#0x1 + and r4,r2,r0 + add r0,r4,r6 + add r0,r0,r5 + sub r1,r0,#0x1 + mov r0,r7 + and r5,r2,r1 + bl OS_GetArenaHi + cmp r5,r0 + addhi sp,sp,#0x4 + movhi r0,#0x0 + ldmhiia sp!,{ r4-r7, lr } + bxhi lr + mov r0,r7 + mov r1,r5 + bl OS_SetArenaLo + mov r0,r4 + add sp,sp,#0x4 + ldmia sp!,{ r4-r7, lr } + bx lr +} +#else +void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align) { + void* ptr; + u8* arenaLo; + ptr = OS_GetArenaLo(id); + if (!ptr) { + return NULL; + } + arenaLo = ptr = (void *)OSi_ROUND(ptr, align); + arenaLo += size; + arenaLo = (u8 *)OSi_ROUND(arenaLo, align); + if (arenaLo > (u8*)OS_GetArenaHi(id)) { + return NULL; + } + OS_SetArenaLo(id, arenaLo); + + return ptr; +} +#endif + +#ifdef MATCH_ASM +asm void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) { + stmdb sp!,{ r4-r6, lr } + mov r4,r0 + mov r6,r1 + mov r5,r2 + bl OS_GetArenaHi + cmp r0,#0x0 + moveq r0,#0x0 + ldmeqia sp!,{ r4-r6, lr } + bxeq lr + sub r1,r5,#0x1 + mvn r2,r1 + and r0,r0,r2 + sub r1,r0,r6 + mov r0,r4 + and r5,r1,r2 + bl OS_GetArenaLo + cmp r5,r0 + movcc r0,#0x0 + ldmccia sp!,{ r4-r6, lr } + bxcc lr + mov r0,r4 + mov r1,r5 + bl OS_SetArenaHi + mov r0,r5 + ldmia sp!,{ r4-r6, lr } + bx lr +} +#else +void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align) { + void* ptr; + u8* arenaHi; + + arenaHi = OS_GetArenaHi(id); + if (!arenaHi) { + return NULL; + } + + arenaHi = (u8 *)OSi_TRUNC(arenaHi, align); + arenaHi -= size; + arenaHi = ptr = (void *)OSi_TRUNC(arenaHi, align); + + if (arenaHi < (u8*)OS_GetArenaLo(id)) { + return NULL; + } + + OS_SetArenaHi(id, arenaHi); + + return ptr; +} +#endif
\ No newline at end of file diff --git a/include/nitro/os_arena.h b/include/nitro/os_arena.h new file mode 100644 index 00000000..f1893a3d --- /dev/null +++ b/include/nitro/os_arena.h @@ -0,0 +1,41 @@ +// +// Created by red031000 on 2020-04-27. +// + +#ifndef POKEDIAMOND_OS_ARENA_H +#define POKEDIAMOND_OS_ARENA_H + +#include "types.h" + +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; + +typedef struct { + void* lo[OS_ARENA_MAX]; + void* hi[OS_ARENA_MAX]; + u16 initialized; + u8 padding[2]; +} OSArenaInfo; + +void OS_InitArena(); +void OS_InitArenaEx(); +void* OS_GetArenaHi(OSArenaId id); +void* OS_GetArenaLo(OSArenaId id); +void* OS_GetInitArenaHi(OSArenaId id); +void* OS_GetInitArenaLo(OSArenaId id); +void OS_SetArenaHi(OSArenaId id, void *newHi); +void OS_SetArenaLo(OSArenaId id, void *newLo); +void* OS_AllocFromArenaLo(OSArenaId id, u32 size, u32 align); +void* OS_AllocFromArenaHi(OSArenaId id, u32 size, u32 align); + +#endif //POKEDIAMOND_OS_ARENA_H diff --git a/include/nitro/os_asm.h b/include/nitro/os_asm.h deleted file mode 100644 index 775955f1..00000000 --- a/include/nitro/os_asm.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by mart on 4/12/20. -// - -#ifndef POKEDIAMOND_OS_ASM_H -#define POKEDIAMOND_OS_ASM_H - -#include "nitro/types.h" - -OSProcMode OS_GetProcMode(); - -#endif //POKEDIAMOND_OS_ASM_H diff --git a/include/nitro/os_asm.s b/include/nitro/os_asm.s deleted file mode 100644 index 86d7603c..00000000 --- a/include/nitro/os_asm.s +++ /dev/null @@ -1,7 +0,0 @@ - -# TODO: make this syntax look correct in CLion -# Potentially switch to AT&T syntax? -OS_GetProcMode: - mrs r0, cpsr - and r0, r0, #0x80 - bx lr diff --git a/include/nitro/os_protectionRegion.c b/include/nitro/os_protectionRegion.c new file mode 100644 index 00000000..b70f9056 --- /dev/null +++ b/include/nitro/os_protectionRegion.c @@ -0,0 +1,17 @@ +// +// Created by red031000 on 2020-04-24. +// + +#include "os_protectionRegion.h" + +asm void OS_SetProtectionRegion1(u32 param) +{ + mcr p15, 0x0, r0, c6, c1, 0x0 + bx lr +} + +asm void OS_SetProtectionRegion2(u32 param) +{ + mcr p15, 0x0, r0, c6, c2, 0x0 + bx lr +}
\ No newline at end of file diff --git a/include/nitro/os_protectionRegion.h b/include/nitro/os_protectionRegion.h new file mode 100644 index 00000000..7b212934 --- /dev/null +++ b/include/nitro/os_protectionRegion.h @@ -0,0 +1,47 @@ +// +// Created by red031000 on 2020-04-24. +// + +#ifndef POKEDIAMOND_OS_PROTECTIONREGION_H +#define POKEDIAMOND_OS_PROTECTIONREGION_H + +#include "types.h" +#include "consts.h" + +void OS_SetProtectionRegion1(u32 param); +void OS_SetProtectionRegion2(u32 param); + +typedef enum +{ + OSi_PR_BASE_MASK_4KB = 0xfffff000, + OSi_PR_BASE_MASK_8KB = 0xffffe000, + OSi_PR_BASE_MASK_16KB = 0xffffc000, + OSi_PR_BASE_MASK_32KB = 0xffff8000, + OSi_PR_BASE_MASK_64KB = 0xffff0000, + OSi_PR_BASE_MASK_128KB = 0xfffe0000, + OSi_PR_BASE_MASK_256KB = 0xfffc0000, + OSi_PR_BASE_MASK_512KB = 0xfff80000, + OSi_PR_BASE_MASK_1MB = 0xfff00000, + OSi_PR_BASE_MASK_2MB = 0xffe00000, + OSi_PR_BASE_MASK_4MB = 0xffc00000, + OSi_PR_BASE_MASK_8MB = 0xff800000, + OSi_PR_BASE_MASK_16MB = 0xff000000, + OSi_PR_BASE_MASK_32MB = 0xfe000000, + OSi_PR_BASE_MASK_64MB = 0xfc000000, + OSi_PR_BASE_MASK_128MB = 0xf8000000, + OSi_PR_BASE_MASK_256MB = 0xf0000000, + OSi_PR_BASE_MASK_512MB = 0xe0000000, + OSi_PR_BASE_MASK_1GB = 0xc0000000, + OSi_PR_BASE_MASK_2GB = 0x80000000, + OSi_PR_BASE_MASK_4GB = 0x00000000 +} OSiProtectionRegionBaseMask; + +static inline u32 OSi_CalcPRParam(u32 address, u32 size, OSiProtectionRegionBaseMask mask) { + return ((address & mask) | size); +} + +#define OS_SetProtectionRegion(regionNo, address, sizeStr) \ + OS_SetProtectionRegion##regionNo(OSi_CalcPRParam(address, HW_C6_PR_##sizeStr, OSi_PR_BASE_MASK_##sizeStr) \ + | 1) + +#endif //POKEDIAMOND_OS_PROTECTIONREGION_H diff --git a/include/nitro/os_system.c b/include/nitro/os_system.c new file mode 100644 index 00000000..2ccb7fc1 --- /dev/null +++ b/include/nitro/os_system.c @@ -0,0 +1,28 @@ +// +// Created by mart on 4/23/20. +// + +#include "os_system.h" + +asm OSIntrMode OS_DisableInterrupts() { + mrs r0, cpsr + orr r1, r0, #HW_PSR_IRQ_DISABLE + msr cpsr_c, r1 + and r0, r0, #HW_PSR_IRQ_DISABLE + bx lr +} + +asm OSIntrMode OS_RestoreInterrupts(OSIntrMode state) { + mrs r1, cpsr + bic r2, r1, #HW_PSR_IRQ_DISABLE + orr r2, r2, r0 + msr cpsr_c, r2 + and r0, r1, #HW_PSR_IRQ_DISABLE + bx lr +} + +asm OSProcMode OS_GetProcMode() { + mrs r0, cpsr + and r0, r0, #HW_PSR_CPU_MODE_MASK + bx lr +}
\ No newline at end of file diff --git a/include/nitro/os_system.h b/include/nitro/os_system.h new file mode 100644 index 00000000..fc6a2f81 --- /dev/null +++ b/include/nitro/os_system.h @@ -0,0 +1,44 @@ +// +// Created by mart on 4/23/20. +// + +#ifndef POKEDIAMOND_OS_SYSTEM_H +#define POKEDIAMOND_OS_SYSTEM_H + +#include "consts.h" + +typedef enum { + OS_PROCMODE_USER=16, + OS_PROCMODE_FIQ=17, + OS_PROCMODE_IRQ=18, + OS_PROCMODE_SVC=19, + OS_PROCMODE_ABORT=23, + OS_PROCMODE_UNDEF=27, + OS_PROCMODE_SYS=31 +} OSProcMode; + +typedef enum { + OS_INTRMODE_IRQ_DISABLE = HW_PSR_IRQ_DISABLE, + OS_INTRMODE_IRQ_ENABLE = 0 +} OSIntrMode_Irq; + +typedef enum { + OS_INTRMODE_FIQ_DISABLE = HW_PSR_FIQ_DISABLE, + OS_INTRMODE_FIQ_ENABLE = 0 +} OSIntrMode_Fiq; + +typedef union { + OSIntrMode_Fiq mode_fiq; + OSIntrMode_Irq mode_irq; +} OSIntrMode; + +OSIntrMode OS_EnableInterrupts(); +OSIntrMode OS_DisableInterrupts(); +OSIntrMode OS_RestoreInterrupts(OSIntrMode state); +OSIntrMode OS_DisableInterrupts_IrqAndFiq(); +OSIntrMode OS_RestoreInterrupts_IrqAndFiq(OSIntrMode state); +OSIntrMode_Irq OS_GetCpsrIrq(); +OSProcMode OS_GetProcMode(); + + +#endif //POKEDIAMOND_OS_SYSTEM_H diff --git a/include/nitro/types.h b/include/nitro/types.h index d702de23..5ad2c75e 100644 --- a/include/nitro/types.h +++ b/include/nitro/types.h @@ -37,14 +37,4 @@ typedef int BOOL; #endif // __cplusplus #endif -typedef enum { - OS_PROCMODE_USER=16, - OS_PROCMODE_FIQ=17, - OS_PROCMODE_IRQ=18, - OS_PROCMODE_SVC=19, - OS_PROCMODE_ABORT=23, - OS_PROCMODE_UNDEF=27, - OS_PROCMODE_SYS=31 -} OSProcMode; - #endif //POKEDIAMOND_NITRO_TYPES_H |