diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_alarm.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_alarm.inc deleted file mode 100644 index 3914e20672..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_alarm.inc +++ /dev/null @@ -1,13 +0,0 @@ -.public OSi_EnterTimerCallback -.public OS_EnableIrqMask -.public OS_DisableIrqMask -.public OSi_SetTimerReserved -.public OS_GetTick -.public OSi_SetTimer -.public OSi_InsertAlarm -.public OSi_AlarmHandler -.public OSi_ArrangeTimer -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public OS_Terminate -.public _ull_div diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_alloc.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_alloc.inc deleted file mode 100644 index 9cd02ad643..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_alloc.inc +++ /dev/null @@ -1,5 +0,0 @@ -.public DLAddFront -.public DLExtract -.public DLInsert -.public OS_DisableInterrupts -.public OS_RestoreInterrupts diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_arena.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_arena.inc deleted file mode 100644 index 9712c402ad..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_arena.inc +++ /dev/null @@ -1,9 +0,0 @@ -.public OS_GetConsoleType -.public OS_GetArenaHi -.public OS_GetArenaLo -.public OS_GetInitArenaHi -.public OS_GetInitArenaLo -.public OS_SetArenaHi -.public OS_SetArenaLo -.public OS_SetProtectionRegion1 -.public OS_SetProtectionRegion2 diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_context.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_context.inc deleted file mode 100644 index d9ebbfaf5d..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_context.inc +++ /dev/null @@ -1,2 +0,0 @@ -.public CP_SaveContext -.public CPi_RestoreContext diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_entropy.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_entropy.inc deleted file mode 100644 index 02e7486658..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_entropy.inc +++ /dev/null @@ -1 +0,0 @@ -.public OS_GetTickLo diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_exception.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_exception.inc deleted file mode 100644 index ace626cfc6..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_exception.inc +++ /dev/null @@ -1,5 +0,0 @@ -.public OS_EnableProtectionUnit -.public OSi_ExceptionHandler -.public OSi_GetAndDisplayContext -.public OSi_SetExContext -.public OSi_DisplayExContext diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_init.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_init.inc deleted file mode 100644 index bb477aab3e..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_init.inc +++ /dev/null @@ -1,16 +0,0 @@ -.public OS_InitIrqTable -.public OS_SetIrqStackChecker -.public OS_InitLock -.public OS_InitThread -.public OSi_WaitVCount0 -.public OS_InitArena -.public OS_InitArenaEx -.public OS_InitException -.public OS_InitVAlarm -.public OS_InitReset -.public OSi_InitVramExclusive -.public MI_Init -.public PXI_Init -.public PM_Init -.public CARD_Init -.public CTRDG_Init diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_interrupt.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_interrupt.inc deleted file mode 100644 index 470e8e24fe..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_interrupt.inc +++ /dev/null @@ -1 +0,0 @@ -.public OS_EnableIrqMask diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_irqhandler.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_irqhandler.inc deleted file mode 100644 index cffdfbc430..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_irqhandler.inc +++ /dev/null @@ -1,14 +0,0 @@ -.public OS_IrqHandler_ThreadSwitch -.public OSi_DoBoot -.public OSi_CpuClear32 -.public OSi_ReloadRomData -.public OSi_ReadCardRom32 -.public MIi_DmaSetParams -.public DC_InvalidateAll -.public DC_StoreAll -.public DC_WaitWriteBufferEmpty -.public IC_InvalidateAll -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public OS_SleepThread -.public MIi_CheckDma0SourceAddress diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_irqtable.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_irqtable.inc deleted file mode 100644 index 0ae6cd1469..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_irqtable.inc +++ /dev/null @@ -1,4 +0,0 @@ -.public OSi_IrqCallback -.public OS_DisableIrqMask -.public OS_IRQTable -.public OSi_IrqThreadQueue diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_message.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_message.inc deleted file mode 100644 index d73bf40d94..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_message.inc +++ /dev/null @@ -1,5 +0,0 @@ -.public OS_SleepThread -.public OS_WakeupThread -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public _s32_div_f diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_mutex.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_mutex.inc deleted file mode 100644 index e14be0a56e..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_mutex.inc +++ /dev/null @@ -1,7 +0,0 @@ -.public OSi_RemoveMutexLinkFromQueue -.public OS_SleepThread -.public OS_WakeupThread -.public OSi_EnqueueTail -.public OSi_DequeueItem -.public OS_DisableInterrupts -.public OS_RestoreInterrupts diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_ownerinfo.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_ownerinfo.inc deleted file mode 100644 index 782d724713..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_ownerinfo.inc +++ /dev/null @@ -1,2 +0,0 @@ -.public MIi_CpuCopy16 -.public MI_CpuCopy8 diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_printf.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_printf.inc deleted file mode 100644 index c1453d6a71..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_printf.inc +++ /dev/null @@ -1,3 +0,0 @@ -.public OS_VSPrintf -.public OS_VSNPrintf -.public STD_TVSNPrintf diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_reset.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_reset.inc deleted file mode 100644 index 8e002b7e03..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_reset.inc +++ /dev/null @@ -1,13 +0,0 @@ -.public OSi_DoResetSystem -.public OS_SetIrqMask -.public OS_ResetRequestIrqMask -.public OS_GetLockID -.public OSi_CommonCallback -.public OSi_SendToPxi -.public OS_Terminate -.public MI_StopDma -.public PXI_Init -.public PXI_SetFifoRecvCallback -.public PXI_IsCallbackReady -.public PXI_SendWordByFifo -.public CARD_LockRom diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_spinlock.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_spinlock.inc deleted file mode 100644 index 30a4bbe71a..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_spinlock.inc +++ /dev/null @@ -1,17 +0,0 @@ -.public SVC_WaitByLoop -.public OSi_DoLockByWord -.public OS_LockByWord -.public OSi_DoUnlockByWord -.public OS_UnlockByWord -.public OSi_DoTryLockByWord -.public OS_UnlockCartridge -.public OSi_AllocateCartridgeBus -.public OSi_FreeCartridgeBus -.public OSi_AllocateCardBus -.public OSi_FreeCardBus -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public OS_DisableInterrupts_IrqAndFiq -.public OS_RestoreInterrupts_IrqAndFiq -.public MIi_CpuClear32 -.public MI_SwapWord diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_system.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_system.inc deleted file mode 100644 index b01ff9901a..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_system.inc +++ /dev/null @@ -1,2 +0,0 @@ -.public SVC_WaitByLoop -.public OS_WaitIrq diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_terminate_proc.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_terminate_proc.inc deleted file mode 100644 index 8796c4fef4..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_terminate_proc.inc +++ /dev/null @@ -1,2 +0,0 @@ -.public OS_DisableInterrupts -.public OS_Halt diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_thread.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_thread.inc deleted file mode 100644 index 919431ae95..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_thread.inc +++ /dev/null @@ -1,38 +0,0 @@ -.public OSi_GetUnusedThreadId -.public OSi_InsertLinkToQueue -.public OSi_RemoveLinkFromQueue -.public OSi_RemoveSpecifiedLinkFromQueue -.public OSi_InsertThreadToList -.public OSi_RemoveThreadFromList -.public OSi_RescheduleThread -.public OS_CreateThread -.public OS_ExitThread -.public OSi_ExitThread_ArgSpecified -.public OSi_ExitThread -.public OSi_ExitThread_Destroy -.public OSi_CancelThreadAlarmForSleep -.public OS_SleepThread -.public OS_WakeupThread -.public OS_WakeupThreadDirect -.public OS_SelectThread -.public OS_RescheduleThread -.public OSi_SleepAlarmCallback -.public OS_SetSwitchThreadCallback -.public OSi_IdleThreadProc -.public OS_DisableScheduler -.public OS_EnableScheduler -.public OS_SetThreadDestructor -.public OS_InitContext -.public OS_SaveContext -.public OS_LoadContext -.public OSi_UnlockAllMutex -.public OS_CreateAlarm -.public OS_SetAlarm -.public OS_CancelAlarm -.public OS_EnableInterrupts -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public OS_GetProcMode -.public OS_Terminate -.public OS_Halt -.public MIi_CpuClear32 diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_tick.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_tick.inc deleted file mode 100644 index 09fb7c156a..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_tick.inc +++ /dev/null @@ -1,7 +0,0 @@ -.public OS_SetIrqFunction -.public OSi_EnterTimerCallback -.public OS_EnableIrqMask -.public OSi_SetTimerReserved -.public OSi_CountUpTick -.public OS_DisableInterrupts -.public OS_RestoreInterrupts diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_valarm.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_valarm.inc deleted file mode 100644 index 83369841bf..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_valarm.inc +++ /dev/null @@ -1 +0,0 @@ -.public OS_DisableIrqMask diff --git a/subprojects/NitroSDK/libraries/os/asm/include/os_vramexclusive.inc b/subprojects/NitroSDK/libraries/os/asm/include/os_vramexclusive.inc deleted file mode 100644 index 0a02f27cf9..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/include/os_vramexclusive.inc +++ /dev/null @@ -1,3 +0,0 @@ -.public OS_DisableInterrupts -.public OS_RestoreInterrupts -.public OsCountZeroBits diff --git a/subprojects/NitroSDK/libraries/os/asm/macros/function.inc b/subprojects/NitroSDK/libraries/os/asm/macros/function.inc deleted file mode 100644 index f71cc4ccae..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/macros/function.inc +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - - .macro arm_func_start name - .balign 4, 0 - .global \name - .type \name, @function - .arm - .endm - - .macro arm_func_end name - .size \name, .-\name - .endm - - .macro thumb_func_start name - .balign 4, 0 - .global \name - .type \name, @function - .thumb - .endm - - .macro non_word_aligned_thumb_func_start name - .global \name - .type \name, @function - .thumb - .endm - - .macro thumb_func_end name - .size \name, .-\name - .endm \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_alarm.s b/subprojects/NitroSDK/libraries/os/asm/os_alarm.s deleted file mode 100644 index 7a02f84c32..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_alarm.s +++ /dev/null @@ -1,334 +0,0 @@ - .include "macros/function.inc" - .include "include/os_alarm.inc" - - .extern Unk_021CCFC4 - .extern OS_IRQTable - - .text - - - arm_func_start OSi_SetTimer -OSi_SetTimer: ; 0x020C3930 - stmfd sp!, {r3, r4, r5, lr} - mov r4, r0 - bl OS_GetTick - ldr r3, _020C39AC ; =0x04000106 - mov r2, #0 - strh r2, [r3] - ldr ip, [r4, #0xc] - ldr r3, [r4, #0x10] - subs r5, ip, r0 - sbc r4, r3, r1 - ldr r1, _020C39B0 ; =OSi_AlarmHandler - mov r0, #1 - bl OSi_EnterTimerCallback - subs r0, r5, #0 - mov r3, #0 - sbcs r0, r4, #0 - ldrlt r3, _020C39B4 ; =0x0000FFFE - blt _020C3990 - subs r0, r5, #0x10000 - sbcs r0, r4, r3 - bge _020C3990 - mvn r0, r5 - mov r0, r0, lsl #0x10 - mov r3, r0, lsr #0x10 -_020C3990: - ldr r2, _020C39B8 ; =0x04000104 - mov r1, #0xc1 - strh r3, [r2] - mov r0, #0x10 - strh r1, [r2, #2] - bl OS_EnableIrqMask - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C39AC: .word 0x04000106 -_020C39B0: .word OSi_AlarmHandler -_020C39B4: .word 0x0000FFFE -_020C39B8: .word 0x04000104 - arm_func_end OSi_SetTimer - - arm_func_start OS_InitAlarm -OS_InitAlarm: ; 0x020C39BC - stmfd sp!, {r3, lr} - ldr r1, _020C39F8 ; =0x021CCFC4 - ldrh r0, [r1] - cmp r0, #0 - ldmneia sp!, {r3, pc} - mov r0, #1 - strh r0, [r1] - bl OSi_SetTimerReserved - ldr r1, _020C39F8 ; =0x021CCFC4 - mov r2, #0 - str r2, [r1, #4] - mov r0, #0x10 - str r2, [r1, #8] - bl OS_DisableIrqMask - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C39F8: .word Unk_021CCFC4 - arm_func_end OS_InitAlarm - - arm_func_start OS_IsAlarmAvailable -OS_IsAlarmAvailable: ; 0x020C39FC - ldr r0, _020C3A08 ; =0x021CCFC4 - ldrh r0, [r0] - bx lr - ; .align 2, 0 -_020C3A08: .word Unk_021CCFC4 - arm_func_end OS_IsAlarmAvailable - - arm_func_start OS_CreateAlarm -OS_CreateAlarm: ; 0x020C3A0C - mov r1, #0 - str r1, [r0, #0] - str r1, [r0, #8] - bx lr - arm_func_end OS_CreateAlarm - - arm_func_start OSi_InsertAlarm -OSi_InsertAlarm: ; 0x020C3A1C - stmfd sp!, {r4, r5, r6, r7, r8, lr} - mov r8, r0 - ldr r0, [r8, #0x20] - ldr r3, [r8, #0x1c] - cmp r0, #0 - mov r7, r1 - mov r6, r2 - cmpeq r3, #0 - beq _020C3A90 - bl OS_GetTick - ldr r6, [r8, #0x28] - ldr r7, [r8, #0x24] - cmp r6, r1 - cmpeq r7, r0 - bhs _020C3A90 - ldr r5, [r8, #0x1c] - ldr r4, [r8, #0x20] - subs r0, r0, r7 - mov r2, r5 - mov r3, r4 - sbc r1, r1, r6 - bl _ull_div - adds r2, r0, #1 - adc r0, r1, #0 - umull r3, r1, r5, r2 - mla r1, r5, r0, r1 - mla r1, r4, r2, r1 - adds r7, r7, r3 - adc r6, r6, r1 -_020C3A90: - str r7, [r8, #0xc] - ldr r0, _020C3B44 ; =0x021CCFC4 - str r6, [r8, #0x10] - ldr r5, [r0, #4] - cmp r5, #0 - beq _020C3B0C - mov r2, #0 - mov r1, r2 -_020C3AB0: - ldr r3, [r5, #0xc] - ldr r0, [r5, #0x10] - subs r4, r7, r3 - sbc r3, r6, r0 - subs r0, r4, r1 - sbcs r0, r3, r2 - bge _020C3B00 - ldr r0, [r5, #0x14] - str r0, [r8, #0x14] - str r8, [r5, #0x14] - str r5, [r8, #0x18] - ldr r0, [r8, #0x14] - cmp r0, #0 - strne r8, [r0, #0x18] - ldmneia sp!, {r4, r5, r6, r7, r8, pc} - ldr r1, _020C3B44 ; =0x021CCFC4 - mov r0, r8 - str r8, [r1, #4] - bl OSi_SetTimer - ldmia sp!, {r4, r5, r6, r7, r8, pc} -_020C3B00: - ldr r5, [r5, #0x18] - cmp r5, #0 - bne _020C3AB0 -_020C3B0C: - ldr r1, _020C3B44 ; =0x021CCFC4 - mov r0, #0 - str r0, [r8, #0x18] - ldr r0, [r1, #8] - str r8, [r1, #8] - str r0, [r8, #0x14] - cmp r0, #0 - strne r8, [r0, #0x18] - ldmneia sp!, {r4, r5, r6, r7, r8, pc} - str r8, [r1, #8] - mov r0, r8 - str r8, [r1, #4] - bl OSi_SetTimer - ldmia sp!, {r4, r5, r6, r7, r8, pc} - ; .align 2, 0 -_020C3B44: .word Unk_021CCFC4 - arm_func_end OSi_InsertAlarm - - arm_func_start OS_SetAlarm -OS_SetAlarm: ; 0x020C3B48 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - movs r6, r0 - mov r5, r1 - mov r4, r2 - mov r7, r3 - beq _020C3B6C - ldr r0, [r6, #0] - cmp r0, #0 - beq _020C3B70 -_020C3B6C: - bl OS_Terminate -_020C3B70: - bl OS_DisableInterrupts - mov r1, #0 - str r1, [r6, #0x1c] - str r1, [r6, #0x20] - str r7, [r6, #0] - ldr r1, [sp, #0x18] - mov r7, r0 - str r1, [r6, #4] - bl OS_GetTick - adds r3, r5, r0 - adc r2, r4, r1 - mov r0, r6 - mov r1, r3 - bl OSi_InsertAlarm - mov r0, r7 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_SetAlarm - - arm_func_start OS_CancelAlarm -OS_CancelAlarm: ; 0x020C3BB4 - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, [r5, #0] - mov r4, r0 - cmp r1, #0 - bne _020C3BD8 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, pc} -_020C3BD8: - ldr r0, [r5, #0x18] - cmp r0, #0 - ldrne r1, [r5, #0x14] - strne r1, [r0, #0x14] - bne _020C3BF8 - ldr r2, [r5, #0x14] - ldr r1, _020C3C38 ; =0x021CCFC4 - str r2, [r1, #8] -_020C3BF8: - ldr r1, [r5, #0x14] - cmp r1, #0 - strne r0, [r1, #0x18] - bne _020C3C1C - ldr r1, _020C3C38 ; =0x021CCFC4 - cmp r0, #0 - str r0, [r1, #4] - beq _020C3C1C - bl OSi_SetTimer -_020C3C1C: - mov r1, #0 - str r1, [r5, #0] - str r1, [r5, #0x1c] - mov r0, r4 - str r1, [r5, #0x20] - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C3C38: .word Unk_021CCFC4 - arm_func_end OS_CancelAlarm - - arm_func_start OSi_AlarmHandler -OSi_AlarmHandler: ; 0x020C3C3C - stmfd sp!, {r0, lr} - bl OSi_ArrangeTimer - ldmia sp!, {r0, lr} - bx lr - arm_func_end OSi_AlarmHandler - - arm_func_start OSi_ArrangeTimer -OSi_ArrangeTimer: ; 0x020C3C4C - stmfd sp!, {r3, r4, r5, lr} - ldr r1, _020C3D30 ; =0x04000106 - mov r2, #0 - mov r0, #0x10 - strh r2, [r1] - bl OS_DisableIrqMask - ldr r0, _020C3D34 ; =0x027E0000 - add r0, r0, #0x3000 - ldr r1, [r0, #0xff8] - orr r1, r1, #0x10 - str r1, [r0, #0xff8] - bl OS_GetTick - ldr r2, _020C3D38 ; =0x021CCFC4 - ldr r4, [r2, #4] - cmp r4, #0 - ldmeqia sp!, {r3, r4, r5, pc} - ldr r3, [r4, #0x10] - ldr ip, [r4, #0xc] - cmp r1, r3 - cmpeq r0, ip - bhs _020C3CAC - mov r0, r4 - bl OSi_SetTimer - ldmia sp!, {r3, r4, r5, pc} -_020C3CAC: - ldr r1, [r4, #0x18] - mov r0, #0 - str r1, [r2, #4] - cmp r1, #0 - streq r0, [r2, #8] - strne r0, [r1, #0x14] - ldr r0, [r4, #0x20] - ldr r1, [r4, #0x1c] - cmp r0, #0 - ldr r5, [r4, #0] - mov r0, #0 - cmpeq r1, #0 - streq r0, [r4] - cmp r5, #0 - beq _020C3CF0 - ldr r0, [r4, #4] - blx r5 -_020C3CF0: - ldr r0, [r4, #0x20] - ldr r1, [r4, #0x1c] - cmp r0, #0 - cmpeq r1, #0 - mov r1, #0 - beq _020C3D18 - mov r0, r4 - mov r2, r1 - str r5, [r4, #0] - bl OSi_InsertAlarm -_020C3D18: - ldr r0, _020C3D38 ; =0x021CCFC4 - ldr r0, [r0, #4] - cmp r0, #0 - ldmeqia sp!, {r3, r4, r5, pc} - bl OSi_SetTimer - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C3D30: .word 0x04000106 -_020C3D34: .word OS_IRQTable -_020C3D38: .word Unk_021CCFC4 - arm_func_end OSi_ArrangeTimer - - .bss - - - .global Unk_021CCFC4 -Unk_021CCFC4: ; 0x021CCFC4 - .space 0x2 - - .global Unk_021CCFC8 -Unk_021CCFC8: ; 0x021CCFC8 - .space 0x8 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_alloc.s b/subprojects/NitroSDK/libraries/os/asm/os_alloc.s deleted file mode 100644 index e545887552..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_alloc.s +++ /dev/null @@ -1,321 +0,0 @@ - .include "macros/function.inc" - .include "include/os_alloc.inc" - - .extern Unk_021CCEE0 - - - .text - - - arm_func_start DLAddFront -DLAddFront: ; 0x020C3128 - str r0, [r1, #4] - mov r2, #0 - str r2, [r1, #0] - cmp r0, #0 - strne r1, [r0] - mov r0, r1 - bx lr - arm_func_end DLAddFront - - arm_func_start DLExtract -DLExtract: ; 0x020C3144 - ldr r3, [r1, #4] - cmp r3, #0 - ldrne r2, [r1] - strne r2, [r3] - ldr r2, [r1, #0] - cmp r2, #0 - ldreq r0, [r1, #4] - ldrne r1, [r1, #4] - strne r1, [r2, #4] - bx lr - arm_func_end DLExtract - - arm_func_start DLInsert -DLInsert: ; 0x020C316C - stmfd sp!, {r3, lr} - mov lr, r0 - cmp r0, #0 - mov ip, #0 - beq _020C3198 -_020C3180: - cmp r1, lr - bls _020C3198 - mov ip, lr - ldr lr, [lr, #4] - cmp lr, #0 - bne _020C3180 -_020C3198: - stmia r1, {ip, lr} - cmp lr, #0 - beq _020C31D4 - str r1, [lr] - ldr r3, [r1, #8] - add r2, r1, r3 - cmp r2, lr - bne _020C31D4 - ldr r2, [lr, #8] - add r2, r3, r2 - str r2, [r1, #8] - ldr lr, [lr, #4] - str lr, [r1, #4] - cmp lr, #0 - strne r1, [lr] -_020C31D4: - cmp ip, #0 - beq _020C320C - str r1, [ip, #4] - ldr r2, [ip, #8] - add r3, ip, r2 - cmp r3, r1 - ldmneia sp!, {r3, pc} - ldr r1, [r1, #8] - cmp lr, #0 - add r1, r2, r1 - str r1, [ip, #8] - str lr, [ip, #4] - strne ip, [lr] - ldmia sp!, {r3, pc} -_020C320C: - mov r0, r1 - ldmia sp!, {r3, pc} - arm_func_end DLInsert - - arm_func_start OS_AllocFromHeap -OS_AllocFromHeap: ; 0x020C3214 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r4, r0 - mov r5, r1 - mov r7, r2 - bl OS_DisableInterrupts - ldr r1, _020C3318 ; =0x021CCEE0 - mov r6, r0 - ldr r1, [r1, r4, lsl #2] - cmp r1, #0 - bne _020C3248 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C3248: - cmp r5, #0 - ldrlt r5, [r1] - ldr r1, [r1, #0x10] - mov r0, #0xc - mla r4, r5, r0, r1 - ldr r0, [r4, #4] - add r1, r7, #0x3f - mov r5, r0 - cmp r0, #0 - bic r7, r1, #0x1f - beq _020C328C -_020C3274: - ldr r1, [r5, #8] - cmp r7, r1 - ble _020C328C - ldr r5, [r5, #4] - cmp r5, #0 - bne _020C3274 -_020C328C: - cmp r5, #0 - bne _020C32A4 - mov r0, r6 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C32A4: - ldr r1, [r5, #8] - sub r1, r1, r7 - cmp r1, #0x40 - bhs _020C32C4 - mov r1, r5 - bl DLExtract - str r0, [r4, #4] - b _020C32F8 -_020C32C4: - str r7, [r5, #8] - add r2, r5, r7 - str r1, [r2, #8] - ldr r0, [r5, #0] - str r0, [r5, r7] - ldr r0, [r5, #4] - str r0, [r2, #4] - cmp r0, #0 - strne r2, [r0] - ldr r0, [r2, #0] - cmp r0, #0 - strne r2, [r0, #4] - streq r2, [r4, #4] -_020C32F8: - ldr r0, [r4, #8] - mov r1, r5 - bl DLAddFront - str r0, [r4, #8] - mov r0, r6 - bl OS_RestoreInterrupts - add r0, r5, #0x20 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - ; .align 2, 0 -_020C3318: .word Unk_021CCEE0 - arm_func_end OS_AllocFromHeap - - arm_func_start OS_FreeToHeap -OS_FreeToHeap: ; 0x020C331C - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r7, r0 - mov r6, r1 - mov r5, r2 - bl OS_DisableInterrupts - ldr r1, _020C3380 ; =0x021CCEE0 - mov r4, r0 - ldr r0, [r1, r7, lsl #2] - cmp r6, #0 - ldrlt r6, [r0] - ldr r1, [r0, #0x10] - mov r0, #0xc - mla r7, r6, r0, r1 - sub r5, r5, #0x20 - ldr r0, [r7, #8] - mov r1, r5 - bl DLExtract - str r0, [r7, #8] - ldr r0, [r7, #4] - mov r1, r5 - bl DLInsert - str r0, [r7, #4] - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, r6, r7, pc} - ; .align 2, 0 -_020C3380: .word Unk_021CCEE0 - arm_func_end OS_FreeToHeap - - arm_func_start OS_SetCurrentHeap -OS_SetCurrentHeap: ; 0x020C3384 - stmfd sp!, {r3, r4, r5, lr} - mov r4, r0 - mov r5, r1 - bl OS_DisableInterrupts - ldr r1, _020C33B0 ; =0x021CCEE0 - ldr r1, [r1, r4, lsl #2] - ldr r4, [r1, #0] - str r5, [r1, #0] - bl OS_RestoreInterrupts - mov r0, r4 - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C33B0: .word Unk_021CCEE0 - arm_func_end OS_SetCurrentHeap - - arm_func_start OS_InitAlloc -OS_InitAlloc: ; 0x020C33B4 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r7, r0 - mov r5, r1 - mov r4, r2 - mov r6, r3 - bl OS_DisableInterrupts - ldr r2, _020C3458 ; =0x021CCEE0 - mov r1, #0xc - str r5, [r2, r7, lsl #2] - add r2, r5, #0x14 - str r2, [r5, #0x10] - mul r1, r6, r1 - str r6, [r5, #4] - cmp r6, #0 - mov lr, #0 - ble _020C3428 - mov r6, lr - mvn ip, #0 - mov r3, lr -_020C3400: - ldr r2, [r5, #0x10] - add lr, lr, #1 - str ip, [r2, r6] - add r2, r2, r6 - str r3, [r2, #8] - str r3, [r2, #4] - ldr r2, [r5, #4] - add r6, r6, #0xc - cmp lr, r2 - blt _020C3400 -_020C3428: - mvn r2, #0 - str r2, [r5, #0] - ldr r3, [r5, #0x10] - bic r2, r4, #0x1f - add r1, r3, r1 - add r1, r1, #0x1f - bic r1, r1, #0x1f - str r1, [r5, #8] - str r2, [r5, #0xc] - bl OS_RestoreInterrupts - ldr r0, [r5, #8] - ldmia sp!, {r3, r4, r5, r6, r7, pc} - ; .align 2, 0 -_020C3458: .word Unk_021CCEE0 - arm_func_end OS_InitAlloc - - arm_func_start OS_ClearAlloc -OS_ClearAlloc: ; 0x020C345C - ldr r1, _020C346C ; =0x021CCEE0 - mov r2, #0 - str r2, [r1, r0, lsl #2] - bx lr - ; .align 2, 0 -_020C346C: .word Unk_021CCEE0 - arm_func_end OS_ClearAlloc - - arm_func_start OS_CreateHeap -OS_CreateHeap: ; 0x020C3470 - stmfd sp!, {r4, r5, r6, lr} - mov r4, r0 - mov r6, r1 - mov r5, r2 - bl OS_DisableInterrupts - ldr r2, _020C3504 ; =0x021CCEE0 - add r1, r6, #0x1f - ldr r2, [r2, r4, lsl #2] - bic r6, r1, #0x1f - ldr ip, [r2, #4] - bic r5, r5, #0x1f - cmp ip, #0 - mov r4, #0 - ble _020C34F8 - ldr r3, [r2, #0x10] -_020C34AC: - ldr r1, [r3, #0] - cmp r1, #0 - bge _020C34E8 - sub r1, r5, r6 - str r1, [r3, #0] - mov r2, #0 - str r2, [r6, #0] - str r2, [r6, #4] - ldr r1, [r3, #0] - str r1, [r6, #8] - str r6, [r3, #4] - str r2, [r3, #8] - bl OS_RestoreInterrupts - mov r0, r4 - ldmia sp!, {r4, r5, r6, pc} -_020C34E8: - add r4, r4, #1 - cmp r4, ip - add r3, r3, #0xc - blt _020C34AC -_020C34F8: - bl OS_RestoreInterrupts - mvn r0, #0 - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C3504: .word Unk_021CCEE0 - arm_func_end OS_CreateHeap - - .bss - - - .global Unk_021CCEE0 -Unk_021CCEE0: ; 0x021CCEE0 - .space 0x24 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_arena.s b/subprojects/NitroSDK/libraries/os/asm/os_arena.s deleted file mode 100644 index 2a207a3836..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_arena.s +++ /dev/null @@ -1,347 +0,0 @@ - .include "macros/function.inc" - .include "include/os_arena.inc" - - .extern Unk_021CCED8 - .extern OS_IRQTable - - .text - - - arm_func_start OS_InitArena -OS_InitArena: ; 0x020C2D14 - stmfd sp!, {r3, lr} - ldr r1, _020C2E14 ; =0x021CCED8 - ldr r0, [r1, #0] - cmp r0, #0 - ldmneia sp!, {r3, pc} - mov r2, #1 - mov r0, #0 - str r2, [r1, #0] - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #0 - bl OS_SetArenaHi - mov r0, #0 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #0 - bl OS_SetArenaLo - mov r0, #2 - mov r1, #0 - bl OS_SetArenaLo - mov r0, #2 - mov r1, #0 - bl OS_SetArenaHi - mov r0, #3 - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #3 - bl OS_SetArenaHi - mov r0, #3 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #3 - bl OS_SetArenaLo - mov r0, #4 - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #4 - bl OS_SetArenaHi - mov r0, #4 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #4 - bl OS_SetArenaLo - mov r0, #5 - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #5 - bl OS_SetArenaHi - mov r0, #5 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #5 - bl OS_SetArenaLo - mov r0, #6 - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #6 - bl OS_SetArenaHi - mov r0, #6 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #6 - bl OS_SetArenaLo - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C2E14: .word Unk_021CCED8 - arm_func_end OS_InitArena - - arm_func_start OS_InitArenaEx -OS_InitArenaEx: ; 0x020C2E18 - stmfd sp!, {r3, lr} - mov r0, #2 - bl OS_GetInitArenaHi - mov r1, r0 - mov r0, #2 - bl OS_SetArenaHi - mov r0, #2 - bl OS_GetInitArenaLo - mov r1, r0 - mov r0, #2 - bl OS_SetArenaLo - ldr r0, _020C2E78 ; =0x021CCED8 - ldr r0, [r0, #4] - cmp r0, #0 - beq _020C2E64 - bl OS_GetConsoleType - and r0, r0, #3 - cmp r0, #1 - ldmneia sp!, {r3, pc} -_020C2E64: - ldr r0, _020C2E7C ; =0x0200002B - bl OS_SetProtectionRegion1 - ldr r0, _020C2E80 ; =0x023E0021 - bl OS_SetProtectionRegion2 - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C2E78: .word Unk_021CCED8 -_020C2E7C: .word 0x0200002B -_020C2E80: .word 0x023E0021 - arm_func_end OS_InitArenaEx - - arm_func_start OS_GetArenaHi -OS_GetArenaHi: ; 0x020C2E84 - mov r0, r0, lsl #2 - add r0, r0, #0x2700000 - add r0, r0, #0xff000 - ldr r0, [r0, #0xdc4] - bx lr - arm_func_end OS_GetArenaHi - - arm_func_start OS_GetArenaLo -OS_GetArenaLo: ; 0x020C2E98 - mov r0, r0, lsl #2 - add r0, r0, #0x2700000 - add r0, r0, #0xff000 - ldr r0, [r0, #0xda0] - bx lr - arm_func_end OS_GetArenaLo - - arm_func_start OS_GetInitArenaHi -OS_GetInitArenaHi: ; 0x020C2EAC - stmfd sp!, {r3, lr} - cmp r0, #6 - addls pc, pc, r0, lsl #2 - b _020C2F68 -_020C2EBC: ; jump table - b _020C2ED8 ; case 0 - b _020C2F68 ; case 1 - b _020C2EE0 ; case 2 - b _020C2F10 ; case 3 - b _020C2F18 ; case 4 - b _020C2F58 ; case 5 - b _020C2F60 ; case 6 -_020C2ED8: - ldr r0, _020C2F70 ; =0x023E0000 - ldmia sp!, {r3, pc} -_020C2EE0: - ldr r0, _020C2F74 ; =0x021CCED8 - ldr r0, [r0, #4] - cmp r0, #0 - beq _020C2F00 - bl OS_GetConsoleType - and r0, r0, #3 - cmp r0, #1 - bne _020C2F08 -_020C2F00: - mov r0, #0 - ldmia sp!, {r3, pc} -_020C2F08: - mov r0, #0x2700000 - ldmia sp!, {r3, pc} -_020C2F10: - mov r0, #0x2000000 - ldmia sp!, {r3, pc} -_020C2F18: - ldr r0, _020C2F78 ; =0x027E0000 - ldr r1, _020C2F7C ; =0x00000000 - ldr r2, _020C2F80 ; =0x00000800 - add r3, r0, #0x3f80 - cmp r1, #0 - sub r2, r3, r2 - bne _020C2F44 - ldr r1, _020C2F84 ; =0x027E0080 - cmp r0, r1 - movlo r0, r1 - ldmia sp!, {r3, pc} -_020C2F44: - cmp r1, #0 - ldrlt r0, _020C2F84 ; =0x027E0080 - sublt r0, r0, r1 - subge r0, r2, r1 - ldmia sp!, {r3, pc} -_020C2F58: - ldr r0, _020C2F88 ; =0x027FF680 - ldmia sp!, {r3, pc} -_020C2F60: - ldr r0, _020C2F8C ; =0x037F8000 - ldmia sp!, {r3, pc} -_020C2F68: - mov r0, #0 - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C2F70: .word 0x023E0000 -_020C2F74: .word Unk_021CCED8 -_020C2F78: .word OS_IRQTable -_020C2F7C: .word 0x00000000 -_020C2F80: .word 0x00000800 -_020C2F84: .word 0x027E0080 -_020C2F88: .word 0x027FF680 -_020C2F8C: .word 0x037F8000 - arm_func_end OS_GetInitArenaHi - - arm_func_start OS_GetInitArenaLo -OS_GetInitArenaLo: ; 0x020C2F90 - stmfd sp!, {r3, lr} - cmp r0, #6 - addls pc, pc, r0, lsl #2 - b _020C3014 -_020C2FA0: ; jump table - b _020C2FBC ; case 0 - b _020C3014 ; case 1 - b _020C2FC4 ; case 2 - b _020C2FF4 ; case 3 - b _020C2FFC ; case 4 - b _020C3004 ; case 5 - b _020C300C ; case 6 -_020C2FBC: - ldr r0, _020C301C ; =0x02270BC0 - ldmia sp!, {r3, pc} -_020C2FC4: - ldr r0, _020C3020 ; =0x021CCED8 - ldr r0, [r0, #4] - cmp r0, #0 - beq _020C2FE4 - bl OS_GetConsoleType - and r0, r0, #3 - cmp r0, #1 - bne _020C2FEC -_020C2FE4: - mov r0, #0 - ldmia sp!, {r3, pc} -_020C2FEC: - ldr r0, _020C3024 ; =0x023E0000 - ldmia sp!, {r3, pc} -_020C2FF4: - ldr r0, _020C3028 ; =0x01FF8680 - ldmia sp!, {r3, pc} -_020C2FFC: - ldr r0, _020C302C ; =0x027E0080 - ldmia sp!, {r3, pc} -_020C3004: - ldr r0, _020C3030 ; =0x027FF000 - ldmia sp!, {r3, pc} -_020C300C: - ldr r0, _020C3034 ; =0x037F8000 - ldmia sp!, {r3, pc} -_020C3014: - mov r0, #0 - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C301C: .word 0x02270BC0 -_020C3020: .word Unk_021CCED8 -_020C3024: .word 0x023E0000 -_020C3028: .word 0x01FF8680 -_020C302C: .word 0x027E0080 -_020C3030: .word 0x027FF000 -_020C3034: .word 0x037F8000 - arm_func_end OS_GetInitArenaLo - - arm_func_start OS_SetArenaHi -OS_SetArenaHi: ; 0x020C3038 - mov r0, r0, lsl #2 - add r0, r0, #0x2700000 - add r0, r0, #0xff000 - str r1, [r0, #0xdc4] - bx lr - arm_func_end OS_SetArenaHi - - arm_func_start OS_SetArenaLo -OS_SetArenaLo: ; 0x020C304C - mov r0, r0, lsl #2 - add r0, r0, #0x2700000 - add r0, r0, #0xff000 - str r1, [r0, #0xda0] - bx lr - arm_func_end OS_SetArenaLo - - arm_func_start OS_AllocFromArenaLo -OS_AllocFromArenaLo: ; 0x020C3060 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r7, r0 - mov r6, r1 - mov r5, r2 - bl OS_GetArenaLo - cmp r0, #0 - moveq r0, #0 - ldmeqia sp!, {r3, r4, r5, r6, r7, pc} - add r0, r0, r5 - sub r1, r5, #1 - mvn r2, r1 - sub r0, r0, #1 - and r4, r2, r0 - add r0, r4, r6 - add r0, r0, r5 - sub r1, r0, #1 - mov r0, r7 - and r5, r2, r1 - bl OS_GetArenaHi - cmp r5, r0 - movhi r0, #0 - ldmhiia sp!, {r3, r4, r5, r6, r7, pc} - mov r0, r7 - mov r1, r5 - bl OS_SetArenaLo - mov r0, r4 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_AllocFromArenaLo - - arm_func_start OS_AllocFromArenaHi -OS_AllocFromArenaHi: ; 0x020C30CC - stmfd sp!, {r4, r5, r6, lr} - mov r4, r0 - mov r6, r1 - mov r5, r2 - bl OS_GetArenaHi - cmp r0, #0 - moveq r0, #0 - ldmeqia sp!, {r4, r5, r6, pc} - sub r1, r5, #1 - mvn r2, r1 - and r0, r0, r2 - sub r1, r0, r6 - mov r0, r4 - and r5, r1, r2 - bl OS_GetArenaLo - cmp r5, r0 - movlo r0, #0 - ldmloia sp!, {r4, r5, r6, pc} - mov r0, r4 - mov r1, r5 - bl OS_SetArenaHi - mov r0, r5 - ldmia sp!, {r4, r5, r6, pc} - arm_func_end OS_AllocFromArenaHi - - .bss - - - .global Unk_021CCED8 -Unk_021CCED8: ; 0x021CCED8 - .space 0x4 - - .global Unk_021CCEDC -Unk_021CCEDC: ; 0x021CCEDC - .space 0x4 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_cache.s b/subprojects/NitroSDK/libraries/os/asm/os_cache.s deleted file mode 100644 index 899a2ce808..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_cache.s +++ /dev/null @@ -1,113 +0,0 @@ - .include "macros/function.inc" - - - - .text - - - arm_func_start DC_InvalidateAll -DC_InvalidateAll: ; 0x020C2BB0 - mov r0, #0 - mcr p15, 0, r0, c7, c6, 0 - bx lr - arm_func_end DC_InvalidateAll - - arm_func_start DC_StoreAll -DC_StoreAll: ; 0x020C2BBC - mov r1, #0 -_020C2BC0: - mov r0, #0 -_020C2BC4: - orr r2, r1, r0 - mcr p15, 0, r2, c7, c10, 2 - add r0, r0, #0x20 - cmp r0, #0x400 - blt _020C2BC4 - add r1, r1, #0x40000000 - cmp r1, #0 - bne _020C2BC0 - bx lr - arm_func_end DC_StoreAll - - arm_func_start DC_FlushAll -DC_FlushAll: ; 0x020C2BE8 - mov ip, #0 - mov r1, #0 -_020C2BF0: - mov r0, #0 -_020C2BF4: - orr r2, r1, r0 - mcr p15, 0, ip, c7, c10, 4 - mcr p15, 0, r2, c7, c14, 2 - add r0, r0, #0x20 - cmp r0, #0x400 - blt _020C2BF4 - add r1, r1, #0x40000000 - cmp r1, #0 - bne _020C2BF0 - bx lr - arm_func_end DC_FlushAll - - arm_func_start DC_InvalidateRange -DC_InvalidateRange: ; 0x020C2C1C - add r1, r1, r0 - bic r0, r0, #0x1f -_020C2C24: - mcr p15, 0, r0, c7, c6, 1 - add r0, r0, #0x20 - cmp r0, r1 - blt _020C2C24 - bx lr - arm_func_end DC_InvalidateRange - - arm_func_start DC_StoreRange -DC_StoreRange: ; 0x020C2C38 - add r1, r1, r0 - bic r0, r0, #0x1f -_020C2C40: - mcr p15, 0, r0, c7, c10, 1 - add r0, r0, #0x20 - cmp r0, r1 - blt _020C2C40 - bx lr - arm_func_end DC_StoreRange - - arm_func_start DC_FlushRange -DC_FlushRange: ; 0x020C2C54 - mov ip, #0 - add r1, r1, r0 - bic r0, r0, #0x1f -_020C2C60: - mcr p15, 0, ip, c7, c10, 4 - mcr p15, 0, r0, c7, c14, 1 - add r0, r0, #0x20 - cmp r0, r1 - blt _020C2C60 - bx lr - arm_func_end DC_FlushRange - - arm_func_start DC_WaitWriteBufferEmpty -DC_WaitWriteBufferEmpty: ; 0x020C2C78 - mov r0, #0 - mcr p15, 0, r0, c7, c10, 4 - bx lr - arm_func_end DC_WaitWriteBufferEmpty - - arm_func_start IC_InvalidateAll -IC_InvalidateAll: ; 0x020C2C84 - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 - bx lr - arm_func_end IC_InvalidateAll - - arm_func_start IC_InvalidateRange -IC_InvalidateRange: ; 0x020C2C90 - add r1, r1, r0 - bic r0, r0, #0x1f -_020C2C98: - mcr p15, 0, r0, c7, c5, 1 - add r0, r0, #0x20 - cmp r0, r1 - blt _020C2C98 - bx lr - arm_func_end IC_InvalidateRange \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_context.s b/subprojects/NitroSDK/libraries/os/asm/os_context.s deleted file mode 100644 index 6657ce3929..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_context.s +++ /dev/null @@ -1,96 +0,0 @@ - .include "macros/function.inc" - .include "include/os_context.inc" - - - - .text - - - arm_func_start OS_InitContext -OS_InitContext: ; 0x020C2614 - add r1, r1, #4 - str r1, [r0, #0x40] - str r2, [r0, #0x44] - sub r2, r2, #0x40 - tst r2, #4 - bne _020C2630 - b _020C2634 -_020C2630: - sub r2, r2, #4 -_020C2634: - str r2, [r0, #0x38] - ands r1, r1, #1 - bne _020C2644 - b _020C2648 -_020C2644: - mov r1, #0x3f -_020C2648: - beq _020C2650 - b _020C2654 -_020C2650: - mov r1, #0x1f -_020C2654: - str r1, [r0, #0] - mov r1, #0 - str r1, [r0, #4] - str r1, [r0, #8] - str r1, [r0, #0xc] - str r1, [r0, #0x10] - str r1, [r0, #0x14] - str r1, [r0, #0x18] - str r1, [r0, #0x1c] - str r1, [r0, #0x20] - str r1, [r0, #0x24] - str r1, [r0, #0x28] - str r1, [r0, #0x2c] - str r1, [r0, #0x30] - str r1, [r0, #0x34] - str r1, [r0, #0x3c] - bx lr - arm_func_end OS_InitContext - - arm_func_start OS_SaveContext -OS_SaveContext: ; 0x020C2698 - stmfd sp!, {r0, lr} - add r0, r0, #0x48 - ldr r1, _020C26E0 ; =CP_SaveContext - blx r1 - ldmia sp!, {r0, lr} - add r1, r0, #0 - mrs r2, cpsr - str r2, [r1, #0], #4 - mov r0, #0xd3 - msr cpsr_c, r0 - str sp, [r1, #0x40] - msr cpsr_c, r2 - mov r0, #1 - stmia r1, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sb, sl, fp, ip, sp, lr} - add r0, pc, #0x8 ; =_020C26E0 - str r0, [r1, #0x3c] - mov r0, #0 - bx lr - ; .align 2, 0 -_020C26E0: .word CP_SaveContext - arm_func_end OS_SaveContext - - arm_func_start OS_LoadContext -OS_LoadContext: ; 0x020C26E4 - stmfd sp!, {r0, lr} - add r0, r0, #0x48 - ldr r1, _020C2724 ; =CPi_RestoreContext - blx r1 - ldmia sp!, {r0, lr} - mrs r1, cpsr - bic r1, r1, #0x1f - orr r1, r1, #0xd3 - msr cpsr_c, r1 - ldr r1, [r0, #0], #4 - msr spsr_fsxc, r1 - ldr sp, [r0, #0x40] - ldr lr, [r0, #0x3c] - ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sb, sl, fp, ip, sp, lr} ^ - mov r0, r0 - subs pc, lr, #4 - ; .align 2, 0 -_020C2724: .word CPi_RestoreContext - arm_func_end OS_LoadContext \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_emulator.s b/subprojects/NitroSDK/libraries/os/asm/os_emulator.s deleted file mode 100644 index ebc2bc4f90..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_emulator.s +++ /dev/null @@ -1,31 +0,0 @@ - .include "macros/function.inc" - - - - .text - - - arm_func_start OS_IsRunOnEmulator -OS_IsRunOnEmulator: ; 0x020C2728 - mov r0, #0 - bx lr - arm_func_end OS_IsRunOnEmulator - - arm_func_start OS_GetConsoleType -OS_GetConsoleType: ; 0x020C2730 - ldr r0, _020C2740 ; =0x82000001 - ldr r1, _020C2744 ; =0x0210115C - str r0, [r1, #0] - bx lr - ; .align 2, 0 -_020C2740: .word 0x82000001 -_020C2744: .word Unk_0210115C - arm_func_end OS_GetConsoleType - - .data - - - .global Unk_0210115C -Unk_0210115C: ; 0x0210115C - .word 0xFFFFFFFF - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_entropy.s b/subprojects/NitroSDK/libraries/os/asm/os_entropy.s deleted file mode 100644 index 62723ffeb1..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_entropy.s +++ /dev/null @@ -1,64 +0,0 @@ - .include "macros/function.inc" - .include "include/os_entropy.inc" - - .extern Unk_021CCFBC - - .text - - - arm_func_start OS_GetLowEntropyData -OS_GetLowEntropyData: ; 0x020C41D8 - stmfd sp!, {r4, r5, r6, lr} - ldr r1, _020C4298 ; =0x04000006 - mov r5, r0 - ldrh r6, [r1] - ldr r4, _020C429C ; =0x027FFC00 - bl OS_GetTickLo - orr r0, r0, r6, lsl #16 - str r0, [r5, #0] - ldr r1, _020C42A0 ; =0x021CCFBC - ldrh ip, [r4, #0xf8] - ldr r3, [r1, #0] - ldr r2, [r1, #4] - mov r0, r4 - eor r2, r3, ip, lsl #16 - str r2, [r5, #4] - ldr r2, [r1, #0] - ldr r3, [r0, #0x3c] - ldr r2, [r1, #4] - ldr r1, [r4, #0xf4] - ldr ip, _020C42A4 ; =0x04000600 - eor r1, r2, r1 - eor r2, r3, r1 - str r2, [r5, #8] - ldr r1, [ip] - eor r1, r2, r1 - str r1, [r5, #8] - ldr r2, [r0, #0x1e8] - add r1, r0, #0x300 - str r2, [r5, #0xc] - ldr r3, [r0, #0x1ec] - sub r2, ip, #0x4d0 - str r3, [r5, #0x10] - ldr r3, [r0, #0x390] - ldrh r4, [r1, #0x94] - add r0, r0, #0x3a8 - eor r3, r3, r4, lsl #16 - str r3, [r5, #0x14] - ldrh r4, [r1, #0xaa] - ldrh r3, [r1, #0xac] - orr r3, r3, r4, lsl #16 - str r3, [r5, #0x18] - ldrh r2, [r2] - ldrh r0, [r0] - ldrh r1, [r1, #0x98] - orr r0, r2, r0 - orr r0, r0, r1, lsl #16 - str r0, [r5, #0x1c] - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C4298: .word 0x04000006 -_020C429C: .word 0x027FFC00 -_020C42A0: .word Unk_021CCFBC -_020C42A4: .word 0x04000600 - arm_func_end OS_GetLowEntropyData \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_exception.s b/subprojects/NitroSDK/libraries/os/asm/os_exception.s deleted file mode 100644 index 1daea76334..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_exception.s +++ /dev/null @@ -1,198 +0,0 @@ - .include "macros/function.inc" - .include "include/os_exception.inc" - - .extern Unk_021CCF04 - .extern Unk_021CCF08 - .extern Unk_021CCF0C - .extern Unk_021CCF30 - - - .text - - - arm_func_start OS_InitException -OS_InitException: ; 0x020C3560 - ldr r0, _020C35C0 ; =0x027FFD9C - ldr r1, [r0, #0] - cmp r1, #0x2600000 - blo _020C3580 - cmp r1, #0x2800000 - ldrlo r0, _020C35C4 ; =0x021CCF04 - strlo r1, [r0] - blo _020C358C -_020C3580: - ldr r0, _020C35C4 ; =0x021CCF04 - mov r1, #0 - str r1, [r0, #0] -_020C358C: - ldr r0, _020C35C4 ; =0x021CCF04 - ldr r0, [r0, #0] - cmp r0, #0 - bne _020C35B0 - ldr r2, _020C35C8 ; =OSi_ExceptionHandler - ldr r1, _020C35C0 ; =0x027FFD9C - ldr r0, _020C35CC ; =0x027E3000 - str r2, [r1, #0] - str r2, [r0, #0xfdc] -_020C35B0: - ldr r0, _020C35C4 ; =0x021CCF04 - mov r1, #0 - str r1, [r0, #8] - bx lr - ; .align 2, 0 -_020C35C0: .word 0x027FFD9C -_020C35C4: .word Unk_021CCF04 -_020C35C8: .word OSi_ExceptionHandler -_020C35CC: .word 0x027E3000 - arm_func_end OS_InitException - - arm_func_start OSi_ExceptionHandler -OSi_ExceptionHandler: ; 0x020C35D0 - ldr ip, _020C364C ; =0x021CCF04 - ldr ip, [ip] - cmp ip, #0 - bne _020C35E4 - b _020C35E8 -_020C35E4: - mov lr, pc -_020C35E8: - bne _020C35F0 - b _020C35F4 -_020C35F0: - bx ip -_020C35F4: - ldr ip, _020C3650 ; =SecureAreaStart - stmdb ip!, {r0, r1, r2, r3, sp, lr} - and r0, sp, #1 - mov sp, ip - mrs r1, cpsr - and r1, r1, #0x1f - teq r1, #0x17 - bne _020C361C - bl OSi_GetAndDisplayContext - b _020C3628 -_020C361C: - teq r1, #0x1b - bne _020C3628 - bl OSi_GetAndDisplayContext -_020C3628: - ldr ip, _020C364C ; =0x021CCF04 - ldr ip, [ip] - cmp ip, #0 -_020C3634: - beq _020C3634 -_020C3638: - mov r0, r0 - b _020C3638 -_020C3640: - .byte 0x0F, 0x50, 0xBD, 0xE8, 0x0C, 0xD0, 0xA0, 0xE1, 0x1E, 0xFF, 0x2F, 0xE1 -_020C364C: .word Unk_021CCF04 -_020C3650: .word 0x02000000 - arm_func_end OSi_ExceptionHandler - - arm_func_start OSi_GetAndDisplayContext -OSi_GetAndDisplayContext: ; 0x020C3654 - stmfd sp!, {r0, lr} - bl OSi_SetExContext - bl OSi_DisplayExContext - ldmia sp!, {r0, lr} - bx lr - arm_func_end OSi_GetAndDisplayContext - - arm_func_start OSi_SetExContext -OSi_SetExContext: ; 0x020C3668 - ldr r1, _020C36F4 ; =0x021CCF30 - mrs r2, cpsr - str r2, [r1, #0x74] - str r0, [r1, #0x6c] - ldr r0, [ip] - str r0, [r1, #4] - ldr r0, [ip, #4] - str r0, [r1, #8] - ldr r0, [ip, #8] - str r0, [r1, #0xc] - ldr r0, [ip, #0xc] - str r0, [r1, #0x10] - ldr r2, [ip, #0x10] - bic r2, r2, #1 - add r0, r1, #0x14 - stmia r0, {r4, r5, r6, r7, r8, sb, sl, fp} - str ip, [r1, #0x70] - ldr r0, [r2, #0] - str r0, [r1, #0x64] - ldr r3, [r2, #4] - str r3, [r1, #0] - ldr r0, [r2, #8] - str r0, [r1, #0x34] - ldr r0, [r2, #0xc] - str r0, [r1, #0x40] - mrs r0, cpsr - orr r3, r3, #0x80 - bic r3, r3, #0x20 - msr cpsr_fsxc, r3 - str sp, [r1, #0x38] - str lr, [r1, #0x3c] - mrs r2, spsr - str r2, [r1, #0x7c] - msr cpsr_fsxc, r0 - bx lr - ; .align 2, 0 -_020C36F4: .word Unk_021CCF30 - arm_func_end OSi_SetExContext - - arm_func_start OSi_DisplayExContext -OSi_DisplayExContext: ; 0x020C36F8 - stmfd sp!, {r3, lr} - ldr r0, _020C375C ; =0x021CCF04 - ldr r0, [r0, #8] - cmp r0, #0 - ldmeqia sp!, {r3, pc} - mrs r2, cpsr - mov r0, sp - ldr r1, _020C3760 ; =0x0000009F - msr cpsr_fsxc, r1 - mov r1, sp - mov sp, r0 - stmfd sp!, {r1, r2} - bl OS_EnableProtectionUnit - ldr r0, _020C3764 ; =0x021CCF30 - ldr r1, _020C3768 ; =0x021CCF08 - ldr r1, [r1, #0] - ldr ip, _020C376C ; =0x021CCF0C - ldr ip, [ip] - ldr lr, _020C3770 ; =0x020C3748 - bx ip -_020C3748: - .byte 0x77, 0xFF, 0xFF, 0xEB, 0x06, 0x00, 0xBD, 0xE8 - .byte 0x01, 0xD0, 0xA0, 0xE1, 0x02, 0xF0, 0x2F, 0xE1, 0x08, 0x80, 0xBD, 0xE8 -_020C375C: .word Unk_021CCF04 -_020C3760: .word 0x0000009F -_020C3764: .word Unk_021CCF30 -_020C3768: .word Unk_021CCF08 -_020C376C: .word Unk_021CCF0C -_020C3770: .word 0x020C3748 - arm_func_end OSi_DisplayExContext - - .bss - - - .global Unk_021CCF04 -Unk_021CCF04: ; 0x021CCF04 - .space 0x4 - - .global Unk_021CCF08 -Unk_021CCF08: ; 0x021CCF08 - .space 0x4 - - .global Unk_021CCF0C -Unk_021CCF0C: ; 0x021CCF0C - .space 0x4 - - .global Unk_021CCF10 -Unk_021CCF10: ; 0x021CCF10 - .space 0x20 - - .global Unk_021CCF30 -Unk_021CCF30: ; 0x021CCF30 - .space 0x80 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_init.s b/subprojects/NitroSDK/libraries/os/asm/os_init.s deleted file mode 100644 index 2baebafe7d..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_init.s +++ /dev/null @@ -1,42 +0,0 @@ - .include "macros/function.inc" - .include "include/os_init.inc" - - - - .text - - - arm_func_start OSi_WaitVCount0 -OSi_WaitVCount0: ; 0x020C2CAC - mov ip, #0x4000000 - ldr r1, [ip, #0x208] - str ip, [ip, #0x208] -_020C2CB8: - ldrh r0, [ip, #6] - cmp r0, #0 - bne _020C2CB8 - str r1, [ip, #0x208] - bx lr - arm_func_end OSi_WaitVCount0 - - arm_func_start OS_Init -OS_Init: ; 0x020C2CCC - stmfd sp!, {r3, lr} - bl OS_InitArena - bl PXI_Init - bl OS_InitLock - bl OS_InitArenaEx - bl OS_InitIrqTable - bl OS_SetIrqStackChecker - bl OS_InitException - bl MI_Init - bl OS_InitVAlarm - bl OSi_InitVramExclusive - bl OS_InitThread - bl OS_InitReset - bl CTRDG_Init - bl CARD_Init - bl PM_Init - bl OSi_WaitVCount0 - ldmia sp!, {r3, pc} - arm_func_end OS_Init \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_interrupt.s b/subprojects/NitroSDK/libraries/os/asm/os_interrupt.s deleted file mode 100644 index c3110deae6..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_interrupt.s +++ /dev/null @@ -1,239 +0,0 @@ - .include "macros/function.inc" - .include "include/os_interrupt.inc" - - .extern OS_IRQTable - .extern OSi_IrqThreadQueue - .extern Unk_021CCBF8 - - - .text - - - arm_func_start OS_InitIrqTable -OS_InitIrqTable: ; 0x020C1434 - ldr r0, _020C1448 ; =0x027E0060 - mov r1, #0 - str r1, [r0, #4] - str r1, [r0, #0] - bx lr - ; .align 2, 0 -_020C1448: .word OSi_IrqThreadQueue - arm_func_end OS_InitIrqTable - - arm_func_start OS_SetIrqFunction -OS_SetIrqFunction: ; 0x020C144C - stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr} - mov r8, #0 - mov r2, #0xc - ldr r4, _020C14CC ; =0x027E0000 - ldr r6, _020C14D0 ; =0x021CCBF8 - mov r7, r8 - mov lr, r8 - mov ip, #1 - mov r3, r2 -_020C1470: - tst r0, #1 - beq _020C14B8 - mov sb, r7 - cmp r8, #8 - blt _020C1494 - cmp r8, #0xb - suble r5, r8, #8 - mlale sb, r5, r3, r6 - ble _020C14B0 -_020C1494: - cmp r8, #3 - blt _020C14AC - cmp r8, #6 - addle r5, r8, #1 - mlale sb, r5, r2, r6 - ble _020C14B0 -_020C14AC: - str r1, [r4, r8, lsl #2] -_020C14B0: - cmp sb, #0 - stmneia sb, {r1, ip, lr} -_020C14B8: - add r8, r8, #1 - cmp r8, #0x16 - mov r0, r0, lsr #1 - blt _020C1470 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} - ; .align 2, 0 -_020C14CC: .word OS_IRQTable -_020C14D0: .word Unk_021CCBF8 - arm_func_end OS_SetIrqFunction - - arm_func_start OS_GetIrqFunction -OS_GetIrqFunction: ; 0x020C14D4 - ldr r2, _020C1558 ; =0x027E0000 - mov r1, #0 -_020C14DC: - tst r0, #1 - beq _020C153C - cmp r1, #8 - blt _020C150C - cmp r1, #0xb - bgt _020C150C - sub r1, r1, #8 - mov r0, #0xc - mul r2, r1, r0 - ldr r0, _020C155C ; =0x021CCBF8 - ldr r0, [r0, r2] - bx lr -_020C150C: - cmp r1, #3 - blt _020C1534 - cmp r1, #6 - bgt _020C1534 - add r1, r1, #1 - mov r0, #0xc - mul r2, r1, r0 - ldr r0, _020C155C ; =0x021CCBF8 - ldr r0, [r0, r2] - bx lr -_020C1534: - ldr r0, [r2, #0] - bx lr -_020C153C: - add r1, r1, #1 - cmp r1, #0x16 - mov r0, r0, lsr #1 - add r2, r2, #4 - blt _020C14DC - mov r0, #0 - bx lr - ; .align 2, 0 -_020C1558: .word OS_IRQTable -_020C155C: .word Unk_021CCBF8 - arm_func_end OS_GetIrqFunction - - arm_func_start OSi_EnterDmaCallback -OSi_EnterDmaCallback: ; 0x020C1560 - stmfd sp!, {r4, r5, r6, lr} - mov r3, #0xc - mul r6, r0, r3 - ldr ip, _020C159C ; =0x021CCBF8 - add r4, r0, #8 - mov r5, #1 - mov r0, r5, lsl r4 - ldr r3, _020C15A0 ; =0x021CCC00 - str r1, [ip, r6] - str r2, [r3, r6] - bl OS_EnableIrqMask - and r1, r0, r5, lsl r4 - ldr r0, _020C15A4 ; =0x021CCBFC - str r1, [r0, r6] - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C159C: .word Unk_021CCBF8 -_020C15A0: .word 0x021CCC00 -_020C15A4: .word 0x021CCBFC - arm_func_end OSi_EnterDmaCallback - - arm_func_start OSi_EnterTimerCallback -OSi_EnterTimerCallback: ; 0x020C15A8 - stmfd sp!, {r4, lr} - mov r3, #0xc - mul r4, r0, r3 - ldr ip, _020C15E4 ; =0x021CCC28 - add r0, r0, #3 - mov r3, #1 - mov r0, r3, lsl r0 - ldr r3, _020C15E8 ; =0x021CCC30 - str r1, [ip, r4] - str r2, [r3, r4] - bl OS_EnableIrqMask - ldr r0, _020C15EC ; =0x021CCC2C - mov r1, #1 - str r1, [r0, r4] - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C15E4: .word 0x021CCC28 -_020C15E8: .word 0x021CCC30 -_020C15EC: .word 0x021CCC2C - arm_func_end OSi_EnterTimerCallback - - arm_func_start OS_SetIrqMask -OS_SetIrqMask: ; 0x020C15F0 - ldr r3, _020C1618 ; =0x04000208 - mov r1, #0 - ldrh r2, [r3] - strh r1, [r3] - ldr r1, [r3, #8] - str r0, [r3, #8] - ldrh r0, [r3] - mov r0, r1 - strh r2, [r3] - bx lr - ; .align 2, 0 -_020C1618: .word 0x04000208 - arm_func_end OS_SetIrqMask - - arm_func_start OS_EnableIrqMask -OS_EnableIrqMask: ; 0x020C161C - ldr r3, _020C1648 ; =0x04000208 - mov r1, #0 - ldrh r2, [r3] - strh r1, [r3] - ldr r1, [r3, #8] - orr r0, r1, r0 - str r0, [r3, #8] - ldrh r0, [r3] - mov r0, r1 - strh r2, [r3] - bx lr - ; .align 2, 0 -_020C1648: .word 0x04000208 - arm_func_end OS_EnableIrqMask - - arm_func_start OS_DisableIrqMask -OS_DisableIrqMask: ; 0x020C164C - ldr ip, _020C1678 ; =0x04000208 - mov r2, #0 - ldrh r3, [ip] - mvn r1, r0 - strh r2, [ip] - ldr r0, [ip, #8] - and r1, r0, r1 - str r1, [ip, #8] - ldrh r1, [ip] - strh r3, [ip] - bx lr - ; .align 2, 0 -_020C1678: .word 0x04000208 - arm_func_end OS_DisableIrqMask - - arm_func_start OS_ResetRequestIrqMask -OS_ResetRequestIrqMask: ; 0x020C167C - ldr r3, _020C16A4 ; =0x04000208 - mov r1, #0 - ldrh r2, [r3] - strh r1, [r3] - ldr r1, [r3, #0xc] - str r0, [r3, #0xc] - ldrh r0, [r3] - mov r0, r1 - strh r2, [r3] - bx lr - ; .align 2, 0 -_020C16A4: .word 0x04000208 - arm_func_end OS_ResetRequestIrqMask - - arm_func_start OS_SetIrqStackChecker -OS_SetIrqStackChecker: ; 0x020C16A8 - ldr ip, _020C16CC ; =0x027E0000 - ldr r3, _020C16D0 ; =0xFDDB597D - add r0, ip, #0x3000 - ldr r2, _020C16D4 ; =0x7BF9DD5B - ldr r1, _020C16D8 ; =0x00000800 - str r3, [r0, #0xf7c] - add r0, ip, #0x3f80 - str r2, [r0, -r1] - bx lr - ; .align 2, 0 -_020C16CC: .word OS_IRQTable -_020C16D0: .word 0xFDDB597D -_020C16D4: .word 0x7BF9DD5B -_020C16D8: .word 0x00000800 - arm_func_end OS_SetIrqStackChecker \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_irqhandler.s b/subprojects/NitroSDK/libraries/os/asm/os_irqhandler.s deleted file mode 100644 index 9998143487..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_irqhandler.s +++ /dev/null @@ -1,403 +0,0 @@ - .include "macros/function.inc" - .include "include/os_irqhandler.inc" - - .extern OSi_ThreadInfo - .extern Unk_021CCFE4 - .extern OS_IRQTable - .extern OSi_IrqThreadQueue - - .text - - arm_func_start OS_WaitIrq -OS_WaitIrq: ; 0x020C12B4 - stmfd sp!, {r4, r5, r6, lr} - mov r5, r0 - mov r4, r1 - bl OS_DisableInterrupts - cmp r5, #0 - beq _020C12E4 - ldr r1, _020C1320 ; =0x027E0000 - mvn r2, r4 - add r1, r1, #0x3000 - ldr r3, [r1, #0xff8] - and r2, r3, r2 - str r2, [r1, #0xff8] -_020C12E4: - bl OS_RestoreInterrupts - ldr r1, _020C1320 ; =0x027E0000 - add r0, r1, #0x3000 - ldr r0, [r0, #0xff8] - tst r4, r0 - ldmneia sp!, {r4, r5, r6, pc} - add r0, r1, #0x3f8 - ldr r5, _020C1324 ; =0x027E0060 - add r6, r0, #0x3c00 -_020C1308: - mov r0, r5 - bl OS_SleepThread - ldr r0, [r6, #0] - tst r4, r0 - beq _020C1308 - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C1320: .word OS_IRQTable -_020C1324: .word OSi_IrqThreadQueue - arm_func_end OS_WaitIrq - - - .section .itcm,4,1,4 - - arm_func_start OS_IrqHandler -OS_IrqHandler: ; 0x01FF8000 - stmdb sp!, {lr} - mov ip, #0x4000000 - add ip, ip, #0x210 - ldr r1, [ip, #-8] - cmp r1, #0 - beq _01FF801C - b _01FF8020 -_01FF801C: - ldmia sp!, {pc} -_01FF8020: - ldmia ip, {r1, r2} - ands r1, r1, r2 - beq _01FF8030 - b _01FF8034 -_01FF8030: - ldmia sp!, {pc} -_01FF8034: - mov r3, #-0x80000000 -_01FF8038: - clz r0, r1 - bics r1, r1, r3, lsr r0 - bne _01FF8038 - mov r1, r3, lsr r0 - str r1, [ip, #4] - rsbs r0, r0, #0x1f - ldr r1, _01FF8060 ; =0x027E0000 - ldr r0, [r1, r0, lsl #2] - ldr lr, _01FF8064 ; =OS_IrqHandler_ThreadSwitch - bx r0 - ; .align 2, 0 -_01FF8060: .word OS_IRQTable -_01FF8064: .word OS_IrqHandler_ThreadSwitch - arm_func_end OS_IrqHandler - - arm_func_start OS_IrqHandler_ThreadSwitch -OS_IrqHandler_ThreadSwitch: ; 0x01FF8068 - ldr ip, _01FF81D4 ; =0x027E0060 - mov r3, #0 - ldr ip, [ip] - mov r2, #1 - cmp ip, #0 - beq _01FF80B8 -_01FF8080: - str r2, [ip, #0x64] - str r3, [ip, #0x78] - str r3, [ip, #0x7c] - ldr r0, [ip, #0x80] - str r3, [ip, #0x80] - mov ip, r0 - cmp ip, #0 - bne _01FF8080 - ldr ip, _01FF81D4 ; =0x027E0060 - str r3, [ip] - str r3, [ip, #4] - ldr ip, _01FF81D8 ; =0x021CCC80 - mov r1, #1 - strh r1, [ip] -_01FF80B8: - ldr ip, _01FF81D8 ; =0x021CCC80 - ldrh r1, [ip] - cmp r1, #0 - beq _01FF80CC - b _01FF80D0 -_01FF80CC: - ldr pc, [sp], #4 -_01FF80D0: - mov r1, #0 - strh r1, [ip] - mov r3, #0xd2 - msr cpsr_c, r3 - add r2, ip, #8 - ldr r1, [r2, #0] -_01FF80E8: - cmp r1, #0 - bne _01FF80F4 - b _01FF80F8 -_01FF80F4: - ldrh r0, [r1, #0x64] -_01FF80F8: - bne _01FF8100 - b _01FF8104 -_01FF8100: - cmp r0, #1 -_01FF8104: - bne _01FF810C - b _01FF8110 -_01FF810C: - ldr r1, [r1, #0x68] -_01FF8110: - bne _01FF80E8 - cmp r1, #0 - bne _01FF8128 -_01FF811C: - mov r3, #0x92 - msr cpsr_c, r3 - ldr pc, [sp], #4 -_01FF8128: - ldr r0, [ip, #4] - cmp r1, r0 - beq _01FF811C - ldr r3, [ip, #0xc] - cmp r3, #0 - beq _01FF8150 - stmfd sp!, {r0, r1, ip} - mov lr, pc - bx r3 -_01FF814C: - .byte 0x03, 0x10, 0xBD, 0xE8 -_01FF8150: - str r1, [ip, #4] - mrs r2, spsr - str r2, [r0, #0]! - stmfd sp!, {r0, r1} - add r0, r0, #0 - add r0, r0, #0x48 - ldr r1, _01FF81DC ; =0x020C99FC - blx r1 - ldmia sp!, {r0, r1} - ldmib sp!, {r2, r3} - stmib r0!, {r2, r3} - ldmib sp!, {r2, r3, ip, lr} - stmib r0!, {r2, r3, r4, r5, r6, r7, r8, sb, sl, fp, ip, sp, lr} ^ - stmib r0!, {lr} - mov r3, #0xd3 - msr cpsr_c, r3 - stmib r0!, {sp} - stmdb sp!, {r1} - add r0, r1, #0 - add r0, r0, #0x48 - ldr r1, _01FF81E0 ; =0x020C9A3C - blx r1 - ldmia sp!, {r1} - ldr sp, [r1, #0x44] - mov r3, #0xd2 - msr cpsr_c, r3 - ldr r2, [r1, #0]! - msr spsr_fc, r2 - ldr lr, [r1, #0x40] - ldmib r1, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sb, sl, fp, ip, sp, lr} ^ - mov r0, r0 - stmda sp!, {r0, r1, r2, r3, ip, lr} - ldmia sp!, {pc} - ; .align 2, 0 -_01FF81D4: .word OSi_IrqThreadQueue -_01FF81D8: .word OSi_ThreadInfo -_01FF81DC: .word 0x020C99FC -_01FF81E0: .word 0x020C9A3C - arm_func_end OS_IrqHandler_ThreadSwitch - - arm_func_start OSi_DoResetSystem -OSi_DoResetSystem: ; 0x01FF81E4 - stmfd sp!, {r3, lr} - ldr r0, _01FF8210 ; =0x021CCFE4 -_01FF81EC: - ldrh r1, [r0] - cmp r1, #0 - beq _01FF81EC - ldr r0, _01FF8214 ; =0x04000208 - mov r1, #0 - strh r1, [r0] - bl OSi_ReloadRomData - bl OSi_DoBoot - ldmia sp!, {r3, pc} - ; .align 2, 0 -_01FF8210: .word Unk_021CCFE4 -_01FF8214: .word 0x04000208 - arm_func_end OSi_DoResetSystem - - arm_func_start OSi_DoBoot -OSi_DoBoot: ; 0x01FF8218 - mov ip, #0x4000000 - str ip, [ip, #0x208] - ldr r1, _01FF82C4 ; =0x027E0000 - add r1, r1, #0x3fc0 - add r1, r1, #0x3c - mov r0, #0 - str r0, [r1, #0] - ldr r1, _01FF82C8 ; =0x04000180 -_01FF8238: - ldrh r0, [r1] - and r0, r0, #0xf - cmp r0, #1 - bne _01FF8238 - mov r0, #0x100 - strh r0, [r1] - mov r0, #0 - ldr r3, _01FF82CC ; =0x027FFD9C - ldr r4, [r3, #0] - ldr r1, _01FF82D0 ; =0x027FFD80 - mov r2, #0x80 - bl OSi_CpuClear32 - str r4, [r3, #0] - ldr r1, _01FF82D4 ; =0x027FFF80 - mov r2, #0x18 - bl OSi_CpuClear32 - ldr r1, _01FF82D8 ; =0x027FFF98 - strh r0, [r1] - ldr r1, _01FF82DC ; =0x027FFF9C - mov r2, #0x64 - bl OSi_CpuClear32 - ldr r1, _01FF82C8 ; =0x04000180 -_01FF8290: - ldrh r0, [r1] - and r0, r0, #0xf - cmp r0, #1 - beq _01FF8290 - mov r0, #0 - strh r0, [r1] - ldr r3, _01FF82E0 ; =0x027FFE00 - ldr ip, [r3, #0x24] - mov lr, ip - ldr fp, _01FF82D4 ; =0x027FFF80 - ldmia fp, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sb, sl} - mov fp, #0 - bx ip - ; .align 2, 0 -_01FF82C4: .word OS_IRQTable -_01FF82C8: .word 0x04000180 -_01FF82CC: .word 0x027FFD9C -_01FF82D0: .word 0x027FFD80 -_01FF82D4: .word 0x027FFF80 -_01FF82D8: .word 0x027FFF98 -_01FF82DC: .word 0x027FFF9C -_01FF82E0: .word 0x027FFE00 - arm_func_end OSi_DoBoot - - arm_func_start OSi_CpuClear32 -OSi_CpuClear32: ; 0x01FF82E4 - add ip, r1, r2 -_01FF82E8: - cmp r1, ip - blt _01FF82F4 - b _01FF82F8 -_01FF82F4: - stmia r1!, {r0} -_01FF82F8: - blt _01FF82E8 - bx lr - arm_func_end OSi_CpuClear32 - - arm_func_start OSi_ReloadRomData -OSi_ReloadRomData: ; 0x01FF8300 - stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, lr} - ldr r1, _01FF83A0 ; =0x027FFC2C - ldr r4, [r1, #0] - cmp r4, #0x8000 - blo _01FF8324 - mov r0, r4 - add r1, r1, #0x1d4 - mov r2, #0x160 - bl OSi_ReadCardRom32 -_01FF8324: - ldr r0, _01FF83A4 ; =0x027FFE20 - ldr r5, [r0, #0] - ldr r6, [r0, #8] - ldr r7, [r0, #0xc] - ldr r8, [r0, #0x10] - ldr sb, [r0, #0x18] - ldr sl, [r0, #0x1c] - bl OS_DisableInterrupts - mov fp, r0 - bl DC_StoreAll - bl DC_InvalidateAll - mov r0, fp - bl OS_RestoreInterrupts - bl IC_InvalidateAll - bl DC_WaitWriteBufferEmpty - add r5, r5, r4 - cmp r5, #0x8000 - bhs _01FF837C - rsb r0, r5, #0x8000 - add r6, r6, r0 - sub r7, r7, r0 - mov r5, #0x8000 -_01FF837C: - mov r0, r5 - mov r1, r6 - mov r2, r7 - bl OSi_ReadCardRom32 - mov r1, sb - mov r2, sl - add r0, r8, r4 - bl OSi_ReadCardRom32 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, sl, fp, pc} - ; .align 2, 0 -_01FF83A0: .word 0x027FFC2C -_01FF83A4: .word 0x027FFE20 - arm_func_end OSi_ReloadRomData - - arm_func_start OSi_ReadCardRom32 -OSi_ReadCardRom32: ; 0x01FF83A8 - stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr} - ldr r4, _01FF846C ; =0x027FFE60 - ldr r3, _01FF8470 ; =0x000001FF - ldr r5, [r4, #0] - and r4, r0, r3 - bic r3, r5, #0x7000000 - ldr r5, _01FF8474 ; =0x040001A4 - orr r3, r3, #0xa1000000 - rsb ip, r4, #0 -_01FF83CC: - ldr r4, [r5, #0] - tst r4, #-0x80000000 - bne _01FF83CC - ldr r7, _01FF8478 ; =0x040001A1 - mov r4, #0x80 - strb r4, [r7] - cmp ip, r2 - add r0, r0, ip - ldmgeia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} - ldr r4, _01FF847C ; =0x04100010 - mov sb, r0, lsr #8 - mov r6, #0xb7 - mov r5, #0 -_01FF8400: - strb r6, [r7, #7] - mov lr, r0, lsr #0x18 - strb lr, [r7, #8] - mov lr, r0, lsr #0x10 - strb lr, [r7, #9] - strb sb, [r7, #0xa] - strb r0, [r7, #0xb] - strb r5, [r7, #0xc] - strb r5, [r7, #0xd] - strb r5, [r7, #0xe] - str r3, [r7, #3] -_01FF842C: - ldr r8, [r7, #3] - tst r8, #0x800000 - beq _01FF8450 - cmp ip, #0 - ldr lr, [r4] - blt _01FF844C - cmp ip, r2 - strlt lr, [r1, ip] -_01FF844C: - add ip, ip, #4 -_01FF8450: - tst r8, #-0x80000000 - bne _01FF842C - cmp ip, r2 - add sb, sb, #2 - add r0, r0, #0x200 - blt _01FF8400 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} - ; .align 2, 0 -_01FF846C: .word 0x027FFE60 -_01FF8470: .word 0x000001FF -_01FF8474: .word 0x040001A4 -_01FF8478: .word 0x040001A1 -_01FF847C: .word 0x04100010 - arm_func_end OSi_ReadCardRom32 diff --git a/subprojects/NitroSDK/libraries/os/asm/os_irqtable.s b/subprojects/NitroSDK/libraries/os/asm/os_irqtable.s deleted file mode 100644 index a5f7ae2b32..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_irqtable.s +++ /dev/null @@ -1,140 +0,0 @@ - .include "macros/function.inc" - .include "include/os_irqtable.inc" - - - .text - - - arm_func_start OS_IrqDummy -OS_IrqDummy: ; 0x020C1328 - bx lr - arm_func_end OS_IrqDummy - - arm_func_start OSi_IrqCallback -OSi_IrqCallback: ; 0x020C132C - stmfd sp!, {r3, r4, r5, lr} - mov r1, #0xc - mul r5, r0, r1 - ldr r2, _020C13A0 ; =0x021CCBF8 - ldr r3, _020C13A4 ; =0x0210114C - mov r4, r0, lsl #1 - ldr r1, [r2, r5] - mov r0, #0 - ldrh r3, [r3, r4] - mov r4, #1 - str r0, [r2, r5] - cmp r1, #0 - mov r4, r4, lsl r3 - beq _020C1370 - ldr r0, _020C13A8 ; =0x021CCC00 - ldr r0, [r0, r5] - blx r1 -_020C1370: - ldr r0, _020C13AC ; =0x027E0000 - ldr r1, _020C13B0 ; =0x021CCBFC - add r0, r0, #0x3000 - ldr r2, [r0, #0xff8] - ldr r1, [r1, r5] - orr r2, r2, r4 - str r2, [r0, #0xff8] - cmp r1, #0 - ldmneia sp!, {r3, r4, r5, pc} - mov r0, r4 - bl OS_DisableIrqMask - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C13A0: .word Unk_021CCBF8 -_020C13A4: .word Unk_0210114C -_020C13A8: .word 0x021CCC00 -_020C13AC: .word OS_IRQTable -_020C13B0: .word 0x021CCBFC - arm_func_end OSi_IrqCallback - - arm_func_start OSi_IrqDma0 -OSi_IrqDma0: ; 0x020C13B4 - ldr ip, _020C13C0 ; =OSi_IrqCallback - mov r0, #0 - bx ip - ; .align 2, 0 -_020C13C0: .word OSi_IrqCallback - arm_func_end OSi_IrqDma0 - - arm_func_start OSi_IrqDma1 -OSi_IrqDma1: ; 0x020C13C4 - ldr ip, _020C13D0 ; =OSi_IrqCallback - mov r0, #1 - bx ip - ; .align 2, 0 -_020C13D0: .word OSi_IrqCallback - arm_func_end OSi_IrqDma1 - - arm_func_start OSi_IrqDma2 -OSi_IrqDma2: ; 0x020C13D4 - ldr ip, _020C13E0 ; =OSi_IrqCallback - mov r0, #2 - bx ip - ; .align 2, 0 -_020C13E0: .word OSi_IrqCallback - arm_func_end OSi_IrqDma2 - - arm_func_start OSi_IrqDma3 -OSi_IrqDma3: ; 0x020C13E4 - ldr ip, _020C13F0 ; =OSi_IrqCallback - mov r0, #3 - bx ip - ; .align 2, 0 -_020C13F0: .word OSi_IrqCallback - arm_func_end OSi_IrqDma3 - - arm_func_start OSi_IrqTimer0 -OSi_IrqTimer0: ; 0x020C13F4 - ldr ip, _020C1400 ; =OSi_IrqCallback - mov r0, #4 - bx ip - ; .align 2, 0 -_020C1400: .word OSi_IrqCallback - arm_func_end OSi_IrqTimer0 - - arm_func_start OSi_IrqTimer1 -OSi_IrqTimer1: ; 0x020C1404 - ldr ip, _020C1410 ; =OSi_IrqCallback - mov r0, #5 - bx ip - ; .align 2, 0 -_020C1410: .word OSi_IrqCallback - arm_func_end OSi_IrqTimer1 - - arm_func_start OSi_IrqTimer2 -OSi_IrqTimer2: ; 0x020C1414 - ldr ip, _020C1420 ; =OSi_IrqCallback - mov r0, #6 - bx ip - ; .align 2, 0 -_020C1420: .word OSi_IrqCallback - arm_func_end OSi_IrqTimer2 - - arm_func_start OSi_IrqTimer3 -OSi_IrqTimer3: ; 0x020C1424 - ldr ip, _020C1430 ; =OSi_IrqCallback - mov r0, #7 - bx ip - ; .align 2, 0 -_020C1430: .word OSi_IrqCallback - arm_func_end OSi_IrqTimer3 - - - .data - - - .global Unk_0210114C -Unk_0210114C: ; 0x0210114C - .short 0x8, 0x9, 0xA, 0xB, 0x3, 0x4, 0x5, 0x6 - - - .bss - - - .global Unk_021CCBF8 -Unk_021CCBF8: ; 0x021CCBF8 - .space 0x60 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_message.s b/subprojects/NitroSDK/libraries/os/asm/os_message.s deleted file mode 100644 index e34645670c..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_message.s +++ /dev/null @@ -1,199 +0,0 @@ - .include "macros/function.inc" - .include "include/os_message.inc" - - - - .text - - - arm_func_start OS_InitMessageQueue -OS_InitMessageQueue: ; 0x020C2748 - mov r3, #0 - str r3, [r0, #4] - str r3, [r0, #0] - str r3, [r0, #0xc] - str r3, [r0, #8] - str r1, [r0, #0x10] - str r2, [r0, #0x14] - str r3, [r0, #0x18] - str r3, [r0, #0x1c] - bx lr - arm_func_end OS_InitMessageQueue - - arm_func_start OS_SendMessage -OS_SendMessage: ; 0x020C2770 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r5, r0 - mov r4, r1 - mov r7, r2 - bl OS_DisableInterrupts - ldr r2, [r5, #0x1c] - ldr r1, [r5, #0x14] - mov r6, r0 - cmp r1, r2 - bgt _020C27CC - and r7, r7, #1 -_020C279C: - cmp r7, #0 - bne _020C27B4 - mov r0, r6 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C27B4: - mov r0, r5 - bl OS_SleepThread - ldr r2, [r5, #0x1c] - ldr r1, [r5, #0x14] - cmp r1, r2 - ble _020C279C -_020C27CC: - ldr r0, [r5, #0x18] - add r0, r0, r2 - bl _s32_div_f - ldr r2, [r5, #0x10] - add r0, r5, #8 - str r4, [r2, r1, lsl #2] - ldr r1, [r5, #0x1c] - add r1, r1, #1 - str r1, [r5, #0x1c] - bl OS_WakeupThread - mov r0, r6 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_SendMessage - - arm_func_start OS_ReceiveMessage -OS_ReceiveMessage: ; 0x020C2804 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl OS_DisableInterrupts - ldr r1, [r6, #0x1c] - mov r4, r0 - cmp r1, #0 - bne _020C2858 - and r7, r7, #1 -_020C282C: - cmp r7, #0 - bne _020C2844 - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C2844: - add r0, r6, #8 - bl OS_SleepThread - ldr r0, [r6, #0x1c] - cmp r0, #0 - beq _020C282C -_020C2858: - cmp r5, #0 - beq _020C2870 - ldr r1, [r6, #0x10] - ldr r0, [r6, #0x18] - ldr r0, [r1, r0, lsl #2] - str r0, [r5, #0] -_020C2870: - ldr r0, [r6, #0x18] - ldr r1, [r6, #0x14] - add r0, r0, #1 - bl _s32_div_f - str r1, [r6, #0x18] - ldr r1, [r6, #0x1c] - mov r0, r6 - sub r1, r1, #1 - str r1, [r6, #0x1c] - bl OS_WakeupThread - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_ReceiveMessage - - arm_func_start OS_JamMessage -OS_JamMessage: ; 0x020C28A8 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl OS_DisableInterrupts - ldr r1, [r6, #0x14] - ldr r2, [r6, #0x1c] - mov r4, r0 - cmp r1, r2 - bgt _020C2904 - and r7, r7, #1 -_020C28D4: - cmp r7, #0 - bne _020C28EC - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C28EC: - mov r0, r6 - bl OS_SleepThread - ldr r1, [r6, #0x14] - ldr r0, [r6, #0x1c] - cmp r1, r0 - ble _020C28D4 -_020C2904: - ldr r0, [r6, #0x18] - add r0, r0, r1 - sub r0, r0, #1 - bl _s32_div_f - str r1, [r6, #0x18] - ldr r0, [r6, #0x10] - str r5, [r0, r1, lsl #2] - ldr r1, [r6, #0x1c] - add r0, r6, #8 - add r1, r1, #1 - str r1, [r6, #0x1c] - bl OS_WakeupThread - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_JamMessage - - arm_func_start OS_ReadMessage -OS_ReadMessage: ; 0x020C2944 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r6, r0 - mov r5, r1 - mov r7, r2 - bl OS_DisableInterrupts - ldr r1, [r6, #0x1c] - mov r4, r0 - cmp r1, #0 - bne _020C2998 - and r7, r7, #1 -_020C296C: - cmp r7, #0 - bne _020C2984 - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} -_020C2984: - add r0, r6, #8 - bl OS_SleepThread - ldr r0, [r6, #0x1c] - cmp r0, #0 - beq _020C296C -_020C2998: - cmp r5, #0 - beq _020C29B0 - ldr r1, [r6, #0x10] - ldr r0, [r6, #0x18] - ldr r0, [r1, r0, lsl #2] - str r0, [r5, #0] -_020C29B0: - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_ReadMessage \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_mutex.s b/subprojects/NitroSDK/libraries/os/asm/os_mutex.s deleted file mode 100644 index dd295c4275..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_mutex.s +++ /dev/null @@ -1,171 +0,0 @@ - .include "macros/function.inc" - .include "include/os_mutex.inc" - - .extern OSi_ThreadInfo - - - .text - - - arm_func_start OS_InitMutex -OS_InitMutex: ; 0x020C29C0 - mov r1, #0 - str r1, [r0, #4] - str r1, [r0, #0] - str r1, [r0, #8] - str r1, [r0, #0xc] - bx lr - arm_func_end OS_InitMutex - - arm_func_start OS_LockMutex -OS_LockMutex: ; 0x020C29D8 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, _020C2A58 ; =0x021CCC80 - mov r4, r0 - ldr r7, [r1, #4] - mov r6, #0 -_020C29F4: - ldr r0, [r5, #8] - cmp r0, #0 - bne _020C2A20 - str r7, [r5, #8] - ldr r1, [r5, #0xc] - mov r0, r7 - add r2, r1, #1 - mov r1, r5 - str r2, [r5, #0xc] - bl OSi_EnqueueTail - b _020C2A4C -_020C2A20: - cmp r0, r7 - bne _020C2A38 - ldr r0, [r5, #0xc] - add r0, r0, #1 - str r0, [r5, #0xc] - b _020C2A4C -_020C2A38: - mov r0, r5 - str r5, [r7, #0x84] - bl OS_SleepThread - str r6, [r7, #0x84] - b _020C29F4 -_020C2A4C: - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, r6, r7, pc} - ; .align 2, 0 -_020C2A58: .word OSi_ThreadInfo - arm_func_end OS_LockMutex - - arm_func_start OS_UnlockMutex -OS_UnlockMutex: ; 0x020C2A5C - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, _020C2AB4 ; =0x021CCC80 - mov r4, r0 - ldr r0, [r1, #4] - ldr r1, [r5, #8] - cmp r1, r0 - bne _020C2AA8 - ldr r1, [r5, #0xc] - subs r1, r1, #1 - str r1, [r5, #0xc] - bne _020C2AA8 - mov r1, r5 - bl OSi_DequeueItem - mov r1, #0 - mov r0, r5 - str r1, [r5, #8] - bl OS_WakeupThread -_020C2AA8: - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C2AB4: .word OSi_ThreadInfo - arm_func_end OS_UnlockMutex - - arm_func_start OSi_UnlockAllMutex -OSi_UnlockAllMutex: ; 0x020C2AB8 - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - ldr r0, [r5, #0x88] - cmp r0, #0 - ldmeqia sp!, {r3, r4, r5, pc} - mov r4, #0 -_020C2AD0: - add r0, r5, #0x88 - bl OSi_RemoveMutexLinkFromQueue - str r4, [r0, #0xc] - str r4, [r0, #8] - bl OS_WakeupThread - ldr r0, [r5, #0x88] - cmp r0, #0 - bne _020C2AD0 - ldmia sp!, {r3, r4, r5, pc} - arm_func_end OSi_UnlockAllMutex - - arm_func_start OS_TryLockMutex -OS_TryLockMutex: ; 0x020C2AF4 - stmfd sp!, {r4, r5, r6, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r2, [r5, #8] - ldr r1, _020C2B64 ; =0x021CCC80 - mov r4, r0 - cmp r2, #0 - ldr r0, [r1, #4] - bne _020C2B38 - str r0, [r5, #8] - ldr r2, [r5, #0xc] - mov r1, r5 - add r2, r2, #1 - str r2, [r5, #0xc] - bl OSi_EnqueueTail - mov r6, #1 - b _020C2B54 -_020C2B38: - cmp r2, r0 - movne r6, #0 - bne _020C2B54 - ldr r0, [r5, #0xc] - mov r6, #1 - add r0, r0, #1 - str r0, [r5, #0xc] -_020C2B54: - mov r0, r4 - bl OS_RestoreInterrupts - mov r0, r6 - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C2B64: .word OSi_ThreadInfo - arm_func_end OS_TryLockMutex - - arm_func_start OSi_EnqueueTail -OSi_EnqueueTail: ; 0x020C2B68 - ldr r2, [r0, #0x8c] - cmp r2, #0 - streq r1, [r0, #0x88] - strne r1, [r2, #0x10] - str r2, [r1, #0x14] - mov r2, #0 - str r2, [r1, #0x10] - str r1, [r0, #0x8c] - bx lr - arm_func_end OSi_EnqueueTail - - arm_func_start OSi_DequeueItem -OSi_DequeueItem: ; 0x020C2B8C - ldr r2, [r1, #0x10] - ldr r1, [r1, #0x14] - cmp r2, #0 - streq r1, [r0, #0x8c] - strne r1, [r2, #0x14] - cmp r1, #0 - streq r2, [r0, #0x88] - strne r2, [r1, #0x10] - bx lr - arm_func_end OSi_DequeueItem diff --git a/subprojects/NitroSDK/libraries/os/asm/os_ownerinfo.s b/subprojects/NitroSDK/libraries/os/asm/os_ownerinfo.s deleted file mode 100644 index 9e3c074f0e..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_ownerinfo.s +++ /dev/null @@ -1,67 +0,0 @@ - .include "macros/function.inc" - .include "include/os_ownerinfo.inc" - - - - .text - - - arm_func_start OS_GetMacAddress -OS_GetMacAddress: ; 0x020C3FA0 - ldr ip, _020C3FB4 ; =MI_CpuCopy8 - mov r1, r0 - ldr r0, _020C3FB8 ; =0x027FFCF4 - mov r2, #6 - bx ip - ; .align 2, 0 -_020C3FB4: .word MI_CpuCopy8 -_020C3FB8: .word 0x027FFCF4 - arm_func_end OS_GetMacAddress - - arm_func_start OS_GetOwnerInfo -OS_GetOwnerInfo: ; 0x020C3FBC - stmfd sp!, {r4, lr} - ldr ip, _020C403C ; =0x027FFC80 - mov r4, r0 - ldrh r2, [ip, #0x64] - add r0, ip, #6 - add r1, r4, #4 - mov r2, r2, lsl #0x1d - mov r2, r2, lsr #0x1d - strb r2, [r4] - ldrb r3, [ip, #2] - mov r2, #0x14 - mov r3, r3, lsl #0x1c - mov r3, r3, lsr #0x1c - strb r3, [r4, #1] - ldrb r3, [ip, #3] - strb r3, [r4, #2] - ldrb r3, [ip, #4] - strb r3, [r4, #3] - ldrb r3, [ip, #0x1a] - strh r3, [r4, #0x1a] - ldrb r3, [ip, #0x50] - strh r3, [r4, #0x52] - bl MIi_CpuCopy16 - ldr r0, _020C403C ; =0x027FFC80 - add r1, r4, #0x1c - add r0, r0, #0x1c - mov r2, #0x34 - bl MIi_CpuCopy16 - mov r0, #0 - strh r0, [r4, #0x18] - strh r0, [r4, #0x50] - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C403C: .word 0x027FFC80 - arm_func_end OS_GetOwnerInfo - - arm_func_start OS_GetOwnerRtcOffset -OS_GetOwnerRtcOffset: ; 0x020C4040 - ldr r1, _020C4050 ; =0x027FFC80 - ldr r0, [r1, #0x68] - ldr r1, [r1, #0x6c] - bx lr - ; .align 2, 0 -_020C4050: .word 0x027FFC80 - arm_func_end OS_GetOwnerRtcOffset \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_printf.s b/subprojects/NitroSDK/libraries/os/asm/os_printf.s deleted file mode 100644 index 9e5c2f556d..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_printf.s +++ /dev/null @@ -1,54 +0,0 @@ - .include "macros/function.inc" - .include "include/os_printf.inc" - - - - .text - - - arm_func_start OS_SPrintf -OS_SPrintf: ; 0x020C1AB0 - stmfd sp!, {r0, r1, r2, r3} - stmfd sp!, {r3, lr} - add r2, sp, #0xc - bic r2, r2, #3 - ldr r1, [sp, #0xc] - add r2, r2, #4 - bl OS_VSPrintf - ldmia sp!, {r3, lr} - add sp, sp, #0x10 - bx lr - arm_func_end OS_SPrintf - - arm_func_start OS_VSPrintf -OS_VSPrintf: ; 0x020C1AD8 - ldr ip, _020C1AEC ; =OS_VSNPrintf - mov r3, r2 - mov r2, r1 - mvn r1, #0x80000000 - bx ip - ; .align 2, 0 -_020C1AEC: .word OS_VSNPrintf - arm_func_end OS_VSPrintf - - arm_func_start OS_SNPrintf -OS_SNPrintf: ; 0x020C1AF0 - stmfd sp!, {r0, r1, r2, r3} - stmfd sp!, {r3, lr} - add r3, sp, #0x10 - bic r3, r3, #3 - ldr r2, [sp, #0x10] - add r3, r3, #4 - bl OS_VSNPrintf - ldmia sp!, {r3, lr} - add sp, sp, #0x10 - bx lr - arm_func_end OS_SNPrintf - - arm_func_start OS_VSNPrintf -OS_VSNPrintf: ; 0x020C1B18 - ldr ip, _020C1B20 ; =STD_TVSNPrintf - bx ip - ; .align 2, 0 -_020C1B20: .word STD_TVSNPrintf - arm_func_end OS_VSNPrintf \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_protectionregion.s b/subprojects/NitroSDK/libraries/os/asm/os_protectionregion.s deleted file mode 100644 index 84900bb246..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_protectionregion.s +++ /dev/null @@ -1,27 +0,0 @@ - .include "macros/function.inc" - - - - .text - - - arm_func_start OS_SetDPermissionsForProtectionRegion -OS_SetDPermissionsForProtectionRegion: ; 0x020C353C - mrc p15, 0, r2, c5, c0, 2 - bic r2, r2, r0 - orr r2, r2, r1 - mcr p15, 0, r2, c5, c0, 2 - bx lr - arm_func_end OS_SetDPermissionsForProtectionRegion - - arm_func_start OS_SetProtectionRegion1 -OS_SetProtectionRegion1: ; 0x020C3550 - mcr p15, 0, r0, c6, c1, 0 - bx lr - arm_func_end OS_SetProtectionRegion1 - - arm_func_start OS_SetProtectionRegion2 -OS_SetProtectionRegion2: ; 0x020C3558 - mcr p15, 0, r0, c6, c2, 0 - bx lr - arm_func_end OS_SetProtectionRegion2 \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_protectionunit.s b/subprojects/NitroSDK/libraries/os/asm/os_protectionunit.s deleted file mode 100644 index d8d0199d51..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_protectionunit.s +++ /dev/null @@ -1,22 +0,0 @@ - .include "macros/function.inc" - - - - .text - - - arm_func_start OS_EnableProtectionUnit -OS_EnableProtectionUnit: ; 0x020C351C - mrc p15, 0, r0, c1, c0, 0 - orr r0, r0, #1 - mcr p15, 0, r0, c1, c0, 0 - bx lr - arm_func_end OS_EnableProtectionUnit - - arm_func_start OS_DisableProtectionUnit -OS_DisableProtectionUnit: ; 0x020C352C - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #1 - mcr p15, 0, r0, c1, c0, 0 - bx lr - arm_func_end OS_DisableProtectionUnit \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_reset.s b/subprojects/NitroSDK/libraries/os/asm/os_reset.s deleted file mode 100644 index 12656e35b3..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_reset.s +++ /dev/null @@ -1,135 +0,0 @@ - .include "macros/function.inc" - .include "include/os_reset.inc" - - .extern Unk_021CCFE4 - - - .text - - - arm_func_start OS_InitReset -OS_InitReset: ; 0x020C3E30 - stmfd sp!, {r3, r4, r5, lr} - ldr r0, _020C3E7C ; =0x021CCFE4 - ldrh r1, [r0, #2] - cmp r1, #0 - ldmneia sp!, {r3, r4, r5, pc} - mov r1, #1 - strh r1, [r0, #2] - bl PXI_Init - mov r5, #0xc - mov r4, #1 -_020C3E58: - mov r0, r5 - mov r1, r4 - bl PXI_IsCallbackReady - cmp r0, #0 - beq _020C3E58 - ldr r1, _020C3E80 ; =OSi_CommonCallback - mov r0, #0xc - bl PXI_SetFifoRecvCallback - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C3E7C: .word Unk_021CCFE4 -_020C3E80: .word OSi_CommonCallback - arm_func_end OS_InitReset - - arm_func_start OSi_CommonCallback -OSi_CommonCallback: ; 0x020C3E84 - stmfd sp!, {r3, lr} - and r0, r1, #0x7f00 - mov r0, r0, lsl #8 - mov r0, r0, lsr #0x10 - cmp r0, #0x10 - bne _020C3EAC - ldr r0, _020C3EB4 ; =0x021CCFE4 - mov r1, #1 - strh r1, [r0] - ldmia sp!, {r3, pc} -_020C3EAC: - bl OS_Terminate - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C3EB4: .word Unk_021CCFE4 - arm_func_end OSi_CommonCallback - - arm_func_start OSi_SendToPxi -OSi_SendToPxi: ; 0x020C3EB8 - stmfd sp!, {r4, r5, r6, lr} - mov r6, r0, lsl #8 - mov r5, #0xc - mov r4, #0 -_020C3EC8: - mov r0, r5 - mov r1, r6 - mov r2, r4 - bl PXI_SendWordByFifo - cmp r0, #0 - bne _020C3EC8 - ldmia sp!, {r4, r5, r6, pc} - arm_func_end OSi_SendToPxi - - arm_func_start OS_ResetSystem -OS_ResetSystem: ; 0x020C3EE4 - stmfd sp!, {r4, lr} - ldr r1, _020C3F74 ; =0x027FFC40 - mov r4, r0 - ldrh r0, [r1] - cmp r0, #2 - moveq r0, #1 - movne r0, #0 - cmp r0, #0 - beq _020C3F0C - bl OS_Terminate -_020C3F0C: - bl OS_GetLockID - mov r0, r0, lsl #0x10 - mov r0, r0, lsr #0x10 - bl CARD_LockRom - ldr r0, _020C3F78 ; =0x00000000 - bl MI_StopDma - ldr r0, _020C3F7C ; =0x00000001 - bl MI_StopDma - ldr r0, _020C3F80 ; =0x00000002 - bl MI_StopDma - ldr r0, _020C3F84 ; =0x00000003 - bl MI_StopDma - ldr r0, _020C3F88 ; =0x00040000 - bl OS_SetIrqMask - ldr r0, _020C3F8C ; =0xFFFFFFFF - bl OS_ResetRequestIrqMask - ldr r1, _020C3F90 ; =0x027FFC20 - ldr r0, _020C3F94 ; =0x00000010 - str r4, [r1, #0] - bl OSi_SendToPxi - ldr r0, _020C3F98 ; =0x027E3F80 - ldr r1, _020C3F9C ; =0x00000800 - sub r0, r0, r1 - mov sp, r0 - bl OSi_DoResetSystem - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C3F74: .word 0x027FFC40 -_020C3F78: .word 0x00000000 -_020C3F7C: .word 0x00000001 -_020C3F80: .word 0x00000002 -_020C3F84: .word 0x00000003 -_020C3F88: .word 0x00040000 -_020C3F8C: .word 0xFFFFFFFF -_020C3F90: .word 0x027FFC20 -_020C3F94: .word 0x00000010 -_020C3F98: .word 0x027E3F80 -_020C3F9C: .word 0x00000800 - arm_func_end OS_ResetSystem - - .bss - - - .global Unk_021CCFE4 -Unk_021CCFE4: ; 0x021CCFE4 - .space 0x2 - - .global Unk_021CCFE6 -Unk_021CCFE6: ; 0x021CCFE6 - .space 0x2 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_spinlock.s b/subprojects/NitroSDK/libraries/os/asm/os_spinlock.s deleted file mode 100644 index dec8155359..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_spinlock.s +++ /dev/null @@ -1,377 +0,0 @@ - .include "macros/function.inc" - .include "include/os_spinlock.inc" - - .extern Unk_021CCC58 - - - .text - - - arm_func_start OS_InitLock -OS_InitLock: ; 0x020C16DC - stmfd sp!, {r3, r4, r5, lr} - ldr r3, _020C1798 ; =0x021CCC58 - ldr r0, [r3, #0] - cmp r0, #0 - ldmneia sp!, {r3, r4, r5, pc} - ldr r1, _020C179C ; =0x027FFFF0 - mov r4, #1 - mov r2, #0 - mov r0, #0x7e - str r4, [r3, #0] - str r2, [r1, #0] - bl OS_LockByWord - ldr r5, _020C179C ; =0x027FFFF0 - ldrh r0, [r5, #6] - cmp r0, #0 - beq _020C1734 - mov r4, #0x400 -_020C1720: - mov r0, r4 - bl SVC_WaitByLoop - ldrh r0, [r5, #6] - cmp r0, #0 - bne _020C1720 -_020C1734: - ldr ip, _020C17A0 ; =0x027FFFB0 - mvn r0, #0 - str r0, [ip] - mov r3, r0, lsl #0x10 - add r1, ip, #0x10 - mov r0, #0 - mov r2, #0x28 - str r3, [ip, #4] - bl MIi_CpuClear32 - ldr ip, _020C17A4 ; =0x04000204 - ldr r1, _020C179C ; =0x027FFFF0 - ldrh r3, [ip] - mov r0, #0x7e - mov r2, #0 - orr r3, r3, #0x800 - strh r3, [ip] - ldrh r3, [ip] - orr r3, r3, #0x80 - strh r3, [ip] - bl OS_UnlockByWord - ldr r1, _020C179C ; =0x027FFFF0 - mov r0, #0x7f - mov r2, #0 - bl OS_LockByWord - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C1798: .word Unk_021CCC58 -_020C179C: .word 0x027FFFF0 -_020C17A0: .word 0x027FFFB0 -_020C17A4: .word 0x04000204 - arm_func_end OS_InitLock - - arm_func_start OSi_DoLockByWord -OSi_DoLockByWord: ; 0x020C17A8 - stmfd sp!, {r4, r5, r6, r7, r8, lr} - mov r8, r0 - mov r7, r1 - mov r6, r2 - mov r5, r3 - bl OSi_DoTryLockByWord - cmp r0, #0 - ldmleia sp!, {r4, r5, r6, r7, r8, pc} - mov r4, #0x400 -_020C17CC: - mov r0, r4 - bl SVC_WaitByLoop - mov r0, r8 - mov r1, r7 - mov r2, r6 - mov r3, r5 - bl OSi_DoTryLockByWord - cmp r0, #0 - bgt _020C17CC - ldmia sp!, {r4, r5, r6, r7, r8, pc} - arm_func_end OSi_DoLockByWord - - arm_func_start OS_LockByWord -OS_LockByWord: ; 0x020C17F4 - ldr ip, _020C1800 ; =OSi_DoLockByWord - mov r3, #0 - bx ip - ; .align 2, 0 -_020C1800: .word OSi_DoLockByWord - arm_func_end OS_LockByWord - - arm_func_start OSi_DoUnlockByWord -OSi_DoUnlockByWord: ; 0x020C1804 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r7, r1 - ldrh r1, [r7, #4] - mov r6, r2 - mov r5, r3 - cmp r0, r1 - mvnne r0, #1 - ldmneia sp!, {r3, r4, r5, r6, r7, pc} - cmp r5, #0 - beq _020C1834 - bl OS_DisableInterrupts_IrqAndFiq - b _020C1838 -_020C1834: - bl OS_DisableInterrupts -_020C1838: - mov r4, r0 - mov r0, #0 - strh r0, [r7, #4] - cmp r6, #0 - beq _020C1850 - blx r6 -_020C1850: - mov r0, #0 - str r0, [r7, #0] - cmp r5, #0 - mov r0, r4 - beq _020C186C - bl OS_RestoreInterrupts_IrqAndFiq - b _020C1870 -_020C186C: - bl OS_RestoreInterrupts -_020C1870: - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OSi_DoUnlockByWord - - arm_func_start OS_UnlockByWord -OS_UnlockByWord: ; 0x020C1878 - ldr ip, _020C1884 ; =OSi_DoUnlockByWord - mov r3, #0 - bx ip - ; .align 2, 0 -_020C1884: .word OSi_DoUnlockByWord - arm_func_end OS_UnlockByWord - - arm_func_start OSi_DoTryLockByWord -OSi_DoTryLockByWord: ; 0x020C1888 - stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr} - movs r6, r3 - mov sb, r0 - mov r8, r1 - mov r7, r2 - beq _020C18A8 - bl OS_DisableInterrupts_IrqAndFiq - b _020C18AC -_020C18A8: - bl OS_DisableInterrupts -_020C18AC: - mov r5, r0 - mov r0, sb - mov r1, r8 - bl MI_SwapWord - movs r4, r0 - bne _020C18D4 - cmp r7, #0 - beq _020C18D0 - blx r7 -_020C18D0: - strh sb, [r8, #4] -_020C18D4: - cmp r6, #0 - mov r0, r5 - beq _020C18E8 - bl OS_RestoreInterrupts_IrqAndFiq - b _020C18EC -_020C18E8: - bl OS_RestoreInterrupts -_020C18EC: - mov r0, r4 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} - arm_func_end OSi_DoTryLockByWord - - arm_func_start OS_LockCartridge -OS_LockCartridge: ; 0x020C18F4 - ldr ip, _020C1908 ; =OSi_DoLockByWord - ldr r1, _020C190C ; =0x027FFFE8 - ldr r2, _020C1910 ; =OSi_AllocateCartridgeBus - mov r3, #1 - bx ip - ; .align 2, 0 -_020C1908: .word OSi_DoLockByWord -_020C190C: .word 0x027FFFE8 -_020C1910: .word OSi_AllocateCartridgeBus - arm_func_end OS_LockCartridge - - arm_func_start OS_UnlockCartridge -OS_UnlockCartridge: ; 0x020C1914 - ldr ip, _020C1928 ; =OSi_DoUnlockByWord - ldr r1, _020C192C ; =0x027FFFE8 - ldr r2, _020C1930 ; =OSi_FreeCartridgeBus - mov r3, #1 - bx ip - ; .align 2, 0 -_020C1928: .word OSi_DoUnlockByWord -_020C192C: .word 0x027FFFE8 -_020C1930: .word OSi_FreeCartridgeBus - arm_func_end OS_UnlockCartridge - - arm_func_start OS_UnLockCartridge -OS_UnLockCartridge: ; 0x020C1934 - ldr r1, _020C193C ; =OS_UnlockCartridge - bx r1 - ; .align 2, 0 -_020C193C: .word OS_UnlockCartridge - arm_func_end OS_UnLockCartridge - - arm_func_start OS_TryLockCartridge -OS_TryLockCartridge: ; 0x020C1940 - ldr ip, _020C1954 ; =OSi_DoTryLockByWord - ldr r1, _020C1958 ; =0x027FFFE8 - ldr r2, _020C195C ; =OSi_AllocateCartridgeBus - mov r3, #1 - bx ip - ; .align 2, 0 -_020C1954: .word OSi_DoTryLockByWord -_020C1958: .word 0x027FFFE8 -_020C195C: .word OSi_AllocateCartridgeBus - arm_func_end OS_TryLockCartridge - - arm_func_start OSi_AllocateCartridgeBus -OSi_AllocateCartridgeBus: ; 0x020C1960 - ldr r1, _020C1974 ; =0x04000204 - ldrh r0, [r1] - bic r0, r0, #0x80 - strh r0, [r1] - bx lr - ; .align 2, 0 -_020C1974: .word 0x04000204 - arm_func_end OSi_AllocateCartridgeBus - - arm_func_start OSi_FreeCartridgeBus -OSi_FreeCartridgeBus: ; 0x020C1978 - ldr r1, _020C198C ; =0x04000204 - ldrh r0, [r1] - orr r0, r0, #0x80 - strh r0, [r1] - bx lr - ; .align 2, 0 -_020C198C: .word 0x04000204 - arm_func_end OSi_FreeCartridgeBus - - arm_func_start OS_LockCard -OS_LockCard: ; 0x020C1990 - ldr ip, _020C19A0 ; =OS_LockByWord - ldr r1, _020C19A4 ; =0x027FFFE0 - ldr r2, _020C19A8 ; =OSi_AllocateCardBus - bx ip - ; .align 2, 0 -_020C19A0: .word OS_LockByWord -_020C19A4: .word 0x027FFFE0 -_020C19A8: .word OSi_AllocateCardBus - arm_func_end OS_LockCard - - arm_func_start OS_UnlockCard -OS_UnlockCard: ; 0x020C19AC - ldr ip, _020C19BC ; =OS_UnlockByWord - ldr r1, _020C19C0 ; =0x027FFFE0 - ldr r2, _020C19C4 ; =OSi_FreeCardBus - bx ip - ; .align 2, 0 -_020C19BC: .word OS_UnlockByWord -_020C19C0: .word 0x027FFFE0 -_020C19C4: .word OSi_FreeCardBus - arm_func_end OS_UnlockCard - - arm_func_start OSi_AllocateCardBus -OSi_AllocateCardBus: ; 0x020C19C8 - ldr r1, _020C19DC ; =0x04000204 - ldrh r0, [r1] - bic r0, r0, #0x800 - strh r0, [r1] - bx lr - ; .align 2, 0 -_020C19DC: .word 0x04000204 - arm_func_end OSi_AllocateCardBus - - arm_func_start OSi_FreeCardBus -OSi_FreeCardBus: ; 0x020C19E0 - ldr r1, _020C19F4 ; =0x04000204 - ldrh r0, [r1] - orr r0, r0, #0x800 - strh r0, [r1] - bx lr - ; .align 2, 0 -_020C19F4: .word 0x04000204 - arm_func_end OSi_FreeCardBus - - arm_func_start OS_ReadOwnerOfLockWord -OS_ReadOwnerOfLockWord: ; 0x020C19F8 - ldrh r0, [r0, #4] - bx lr - arm_func_end OS_ReadOwnerOfLockWord - - arm_func_start OS_GetLockID -OS_GetLockID: ; 0x020C1A00 - ldr r3, _020C1A60 ; =0x027FFFB0 - ldr r1, [r3, #0] - clz r2, r1 - cmp r2, #0x20 - bne _020C1A18 - b _020C1A1C -_020C1A18: - mov r0, #0x40 -_020C1A1C: - bne _020C1A44 - add r3, r3, #4 - ldr r1, [r3, #0] - clz r2, r1 - cmp r2, #0x20 - ldr r0, _020C1A64 ; =0xFFFFFFFD - beq _020C1A3C - b _020C1A40 -_020C1A3C: - bx lr -_020C1A40: - mov r0, #0x60 -_020C1A44: - add r0, r0, r2 - mov r1, #-0x80000000 - mov r1, r1, lsr r2 - ldr r2, [r3, #0] - bic r2, r2, r1 - str r2, [r3, #0] - bx lr - ; .align 2, 0 -_020C1A60: .word 0x027FFFB0 -_020C1A64: .word 0xFFFFFFFD - arm_func_end OS_GetLockID - - arm_func_start OS_ReleaseLockID -OS_ReleaseLockID: ; 0x020C1A68 - ldr r3, _020C1AAC ; =0x027FFFB0 - cmp r0, #0x60 - bpl _020C1A78 - b _020C1A7C -_020C1A78: - add r3, r3, #4 -_020C1A7C: - bpl _020C1A84 - b _020C1A88 -_020C1A84: - sub r0, r0, #0x60 -_020C1A88: - bmi _020C1A90 - b _020C1A94 -_020C1A90: - sub r0, r0, #0x40 -_020C1A94: - mov r1, #-0x80000000 - mov r1, r1, lsr r0 - ldr r2, [r3, #0] - orr r2, r2, r1 - str r2, [r3, #0] - bx lr - ; .align 2, 0 -_020C1AAC: .word 0x027FFFB0 - arm_func_end OS_ReleaseLockID - - .bss - - - .global Unk_021CCC58 -Unk_021CCC58: ; 0x021CCC58 - .space 0x4 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_system.s b/subprojects/NitroSDK/libraries/os/asm/os_system.s deleted file mode 100644 index caf1a32e18..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_system.s +++ /dev/null @@ -1,86 +0,0 @@ - .include "macros/function.inc" - .include "include/os_system.inc" - - - - .text - - - arm_func_start OS_EnableInterrupts -OS_EnableInterrupts: ; 0x020C3D84 - mrs r0, cpsr - bic r1, r0, #0x80 - msr cpsr_c, r1 - and r0, r0, #0x80 - bx lr - arm_func_end OS_EnableInterrupts - - arm_func_start OS_DisableInterrupts -OS_DisableInterrupts: ; 0x020C3D98 - mrs r0, cpsr - orr r1, r0, #0x80 - msr cpsr_c, r1 - and r0, r0, #0x80 - bx lr - arm_func_end OS_DisableInterrupts - - arm_func_start OS_RestoreInterrupts -OS_RestoreInterrupts: ; 0x020C3DAC - mrs r1, cpsr - bic r2, r1, #0x80 - orr r2, r2, r0 - msr cpsr_c, r2 - and r0, r1, #0x80 - bx lr - arm_func_end OS_RestoreInterrupts - - arm_func_start OS_DisableInterrupts_IrqAndFiq -OS_DisableInterrupts_IrqAndFiq: ; 0x020C3DC4 - mrs r0, cpsr - orr r1, r0, #0xc0 - msr cpsr_c, r1 - and r0, r0, #0xc0 - bx lr - arm_func_end OS_DisableInterrupts_IrqAndFiq - - arm_func_start OS_RestoreInterrupts_IrqAndFiq -OS_RestoreInterrupts_IrqAndFiq: ; 0x020C3DD8 - mrs r1, cpsr - bic r2, r1, #0xc0 - orr r2, r2, r0 - msr cpsr_c, r2 - and r0, r1, #0xc0 - bx lr - arm_func_end OS_RestoreInterrupts_IrqAndFiq - - arm_func_start OS_GetCpsrIrq -OS_GetCpsrIrq: ; 0x020C3DF0 - mrs r0, cpsr - and r0, r0, #0x80 - bx lr - arm_func_end OS_GetCpsrIrq - - arm_func_start OS_GetProcMode -OS_GetProcMode: ; 0x020C3DFC - mrs r0, cpsr - and r0, r0, #0x1f - bx lr - arm_func_end OS_GetProcMode - - arm_func_start OS_SpinWait -OS_SpinWait: - subs r0, r0, #4 - bhs OS_SpinWait - bx lr - arm_func_end OS_SpinWait - - arm_func_start OS_WaitVBlankIntr -OS_WaitVBlankIntr: ; 0x020C3E14 - stmfd sp!, {r3, lr} - mov r0, #1 - bl SVC_WaitByLoop - mov r0, #1 - mov r1, r0 - bl OS_WaitIrq - ldmia sp!, {r3, pc} - arm_func_end OS_WaitVBlankIntr \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_tcm.s b/subprojects/NitroSDK/libraries/os/asm/os_tcm.s deleted file mode 100644 index 2efc16f7d5..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_tcm.s +++ /dev/null @@ -1,16 +0,0 @@ - .include "macros/function.inc" - - - - .text - - - arm_func_start OS_GetDTCMAddress -OS_GetDTCMAddress: ; 0x020C3508 - mrc p15, 0, r0, c9, c1, 0 - ldr r1, _020C3518 ; =0xFFFFF000 - and r0, r0, r1 - bx lr - ; .align 2, 0 -_020C3518: .word 0xFFFFF000 - arm_func_end OS_GetDTCMAddress \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_terminate_proc.s b/subprojects/NitroSDK/libraries/os/asm/os_terminate_proc.s deleted file mode 100644 index 48b4abfbe6..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_terminate_proc.s +++ /dev/null @@ -1,23 +0,0 @@ - .include "macros/function.inc" - .include "include/os_terminate_proc.inc" - - - - .text - - - arm_func_start OS_Terminate -OS_Terminate: ; 0x020C42A8 - stmfd sp!, {r3, lr} -_020C42AC: - bl OS_DisableInterrupts - bl OS_Halt - b _020C42AC - arm_func_end OS_Terminate - - arm_func_start OS_Halt -OS_Halt: ; 0x020C42B8 - mov r0, #0 - mcr p15, 0, r0, c7, c0, 4 - bx lr - arm_func_end OS_Halt \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/asm/os_thread.s b/subprojects/NitroSDK/libraries/os/asm/os_thread.s deleted file mode 100644 index 4b3316b52c..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_thread.s +++ /dev/null @@ -1,971 +0,0 @@ - .include "macros/function.inc" - .include "include/os_thread.inc" - - .extern Unk_021CCC5C - .extern Unk_021CCC68 - .extern OSi_ThreadInfo - .extern Unk_021CCC90 - .extern Unk_021CCD50 - .extern Unk_021CCED8 - .extern OS_IRQTable - - .text - - - arm_func_start OSi_GetUnusedThreadId -OSi_GetUnusedThreadId: ; 0x020C1B24 - ldr r1, _020C1B38 ; =0x021CCC5C - ldr r0, [r1, #0x20] - add r0, r0, #1 - str r0, [r1, #0x20] - bx lr - ; .align 2, 0 -_020C1B38: .word Unk_021CCC5C - arm_func_end OSi_GetUnusedThreadId - - arm_func_start OSi_InsertLinkToQueue -OSi_InsertLinkToQueue: ; 0x020C1B3C - ldr ip, [r0] - b _020C1B50 -_020C1B44: - cmp ip, r1 - bxeq lr - ldr ip, [ip, #0x80] -_020C1B50: - cmp ip, #0 - beq _020C1B68 - ldr r3, [ip, #0x70] - ldr r2, [r1, #0x70] - cmp r3, r2 - bls _020C1B44 -_020C1B68: - cmp ip, #0 - bne _020C1B94 - ldr r2, [r0, #4] - cmp r2, #0 - streq r1, [r0] - strne r1, [r2, #0x80] - str r2, [r1, #0x7c] - mov r2, #0 - str r2, [r1, #0x80] - str r1, [r0, #4] - bx lr -_020C1B94: - ldr r2, [ip, #0x7c] - cmp r2, #0 - streq r1, [r0] - strne r1, [r2, #0x80] - str r2, [r1, #0x7c] - str ip, [r1, #0x80] - str r1, [ip, #0x7c] - bx lr - arm_func_end OSi_InsertLinkToQueue - - arm_func_start OSi_RemoveLinkFromQueue -OSi_RemoveLinkFromQueue: ; 0x020C1BB4 - ldr r2, [r0, #0] - cmp r2, #0 - beq _020C1BE0 - ldr r1, [r2, #0x80] - str r1, [r0, #0] - cmp r1, #0 - movne r0, #0 - strne r0, [r1, #0x7c] - moveq r1, #0 - streq r1, [r0, #4] - streq r1, [r2, #0x78] -_020C1BE0: - mov r0, r2 - bx lr - arm_func_end OSi_RemoveLinkFromQueue - - arm_func_start OSi_RemoveSpecifiedLinkFromQueue -OSi_RemoveSpecifiedLinkFromQueue: ; 0x020C1BE8 - ldr ip, [r0] - mov r2, ip - cmp ip, #0 - beq _020C1C34 -_020C1BF8: - cmp r2, r1 - ldr r3, [r2, #0x80] - bne _020C1C28 - cmp ip, r2 - ldr ip, [r2, #0x7c] - streq r3, [r0] - strne r3, [ip, #0x80] - ldr r1, [r0, #4] - cmp r1, r2 - streq ip, [r0, #4] - strne ip, [r3, #0x7c] - b _020C1C34 -_020C1C28: - mov r2, r3 - cmp r3, #0 - bne _020C1BF8 -_020C1C34: - mov r0, r2 - bx lr - arm_func_end OSi_RemoveSpecifiedLinkFromQueue - - arm_func_start OSi_RemoveMutexLinkFromQueue -OSi_RemoveMutexLinkFromQueue: ; 0x020C1C3C - ldr r2, [r0, #0] - cmp r2, #0 - beq _020C1C64 - ldr r1, [r2, #0x10] - str r1, [r0, #0] - cmp r1, #0 - movne r0, #0 - strne r0, [r1, #0x14] - moveq r1, #0 - streq r1, [r0, #4] -_020C1C64: - mov r0, r2 - bx lr - arm_func_end OSi_RemoveMutexLinkFromQueue - - arm_func_start OSi_InsertThreadToList -OSi_InsertThreadToList: ; 0x020C1C6C - stmfd sp!, {r3, lr} - ldr r1, _020C1CC8 ; =0x021CCC5C - mov ip, #0 - ldr lr, [r1, #0x2c] - mov r3, lr - b _020C1C8C -_020C1C84: - mov ip, r3 - ldr r3, [r3, #0x68] -_020C1C8C: - cmp r3, #0 - beq _020C1CA4 - ldr r2, [r3, #0x70] - ldr r1, [r0, #0x70] - cmp r2, r1 - blo _020C1C84 -_020C1CA4: - cmp ip, #0 - ldrne r1, [ip, #0x68] - strne r1, [r0, #0x68] - strne r0, [ip, #0x68] - ldmneia sp!, {r3, pc} - ldr r1, _020C1CC8 ; =0x021CCC5C - str lr, [r0, #0x68] - str r0, [r1, #0x2c] - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C1CC8: .word Unk_021CCC5C - arm_func_end OSi_InsertThreadToList - - arm_func_start OSi_RemoveThreadFromList -OSi_RemoveThreadFromList: ; 0x020C1CCC - ldr r1, _020C1D10 ; =0x021CCC5C - mov r2, #0 - ldr r1, [r1, #0x2c] - b _020C1CE4 -_020C1CDC: - mov r2, r1 - ldr r1, [r1, #0x68] -_020C1CE4: - cmp r1, #0 - cmpne r1, r0 - bne _020C1CDC - cmp r2, #0 - ldrne r0, [r0, #0x68] - strne r0, [r2, #0x68] - bxne lr - ldr r1, [r0, #0x68] - ldr r0, _020C1D10 ; =0x021CCC5C - str r1, [r0, #0x2c] - bx lr - ; .align 2, 0 -_020C1D10: .word Unk_021CCC5C - arm_func_end OSi_RemoveThreadFromList - - arm_func_start OSi_RescheduleThread -OSi_RescheduleThread: ; 0x020C1D14 - stmfd sp!, {r4, r5, r6, lr} - ldr r0, _020C1DD4 ; =0x021CCC5C - ldr r1, [r0, #4] - cmp r1, #0 - ldmneia sp!, {r4, r5, r6, pc} - ldrh r0, [r0, #0x26] - ldr r4, _020C1DD8 ; =0x021CCC80 - cmp r0, #0 - bne _020C1D44 - bl OS_GetProcMode - cmp r0, #0x12 - bne _020C1D50 -_020C1D44: - mov r0, #1 - strh r0, [r4] - ldmia sp!, {r4, r5, r6, pc} -_020C1D50: - ldr r0, _020C1DD4 ; =0x021CCC5C - ldr r0, [r0, #8] - ldr r6, [r0, #0] - bl OS_SelectThread - mov r5, r0 - cmp r6, r5 - cmpne r5, #0 - ldmeqia sp!, {r4, r5, r6, pc} - ldr r0, [r6, #0x64] - cmp r0, #2 - beq _020C1D8C - mov r0, r6 - bl OS_SaveContext - cmp r0, #0 - ldmneia sp!, {r4, r5, r6, pc} -_020C1D8C: - ldr r0, _020C1DD4 ; =0x021CCC5C - ldr r2, [r0, #0] - cmp r2, #0 - beq _020C1DA8 - mov r0, r6 - mov r1, r5 - blx r2 -_020C1DA8: - ldr r2, [r4, #0xc] - cmp r2, #0 - beq _020C1DC0 - mov r0, r6 - mov r1, r5 - blx r2 -_020C1DC0: - ldr r1, _020C1DD4 ; =0x021CCC5C - mov r0, r5 - str r5, [r1, #0x28] - bl OS_LoadContext - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C1DD4: .word Unk_021CCC5C -_020C1DD8: .word OSi_ThreadInfo - arm_func_end OSi_RescheduleThread - - arm_func_start OS_InitThread -OS_InitThread: ; 0x020C1DDC - stmfd sp!, {r3, lr} - sub sp, sp, #8 - ldr r0, _020C1EEC ; =0x021CCC5C - ldr r1, [r0, #0xc] - cmp r1, #0 - addne sp, sp, #8 - ldmneia sp!, {r3, pc} - mov r2, #1 - ldr r1, _020C1EF0 ; =0x021CCC84 - str r2, [r0, #0xc] - str r1, [r0, #8] - mov r1, #0x10 - str r1, [r0, #0x164] - mov r3, #0 - str r3, [r0, #0x160] - str r2, [r0, #0x158] - str r3, [r0, #0x15c] - ldr r2, _020C1EF4 ; =0x00000000 - ldr r1, _020C1EF8 ; =0x021CCD50 - str r3, [r0, #0x168] - str r1, [r0, #0x2c] - str r1, [r0, #0x28] - cmp r2, #0 - ldrle r0, _020C1EFC ; =0x027E0080 - ble _020C1E50 - ldr r1, _020C1F00 ; =0x027E0000 - ldr r0, _020C1F04 ; =0x00000800 - add r1, r1, #0x3f80 - sub r0, r1, r0 -_020C1E50: - ldr r1, _020C1F00 ; =0x027E0000 - sub ip, r0, r2 - add r2, r1, #0x3f80 - ldr r0, _020C1F04 ; =0x00000800 - ldr r1, _020C1EEC ; =0x021CCC5C - sub r3, r2, r0 - str r3, [r1, #0x188] - str ip, [r1, #0x184] - mov r0, #0 - ldr r2, _020C1F08 ; =0xFDDB597D - str r0, [r1, #0x18c] - str r2, [r3, #-4] - ldr r2, [r1, #0x184] - ldr ip, _020C1F0C ; =0x7BF9DD5B - ldr r3, _020C1F10 ; =0x021CCC80 - str ip, [r2] - str r0, [r1, #0x194] - str r0, [r1, #0x190] - strh r0, [r1, #0x24] - ldr r2, _020C1F14 ; =0x027FFFA0 - strh r0, [r1, #0x26] - str r3, [r2, #0] - bl OS_SetSwitchThreadCallback - mov r2, #0xc8 - str r2, [sp] - mov ip, #0x1f - ldr r0, _020C1F18 ; =0x021CCC90 - ldr r1, _020C1F1C ; =OSi_IdleThreadProc - ldr r3, _020C1F20 ; =0x021CCED8 - mov r2, #0 - str ip, [sp, #4] - bl OS_CreateThread - ldr r0, _020C1EEC ; =0x021CCC5C - mov r1, #0x20 - str r1, [r0, #0xa4] - mov r1, #1 - str r1, [r0, #0x98] - add sp, sp, #8 - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C1EEC: .word Unk_021CCC5C -_020C1EF0: .word 0x021CCC84 -_020C1EF4: .word 0x00000000 -_020C1EF8: .word Unk_021CCD50 -_020C1EFC: .word 0x027E0080 -_020C1F00: .word OS_IRQTable -_020C1F04: .word 0x00000800 -_020C1F08: .word 0xFDDB597D -_020C1F0C: .word 0x7BF9DD5B -_020C1F10: .word OSi_ThreadInfo -_020C1F14: .word 0x027FFFA0 -_020C1F18: .word Unk_021CCC90 -_020C1F1C: .word OSi_IdleThreadProc -_020C1F20: .word Unk_021CCED8 - arm_func_end OS_InitThread - - arm_func_start OS_IsThreadAvailable -OS_IsThreadAvailable: ; 0x020C1F24 - ldr r0, _020C1F30 ; =0x021CCC68 - ldr r0, [r0, #0] - bx lr - ; .align 2, 0 -_020C1F30: .word Unk_021CCC68 - arm_func_end OS_IsThreadAvailable - - arm_func_start OS_CreateThread -OS_CreateThread: ; 0x020C1F34 - stmfd sp!, {r4, r5, r6, r7, r8, lr} - mov r8, r0 - mov r5, r1 - mov r7, r2 - mov r6, r3 - bl OS_DisableInterrupts - mov r4, r0 - bl OSi_GetUnusedThreadId - ldr r2, [sp, #0x1c] - mov r1, #0 - str r2, [r8, #0x70] - str r0, [r8, #0x6c] - str r1, [r8, #0x64] - mov r0, r8 - str r1, [r8, #0x74] - bl OSi_InsertThreadToList - ldr r0, [sp, #0x18] - mov r1, r5 - str r6, [r8, #0x94] - sub r5, r6, r0 - sub r2, r6, #4 - mov ip, #0 - str r5, [r8, #0x90] - str ip, [r8, #0x98] - ldr r6, _020C2024 ; =0xFDDB597D - ldr r0, [r8, #0x94] - ldr r3, _020C2028 ; =0x7BF9DD5B - str r6, [r0, #-4] - ldr r0, [r8, #0x90] - str r3, [r0, #0] - str ip, [r8, #0xa0] - mov r0, r8 - str ip, [r8, #0x9c] - bl OS_InitContext - ldr r2, _020C202C ; =OS_ExitThread - str r7, [r8, #4] - str r2, [r8, #0x3c] - ldr r2, [sp, #0x18] - add r1, r5, #4 - mov r0, #0 - sub r2, r2, #8 - bl MIi_CpuClear32 - mov r1, #0 - str r1, [r8, #0x84] - str r1, [r8, #0x88] - mov r0, r8 - str r1, [r8, #0x8c] - bl OS_SetThreadDestructor - mov r0, #0 - str r0, [r8, #0x78] - str r0, [r8, #0x80] - add r1, r8, #0xa4 - mov r2, #0xc - str r0, [r8, #0x7c] - bl MIi_CpuClear32 - mov r1, #0 - mov r0, r4 - str r1, [r8, #0xb0] - bl OS_RestoreInterrupts - ldmia sp!, {r4, r5, r6, r7, r8, pc} - ; .align 2, 0 -_020C2024: .word 0xFDDB597D -_020C2028: .word 0x7BF9DD5B -_020C202C: .word OS_ExitThread - arm_func_end OS_CreateThread - - arm_func_start OS_ExitThread -OS_ExitThread: ; 0x020C2030 - stmfd sp!, {r3, lr} - bl OS_DisableInterrupts - ldr r0, _020C204C ; =0x021CCC5C - mov r1, #0 - ldr r0, [r0, #0x28] - bl OSi_ExitThread_ArgSpecified - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C204C: .word Unk_021CCC5C - arm_func_end OS_ExitThread - - arm_func_start OSi_ExitThread_ArgSpecified -OSi_ExitThread_ArgSpecified: ; 0x020C2050 - stmfd sp!, {r3, r4, r5, lr} - ldr r2, _020C20A4 ; =0x021CCC5C - mov r5, r0 - ldr r2, [r2, #0x1c] - mov r4, r1 - cmp r2, #0 - beq _020C2098 - ldr r1, _020C20A8 ; =OSi_ExitThread - bl OS_InitContext - str r4, [r5, #4] - ldr r1, [r5, #0] - mov r0, r5 - orr r1, r1, #0x80 - str r1, [r5, #0] - mov r1, #1 - str r1, [r5, #0x64] - bl OS_LoadContext - ldmia sp!, {r3, r4, r5, pc} -_020C2098: - mov r0, r4 - bl OSi_ExitThread - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C20A4: .word Unk_021CCC5C -_020C20A8: .word OSi_ExitThread - arm_func_end OSi_ExitThread_ArgSpecified - - arm_func_start OSi_ExitThread -OSi_ExitThread: ; 0x020C20AC - stmfd sp!, {r3, lr} - ldr r1, _020C20E0 ; =0x021CCC5C - ldr r1, [r1, #8] - ldr r3, [r1, #0] - ldr r2, [r3, #0xb4] - cmp r2, #0 - beq _020C20D8 - mov r1, #0 - str r1, [r3, #0xb4] - blx r2 - bl OS_DisableInterrupts -_020C20D8: - bl OSi_ExitThread_Destroy - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C20E0: .word Unk_021CCC5C - arm_func_end OSi_ExitThread - - arm_func_start OSi_ExitThread_Destroy -OSi_ExitThread_Destroy: ; 0x020C20E4 - stmfd sp!, {r4, lr} - ldr r0, _020C213C ; =0x021CCC5C - ldr r0, [r0, #8] - ldr r4, [r0, #0] - bl OS_DisableScheduler - mov r0, r4 - bl OSi_UnlockAllMutex - ldr r0, [r4, #0x78] - cmp r0, #0 - beq _020C2114 - mov r1, r4 - bl OSi_RemoveSpecifiedLinkFromQueue -_020C2114: - mov r0, r4 - bl OSi_RemoveThreadFromList - mov r1, #2 - add r0, r4, #0x9c - str r1, [r4, #0x64] - bl OS_WakeupThread - bl OS_EnableScheduler - bl OS_RescheduleThread - bl OS_Terminate - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C213C: .word Unk_021CCC5C - arm_func_end OSi_ExitThread_Destroy - - arm_func_start OS_DestroyThread -OS_DestroyThread: ; 0x020C2140 - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, _020C21B8 ; =0x021CCC5C - mov r4, r0 - ldr r0, [r1, #0x28] - cmp r0, r5 - bne _020C2164 - bl OSi_ExitThread_Destroy -_020C2164: - bl OS_DisableScheduler - mov r0, r5 - bl OSi_UnlockAllMutex - mov r0, r5 - bl OSi_CancelThreadAlarmForSleep - ldr r0, [r5, #0x78] - cmp r0, #0 - beq _020C218C - mov r1, r5 - bl OSi_RemoveSpecifiedLinkFromQueue -_020C218C: - mov r0, r5 - bl OSi_RemoveThreadFromList - mov r1, #2 - add r0, r5, #0x9c - str r1, [r5, #0x64] - bl OS_WakeupThread - bl OS_EnableScheduler - mov r0, r4 - bl OS_RestoreInterrupts - bl OS_RescheduleThread - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C21B8: .word Unk_021CCC5C - arm_func_end OS_DestroyThread - - arm_func_start OSi_CancelThreadAlarmForSleep -OSi_CancelThreadAlarmForSleep: ; 0x020C21BC - stmfd sp!, {r3, lr} - ldr r0, [r0, #0xb0] - cmp r0, #0 - ldmeqia sp!, {r3, pc} - bl OS_CancelAlarm - ldmia sp!, {r3, pc} - arm_func_end OSi_CancelThreadAlarmForSleep - - arm_func_start OS_JoinThread -OS_JoinThread: ; 0x020C21D4 - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, [r5, #0x64] - mov r4, r0 - cmp r1, #2 - beq _020C21F8 - add r0, r5, #0x9c - bl OS_SleepThread -_020C21F8: - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, pc} - arm_func_end OS_JoinThread - - arm_func_start OS_IsThreadTerminated -OS_IsThreadTerminated: ; 0x020C2204 - ldr r0, [r0, #0x64] - cmp r0, #2 - moveq r0, #1 - movne r0, #0 - bx lr - arm_func_end OS_IsThreadTerminated - - arm_func_start OS_SleepThread -OS_SleepThread: ; 0x020C2218 - stmfd sp!, {r4, r5, r6, lr} - mov r6, r0 - bl OS_DisableInterrupts - ldr r1, _020C2264 ; =0x021CCC5C - mov r4, r0 - ldr r0, [r1, #8] - cmp r6, #0 - ldr r5, [r0, #0] - beq _020C224C - mov r0, r6 - mov r1, r5 - str r6, [r5, #0x78] - bl OSi_InsertLinkToQueue -_020C224C: - mov r0, #0 - str r0, [r5, #0x64] - bl OSi_RescheduleThread - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r4, r5, r6, pc} - ; .align 2, 0 -_020C2264: .word Unk_021CCC5C - arm_func_end OS_SleepThread - - arm_func_start OS_WakeupThread -OS_WakeupThread: ; 0x020C2268 - stmfd sp!, {r3, r4, r5, r6, r7, lr} - mov r7, r0 - bl OS_DisableInterrupts - ldr r1, [r7, #0] - mov r6, r0 - cmp r1, #0 - beq _020C22C4 - beq _020C22B4 - mov r5, #1 - mov r4, #0 -_020C2290: - mov r0, r7 - bl OSi_RemoveLinkFromQueue - str r5, [r0, #0x64] - str r4, [r0, #0x78] - str r4, [r0, #0x80] - str r4, [r0, #0x7c] - ldr r0, [r7, #0] - cmp r0, #0 - bne _020C2290 -_020C22B4: - mov r0, #0 - str r0, [r7, #4] - str r0, [r7, #0] - bl OSi_RescheduleThread -_020C22C4: - mov r0, r6 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, r6, r7, pc} - arm_func_end OS_WakeupThread - - arm_func_start OS_WakeupThreadDirect -OS_WakeupThreadDirect: ; 0x020C22D0 - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - mov r1, #1 - mov r4, r0 - str r1, [r5, #0x64] - bl OSi_RescheduleThread - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r3, r4, r5, pc} - arm_func_end OS_WakeupThreadDirect - - arm_func_start OS_SelectThread -OS_SelectThread: ; 0x020C22F8 - ldr r0, _020C231C ; =0x021CCC5C - ldr r0, [r0, #0x2c] - b _020C2308 -_020C2304: - ldr r0, [r0, #0x68] -_020C2308: - cmp r0, #0 - ldrne r1, [r0, #0x64] - cmpne r1, #1 - bne _020C2304 - bx lr - ; .align 2, 0 -_020C231C: .word Unk_021CCC5C - arm_func_end OS_SelectThread - - arm_func_start OS_RescheduleThread -OS_RescheduleThread: ; 0x020C2320 - stmfd sp!, {r4, lr} - bl OS_DisableInterrupts - mov r4, r0 - bl OSi_RescheduleThread - mov r0, r4 - bl OS_RestoreInterrupts - ldmia sp!, {r4, pc} - arm_func_end OS_RescheduleThread - - arm_func_start OS_YieldThread -OS_YieldThread: ; 0x020C233C - stmfd sp!, {r4, r5, r6, r7, r8, lr} - ldr r0, _020C23F0 ; =0x021CCC5C - mov r4, #0 - mov r5, r4 - mov r6, r4 - ldr r8, [r0, #0x28] - bl OS_DisableInterrupts - ldr r1, _020C23F0 ; =0x021CCC5C - mov r7, r0 - ldr r1, [r1, #0x2c] - mov r0, r4 - cmp r1, #0 - beq _020C239C - ldr r2, [r8, #0x70] -_020C2374: - cmp r1, r8 - moveq r4, r0 - ldr r0, [r1, #0x70] - cmp r2, r0 - moveq r5, r1 - mov r0, r1 - ldr r1, [r1, #0x68] - addeq r6, r6, #1 - cmp r1, #0 - bne _020C2374 -_020C239C: - cmp r6, #1 - ble _020C23AC - cmp r5, r8 - bne _020C23B8 -_020C23AC: - mov r0, r7 - bl OS_RestoreInterrupts - ldmia sp!, {r4, r5, r6, r7, r8, pc} -_020C23B8: - cmp r4, #0 - ldrne r0, [r8, #0x68] - strne r0, [r4, #0x68] - bne _020C23D4 - ldr r1, [r8, #0x68] - ldr r0, _020C23F0 ; =0x021CCC5C - str r1, [r0, #0x2c] -_020C23D4: - ldr r0, [r5, #0x68] - str r0, [r8, #0x68] - str r8, [r5, #0x68] - bl OSi_RescheduleThread - mov r0, r7 - bl OS_RestoreInterrupts - ldmia sp!, {r4, r5, r6, r7, r8, pc} - ; .align 2, 0 -_020C23F0: .word Unk_021CCC5C - arm_func_end OS_YieldThread - - arm_func_start OS_SetThreadPriority -OS_SetThreadPriority: ; 0x020C23F4 - stmfd sp!, {r4, r5, r6, r7, r8, lr} - ldr r2, _020C2494 ; =0x021CCC5C - mov r7, r0 - mov r6, r1 - ldr r8, [r2, #0x2c] - mov r4, #0 - bl OS_DisableInterrupts - mov r5, r0 - b _020C2420 -_020C2418: - mov r4, r8 - ldr r8, [r8, #0x68] -_020C2420: - cmp r8, #0 - cmpne r8, r7 - bne _020C2418 - cmp r8, #0 - ldrne r0, _020C2498 ; =0x021CCC90 - cmpne r8, r0 - bne _020C244C - mov r0, r5 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r4, r5, r6, r7, r8, pc} -_020C244C: - ldr r0, [r8, #0x70] - cmp r0, r6 - beq _020C2484 - cmp r4, #0 - ldrne r0, [r7, #0x68] - strne r0, [r4, #0x68] - bne _020C2474 - ldr r1, [r7, #0x68] - ldr r0, _020C2494 ; =0x021CCC5C - str r1, [r0, #0x2c] -_020C2474: - mov r0, r7 - str r6, [r7, #0x70] - bl OSi_InsertThreadToList - bl OSi_RescheduleThread -_020C2484: - mov r0, r5 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r4, r5, r6, r7, r8, pc} - ; .align 2, 0 -_020C2494: .word Unk_021CCC5C -_020C2498: .word Unk_021CCC90 - arm_func_end OS_SetThreadPriority - - arm_func_start OS_GetThreadPriority -OS_GetThreadPriority: ; 0x020C249C - ldr r0, [r0, #0x70] - bx lr - arm_func_end OS_GetThreadPriority - - arm_func_start OS_Sleep -OS_Sleep: ; 0x020C24A4 - stmfd sp!, {r4, r5, lr} - sub sp, sp, #0x34 - mov r4, r0 - add r0, sp, #8 - bl OS_CreateAlarm - ldr r0, _020C2540 ; =0x021CCC5C - ldr r0, [r0, #8] - ldr r0, [r0, #0] - str r0, [sp, #4] - bl OS_DisableInterrupts - ldr r1, _020C2544 ; =0x000082EA - mov r2, #0 - umull r5, r3, r4, r1 - mla r3, r4, r2, r3 - mla r3, r2, r1, r3 - mov r1, r5, lsr #6 - mov r4, r0 - ldr r5, [sp, #4] - add r0, sp, #8 - add r2, sp, #4 - str r0, [r5, #0xb0] - str r2, [sp] - mov r2, r3, lsr #6 - orr r1, r1, r3, lsl #26 - ldr r3, _020C2548 ; =OSi_SleepAlarmCallback - bl OS_SetAlarm - ldr r0, [sp, #4] - cmp r0, #0 - beq _020C2530 - mov r5, #0 -_020C251C: - mov r0, r5 - bl OS_SleepThread - ldr r0, [sp, #4] - cmp r0, #0 - bne _020C251C -_020C2530: - mov r0, r4 - bl OS_RestoreInterrupts - add sp, sp, #0x34 - ldmia sp!, {r4, r5, pc} - ; .align 2, 0 -_020C2540: .word Unk_021CCC5C -_020C2544: .word 0x000082EA -_020C2548: .word OSi_SleepAlarmCallback - arm_func_end OS_Sleep - - arm_func_start OSi_SleepAlarmCallback -OSi_SleepAlarmCallback: ; 0x020C254C - ldr r2, [r0, #0] - mov r1, #0 - str r1, [r0, #0] - ldr ip, _020C2568 ; =OS_WakeupThreadDirect - mov r0, r2 - str r1, [r2, #0xb0] - bx ip - ; .align 2, 0 -_020C2568: .word OS_WakeupThreadDirect - arm_func_end OSi_SleepAlarmCallback - - arm_func_start OS_SetSwitchThreadCallback -OS_SetSwitchThreadCallback: ; 0x020C256C - stmfd sp!, {r3, r4, r5, lr} - mov r5, r0 - bl OS_DisableInterrupts - ldr r1, _020C2590 ; =0x021CCC5C - ldr r4, [r1, #0x30] - str r5, [r1, #0x30] - bl OS_RestoreInterrupts - mov r0, r4 - ldmia sp!, {r3, r4, r5, pc} - ; .align 2, 0 -_020C2590: .word Unk_021CCC5C - arm_func_end OS_SetSwitchThreadCallback - - arm_func_start OSi_IdleThreadProc -OSi_IdleThreadProc: ; 0x020C2594 - stmfd sp!, {r3, lr} - bl OS_EnableInterrupts -_020C259C: - bl OS_Halt - b _020C259C - arm_func_end OSi_IdleThreadProc - - arm_func_start OS_DisableScheduler -OS_DisableScheduler: ; 0x020C25A4 - stmfd sp!, {r4, lr} - bl OS_DisableInterrupts - ldr r2, _020C25D4 ; =0x021CCC5C - mvn r1, #0 - ldr r3, [r2, #4] - cmp r3, r1 - addlo r1, r3, #1 - movlo r4, r3 - strlo r1, [r2, #4] - bl OS_RestoreInterrupts - mov r0, r4 - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C25D4: .word Unk_021CCC5C - arm_func_end OS_DisableScheduler - - arm_func_start OS_EnableScheduler -OS_EnableScheduler: ; 0x020C25D8 - stmfd sp!, {r4, lr} - bl OS_DisableInterrupts - ldr r1, _020C2608 ; =0x021CCC5C - mov r4, #0 - ldr r3, [r1, #4] - cmp r3, #0 - subne r2, r3, #1 - movne r4, r3 - strne r2, [r1, #4] - bl OS_RestoreInterrupts - mov r0, r4 - ldmia sp!, {r4, pc} - ; .align 2, 0 -_020C2608: .word Unk_021CCC5C - arm_func_end OS_EnableScheduler - - arm_func_start OS_SetThreadDestructor -OS_SetThreadDestructor: ; 0x020C260C - str r1, [r0, #0xb4] - bx lr - arm_func_end OS_SetThreadDestructor - - .bss - - - .global Unk_021CCC5C -Unk_021CCC5C: ; 0x021CCC5C - .space 0x4 - - .global Unk_021CCC60 -Unk_021CCC60: ; 0x021CCC60 - .space 0x4 - - .global Unk_021CCC64 -Unk_021CCC64: ; 0x021CCC64 - .space 0x4 - - .global Unk_021CCC68 -Unk_021CCC68: ; 0x021CCC68 - .space 0x4 - - .global Unk_021CCC6C -Unk_021CCC6C: ; 0x021CCC6C - .space 0x4 - - .global Unk_021CCC70 -Unk_021CCC70: ; 0x021CCC70 - .space 0x4 - - .global Unk_021CCC74 -Unk_021CCC74: ; 0x021CCC74 - .space 0x4 - - .global Unk_021CCC78 -Unk_021CCC78: ; 0x021CCC78 - .space 0x4 - - .global Unk_021CCC7C -Unk_021CCC7C: ; 0x021CCC7C - .space 0x4 - - .global OSi_ThreadInfo -OSi_ThreadInfo: ; 0x021CCC80 - .space 0x10 - - .global Unk_021CCC90 -Unk_021CCC90: ; 0x021CCC90 - .space 0xC0 - - .global Unk_021CCD50 -Unk_021CCD50: ; 0x021CCD50 - .space 0xC0 - - .global Unk_021CCE10 -Unk_021CCE10: ; 0x021CCE10 - .space 0xC8 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_tick.s b/subprojects/NitroSDK/libraries/os/asm/os_tick.s deleted file mode 100644 index 623d0fd1ae..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_tick.s +++ /dev/null @@ -1,155 +0,0 @@ - .include "macros/function.inc" - .include "include/os_tick.inc" - - .extern Unk_021CCFB4 - - - .text - - - arm_func_start OS_InitTick -OS_InitTick: ; 0x020C3790 - stmfd sp!, {r3, lr} - ldr r1, _020C37FC ; =0x021CCFB4 - ldrh r0, [r1] - cmp r0, #0 - ldmneia sp!, {r3, pc} - mov r2, #1 - mov r0, #0 - strh r2, [r1] - bl OSi_SetTimerReserved - ldr r0, _020C37FC ; =0x021CCFB4 - mov r2, #0 - str r2, [r0, #8] - ldr r3, _020C3800 ; =0x04000102 - str r2, [r0, #0xc] - strh r2, [r3] - ldr r1, _020C3804 ; =OSi_CountUpTick - strh r2, [r3, #-2] - mov r2, #0xc1 - mov r0, #8 - strh r2, [r3] - bl OS_SetIrqFunction - mov r0, #8 - bl OS_EnableIrqMask - ldr r0, _020C37FC ; =0x021CCFB4 - mov r1, #0 - str r1, [r0, #4] - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C37FC: .word Unk_021CCFB4 -_020C3800: .word 0x04000102 -_020C3804: .word OSi_CountUpTick - arm_func_end OS_InitTick - - arm_func_start OS_IsTickAvailable -OS_IsTickAvailable: ; 0x020C3808 - ldr r0, _020C3814 ; =0x021CCFB4 - ldrh r0, [r0] - bx lr - ; .align 2, 0 -_020C3814: .word Unk_021CCFB4 - arm_func_end OS_IsTickAvailable - - arm_func_start OSi_CountUpTick -OSi_CountUpTick: ; 0x020C3818 - ldr r0, _020C3870 ; =0x021CCFB4 - mov r3, #0 - ldr r2, [r0, #8] - ldr r1, [r0, #0xc] - adds r2, r2, #1 - str r2, [r0, #8] - adc r1, r1, #0 - str r1, [r0, #0xc] - ldr r1, [r0, #4] - cmp r1, #0 - beq _020C385C - ldr r2, _020C3874 ; =0x04000102 - mov r1, #0xc1 - strh r3, [r2] - strh r3, [r2, #-2] - strh r1, [r2] - str r3, [r0, #4] -_020C385C: - ldr ip, _020C3878 ; =OSi_EnterTimerCallback - mov r0, #0 - ldr r1, _020C387C ; =OSi_CountUpTick - mov r2, r0 - bx ip - ; .align 2, 0 -_020C3870: .word Unk_021CCFB4 -_020C3874: .word 0x04000102 -_020C3878: .word OSi_EnterTimerCallback -_020C387C: .word OSi_CountUpTick - arm_func_end OSi_CountUpTick - - arm_func_start OS_GetTick -OS_GetTick: ; 0x020C3880 - stmdb sp!, {lr} - sub sp, sp, #0xc - bl OS_DisableInterrupts - ldr lr, _020C3914 ; =0x04000100 - ldr r2, _020C3918 ; =0x0000FFFF - ldrh ip, [lr] - ldr r3, _020C391C ; =0x021CCFB4 - sub r1, r2, #0x10000 - strh ip, [sp] - ldr ip, [r3, #8] - ldr r3, [r3, #0xc] - and ip, ip, r1 - and r1, r3, r2 - str ip, [sp, #4] - str r1, [sp, #8] - ldr r1, [lr, #0x114] - tst r1, #8 - beq _020C38EC - ldrh r1, [sp] - tst r1, #0x8000 - bne _020C38EC - ldr r2, [sp, #4] - ldr r1, [sp, #8] - adds r2, r2, #1 - adc r1, r1, #0 - str r2, [sp, #4] - str r1, [sp, #8] -_020C38EC: - bl OS_RestoreInterrupts - ldr r2, [sp, #4] - ldr r1, [sp, #8] - ldrh r0, [sp] - mov r1, r1, lsl #0x10 - orr r1, r1, r2, lsr #16 - orr r1, r1, r0, asr #31 - orr r0, r0, r2, lsl #16 - add sp, sp, #0xc - ldmia sp!, {pc} - ; .align 2, 0 -_020C3914: .word 0x04000100 -_020C3918: .word 0x0000FFFF -_020C391C: .word Unk_021CCFB4 - arm_func_end OS_GetTick - - arm_func_start OS_GetTickLo -OS_GetTickLo: ; 0x020C3920 - ldr r0, _020C392C ; =0x04000100 - ldrh r0, [r0] - bx lr - ; .align 2, 0 -_020C392C: .word 0x04000100 - arm_func_end OS_GetTickLo - - .bss - - - .global Unk_021CCFB4 -Unk_021CCFB4: ; 0x021CCFB4 - .space 0x4 - - .global Unk_021CCFB8 -Unk_021CCFB8: ; 0x021CCFB8 - .space 0x4 - - .global Unk_021CCFBC -Unk_021CCFBC: ; 0x021CCFBC - .space 0x8 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_timer.s b/subprojects/NitroSDK/libraries/os/asm/os_timer.s deleted file mode 100644 index 6ce083b6be..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_timer.s +++ /dev/null @@ -1,27 +0,0 @@ - .include "macros/function.inc" - - - .extern Unk_021CCFB0 - - .text - - - arm_func_start OSi_SetTimerReserved -OSi_SetTimerReserved: ; 0x020C3774 - ldr r1, _020C378C ; =0x021CCFB0 - mov r2, #1 - ldrh r3, [r1] - orr r0, r3, r2, lsl r0 - strh r0, [r1] - bx lr - ; .align 2, 0 -_020C378C: .word Unk_021CCFB0 - arm_func_end OSi_SetTimerReserved - - .bss - - - .global Unk_021CCFB0 -Unk_021CCFB0: ; 0x021CCFB0 - .space 0x2 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_valarm.s b/subprojects/NitroSDK/libraries/os/asm/os_valarm.s deleted file mode 100644 index 01c4fcced0..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_valarm.s +++ /dev/null @@ -1,51 +0,0 @@ - .include "macros/function.inc" - .include "include/os_valarm.inc" - - .extern Unk_021CCFD0 - - - .text - - - arm_func_start OS_InitVAlarm -OS_InitVAlarm: ; 0x020C3D3C - stmfd sp!, {r3, lr} - ldr r1, _020C3D80 ; =0x021CCFD0 - ldrh r0, [r1] - cmp r0, #0 - ldmneia sp!, {r3, pc} - mov r0, #1 - strh r0, [r1] - mov r2, #0 - str r2, [r1, #0xc] - mov r0, #4 - str r2, [r1, #0x10] - bl OS_DisableIrqMask - ldr r0, _020C3D80 ; =0x021CCFD0 - mov r1, #0 - str r1, [r0, #8] - str r1, [r0, #4] - ldmia sp!, {r3, pc} - ; .align 2, 0 -_020C3D80: .word Unk_021CCFD0 - arm_func_end OS_InitVAlarm - - .bss - - - .global Unk_021CCFD0 -Unk_021CCFD0: ; 0x021CCFD0 - .space 0x2 - - .global Unk_021CCFD4 -Unk_021CCFD4: ; 0x021CCFD4 - .space 0x4 - - .global Unk_021CCFD8 -Unk_021CCFD8: ; 0x021CCFD8 - .space 0x4 - - .global Unk_021CCFDC -Unk_021CCFDC: ; 0x021CCFDC - .space 0x8 - diff --git a/subprojects/NitroSDK/libraries/os/asm/os_vramexclusive.s b/subprojects/NitroSDK/libraries/os/asm/os_vramexclusive.s deleted file mode 100644 index a692815a23..0000000000 --- a/subprojects/NitroSDK/libraries/os/asm/os_vramexclusive.s +++ /dev/null @@ -1,144 +0,0 @@ - .include "macros/function.inc" - .include "include/os_vramexclusive.inc" - - .extern Unk_021CCFE8 - .extern Unk_021CCFEC - - - .text - - - arm_func_start OsCountZeroBits -OsCountZeroBits: ; 0x020C4054 - clz r0, r0 - bx lr - arm_func_end OsCountZeroBits - - arm_func_start OSi_InitVramExclusive -OSi_InitVramExclusive: ; 0x020C405C - ldr r0, _020C4088 ; =0x021CCFE8 - mov r3, #0 - str r3, [r0, #0] - ldr r0, _020C408C ; =0x021CCFEC - mov r2, r3 -_020C4070: - mov r1, r3, lsl #1 - add r3, r3, #1 - strh r2, [r0, r1] - cmp r3, #9 - blt _020C4070 - bx lr - ; .align 2, 0 -_020C4088: .word Unk_021CCFE8 -_020C408C: .word Unk_021CCFEC - arm_func_end OSi_InitVramExclusive - - arm_func_start OSi_TryLockVram -OSi_TryLockVram: ; 0x020C4090 - stmfd sp!, {r3, r4, r5, r6, r7, r8, sb, lr} - mov r7, r0 - mov r8, r1 - bl OS_DisableInterrupts - ldr r1, _020C4144 ; =0x021CCFE8 - mov r6, r0 - ldr r0, [r1, #0] - ldr sb, _020C4148 ; =0x021CCFEC - and r5, r7, r0 - mov r4, #1 -_020C40B8: - mov r0, r5 - bl OsCountZeroBits - rsbs r1, r0, #0x1f - bmi _020C40F0 - mov r0, r1, lsl #1 - ldrh r0, [sb, r0] - mvn r1, r4, lsl r1 - cmp r8, r0 - and r5, r5, r1 - beq _020C40B8 - mov r0, r6 - bl OS_RestoreInterrupts - mov r0, #0 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} -_020C40F0: - ldr r0, _020C414C ; =0x000001FF - ldr r4, _020C4148 ; =0x021CCFEC - ldr sb, _020C4144 ; =0x021CCFE8 - and r7, r7, r0 - mov r5, #1 -_020C4104: - mov r0, r7 - bl OsCountZeroBits - rsbs r1, r0, #0x1f - bmi _020C4134 - ldr r0, [sb] - mvn r2, r5, lsl r1 - orr r0, r0, r5, lsl r1 - mov r1, r1, lsl #1 - strh r8, [r4, r1] - str r0, [sb] - and r7, r7, r2 - b _020C4104 -_020C4134: - mov r0, r6 - bl OS_RestoreInterrupts - mov r0, #1 - ldmia sp!, {r3, r4, r5, r6, r7, r8, sb, pc} - ; .align 2, 0 -_020C4144: .word Unk_021CCFE8 -_020C4148: .word Unk_021CCFEC -_020C414C: .word 0x000001FF - arm_func_end OSi_TryLockVram - - arm_func_start OSi_UnlockVram -OSi_UnlockVram: ; 0x020C4150 - stmfd sp!, {r4, r5, r6, r7, r8, sb, sl, lr} - mov r5, r0 - mov sl, r1 - bl OS_DisableInterrupts - ldr r4, _020C41CC ; =0x021CCFE8 - ldr r1, _020C41D0 ; =0x000001FF - ldr r2, [r4, #0] - mov sb, r0 - and r0, r5, r2 - ldr r6, _020C41D4 ; =0x021CCFEC - and r8, r0, r1 - mov r7, #1 - mov r5, #0 -_020C4184: - mov r0, r8 - bl OsCountZeroBits - rsbs r2, r0, #0x1f - bmi _020C41C0 - mov r1, r2, lsl #1 - ldrh r0, [r6, r1] - mvn r2, r7, lsl r2 - cmp sl, r0 - and r8, r8, r2 - bne _020C4184 - ldr r0, [r4, #0] - strh r5, [r6, r1] - and r0, r0, r2 - str r0, [r4, #0] - b _020C4184 -_020C41C0: - mov r0, sb - bl OS_RestoreInterrupts - ldmia sp!, {r4, r5, r6, r7, r8, sb, sl, pc} - ; .align 2, 0 -_020C41CC: .word Unk_021CCFE8 -_020C41D0: .word 0x000001FF -_020C41D4: .word Unk_021CCFEC - arm_func_end OSi_UnlockVram - - .bss - - - .global Unk_021CCFE8 -Unk_021CCFE8: ; 0x021CCFE8 - .space 0x4 - - .global Unk_021CCFEC -Unk_021CCFEC: ; 0x021CCFEC - .space 0x12 - diff --git a/subprojects/NitroSDK/libraries/os/meson.build b/subprojects/NitroSDK/libraries/os/meson.build index 74b8e523b1..3e1cb05554 100644 --- a/subprojects/NitroSDK/libraries/os/meson.build +++ b/subprojects/NitroSDK/libraries/os/meson.build @@ -1,32 +1,32 @@ libos_srcs = files( - 'asm/os_irqhandler.s', - 'asm/os_irqtable.s', - 'asm/os_interrupt.s', - 'asm/os_spinlock.s', - 'asm/os_printf.s', - 'asm/os_thread.s', - 'asm/os_context.s', - 'asm/os_emulator.s', - 'asm/os_message.s', - 'asm/os_mutex.s', - 'asm/os_cache.s', - 'asm/os_init.s', - 'asm/os_arena.s', - 'asm/os_alloc.s', - 'asm/os_tcm.s', - 'asm/os_protectionunit.s', - 'asm/os_protectionregion.s', - 'asm/os_exception.s', - 'asm/os_timer.s', - 'asm/os_tick.s', - 'asm/os_alarm.s', - 'asm/os_valarm.s', - 'asm/os_system.s', - 'asm/os_reset.s', - 'asm/os_ownerinfo.s', - 'asm/os_vramexclusive.s', - 'asm/os_entropy.s', - 'asm/os_terminate_proc.s' + 'src/os_irqHandler.c', + 'src/os_irqTable.c', + 'src/os_interrupt.c', + 'src/os_spinLock.c', + 'src/os_printf.c', + 'src/os_thread.c', + 'src/os_context.c', + 'src/os_emulator.c', + 'src/os_message.c', + 'src/os_mutex.c', + 'src/os_cache.c', + 'src/os_init.c', + 'src/os_arena.c', + 'src/os_alloc.c', + 'src/os_tcm.c', + 'src/os_protectionUnit.c', + 'src/os_protectionRegion.c', + 'src/os_exception.c', + 'src/os_timer.c', + 'src/os_tick.c', + 'src/os_alarm.c', + 'src/os_valarm.c', + 'src/os_system.c', + 'src/os_reset.c', + 'src/os_ownerInfo.c', + 'src/os_vramExclusive.c', + 'src/os_entropy.c', + 'src/os_terminate_proc.c' ) libos = static_library('os', diff --git a/subprojects/NitroSDK/libraries/os/src/os_alarm.c b/subprojects/NitroSDK/libraries/os/src/os_alarm.c new file mode 100644 index 0000000000..a2ca58997d --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_alarm.c @@ -0,0 +1,360 @@ +#include + +#define OSi_ALARM_TIMERCONTROL (REG_OS_TM0CNT_H_E_MASK | REG_OS_TM0CNT_H_I_MASK | OS_TIMER_PRESCALER_64) + +#define OSi_ALARM_TIMER OS_TIMER_1 + +#define OSi_ALARM_IE_TIMER OS_IE_TIMER1 + +static u16 OSi_UseAlarm = FALSE; + +static struct OSiAlarmQueue OSi_AlarmQueue; + +u16 OSi_IsTimerReserved(int timerNum); +void OSi_SetTimerReserved(int timerNum); +void OSi_UnsetTimerReserved(int timerNum); + +static void OSi_SetTimer(OSAlarm *alarm); +static void OSi_InsertAlarm(OSAlarm *alarm, OSTick fire); + +static void OSi_AlarmHandler(void *arg); +static void OSi_ArrangeTimer(void); + +static void OSi_SetTimer (OSAlarm *alarm) +{ + s64 delta; + OSTick tick = OS_GetTick(); + u16 timerCount; + + OS_SetTimerControl(OSi_ALARM_TIMER, 0); + + delta = (s64)(alarm->fire - tick); + + OSi_EnterTimerCallback(OSi_ALARM_TIMER, OSi_AlarmHandler, NULL); + + if (delta < 0) { + timerCount = (u16) ~1; + } else if (delta < 0x10000) { + timerCount = (u16)(~delta); + } else { + timerCount = 0; + } + + OS_SetTimerCount((OSTimer)OSi_ALARM_TIMER, timerCount); + OS_SetTimerControl(OSi_ALARM_TIMER, (u16)OSi_ALARM_TIMERCONTROL); + + (void)OS_EnableIrqMask(OSi_ALARM_IE_TIMER); +} + +void OS_InitAlarm (void) +{ + if (!OSi_UseAlarm) { + OSi_UseAlarm = TRUE; + + SDK_ASSERTMSG(OS_IsTickAvailable(), "OS_InitAlarm: alarm system needs of tick system."); + + SDK_ASSERT(!OSi_IsTimerReserved(OSi_ALARM_TIMER)); + OSi_SetTimerReserved(OSi_ALARM_TIMER); + + OSi_AlarmQueue.head = NULL; + OSi_AlarmQueue.tail = NULL; + + (void)OS_DisableIrqMask(OSi_ALARM_IE_TIMER); + } +} + +void OS_EndAlarm (void) +{ + OSIntrMode enabled; + + SDK_ASSERT(OSi_UseAlarm); + enabled = OS_DisableInterrupts(); + + if (OSi_UseAlarm) { + SDK_ASSERTMSG(!OSi_AlarmQueue.head, + "OS_EndAlarm: Cannot end alarm system while using alarm."); + + SDK_ASSERT(OSi_IsTimerReserved(OSi_ALARM_TIMER)); + OSi_UnsetTimerReserved(OSi_ALARM_TIMER); + + OSi_UseAlarm = FALSE; + } + + (void)OS_RestoreInterrupts(enabled); +} + +BOOL OS_IsAlarmAvailable (void) +{ + return OSi_UseAlarm; +} + +void OS_CreateAlarm (OSAlarm *alarm) +{ + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERT(alarm); + + alarm->handler = 0; + alarm->tag = 0; +} + +static void OSi_InsertAlarm (OSAlarm *alarm, OSTick fire) +{ + OSAlarm *prev; + OSAlarm *next; + + if (alarm->period > 0) { + OSTick tick = OS_GetTick(); + + fire = alarm->start; + if (alarm->start < tick) { + fire += alarm->period * ((tick - alarm->start) / alarm->period + 1); + } + } + + alarm->fire = fire; + + for (next = OSi_AlarmQueue.head; next; next = next->next) { + + if ((s64)(fire - next->fire) >= 0) { + continue; + } + + alarm->prev = next->prev; + next->prev = alarm; + alarm->next = next; + prev = alarm->prev; + if (prev) { + prev->next = alarm; + } else { + OSi_AlarmQueue.head = alarm; + OSi_SetTimer(alarm); + } + + return; + } + + alarm->next = 0; + prev = OSi_AlarmQueue.tail; + OSi_AlarmQueue.tail = alarm; + alarm->prev = prev; + if (prev) { + prev->next = alarm; + } else { + OSi_AlarmQueue.head = OSi_AlarmQueue.tail = alarm; + OSi_SetTimer(alarm); + } +} + +void OS_SetAlarm (OSAlarm *alarm, OSTick tick, OSAlarmHandler handler, void *arg) +{ + OSIntrMode enabled; + + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERTMSG(handler, "OS_SetAlarm: handler must not be NULL."); + if (!alarm || alarm->handler) { +#ifndef SDK_FINALROM + OS_Panic("alarm could be already used."); +#else + OS_Panic(""); +#endif + } + + enabled = OS_DisableInterrupts(); + + alarm->period = 0; + + alarm->handler = handler; + alarm->arg = arg; + + OSi_InsertAlarm(alarm, OS_GetTick() + tick); + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_SetPeriodicAlarm (OSAlarm *alarm, OSTick start, OSTick period, OSAlarmHandler handler, + void *arg) +{ + u32 enabled; + + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERTMSG(handler, "OS_SetPeriodicAlarm: handler must not be NULL\n"); + SDK_ASSERTMSG(period > 0, "OS_SetPeriodicAlarm: bad period specified."); + if (!alarm || alarm->handler) { +#ifndef SDK_FINALROM + OS_Panic("alarm could be already used."); +#else + OS_Panic(""); +#endif + } + + enabled = OS_DisableInterrupts(); + + alarm->period = period; + alarm->start = start; + + alarm->handler = handler; + alarm->arg = arg; + + OSi_InsertAlarm(alarm, 0); + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_CancelAlarm (OSAlarm *alarm) +{ + OSAlarm *next; + u32 enabled; + + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERT(alarm); + + enabled = OS_DisableInterrupts(); + + if (alarm->handler == NULL) { + (void)OS_RestoreInterrupts(enabled); + return; + } + + next = alarm->next; + if (next == NULL) { + OSi_AlarmQueue.tail = alarm->prev; + } else { + next->prev = alarm->prev; + } + + if (alarm->prev) { + alarm->prev->next = next; + } else { + OSi_AlarmQueue.head = next; + if (next) { + OSi_SetTimer(next); + } + } + + alarm->handler = NULL; + alarm->period = 0; + + (void)OS_RestoreInterrupts(enabled); +} + +#include +asm void OSi_AlarmHandler ( void *arg ) +{ + stmfd sp !, {r0, lr} + bl OSi_ArrangeTimer + ldmfd sp !, {r0, lr} + bx lr +} +#include + +static void OSi_ArrangeTimer (void) +{ + OSTick tick; + OSAlarm *alarm; + OSAlarm *next; + OSAlarmHandler handler; + + OS_SetTimerControl(OSi_ALARM_TIMER, 0); + + (void)OS_DisableIrqMask(OSi_ALARM_IE_TIMER); + + OS_SetIrqCheckFlag(OSi_ALARM_IE_TIMER); + + tick = OS_GetTick(); + alarm = OSi_AlarmQueue.head; + + if (alarm == NULL) { + return; + } + + if (tick < alarm->fire) { + OSi_SetTimer(alarm); + return; + } + + next = alarm->next; + OSi_AlarmQueue.head = next; + + if (next == NULL) { + OSi_AlarmQueue.tail = NULL; + } else { + next->prev = NULL; + } + + handler = alarm->handler; + + if (alarm->period == 0) { + alarm->handler = NULL; + } + + if (handler) { + (handler) (alarm->arg); + } + + if (alarm->period > 0) { + alarm->handler = handler; + OSi_InsertAlarm(alarm, 0); + } + + if (OSi_AlarmQueue.head) { + OSi_SetTimer(OSi_AlarmQueue.head); + } +} + +void OS_SetAlarmTag (OSAlarm *alarm, u32 tag) +{ + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERT(alarm); + SDK_ASSERTMSG(tag > 0, "OS_SetAlarmTag: Tag must be >0."); + + alarm->tag = tag; +} + +void OS_CancelAlarms (u32 tag) +{ + u32 enabled; + OSAlarm *alarm; + OSAlarm *next; + + SDK_ASSERT(OSi_UseAlarm); + SDK_ASSERTMSG(tag > 0, "OSCancelAlarms: Tag must be >0."); + + if (tag == 0) { + return; + } + + enabled = OS_DisableInterrupts(); + + for (alarm = OSi_AlarmQueue.head, next = alarm ? alarm->next : NULL; + alarm; alarm = next, next = alarm ? alarm->next : NULL) { + if (alarm->tag == tag) { + + OS_CancelAlarm(alarm); + } + } + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_CancelAllAlarms (void) +{ + u32 enabled; + OSAlarm *alarm; + OSAlarm *next; + + SDK_ASSERT(OSi_UseAlarm); + enabled = OS_DisableInterrupts(); + + for (alarm = OSi_AlarmQueue.head, next = alarm ? alarm->next : NULL; + alarm; alarm = next, next = alarm ? alarm->next : NULL) { + + OS_CancelAlarm(alarm); + } + + (void)OS_RestoreInterrupts(enabled); +} + +struct OSiAlarmQueue *OSi_GetAlarmQueue (void) +{ + return &OSi_AlarmQueue; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_alloc.c b/subprojects/NitroSDK/libraries/os/src/os_alloc.c new file mode 100644 index 0000000000..b4b0a3d7d0 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_alloc.c @@ -0,0 +1,1079 @@ +#include +#include + +#define OS_ERR_ALLOCFROMHEAP_NOHEAP "OS_AllocFromHeap(): heap is not initialized." +#define OS_ERR_ALLOCFROMHEAP_INVSIZE "OS_AllocFromHeap(): invalid size." +#define OS_ERR_ALLOCFROMHEAP_INVHEAP "OS_AllocFromHeap(): invalid heap handle." +#define OS_ERR_ALLOCFROMHEAP_BROKENHEAP "OS_AllocFromHeap(): heap is broken." +#define OS_ERR_ALLOCFIXED_NOHEAP "OS_AllocFixed(): heap is not initialized." +#define OS_ERR_ALLOCFIXED_INVRANGE "OS_AllocFixed(): invalid range." +#define OS_ERR_FREETOHEAP_NOHEAP "OS_FreeToHeap(): heap is not initialized." +#define OS_ERR_FREETOHEAP_INVPTR "OS_FreeToHeap(): invalid pointer." +#define OS_ERR_FREETOHEAP_INVHEAP "OS_FreeToHeap(): invalid heap handle." +#define OS_ERR_SETCURRENTHEAP_NOHEAP "OS_SetCurrentHeap(): heap is not initialized." +#define OS_ERR_SETCURRENTHEAP_INVHEAP "OS_SetCurrentHeap(): invalid heap handle." +#define OS_ERR_INITALLOC_INVNUMHEAPS "OS_InitAlloc(): invalid number of heaps." +#define OS_ERR_INITALLOC_INVRANGE "OS_InitAlloc(): invalid range." +#define OS_ERR_INITALLOC_INSRANGE "OS_InitAlloc(): too small range." +#define OS_ERR_CLEARALLOC_INVID "OS_ClearAlloc(): invalid arena id." +#define OS_ERR_CREATEHEAP_NOHEAP "OS_CreateHeap(): heap is not initialized." +#define OS_ERR_CREATEHEAP_INVRANGE "OS_CreateHeap(): invalid range." +#define OS_ERR_CREATEHEAP_INSRANGE "OS_CreateHeap(): too small range." +#define OS_ERR_DESTROYHEAP_NOHEAP "OS_DestroyHeap(): heap is not initialized." +#define OS_ERR_DESTROYHEAP_INVHEAP "OS_DestroyHeap(): invalid heap handle." +#define OS_ERR_ADDTOHEAP_NOHEAP "OS_AddToHeap(): heap is not initialized." +#define OS_ERR_ADDTOHEAP_INVHEAP "OS_AddToHeap(): invalid heap handle." +#define OS_ERR_ADDTOHEAP_INVRANGE "OS_AddToHeap(): invalid range." +#define OS_ERR_ADDTOHEAP_INSRANGE "OS_AddToHeap(): too small range." +#define OS_ERR_REFERENT_NOHEAP "OS_ReferentSize(): heap is not initialized." +#define OS_ERR_REFERENT_INVPTR "OS_ReferentSize(): invalid pointer." +#define OS_ERR_DUMPHEAP_NOHEAP "OS_DumpHeap(): heap is not initialized." +#define OS_ERR_DUMPHEAP_INVHEAP "OS_DumpHeap(): invalid heap handle." +#define OS_ERR_DUMPHEAP_BROKENHEAP "OS_DumpHeap(): heap is broken." +#define OS_ERR_ALLOCFROMHEAP_INVID "OS_AllocFromHeap(): illegal arena id." +#define OS_ERR_ALLOCFROMHEAP_NOINFO "OS_AllocFromHeap(): heap not initialized." +#define OS_ERR_ALLOCFIXED_INVID "OS_AllocFixed(): illegal arena id." +#define OS_ERR_ALLOCFIXED_NOINFO "OS_AllocFixed(): heap not initialized." +#define OS_ERR_FREETOHEAP_INVID "OS_FreeToHeap(): illegal arena id." +#define OS_ERR_FREETOHEAP_NOINFO "OS_FreeToHeap(): heap not initialized." +#define OS_ERR_SETCURRENTHEAP_INVID "OS_SetCurrentHeap(): illegal arena id." +#define OS_ERR_SETCURRENTHEAP_NOINFO "OS_SetCurrentHeap(): heap not initialized." +#define OS_ERR_INITALLOC_INVID "OS_SetInitAlloc(): illegal arena id." +#define OS_ERR_INITALLOC_INVINFO "OS_SetInitAlloc(): heap already initialized." +#define OS_ERR_CREATEHEAP_INVID "OS_CreateHeap(): illegal arena id." +#define OS_ERR_CREATEHEAP_NOINFO "OS_CreateHeap(): heap not initialized." +#define OS_ERR_DESTROYHEAP_INVID "OS_DestroyHeap(): illegal arena id." +#define OS_ERR_DESTROYHEAP_NOINFO "OS_DestroyHeap(): heap not initialized." +#define OS_ERR_ADDTOHEAP_INVID "OS_AddToHeap(): illegal arena id." +#define OS_ERR_ADDTOHEAP_NOINFO "OS_AddToHeap(): heap not initialized." +#define OS_ERR_CHECKHEAP_INVID "OS_CheckHeap(): illegal arena id." +#define OS_ERR_CHECKHEAP_NOINFO "OS_CheckHeap(): heap not initialized." +#define OS_ERR_REFERENTSIZE_INVID "OS_ReferentSize(): illegal arena id." +#define OS_ERR_REFERENTSIZE_NOINFO "OS_ReferrentSize(): heap not initialized." +#define OS_ERR_DUMPHEAP_INVID "OS_DumpHeap(): illegal arena id." +#define OS_ERR_DUMPHEAP_NOINFO "OS_DumpHeap(): heap not initialized." +#define OS_ERR_VISITALLOCATED_INVID "OS_VisitAllocated(): illegal arena id." +#define OS_ERR_VISITALLOCATED_NOINFO "OS_VisitAllocated(): heap not initialized." + +#define OFFSET(n, a) (((u32) (n)) & ((a) - 1)) +#define TRUNC(n, a) (((u32) (n)) & ~((a) - 1)) +#define ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1)) + +#define ALIGNMENT 32 +#define MINOBJSIZE (HEADERSIZE + ALIGNMENT) +#define HEADERSIZE ROUND(sizeof(Cell), ALIGNMENT) + +#define InRange(targ, a, b) \ + ((u32)(a) <= (u32)(targ) && (u32)(targ) < (u32)(b)) + +#define RangeOverlap(aStart, aEnd, bStart, bEnd) \ + ((u32)(bStart) <= (u32)(aStart) && (u32)(aStart) < (u32)(bEnd) || \ + (u32)(bStart) < (u32)(aEnd) && (u32)(aEnd) <= (u32)(bEnd)) + +#define RangeSubset(aStart, aEnd, bStart, bEnd) \ + ((u32)(bStart) <= (u32)(aStart) && (u32)(aEnd) <= (u32)(bEnd)) + +typedef struct Cell Cell; +typedef struct HeapDesc HeapDesc; + +struct Cell { + Cell *prev; + Cell *next; + long size; +#ifdef SDK_DEBUG + HeapDesc *hd; + long requested; +#endif +}; + +struct HeapDesc { + long size; + Cell *free; + Cell *allocated; +#ifdef SDK_DEBUG + u32 paddingBytes; + u32 headerBytes; + u32 payloadBytes; +#endif +}; + +typedef struct { + volatile OSHeapHandle currentHeap; + int numHeaps; + void *arenaStart; + void *arenaEnd; + HeapDesc *heapArray; +} OSHeapInfo; + +void *OSiHeapInfo[OS_ARENA_MAX] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +static Cell *DLAddFront (Cell *list, Cell *cell) +{ + cell->next = list; + cell->prev = NULL; + if (list) { + list->prev = cell; + } + return cell; +} + +static Cell *DLLookup (Cell *list, Cell *cell) +{ + for (; list; list = list->next) { + if (list == cell) { + return list; + } + } + return NULL; +} + +static Cell *DLExtract (Cell *list, Cell *cell) +{ + if (cell->next) { + cell->next->prev = cell->prev; + } + + if (cell->prev == NULL) { + return cell->next; + } else { + cell->prev->next = cell->next; + return list; + } +} + +static Cell *DLInsert (Cell *list, Cell *cell) +{ + Cell *prev; + Cell *next; + + for (next = list, prev = NULL; next; prev = next, next = next->next) { + if (cell <= next) { + break; + } + } + + cell->next = next; + cell->prev = prev; + if (next) { + next->prev = cell; + if ((char *)cell + cell->size == (char *)next) { + + cell->size += next->size; + cell->next = next = next->next; + if (next) { + next->prev = cell; + } + } + } + if (prev) { + prev->next = cell; + if ((char *)prev + prev->size == (char *)cell) { + + prev->size += cell->size; + prev->next = next; + if (next) { + next->prev = prev; + } + } + return list; + } else { + return cell; + } +} + +static BOOL DLOverlap (Cell *list, void *start, void *end) +{ + Cell *cell; + + for (cell = list; cell; cell = cell->next) { + if (RangeOverlap(cell, (char *)cell + cell->size, start, end)) { + return TRUE; + } + } + return FALSE; +} + +static long DLSize (Cell *list) +{ + Cell *cell; + long size = 0; + + for (cell = list; cell; cell = cell->next) { + size += cell->size; + } + return size; +} + +void *OS_AllocFromHeap (OSArenaId id, OSHeapHandle heap, u32 size) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + Cell *newCell; + long leftoverSize; + OSIntrMode enabled = OS_DisableInterrupts(); + +#ifdef SDK_DEBUG + long requested = (long)size; +#endif + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_ALLOCFROMHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_ALLOCFROMHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + if (!heapInfo) { + (void)OS_RestoreInterrupts(enabled); + return NULL; + } + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_ALLOCFROMHEAP_NOHEAP); + SDK_ASSERTMSG(0 < ((long)size), OS_ERR_ALLOCFROMHEAP_INVSIZE); + SDK_ASSERTMSG(0 <= heap && heap < heapInfo->numHeaps, OS_ERR_ALLOCFROMHEAP_INVHEAP); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, OS_ERR_ALLOCFROMHEAP_INVHEAP); + + hd = &heapInfo->heapArray[heap]; + + size += HEADERSIZE; + size = ROUND(size, ALIGNMENT); + + for (cell = hd->free; cell != NULL; cell = cell->next) { + if ((long)size <= cell->size) { + break; + } + } + + if (cell == NULL) { +#ifdef SDK_DEBUG + OS_Printf("OS_AllocFromHeap: Warning- failed to allocate %d bytes\n", size); +#endif + (void)OS_RestoreInterrupts(enabled); + return NULL; + } + + SDK_ASSERTMSG(OFFSET(cell, ALIGNMENT) == 0, OS_ERR_ALLOCFROMHEAP_BROKENHEAP); + SDK_ASSERTMSG(cell->hd == NULL, OS_ERR_ALLOCFROMHEAP_BROKENHEAP); + + 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; +#ifdef SDK_DEBUG + newCell->hd = NULL; +#endif + 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 { + SDK_ASSERTMSG(hd->free == cell, OS_ERR_ALLOCFROMHEAP_BROKENHEAP); + hd->free = newCell; + } + } + + hd->allocated = DLAddFront(hd->allocated, cell); + +#ifdef SDK_DEBUG + cell->hd = hd; + cell->requested = requested; + hd->headerBytes += HEADERSIZE; + hd->paddingBytes += cell->size - (HEADERSIZE + requested); + hd->payloadBytes += requested; +#endif + + (void)OS_RestoreInterrupts(enabled); + + return (void *)((char *)cell + HEADERSIZE); +} + +void *OS_AllocFixed (OSArenaId id, void **rstart, void **rend) +{ + OSHeapInfo *heapInfo; + OSHeapHandle i; + Cell *cell; + Cell *newCell; + HeapDesc *hd; + void *start = (void *)TRUNC(*rstart, ALIGNMENT); + void *end = (void *)ROUND(*rend, ALIGNMENT); + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_ALLOCFIXED_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_ALLOCFIXED_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_ALLOCFIXED_NOHEAP); + SDK_ASSERTMSG(start < end, OS_ERR_ALLOCFIXED_INVRANGE); + SDK_ASSERTMSG(RangeSubset(start, end, heapInfo->arenaStart, heapInfo->arenaEnd), + OS_ERR_ALLOCFIXED_INVRANGE); + + for (i = 0; i < heapInfo->numHeaps; i++) { + hd = &heapInfo->heapArray[i]; + if (hd->size < 0) { + continue; + } + + if (DLOverlap(hd->allocated, start, end)) { +#ifdef SDK_DEBUG + OS_Printf("OS_AllocFixed: Warning - failed to allocate from %p to %p\n", start, end); +#endif + (void)OS_RestoreInterrupts(enabled); + return NULL; + } + } + + for (i = 0; i < heapInfo->numHeaps; i++) { + hd = &heapInfo->heapArray[i]; + + if (hd->size < 0) { + continue; + } + + for (cell = hd->free; cell; cell = cell->next) { + void *cellEnd = (char *)cell + cell->size; + + if ((char *)cellEnd <= (char *)start) { + continue; + } + + if ((char *)end <= (char *)cell) { + break; + } + + if (InRange(cell, (char *)start - HEADERSIZE, end) && + InRange((char *)cellEnd, start, (char *)end + MINOBJSIZE)) { + if ((char *)cell < (char *)start) + start = (void *)cell; + if ((char *)end < (char *)cellEnd) + end = (void *)cellEnd; + + hd->free = DLExtract(hd->free, cell); + hd->size -= cell->size; + continue; + } + + if (InRange(cell, (char *)start - HEADERSIZE, end)) { + if ((char *)cell < (char *)start) { + start = (void *)cell; + } + + SDK_ASSERT(MINOBJSIZE <= (char *)cellEnd - (char *)end); + newCell = (Cell *) end; + newCell->size = (char *)cellEnd - (char *)end; +#ifdef SDK_DEBUG + newCell->hd = NULL; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell->prev; + if (newCell->prev) { + newCell->prev->next = newCell; + } else { + hd->free = newCell; + } + hd->size -= (char *)end - (char *)cell; + break; + } + + if (InRange((char *)cellEnd, start, (char *)end + MINOBJSIZE)) { + if ((char *)end < (char *)cellEnd) { + end = (void *)cellEnd; + } + + SDK_ASSERT(MINOBJSIZE <= (char *)start - (char *)cell); + hd->size -= (char *)cellEnd - (char *)start; + cell->size = (char *)start - (char *)cell; + continue; + } + + SDK_ASSERT(MINOBJSIZE <= (char *)cellEnd - (char *)end); + newCell = (Cell *) end; + newCell->size = (char *)cellEnd - (char *)end; +#ifdef SDK_DEBUG + newCell->hd = NULL; +#endif + newCell->next = cell->next; + if (newCell->next) { + newCell->next->prev = newCell; + } + newCell->prev = cell; + cell->next = newCell; + cell->size = (char *)start - (char *)cell; + hd->size -= (char *)end - (char *)start; + break; + } + SDK_ASSERT(0 <= hd->size); + } + + SDK_ASSERT(OFFSET(start, ALIGNMENT) == 0); + SDK_ASSERT(OFFSET(end, ALIGNMENT) == 0); + SDK_ASSERT(start < end); + *rstart = start; + *rend = end; + + (void)OS_RestoreInterrupts(enabled); + return *rstart; +} + +void OS_FreeToHeap (OSArenaId id, OSHeapHandle heap, void *ptr) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_FREETOHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_FREETOHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_FREETOHEAP_NOHEAP); + SDK_ASSERTMSG(InRange + (ptr, (char *)heapInfo->arenaStart + HEADERSIZE, (char *)heapInfo->arenaEnd), + OS_ERR_FREETOHEAP_INVPTR); + SDK_ASSERTMSG(OFFSET(ptr, ALIGNMENT) == 0, OS_ERR_FREETOHEAP_INVPTR); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, OS_ERR_FREETOHEAP_INVHEAP); + + cell = (Cell *) ((char *)ptr - HEADERSIZE); + hd = &heapInfo->heapArray[heap]; + + SDK_ASSERTMSG(cell->hd == hd, OS_ERR_FREETOHEAP_INVPTR); + SDK_ASSERTMSG(DLLookup(hd->allocated, cell), OS_ERR_FREETOHEAP_INVPTR); + +#ifdef SDK_DEBUG + cell->hd = NULL; + hd->headerBytes -= HEADERSIZE; + hd->paddingBytes -= cell->size - (HEADERSIZE + cell->requested); + hd->payloadBytes -= cell->requested; +#endif + + hd->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_FreeAllToHeap (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_FREETOHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_FREETOHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + SDK_ASSERTMSG(heapInfo->heapArray, "heap not initialized"); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, "invalid heap handle"); + + hd = &heapInfo->heapArray[heap]; + while ((cell = hd->allocated) != NULL) { + SDK_ASSERT(cell->hd == hd); + SDK_ASSERT(DLLookup(hd->allocated, cell)); + +#ifdef SDK_DEBUG + cell->hd = NULL; + hd->headerBytes -= HEADERSIZE; + hd->paddingBytes -= cell->size - (HEADERSIZE + cell->requested); + hd->payloadBytes -= cell->requested; +#endif + + hd->allocated = DLExtract(hd->allocated, cell); + hd->free = DLInsert(hd->free, cell); + } + + (void)OS_RestoreInterrupts(enabled); +} + +OSHeapHandle OS_SetCurrentHeap (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + OSHeapHandle prev; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_SETCURRENTHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_SETCURRENTHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_SETCURRENTHEAP_NOHEAP); + SDK_ASSERTMSG(0 <= heap && heap < heapInfo->numHeaps, OS_ERR_SETCURRENTHEAP_INVHEAP); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, OS_ERR_SETCURRENTHEAP_INVHEAP); + prev = heapInfo->currentHeap; + heapInfo->currentHeap = heap; + + (void)OS_RestoreInterrupts(enabled); + return prev; +} + +void *OS_InitAlloc (OSArenaId id, void *arenaStart, void *arenaEnd, int maxHeaps) +{ + OSHeapInfo *heapInfo; + u32 arraySize; + OSHeapHandle i; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_INITALLOC_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id] == NULL, OS_ERR_INITALLOC_INVINFO); + + SDK_ASSERTMSG(0 < maxHeaps, OS_ERR_INITALLOC_INVNUMHEAPS); + SDK_ASSERTMSG((char *)arenaStart < (char *)arenaEnd, OS_ERR_INITALLOC_INVRANGE); + SDK_ASSERTMSG(maxHeaps <= ((char *)arenaEnd - (char *)arenaStart) / sizeof(HeapDesc), + OS_ERR_INITALLOC_INSRANGE); + + heapInfo = arenaStart; + OSiHeapInfo[id] = heapInfo; + + arraySize = sizeof(HeapDesc) * maxHeaps; + heapInfo->heapArray = (void *)((u32)arenaStart + sizeof(OSHeapInfo)); + heapInfo->numHeaps = maxHeaps; + + for (i = 0; i < heapInfo->numHeaps; i++) { + HeapDesc *hd = &heapInfo->heapArray[i]; + + hd->size = -1; + hd->free = hd->allocated = NULL; +#ifdef SDK_DEBUG + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + } + + heapInfo->currentHeap = -1; + + arenaStart = (void *)((char *)heapInfo->heapArray + arraySize); + arenaStart = (void *)ROUND(arenaStart, ALIGNMENT); + + heapInfo->arenaStart = arenaStart; + heapInfo->arenaEnd = (void *)TRUNC(arenaEnd, ALIGNMENT); + SDK_ASSERTMSG(MINOBJSIZE <= (char *)heapInfo->arenaEnd - (char *)heapInfo->arenaStart, + OS_ERR_INITALLOC_INSRANGE); + + (void)OS_RestoreInterrupts(enabled); + return heapInfo->arenaStart; +} + +void OS_ClearAlloc (OSArenaId id) +{ + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_CLEARALLOC_INVID); + OSiHeapInfo[id] = NULL; +} + +OSHeapHandle OS_CreateHeap (OSArenaId id, void *start, void *end) +{ + OSHeapInfo *heapInfo; + OSHeapHandle heap; + HeapDesc *hd; + Cell *cell; + + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_CREATEHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_CREATEHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_CREATEHEAP_NOHEAP); + SDK_ASSERTMSG(start < end, OS_ERR_CREATEHEAP_INVRANGE); + start = (void *)ROUND(start, ALIGNMENT); + end = (void *)TRUNC(end, ALIGNMENT); + SDK_ASSERTMSG(start < end, OS_ERR_CREATEHEAP_INVRANGE); + SDK_ASSERTMSG(RangeSubset(start, end, heapInfo->arenaStart, heapInfo->arenaEnd), + OS_ERR_CREATEHEAP_INVRANGE); + SDK_ASSERTMSG(MINOBJSIZE <= (char *)end - (char *)start, OS_ERR_CREATEHEAP_INSRANGE); + +#ifdef SDK_DEBUG + for (heap = 0; heap < heapInfo->numHeaps; heap++) { + if (heapInfo->heapArray[heap].size < 0) { + continue; + } + SDK_ASSERTMSG(!DLOverlap(heapInfo->heapArray[heap].free, start, end), + OS_ERR_CREATEHEAP_INVRANGE); + SDK_ASSERTMSG(!DLOverlap(heapInfo->heapArray[heap].allocated, start, end), + OS_ERR_CREATEHEAP_INVRANGE); + } +#endif + + for (heap = 0; heap < heapInfo->numHeaps; heap++) { + hd = &heapInfo->heapArray[heap]; + if (hd->size < 0) { + hd->size = (char *)end - (char *)start; + + cell = (Cell *) start; + cell->prev = NULL; + cell->next = NULL; + cell->size = hd->size; +#ifdef SDK_DEBUG + cell->hd = NULL; +#endif + + hd->free = cell; + hd->allocated = 0; +#ifdef SDK_DEBUG + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + + (void)OS_RestoreInterrupts(enabled); + return heap; + } + } + +#ifdef SDK_DEBUG + OS_Printf("OS_CreateHeap: Warning - Failed to find free heap descriptor."); +#endif + + (void)OS_RestoreInterrupts(enabled); + return -1; +} + +void OS_DestroyHeap (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; +#ifdef SDK_DEBUG + long size; +#endif + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_DESTROYHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_DESTROYHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_DESTROYHEAP_NOHEAP); + SDK_ASSERTMSG(0 <= heap && heap < heapInfo->numHeaps, OS_ERR_DESTROYHEAP_INVHEAP); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, OS_ERR_DESTROYHEAP_INVHEAP); + + hd = &heapInfo->heapArray[heap]; + +#ifdef SDK_DEBUG + + size = DLSize(hd->free); + if (hd->size != size) { + OS_Printf("OS_DestroyHeap(%d): Warning - free list size %d, heap size %d\n", heap, size, + hd->size); + } +#endif + + hd->size = -1; + hd->free = hd->allocated = NULL; + +#ifdef SDK_DEBUG + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; + if (heapInfo->currentHeap == heap) { + heapInfo->currentHeap = -1; + } +#endif + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_AddToHeap (OSArenaId id, OSHeapHandle heap, void *start, void *end) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; +#ifdef SDK_DEBUG + OSHeapHandle i; +#endif + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_ADDTOHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_ADDTOHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_ADDTOHEAP_NOHEAP); + SDK_ASSERTMSG(0 <= heap && heap < heapInfo->numHeaps, OS_ERR_ADDTOHEAP_INVHEAP); + SDK_ASSERTMSG(0 <= heapInfo->heapArray[heap].size, OS_ERR_ADDTOHEAP_INVHEAP); + + hd = &heapInfo->heapArray[heap]; + + SDK_ASSERTMSG(start < end, OS_ERR_ADDTOHEAP_INVRANGE); + start = (void *)ROUND(start, ALIGNMENT); + end = (void *)TRUNC(end, ALIGNMENT); + SDK_ASSERTMSG(MINOBJSIZE <= (char *)end - (char *)start, OS_ERR_ADDTOHEAP_INSRANGE); + SDK_ASSERTMSG(RangeSubset(start, end, heapInfo->arenaStart, heapInfo->arenaEnd), + OS_ERR_ADDTOHEAP_INVRANGE); + +#ifdef SDK_DEBUG + + for (i = 0; i < heapInfo->numHeaps; i++) { + if (heapInfo->heapArray[i].size < 0) { + continue; + } + SDK_ASSERTMSG(!DLOverlap(heapInfo->heapArray[i].free, start, end), + OS_ERR_ADDTOHEAP_INVRANGE); + SDK_ASSERTMSG(!DLOverlap(heapInfo->heapArray[i].allocated, start, end), + OS_ERR_ADDTOHEAP_INVRANGE); + } +#endif + + cell = (Cell *) start; + cell->size = (char *)end - (char *)start; +#ifdef SDK_DEBUG + cell->hd = NULL; +#endif + + hd->size += cell->size; + hd->free = DLInsert(hd->free, cell); + + (void)OS_RestoreInterrupts(enabled); +} + +#ifndef SDK_NO_MESSAGE +#define OSi_CHECK( exp ) \ + do \ + { \ + if ( !(exp)) \ + { \ + OS_Printf( "OS_CheckHeap: Failed " #exp " in %d\n", __LINE__ ); \ + goto exit_OS_CheckHeap; \ + } \ + } while (0) +#else +#define OSi_CHECK( exp ) \ + do \ + { \ + if ( !(exp)) \ + { \ + goto exit_OS_CheckHeap; \ + } \ + } while (0) +#endif + +s32 OS_CheckHeap (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + long total = 0; + long free = 0; + long retValue = -1; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_CHECKHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_CHECKHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + if (heap == OS_CURRENT_HEAP_HANDLE) { + heap = heapInfo->currentHeap; + } + SDK_ASSERT(heap >= 0); + + OSi_CHECK(heapInfo->heapArray); + OSi_CHECK(0 <= heap && heap < heapInfo->numHeaps); + + hd = &heapInfo->heapArray[heap]; + OSi_CHECK(0 <= hd->size); + + OSi_CHECK(hd->allocated == NULL || hd->allocated->prev == NULL); + for (cell = hd->allocated; cell; cell = cell->next) { + OSi_CHECK(InRange(cell, heapInfo->arenaStart, heapInfo->arenaEnd)); + OSi_CHECK(OFFSET(cell, ALIGNMENT) == 0); + OSi_CHECK(cell->next == NULL || cell->next->prev == cell); + OSi_CHECK(MINOBJSIZE <= cell->size); + OSi_CHECK(OFFSET(cell->size, ALIGNMENT) == 0); + + total += cell->size; + OSi_CHECK(0 < total && total <= hd->size); + +#ifdef SDK_DEBUG + OSi_CHECK(cell->hd == hd); + OSi_CHECK(HEADERSIZE + cell->requested <= cell->size); +#endif + } + + OSi_CHECK(hd->free == NULL || hd->free->prev == NULL); + for (cell = hd->free; cell; cell = cell->next) { + OSi_CHECK(InRange(cell, heapInfo->arenaStart, heapInfo->arenaEnd)); + OSi_CHECK(OFFSET(cell, ALIGNMENT) == 0); + OSi_CHECK(cell->next == NULL || cell->next->prev == cell); + OSi_CHECK(MINOBJSIZE <= cell->size); + OSi_CHECK(OFFSET(cell->size, ALIGNMENT) == 0); + OSi_CHECK(cell->next == NULL || (char *)cell + cell->size < (char *)cell->next); + + total += cell->size; + free += cell->size - HEADERSIZE; + OSi_CHECK(0 < total && total <= hd->size); + +#ifdef SDK_DEBUG + OSi_CHECK(cell->hd == NULL); +#endif + } + + OSi_CHECK(total == hd->size); + retValue = free; + +exit_OS_CheckHeap: + (void)OS_RestoreInterrupts(enabled); + return retValue; +} + +u32 OS_ReferentSize (OSArenaId id, void *ptr) +{ + OSHeapInfo *heapInfo; + Cell *cell; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_REFERENTSIZE_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_REFERENTSIZE_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo->heapArray, OS_ERR_REFERENT_NOHEAP); + SDK_ASSERTMSG(InRange + (ptr, (char *)heapInfo->arenaStart + HEADERSIZE, (char *)heapInfo->arenaEnd), + OS_ERR_REFERENT_INVPTR); + SDK_ASSERTMSG(OFFSET(ptr, ALIGNMENT) == 0, OS_ERR_REFERENT_INVPTR); + + cell = (Cell *) ((char *)ptr - HEADERSIZE); + + SDK_ASSERTMSG(cell->hd, OS_ERR_REFERENT_INVPTR); + SDK_ASSERTMSG(((char *)cell->hd - (char *)heapInfo->heapArray) % sizeof(HeapDesc) == 0, + OS_ERR_REFERENT_INVPTR); + SDK_ASSERTMSG(heapInfo->heapArray <= cell->hd + && cell->hd < &heapInfo->heapArray[heapInfo->numHeaps], OS_ERR_REFERENT_INVPTR); + SDK_ASSERTMSG(0 <= cell->hd->size, OS_ERR_REFERENT_INVPTR); + SDK_ASSERTMSG(DLLookup(cell->hd->allocated, cell), OS_ERR_REFERENT_INVPTR); + + (void)OS_RestoreInterrupts(enabled); + return (u32)(cell->size - HEADERSIZE); +} + +void OS_DumpHeap (OSArenaId id, OSHeapHandle heap) +{ +#ifndef SDK_FINALROM + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + OSIntrMode enabled = OS_DisableInterrupts(); + + OS_Printf("\nOS_DumpHeap(%d):\n", heap); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_DUMPHEAP_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_DUMPHEAP_NOINFO); + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo && heapInfo->heapArray, OS_ERR_DUMPHEAP_NOHEAP); + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + SDK_ASSERTMSG(0 <= heap && heap < heapInfo->numHeaps, OS_ERR_DUMPHEAP_INVHEAP); + + hd = &heapInfo->heapArray[heap]; + if (hd->size < 0) { + OS_Printf("--------Inactive\n"); + return; + } + + SDK_ASSERTMSG(0 <= OS_CheckHeap(id, heap), OS_ERR_DUMPHEAP_BROKENHEAP); + +#ifdef SDK_DEBUG + OS_Printf("padding %d/(%f%%) header %d/(%f%%) payload %d/(%f%%)\n", + hd->paddingBytes, 100.0 * hd->paddingBytes / hd->size, + hd->headerBytes, 100.0 * hd->headerBytes / hd->size, + hd->payloadBytes, 100.0 * hd->payloadBytes / hd->size); +#endif + + OS_Printf("addr\tsize\tend\tprev\tnext\n"); + OS_Printf("--------Allocated\n"); + SDK_ASSERTMSG(hd->allocated == NULL || hd->allocated->prev == NULL, OS_ERR_DUMPHEAP_BROKENHEAP); + for (cell = hd->allocated; cell; cell = cell->next) { + OS_Printf("%x\t%d\t%x\t%x\t%x\n", + cell, cell->size, (char *)cell + cell->size, cell->prev, cell->next); + } + + OS_Printf("--------Free\n"); + for (cell = hd->free; cell; cell = cell->next) { + OS_Printf("%x\t%d\t%x\t%x\t%x\n", + cell, cell->size, (char *)cell + cell->size, cell->prev, cell->next); + } + + (void)OS_RestoreInterrupts(enabled); +#else + +#pragma unused( id, heap ) + +#endif +} + +void OS_VisitAllocated (OSArenaId id, OSAllocVisitor visitor) +{ + OSHeapInfo *heapInfo; + u32 heap; + Cell *cell; + + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, OS_ERR_VISITALLOCATED_INVID); + SDK_ASSERTMSG(OSiHeapInfo[id], OS_ERR_VISITALLOCATED_NOINFO); + heapInfo = OSiHeapInfo[id]; + + for (heap = 0; heap < heapInfo->numHeaps; heap++) { + if (heapInfo->heapArray[heap].size >= 0) { + for (cell = heapInfo->heapArray[heap].allocated; cell; cell = cell->next) { + visitor((void *)((u8 *)cell + HEADERSIZE), (u32)(cell->size - HEADERSIZE)); + } + } + } + + (void)OS_RestoreInterrupts(enabled); +} + +u32 OSi_GetTotalAllocSize (OSArenaId id, OSHeapHandle heap, BOOL isHeadInclude) +{ + OSHeapInfo *heapInfo; + Cell *cell; + u32 sum = 0; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERT(id < OS_ARENA_MAX); + heapInfo = OSiHeapInfo[id]; + SDK_ASSERT(heapInfo); + SDK_ASSERT(heap < heapInfo->numHeaps); + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + if (isHeadInclude) { + for (cell = heapInfo->heapArray[heap].allocated; cell; cell = cell->next) { + sum += (u32)(cell->size); + } + } else { + for (cell = heapInfo->heapArray[heap].allocated; cell; cell = cell->next) { + sum += (u32)(cell->size - HEADERSIZE); + } + } + + (void)OS_RestoreInterrupts(enabled); + + return sum; +} + +u32 OS_GetTotalFreeSize (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + Cell *cell; + u32 sum = 0; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERT(id < OS_ARENA_MAX); + heapInfo = OSiHeapInfo[id]; + SDK_ASSERT(heapInfo); + SDK_ASSERT(heap < heapInfo->numHeaps); + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + for (cell = heapInfo->heapArray[heap].free; cell; cell = cell->next) { + sum += (u32)(cell->size - HEADERSIZE); + } + + (void)OS_RestoreInterrupts(enabled); + + return sum; +} + +u32 OS_GetMaxFreeSize (OSArenaId id, OSHeapHandle heap) +{ + OSHeapInfo *heapInfo; + Cell *cell; + u32 candidate = 0; + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERT(id < OS_ARENA_MAX); + heapInfo = OSiHeapInfo[id]; + SDK_ASSERT(heapInfo); + SDK_ASSERT(heap < heapInfo->numHeaps); + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + for (cell = heapInfo->heapArray[heap].free; cell; cell = cell->next) { + u32 size = (u32)(cell->size - HEADERSIZE); + if (size > candidate) { + candidate = size; + } + } + + (void)OS_RestoreInterrupts(enabled); + + return candidate; +} + +void OS_ClearHeap (OSArenaId id, OSHeapHandle heap, void *start, void *end) +{ + OSHeapInfo *heapInfo; + HeapDesc *hd; + Cell *cell; + + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERTMSG(id < OS_ARENA_MAX, "invalid id"); + + heapInfo = OSiHeapInfo[id]; + + SDK_ASSERTMSG(heapInfo && heapInfo->heapArray, "heap not initialized"); + SDK_ASSERTMSG(start < end, "invalid range"); + start = (void *)ROUND(start, ALIGNMENT); + end = (void *)TRUNC(end, ALIGNMENT); + SDK_ASSERTMSG(start < end, "invalid range"); + SDK_ASSERTMSG(RangeSubset(start, end, heapInfo->arenaStart, heapInfo->arenaEnd), + "invalid range"); + SDK_ASSERTMSG(MINOBJSIZE <= (char *)end - (char *)start, "too small range"); + + if (heap < 0) { + heap = heapInfo->currentHeap; + } + + hd = &heapInfo->heapArray[heap]; + hd->size = (char *)end - (char *)start; + + cell = (Cell *) start; + cell->prev = NULL; + cell->next = NULL; + cell->size = hd->size; +#ifdef SDK_DEBUG + cell->hd = NULL; +#endif + + hd->free = cell; + hd->allocated = 0; +#ifdef SDK_DEBUG + hd->paddingBytes = hd->headerBytes = hd->payloadBytes = 0; +#endif + + (void)OS_RestoreInterrupts(enabled); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_arena.c b/subprojects/NitroSDK/libraries/os/src/os_arena.c new file mode 100644 index 0000000000..dc1d59dcd8 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_arena.c @@ -0,0 +1,382 @@ +#include + +#define OSi_TRUNC(n, a) (((u32) (n)) & ~((a) - 1)) +#define OSi_ROUND(n, a) (((u32) (n) + (a) - 1) & ~((a) - 1)) + +#define OS_ERR_GETARENAHI_INIT "OS_GetArenaHi: init in advance" +#define OS_ERR_GETARENAHI_INVALID "OS_GetArenaHi: invalid arena (hi (u32)HW_PRV_WRAM) { + sysStackLo = (u32)SDK_WRAM_ARENA_LO; + } + + if (OSi_SYS_STACKSIZE == 0) { + + } else if (OSi_SYS_STACKSIZE < 0) { + sysStackLo -= OSi_SYS_STACKSIZE; + } else { + sysStackLo = irqStackLo - OSi_SYS_STACKSIZE; + } + SDK_ASSERT((u32)HW_PRV_WRAM <= sysStackLo && sysStackLo < irqStackLo); + return (void *)sysStackLo; + } +#endif + default: + SDK_WARNING(0, "Bad arena id"); + } + + return NULL; +} + +void *OS_GetInitArenaLo (OSArenaId id) +{ + SDK_ASSERT(OSi_Initialized); + SDK_ARENAID_ASSERT(id); + + switch (id) { +#ifdef SDK_ARM9 + case OS_ARENA_MAIN: + return (void *)OSi_MAIN_ARENA_LO_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_LO_DEFAULT; + } + case OS_ARENA_ITCM: + return (void *)OSi_ITCM_ARENA_LO_DEFAULT; + case OS_ARENA_DTCM: + return (void *)OSi_DTCM_ARENA_LO_DEFAULT; + case OS_ARENA_SHARED: + return (void *)HW_SHARED_ARENA_LO_DEFAULT; + case OS_ARENA_WRAM_MAIN: + return (void *)OSi_WRAM_MAIN_ARENA_LO_DEFAULT; +#else + case OS_ARENA_MAIN_SUBPRIV: + return (void *)OSi_MAIN_SUBPRIV_ARENA_LO_DEFAULT; + case OS_ARENA_WRAM_SUB: + { + u32 wramSubLo = OSi_WRAM_SUB_ARENA_LO_DEFAULT; + if ((u32)HW_WRAM_END < (u32)wramSubLo) { + wramSubLo = (u32)HW_WRAM_END; + } + return (void *)wramSubLo; + } + case OS_ARENA_WRAM_SUBPRIV: + { + u32 privWramLo = OSi_WRAM_SUBPRIV_ARENA_LO_DEFAULT; + if ((u32)SDK_WRAM_ARENA_LO > (u32)privWramLo) { + privWramLo = (u32)SDK_WRAM_ARENA_LO; + } + return (void *)privWramLo; + } +#endif + default: + SDK_WARNING(0, "Bad arena id"); + } + + return NULL; +} + +void OS_SetArenaHi (OSArenaId id, void *newHi) +{ + SDK_ASSERT(OSi_Initialized); + SDK_ARENAID_ASSERT(id); + + OSi_GetArenaInfo().hi[id] = newHi; +} + +void OS_SetArenaLo (OSArenaId id, void *newLo) +{ + SDK_ASSERT(OSi_Initialized); + SDK_ARENAID_ASSERT(id); + + OSi_GetArenaInfo().lo[id] = newLo; +} + +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 > OS_GetArenaHi(id)) { + return NULL; + } + + OS_SetArenaLo(id, arenaLo); + + return ptr; +} + +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 < OS_GetArenaLo(id)) { + return NULL; + } + + OS_SetArenaHi(id, arenaHi); + + return ptr; +} + +#ifdef SDK_ARM9 + +void OS_EnableMainExArena (void) +{ + SDK_ASSERT(!OSi_Initialized); + + OSi_MainExArenaEnabled = TRUE; +} + +void OS_DisableMainExArena (void) +{ + SDK_ASSERT(!OSi_Initialized); + + OSi_MainExArenaEnabled = FALSE; +} +#endif \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_cache.c b/subprojects/NitroSDK/libraries/os/src/os_cache.c new file mode 100644 index 0000000000..8756a9afbc --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_cache.c @@ -0,0 +1,321 @@ +#include +#include + +#define SDK_AVOID_FLUSH + +asm BOOL DC_Enable (void) +{ + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_DCACHE_ENABLE + mov r0, r0, LSR #HW_C1_DCACHE_ENABLE_SHIFT + orr r1, r1, #HW_C1_DCACHE_ENABLE + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm BOOL DC_Disable (void) +{ + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_DCACHE_ENABLE + mov r0, r0, LSR #HW_C1_DCACHE_ENABLE_SHIFT + bic r1, r1, #HW_C1_DCACHE_ENABLE + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm BOOL DC_Restore (register BOOL enable) +{ + cmp r0, #0 + moveq r2, #0 + movne r2, #HW_C1_DCACHE_ENABLE + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_DCACHE_ENABLE + mov r0, r0, LSR #HW_C1_DCACHE_ENABLE_SHIFT + bic r1, r1, #HW_C1_DCACHE_ENABLE + orr r1, r1, r2 + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm void DC_InvalidateAll (void) +{ + mov r0, #0 + mcr p15, 0, r0, c7, c6, 0 + bx lr +} + +asm void DC_StoreAll (void) +{ + mov r1, #0 + + @1: + mov r0, #0 + + @2: + orr r2, r1, r0 + mcr p15, 0, r2, c7, c10, 2 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, #HW_DCACHE_SIZE / 4 + blt @2 + add r1, r1, #1 << HW_C7_CACHE_SET_NO_SHIFT + cmp r1, #0 + bne @1 + bx lr +} + +asm void DC_FlushAll (void) +{ + mov r12, #0 + mov r1, #0 + + @1: + mov r0, #0 + + @2: + orr r2, r1, r0 + mcr p15, 0, r12, c7, c10, 4 + mcr p15, 0, r2, c7, c14, 2 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, #HW_DCACHE_SIZE / 4 + blt @2 + add r1, r1, #1 << HW_C7_CACHE_SET_NO_SHIFT + cmp r1, #0 + bne @1 + bx lr +} + +asm void DC_InvalidateRange (register void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1: + mcr p15, 0, r0, c7, c6, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +asm void DC_StoreRange (register const void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1 : + mcr p15, 0, r0, c7, c10, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +asm void DC_FlushRange (register const void *startAddr, register u32 nBytes) +{ + mov r12, #0 + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1: + mcr p15, 0, r12, c7, c10, 4 + mcr p15, 0, r0, c7, c14, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +asm void DC_TouchRange (register const void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1: + pld[r0] + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +asm void DC_LockdownRange (register const void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + mrc p15, 0, r3, c9, c0, 0 + and r3, r3, #HW_C9_LOCKDOWN_SET_NO_MASK + cmp r3, #3 + mvneq r0, #0 + bxeq lr + stmfd sp !, { lr, r0, r1 } + ldr r0, = OS_DisableInterrupts + blx r0 + mov r2, r0 + ldmfd sp !, { lr, r0, r1 } + orr r3, r3, #HW_C9_LOCKDOWN_LOAD_MODE + mcr p15, 0, r3, c9, c0, 0 + + @111 : + mcr p15, 0, r0, c7, c14, 1 + ldr r12, [r0] + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @111 + add r3, r3, #1 + bic r0, r3, #HW_C9_LOCKDOWN_LOAD_MODE + mcr p15, 0, r3, c9, c0, 0 + stmfd sp !, { lr } + mov r0, r2 + ldr r1, = OS_RestoreInterrupts + blx r1 + ldmfd sp !, { lr } + bx lr +} + +asm void DC_UnlockdownAll (void) +{ + mov r3, #0 + mcr p15, 0, r3, c9, c0, 0 + bx lr +} + +asm void DC_Unlockdown (register u32 num) +{ + mrc p15, 0, r3, c9, c0, 0 + and r3, r3, #HW_C9_LOCKDOWN_SET_NO_MASK + subs r3, r3, r0 + movmi r3, #0 + mcr p15, 0, r3, c9, c0, 0 + bx lr +} + +asm void DC_WaitWriteBufferEmpty (void) +{ + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 + bx lr +} + +asm BOOL IC_Enable (void) +{ + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_ICACHE_ENABLE + mov r0, r0, LSR #HW_C1_ICACHE_ENABLE_SHIFT + orr r1, r1, #HW_C1_ICACHE_ENABLE + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm BOOL IC_Disable (void) +{ + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_ICACHE_ENABLE + mov r0, r0, LSR #HW_C1_ICACHE_ENABLE_SHIFT + bic r1, r1, #HW_C1_ICACHE_ENABLE + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm BOOL IC_Restore (register BOOL enable) +{ + cmp r0, #0 + moveq r2, #0 + movne r2, #HW_C1_ICACHE_ENABLE + mrc p15, 0, r1, c1, c0, 0 + and r0, r1, #HW_C1_ICACHE_ENABLE + mov r0, r0, LSR #HW_C1_ICACHE_ENABLE_SHIFT + bic r1, r1, #HW_C1_ICACHE_ENABLE + orr r1, r1, r2 + mcr p15, 0, r1, c1, c0, 0 + bx lr +} + +asm void IC_InvalidateAll (void) +{ + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 + bx lr +} + +asm void IC_InvalidateRange (register void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1: + mcr p15, 0, r0, c7, c5, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +asm void IC_PrefetchRange (register const void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + + @1: + mcr p15, 0, r0, c7, c13, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + bx lr +} + +#include + +asm void IC_LockdownRange (register const void *startAddr, register u32 nBytes) +{ + add r1, r1, r0 + bic r0, r0, #HW_CACHE_LINE_SIZE - 1 + mrc p15, 0, r3, c9, c0, 1 + and r3, r3, #HW_C9_LOCKDOWN_SET_NO_MASK + cmp r3, #3 + mvneq r0, #0 + bxeq lr + stmfd sp !, { lr, r0, r1 } + ldr r0, = OS_DisableInterrupts + blx r0 + mov r2, r0 + ldmfd sp !, { lr, r0, r1 } + orr r3, r3, #HW_C9_LOCKDOWN_LOAD_MODE + mcr p15, 0, r3, c9, c0, 1 + + @1: + mcr p15, 0, r0, c7, c5, 1 + mcr p15, 0, r0, c7, c13, 1 + add r0, r0, #HW_CACHE_LINE_SIZE + cmp r0, r1 + blt @1 + add r3, r3, #1 + bic r0, r3, #HW_C9_LOCKDOWN_LOAD_MODE + mcr p15, 0, r3, c9, c0, 1 + stmfd sp !, { lr } + mov r0, r2 + ldr r1, = OS_RestoreInterrupts + blx r1 + ldmfd sp !, { lr } + bx lr +} + +#include + +asm void IC_UnlockdownAll (void) +{ + mov r3, #0 + mcr p15, 0, r3, c9, c0, 1 + bx lr +} + +asm void IC_Unlockdown (register u32 num) +{ + mrc p15, 0, r3, c9, c0, 1 + and r3, r3, #HW_C9_LOCKDOWN_SET_NO_MASK + subs r3, r3, r0 + movmi r3, #0 + mcr p15, 0, r3, c9, c0, 1 + bx lr +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_context.c b/subprojects/NitroSDK/libraries/os/src/os_context.c new file mode 100644 index 0000000000..1a61ba7588 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_context.c @@ -0,0 +1,143 @@ +#include +#include + +#ifdef SDK_ARM9 +#include +#endif + +#include +asm void OS_InitContext (register OSContext *context, register u32 newpc, register u32 newsp) +{ + add newpc, newpc, #4 + str newpc, [context, #OS_CONTEXT_PC_PLUS4] + +#ifdef SDK_CONTEXT_HAS_SP_SVC + str newsp, [context, #OS_CONTEXT_SP_SVC] + sub newsp, newsp, #HW_SVC_STACK_SIZE +#endif + tst newsp, #4 + bne @subne1 + b @subne2 +@subne1: + sub newsp, newsp, #4 +@subne2: + str newsp, [context, #OS_CONTEXT_SP] + ands r1, newpc, #1 + bne @movne1 + b @movne2 +@movne1: + mov r1, #HW_PSR_SYS_MODE | HW_PSR_THUMB_STATE +@movne2: + beq @moveq1 + b @moveq2 +@moveq1: + mov r1, #HW_PSR_SYS_MODE | HW_PSR_ARM_STATE +@moveq2: + str r1, [context, #OS_CONTEXT_CPSR] + mov r1, #0 + str r1, [context, #OS_CONTEXT_R0] + str r1, [context, #OS_CONTEXT_R1] + str r1, [context, #OS_CONTEXT_R2] + str r1, [context, #OS_CONTEXT_R3] + str r1, [context, #OS_CONTEXT_R4] + str r1, [context, #OS_CONTEXT_R5] + str r1, [context, #OS_CONTEXT_R6] + str r1, [context, #OS_CONTEXT_R7] + str r1, [context, #OS_CONTEXT_R8] + str r1, [context, #OS_CONTEXT_R9] + str r1, [context, #OS_CONTEXT_R10] + str r1, [context, #OS_CONTEXT_R11] + str r1, [context, #OS_CONTEXT_R12] + str r1, [context, #OS_CONTEXT_LR] + bx lr +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +asm BOOL OS_SaveContext (register OSContext *context) +{ +#if defined(SDK_ARM9) + stmfd sp !, { lr, r0 } + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, = CP_SaveContext + blx r1 + ldmfd sp !, { lr, r0 } +#endif + add r1, r0, #OS_CONTEXT_CPSR + mrs r2, cpsr + str r2, [r1], #OS_CONTEXT_R0 - OS_CONTEXT_CPSR + +#ifdef SDK_CONTEXT_HAS_SP_SVC + mov r0, #HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE | HW_PSR_ARM_STATE + msr cpsr_c, r0 + str sp, [r1, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0] + msr cpsr_c, r2 +#endif + mov r0, #1 + stmia r1, {r0 - r14} + add r0, pc, #8 + str r0, [r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0] + mov r0, #0 + bx lr +} + +#define OFFSETOF(x, y) (int)(&(((x *)0)->y)) + +asm void OS_LoadContext (register OSContext *context) +{ +#if OS_CONTEXT_CPSR != 0 +#pragma message(has changed!!!) + add r0, r0, #OS_CONTEXT_CPSR +#endif + +#if defined(SDK_ARM9) + stmfd sp !, { lr, r0 } + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, = CPi_RestoreContext + blx r1 + ldmfd sp !, { lr, r0 } +#endif + mrs r1, cpsr + bic r1, r1, #HW_PSR_CPU_MODE_MASK + orr r1, r1, #HW_PSR_SVC_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_FIQ_DISABLE + msr cpsr_c, r1 + ldr r1, [r0], #OS_CONTEXT_R0 - OS_CONTEXT_CPSR + msr spsr_fsxc, r1 +#ifdef SDK_CONTEXT_HAS_SP_SVC + ldr sp, [r0, #OS_CONTEXT_SP_SVC - OS_CONTEXT_R0] +#endif + ldr lr, [r0, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_R0] + ldmia r0, { r0 - r14 }^ + nop + subs pc, lr, #4 +} +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +#include + +void OS_DumpContext (OSContext *context) +{ +#ifndef SDK_FINALROM + s32 i; + + OS_Printf("context=%08x\n", context); + if (context) { + OS_Printf("CPSR %08x\n", context->cpsr); + for (i = 0; i < 13; i++) { + OS_Printf("R%02d %08x\n", i, context->r[i]); + } + OS_Printf("SP %08x\n", context->sp); + OS_Printf("LR %08x\n", context->lr); + OS_Printf("PC+4 %08x\n", context->pc_plus4); +#ifdef SDK_CONTEXT_HAS_SP_SVC + OS_Printf("SPsvc %08x\n", context->sp_svc); +#endif + } +#else + (void)context; +#endif +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_emulator.c b/subprojects/NitroSDK/libraries/os/src/os_emulator.c new file mode 100644 index 0000000000..308fd28a49 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_emulator.c @@ -0,0 +1,113 @@ +#include + +#ifdef SDK_ARM9 +#define OSi_CURPROC_LOCKED_FLAG OS_MAINP_LOCKED_FLAG +#else +#define OSi_CURPROC_LOCKED_FLAG OS_SUBP_LOCKED_FLAG +#endif + +static u32 OSi_ConsoleTypeCache = OSi_CONSOLE_NOT_DETECT; + +u32 OSi_GetDeviceType(void); +BOOL OSi_IsRunOnDebugger(void); + +BOOL OS_IsRunOnEmulator (void) +{ +#ifdef SDK_ARM9 +#ifndef SDK_FINALROM + static int onEmu = -1; + u32 val; + OSIntrMode intr; + + if (onEmu == -1) { + intr = OS_DisableInterrupts(); + { + (*(REGType32v *)REG_CLIPMTX_RESULT_0_ADDR) = 0x2468ace0; + + val = *(vu16 *)REG_VCOUNT_ADDR & 0x1ffU; + + if (val == 270) { + *(vu32 *)0x4fff010 = 0x13579bdf; + *(vu32 *)0x4fff010 = 0xfdb97531; + onEmu = TRUE; + } else { + onEmu = FALSE; + } + } + (void)OS_RestoreInterrupts(intr); + } + return (BOOL)onEmu; +#else + return FALSE; +#endif + +#else + return FALSE; +#endif +} + +u32 OS_GetConsoleType (void) +{ +#if defined(SDK_FINALROM) || defined(SDK_SMALL_BUILD) + OSi_ConsoleTypeCache = OS_CONSOLE_NITRO | OS_CONSOLE_DEV_CARD | OS_CONSOLE_SIZE_4MB; + +#else + if (OSi_ConsoleTypeCache == OSi_CONSOLE_NOT_DETECT) { + u32 type = OSi_GetDeviceType(); + + if (OS_IsRunOnEmulator()) { + type |= OS_CONSOLE_ENSATA; + } else if (OSi_IsRunOnDebugger()) { + type |= OS_CONSOLE_ISDEBUGGER; + } else if (type & OS_CONSOLE_DEV_CARTRIDGE) { + type |= OS_CONSOLE_ISEMULATOR; + } else { + type |= OS_CONSOLE_NITRO; + } + + type |= *(u16 *)HW_MMEMCHECKER_SUB; + + OSi_ConsoleTypeCache = type; + } +#endif + + return OSi_ConsoleTypeCache; +} + +u32 OSi_GetDeviceType (void) +{ + BOOL checked = FALSE; + u16 lockId = (u16)OS_GetLockID(); + u32 result = 0; + + do { + s32 ret = OS_LOCK_ERROR; + OSIntrMode enabled = OS_DisableInterrupts(); + + if ((OS_ReadOwnerOfLockCartridge() & OSi_CURPROC_LOCKED_FLAG) + || ((ret = (s32)OS_TryLockCartridge(lockId)) == OS_LOCK_SUCCESS)) { + + result = + (u32)(((((vu32 *)HW_CTRDG_ROM)[0] == (u32)'TNIN') && + (((vu32 *)HW_CTRDG_ROM)[1] == (u32)'ODNE')) ? + OS_CONSOLE_DEV_CARTRIDGE : OS_CONSOLE_DEV_CARD); + + if (ret == OS_LOCK_SUCCESS) { + (void)OS_UnlockCartridge(lockId); + checked = TRUE; + } + } + + (void)OS_RestoreInterrupts(enabled); + } while (!checked); + + return result; +} + +BOOL OSi_IsRunOnDebugger (void) +{ + u16 *checkAddress = (u16 *)((*(u16 *)HW_CHECK_DEBUGGER_SW == + 0) ? HW_CHECK_DEBUGGER_BUF1 : HW_CHECK_DEBUGGER_BUF2); + + return (*checkAddress == 1) ? TRUE : FALSE; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_entropy.c b/subprojects/NitroSDK/libraries/os/src/os_entropy.c new file mode 100644 index 0000000000..7120fcc94a --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_entropy.c @@ -0,0 +1,23 @@ +#include +#include + +extern vu64 OSi_TickCounter; + +void OS_GetLowEntropyData (u32 buffer[OS_LOW_ENTROPY_DATA_SIZE / sizeof(u32)]) +{ + const OSSystemWork *work = OS_GetSystemWork(); + const u8 *macAddress = + (u8 *)((u32)(work->nvramUserInfo) + ((sizeof(NVRAMConfig) + 3) & ~0x00000003)); + + buffer[0] = (u32)((GX_GetVCount() << 16) | OS_GetTickLo()); + buffer[1] = (u32)(*(u16 *)(macAddress + 4) << 16) ^ (u32)(OSi_TickCounter); + buffer[2] = (u32)(OSi_TickCounter >> 32) ^ *(u32 *)macAddress ^ work->vblankCount; +#ifdef reg_G3X_GXSTAT + buffer[2] ^= reg_G3X_GXSTAT; +#endif + buffer[3] = *(u32 *)(&work->real_time_clock[0]); + buffer[4] = *(u32 *)(&work->real_time_clock[4]); + buffer[5] = (((u32)work->mic_sampling_data) << 16) ^ work->mic_last_address; + buffer[6] = (u32)((*(u16 *)(&work->touch_panel[0]) << 16) | *(u16 *)(&work->touch_panel[2])); + buffer[7] = (u32)((work->wm_rssi_pool << 16) | (reg_PAD_KEYINPUT | *(vu16 *)HW_BUTTON_XY_BUF)); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_exception.c b/subprojects/NitroSDK/libraries/os/src/os_exception.c new file mode 100644 index 0000000000..984f396329 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_exception.c @@ -0,0 +1,314 @@ +#include +#include +#include + +#ifdef SDK_ARM9 +#define OSi_ExPrintf OS_Printf + +#else +#define OSi_ExPrintf OS_Printf +#endif + +static asm void OSi_ExceptionHandler(void); +static asm void OSi_GetAndDisplayContext(void); +static asm void OSi_SetExContext(void); +static void OSi_DisplayExContext(void); + +typedef struct { + OSContext context; + u32 cp15; + u32 spsr; + u32 exinfo; + u32 debug[4]; +} OSiExContext; + +static OSiExContext OSi_ExContext; + +static OSExceptionHandler OSi_UserExceptionHandler; +static void *OSi_UserExceptionHandlerArg; + +static void *OSi_DebuggerHandler = NULL; + +#include +asm void OS_SetExceptionVectorUpper (void) +{ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #HW_C1_EXCEPT_VEC_UPPER + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_SetExceptionVectorLower (void) +{ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #HW_C1_EXCEPT_VEC_UPPER + mcr p15, 0, r0, c1, c0, 0 + bx lr +} +#include + +#define HW_EXCP_VECTOR_BUF_FOR_DEBUGGER 0x027ffd9c + +void OS_InitException (void) +{ + if (0x2600000 <= *(u32 *)HW_EXCP_VECTOR_BUF_FOR_DEBUGGER + && *(u32 *)HW_EXCP_VECTOR_BUF_FOR_DEBUGGER < 0x2800000) { + OSi_DebuggerHandler = *(void **)HW_EXCP_VECTOR_BUF_FOR_DEBUGGER; + } else { + OSi_DebuggerHandler = NULL; + } + + if (!OSi_DebuggerHandler) { + *(u32 *)(HW_EXCP_VECTOR_BUF_FOR_DEBUGGER) = (u32)OSi_ExceptionHandler; + *(u32 *)(HW_EXCP_VECTOR_BUF) = (u32)OSi_ExceptionHandler; + } + + OSi_UserExceptionHandler = NULL; +} + +#if defined(SDK_ARM9) + +#include +static u32 OSi_ExceptionHookStack[8]; +asm static void OSi_DebuggerExceptionHook (void) +{ + ldr r12, = OSi_ExceptionHookStack + stmia r12, {r0 - r4, sp, lr} + mrs r4, CPSR + mrs r0, CPSR + and r0, r0, #0x1f + teq r0, #0x17 + beq user_exception + teq r0, #0x1b + bne user_exception_end +is_und: + bic r0, sp, #1 + ldr r1, [r0, #4] + ldr r0, [r0, #12] + tst r1, #0x20 + beq is_und_arm +is_und_thumb: + bic r0, r0, #1 + ldrh r0, [r0, #- 2] + ldr r1, = 0x0000EFFF + cmp r0, r1 + beq user_exception_end + ldr r1, = 0x0000DEFE + cmp r0, r1 + beq user_exception_end + ldr r1, = 0x0000BE00 + cmp r0, r1 + beq user_exception_end + b user_exception +is_und_arm: + bic r0, r0, #3 + ldr r0, [r0, #- 4] + ldr r1, = 0xE7FFFFFF + cmp r0, r1 + beq user_exception_end + ldr r1, = 0xE7FDDEFE + cmp r0, r1 + beq user_exception_end + ldr r1, = 0xE6000010 + cmp r0, r1 + beq user_exception_end + b user_exception +user_exception: + ldmia r12, {r0 - r1} + ldr r12, = HW_ITCM_END + stmfd r12 !, {r0 - r3, sp, lr} + and r0, sp, #1 + mov sp, r12 + bl OSi_GetAndDisplayContext + ldmfd sp !, {r0 - r3, r12, lr} + mov sp, r12 +user_exception_end: + msr CPSR_cxsf, r4 + ldr r12, = OSi_ExceptionHookStack + ldmia r12, {r0 - r4, sp, lr} + ldr r12, = OSi_DebuggerHandler + ldr r12, [r12] + cmp r12, #0 + bxne r12 + bx lr +} +#include + +void OS_EnableUserExceptionHandlerOnDebugger (void) +{ + if (OSi_DebuggerHandler) { + *(u32 *)(HW_EXCP_VECTOR_BUF_FOR_DEBUGGER) = (u32)OSi_DebuggerExceptionHook; + } +} +#endif + +void OS_SetUserExceptionHandler (OSExceptionHandler handler, void *arg) +{ + OSi_UserExceptionHandler = handler; + OSi_UserExceptionHandlerArg = arg; +} + +#include +asm void OSi_ExceptionHandler (void) +{ + ldr r12, = OSi_DebuggerHandler + ldr r12, [r12] + cmp r12, #0 + bne @movne1 + b @movne2 +@movne1: + mov lr, pc +@movne2: + bne @bxne1 + b @bxne2 +@bxne1: + bx r12 +@bxne2: + +#ifdef SDK_ARM9 + ldr r12, = HW_ITCM_END +#else + ldr r12, = 0x3806000 +#endif + stmfd r12 !, {r0 - r3, sp, lr} + and r0, sp, #1 + mov sp, r12 + mrs r1, CPSR + and r1, r1, #0x1f + teq r1, #0x17 + bne @10 + bl OSi_GetAndDisplayContext + b usr_return + + @10: + teq r1, #0x1b + bne usr_return + bl OSi_GetAndDisplayContext + +usr_return: + ldr r12, = OSi_DebuggerHandler + ldr r12, [r12] + cmp r12, #0 + @1: beq @1 + @2: + mov r0, r0 + b @2 + ldmfd sp !, {r0 - r3, r12, lr} + mov sp, r12 + bx lr +} + +static asm void OSi_GetAndDisplayContext (void) +{ + stmfd sp !, {r0, lr} + bl OSi_SetExContext + bl OSi_DisplayExContext + ldmfd sp !, {r0, lr} + bx lr +} + +static asm void OSi_SetExContext (void) +{ + ldr r1, = OSi_ExContext; + mrs r2, CPSR + str r2, [r1, #OSiExContext.debug[1]] + str r0, [r1, #OSiExContext.exinfo] + ldr r0, [r12, #0] + str r0, [r1, #OS_CONTEXT_R0] + ldr r0, [r12, #4] + str r0, [r1, #OS_CONTEXT_R1] + ldr r0, [r12, #8] + str r0, [r1, #OS_CONTEXT_R2] + ldr r0, [r12, #12] + str r0, [r1, #OS_CONTEXT_R3] + ldr r2, [r12, #16] + bic r2, r2, #1 + add r0, r1, #OS_CONTEXT_R4 + stmia r0, {r4 - r11} + str r12, [r1, #OSiExContext.debug[0]] + +#ifdef SDK_ARM9 + ldr r0, [r2, #0] + str r0, [r1, #OSiExContext.cp15] + ldr r3, [r2, #4] + str r3, [r1, #OS_CONTEXT_CPSR] + ldr r0, [r2, #8] + str r0, [r1, #OS_CONTEXT_R12] + ldr r0, [r2, #12] + str r0, [r1, #OS_CONTEXT_PC_PLUS4] +#else + mov r0, #0 + str r0, [r1, #OSiExContext.cp15] + ldr r3, [r2, #0] + str r3, [r1, #OS_CONTEXT_CPSR] + ldr r0, [r2, #4] + str r0, [r1, #OS_CONTEXT_R12] + ldr r0, [r2, #8] + str r0, [r1, #OS_CONTEXT_PC_PLUS4] +#endif + mrs r0, CPSR + orr r3, r3, #0x80 + bic r3, r3, #0x20 + msr CPSR_cxsf, r3 + str sp, [r1, #OS_CONTEXT_R13] + str lr, [r1, #OS_CONTEXT_R14] + mrs r2, SPSR + str r2, [r1, #OSiExContext.debug[3]] + msr CPSR_cxsf, r0 + bx lr +} + +static void OSi_DisplayExContext (void) +{ +#ifndef SDK_FINALROM + int i; + + OSi_ExPrintf("**** Exception Occurred ****\n"); + + for (i = 0; i < 13; i++) { + OSi_ExPrintf("R%02d=%08X %c", i, OSi_ExContext.context.r[i], ((i & 3) == 3) ? '\n' : ' '); + } + OSi_ExPrintf("SP =%08X ", OSi_ExContext.context.sp); + OSi_ExPrintf("LR =%08X ", OSi_ExContext.context.lr); + OSi_ExPrintf("PC =%08X\n", OSi_ExContext.context.pc_plus4); + +#ifdef SDK_ARM9 + OSi_ExPrintf(" CPSR=%08X SPSR=%08X CP15=%08X\n", + OSi_ExContext.context.cpsr, OSi_ExContext.spsr, OSi_ExContext.cp15); +#else + OSi_ExPrintf(" CPSR=%08X SPSR=%08X\n", OSi_ExContext.context.cpsr, OSi_ExContext.spsr); +#endif + OSi_ExPrintf("\n\n"); +#endif + if (OSi_UserExceptionHandler) { + asm { + mrs r2, CPSR + mov r0, sp + ldr r1, = 0x9f + msr CPSR_cxsf, r1 + mov r1, sp + mov sp, r0 + stmfd sp !, {r1, r2} +#ifdef SDK_ARM9 + bl OS_EnableProtectionUnit +#endif + ldr r0, = OSi_ExContext + ldr r1, = OSi_UserExceptionHandlerArg + ldr r1, [r1] + ldr r12, = OSi_UserExceptionHandler + ldr r12, [r12] + ldr lr, = @1 + bx r12 + @1: +#ifdef SDK_ARM9 + bl OS_DisableProtectionUnit +#endif + ldmfd sp !, {r1, r2} + mov sp, r1 + msr CPSR_cxsf, r2 + + } + } +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_init.c b/subprojects/NitroSDK/libraries/os/src/os_init.c new file mode 100644 index 0000000000..80a0f25bbb --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_init.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include + +#ifndef SDK_TEG +#include +#endif + +#include +static asm void OSi_WaitVCount0 (void) +{ + mov r12, #HW_REG_BASE + ldr r1, [r12, #REG_IME_OFFSET] + str r12, [r12, #REG_IME_OFFSET] + +@wait_vcount_0: + ldrh r0, [r12, #REG_VCOUNT_OFFSET] + cmp r0, #0 + bne @wait_vcount_0 + str r1, [r12, #REG_IME_OFFSET] + bx lr +} + +#include + +#pragma profile off +void OS_Init (void) +{ +#ifdef SDK_ARM9 + SDK_ASSERT((u32) & (OS_GetSystemWork()->command_area) == HW_CMD_AREA); +#ifdef SDK_ENABLE_ARM7_PRINT + OS_InitPrintServer(); +#endif + OS_InitArena(); + PXI_Init(); + OS_InitLock(); + OS_InitArenaEx(); + OS_InitIrqTable(); + OS_SetIrqStackChecker(); + OS_InitException(); + MI_Init(); + OS_InitVAlarm(); + OSi_InitVramExclusive(); + +#ifndef SDK_NO_THREAD + OS_InitThread(); +#endif + +#ifndef SDK_SMALL_BUILD + OS_InitReset(); +#endif + +#ifndef SDK_TEG + CTRDG_Init(); +#endif + +#ifndef SDK_SMALL_BUILD + CARD_Init(); +#endif + +#ifndef SDK_TEG + PM_Init(); +#endif + OSi_WaitVCount0(); +#else + OS_InitArena(); + PXI_Init(); + OS_InitLock(); + OS_InitIrqTable(); + +#define SDK_EXCEPTION_BUG +#ifndef SDK_EXCEPTION_BUG + OS_InitException(); +#endif + + OS_InitTick(); + OS_InitAlarm(); + OS_InitThread(); + +#ifndef SDK_SMALL_BUILD + OS_InitReset(); +#endif + +#ifndef SDK_TEG + CTRDG_Init(); +#endif + +#endif +} + +#pragma profile reset \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_interrupt.c b/subprojects/NitroSDK/libraries/os/src/os_interrupt.c new file mode 100644 index 0000000000..703fba58e9 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_interrupt.c @@ -0,0 +1,216 @@ +#include + +extern OSThreadQueue OSi_IrqThreadQueue; + +void OS_InitIrqTable (void) +{ + OS_InitThreadQueue(&OSi_IrqThreadQueue); + +#ifdef SDK_ARM7 + OSi_SetVBlankCount(0); +#endif +} + +void OS_SetIrqFunction (OSIrqMask intrBit, OSIrqFunction function) +{ + int i; + OSIrqCallbackInfo *info; + + for (i = 0; i < OS_IRQ_TABLE_MAX; i++) { + if (intrBit & 1) { + info = NULL; + + if (REG_OS_IE_D0_SHIFT <= i && i <= REG_OS_IE_D3_SHIFT) { + info = &OSi_IrqCallbackInfo[i - REG_OS_IE_D0_SHIFT]; + } else if (REG_OS_IE_T0_SHIFT <= i && i <= REG_OS_IE_T3_SHIFT) { + info = &OSi_IrqCallbackInfo[i - REG_OS_IE_T0_SHIFT + OSi_IRQCALLBACK_NO_TIMER0]; + } +#ifdef SDK_ARM7 + else if (REG_OS_IE_VB_SHIFT == i) { + info = &OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK]; + } +#endif + else { + OS_IRQTable[i] = function; + } + + if (info) { + info->func = (void (*)(void *)) function; + info->arg = 0; + info->enable = TRUE; + } + + } + intrBit >>= 1; + } +} + +OSIrqFunction OS_GetIrqFunction (OSIrqMask intrBit) +{ + int i; + OSIrqFunction *funcPtr = &OS_IRQTable[0]; + + for (i = 0; i < OS_IRQ_TABLE_MAX; i++) { + if (intrBit & 1) { + if (REG_OS_IE_D0_SHIFT <= i && i <= REG_OS_IE_D3_SHIFT) { + return (void (*)(void)) OSi_IrqCallbackInfo[i - REG_OS_IE_D0_SHIFT].func; + } else if (REG_OS_IE_T0_SHIFT <= i && i <= REG_OS_IE_T3_SHIFT) { + return (void (*)(void)) OSi_IrqCallbackInfo[i - REG_OS_IE_T0_SHIFT + + OSi_IRQCALLBACK_NO_TIMER0].func; + } +#ifdef SDK_ARM7 + else if (REG_OS_IE_VB_SHIFT == i) { + return (void (*)(void)) OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK].func; + } +#endif + + return *funcPtr; + } + intrBit >>= 1; + funcPtr++; + } + return 0; +} + +void OSi_EnterDmaCallback (u32 dmaNo, void (*callback)(void *), void *arg) +{ + OSIrqMask imask = (1UL << (REG_OS_IE_D0_SHIFT + dmaNo)); + + OSi_IrqCallbackInfo[dmaNo].func = callback; + OSi_IrqCallbackInfo[dmaNo].arg = arg; + OSi_IrqCallbackInfo[dmaNo].enable = OS_EnableIrqMask(imask) & imask; +} + +void OSi_EnterTimerCallback (u32 timerNo, void (*callback)(void *), void *arg) +{ + OSIrqMask imask = (1UL << (REG_OS_IE_T0_SHIFT + timerNo)); + + OSi_IrqCallbackInfo[timerNo + 4].func = callback; + OSi_IrqCallbackInfo[timerNo + 4].arg = arg; + + (void)OS_EnableIrqMask(imask); + OSi_IrqCallbackInfo[timerNo + 4].enable = TRUE; +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +OSIrqMask OS_SetIrqMask (OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = intr; + (void)OS_RestoreIrq(ime); + return prep; +} + +OSIrqMask OS_EnableIrqMask (OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = prep | intr; + (void)OS_RestoreIrq(ime); + return prep; +} + +OSIrqMask OS_DisableIrqMask (OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); + OSIrqMask prep = reg_OS_IE; + reg_OS_IE = prep & ~intr; + (void)OS_RestoreIrq(ime); + return prep; +} + +OSIrqMask OS_ResetRequestIrqMask (OSIrqMask intr) +{ + BOOL ime = OS_DisableIrq(); + OSIrqMask prep = reg_OS_IF; + reg_OS_IF = intr; + (void)OS_RestoreIrq(ime); + return prep; +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) + #include +#endif + +extern void SDK_IRQ_STACKSIZE(void); + +#ifdef SDK_ARM9 + #define OSi_IRQ_STACK_TOP (HW_DTCM_SVC_STACK - ((s32)SDK_IRQ_STACKSIZE)) + #define OSi_IRQ_STACK_BOTTOM HW_DTCM_SVC_STACK +#else + #define OSi_IRQ_STACK_TOP (HW_PRV_WRAM_IRQ_STACK_END - ((s32)SDK_IRQ_STACKSIZE)) + #define OSi_IRQ_STACK_BOTTOM HW_PRV_WRAM_IRQ_STACK_END +#endif + +#ifdef SDK_ARM9 + #define OSi_IRQ_STACK_CHECKNUM_BOTTOM 0xfddb597dUL + #define OSi_IRQ_STACK_CHECKNUM_TOP 0x7bf9dd5bUL + #define OSi_IRQ_STACK_CHECKNUM_WARN 0x597dfbd9UL +#else + #define OSi_IRQ_STACK_CHECKNUM_BOTTOM 0xd73bfdf7UL + #define OSi_IRQ_STACK_CHECKNUM_TOP 0xfbdd37bbUL + #define OSi_IRQ_STACK_CHECKNUM_WARN 0xbdf7db3dUL +#endif + +static u32 OSi_IrqStackWarningOffset = 0; + +void OS_SetIrqStackChecker (void) +{ + *(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) = OSi_IRQ_STACK_CHECKNUM_BOTTOM; + *(u32 *)(OSi_IRQ_STACK_TOP) = OSi_IRQ_STACK_CHECKNUM_TOP; +} + +void OS_SetIrqStackWarningOffset (u32 offset) +{ + SDK_ASSERTMSG((offset & 3) == 0, "Offset must be aligned by 4"); + SDK_ASSERTMSG(offset > 0, "Cannot set warning level to stack top."); + SDK_ASSERTMSG(offset < ((u32)SDK_IRQ_STACKSIZE), "Cannot set warning level over stack bottom."); + + OSi_IrqStackWarningOffset = offset; + + if (offset != 0) { + *(u32 *)(OSi_IRQ_STACK_TOP + offset) = OSi_IRQ_STACK_CHECKNUM_WARN; + } +} + +OSStackStatus OS_GetIrqStackStatus (void) +{ + + if (*(u32 *)(OSi_IRQ_STACK_TOP) != OSi_IRQ_STACK_CHECKNUM_TOP) { + return OS_STACK_OVERFLOW; + } else if (OSi_IrqStackWarningOffset + && *(u32 *)(OSi_IRQ_STACK_TOP + OSi_IrqStackWarningOffset) != + OSi_IRQ_STACK_CHECKNUM_WARN) { + return OS_STACK_ABOUT_TO_OVERFLOW; + } else if (*(u32 *)(OSi_IRQ_STACK_BOTTOM - sizeof(u32)) != OSi_IRQ_STACK_CHECKNUM_BOTTOM) { + return OS_STACK_UNDERFLOW; + } else { + return OS_STACK_NO_ERROR; + } +} + +static char *OSi_CheckIrqStack_mesg[] = { + "overflow", "about to overflow", "underflow" +}; + +#ifndef SDK_FINALROM +#ifndef SDK_NO_MESSAGE +void OSi_CheckIrqStack (char *file, int line) +{ + OSStackStatus st = OS_GetIrqStackStatus(); + + if (st == OS_STACK_NO_ERROR) { + return; + } + + OSi_Panic(file, line, "irq stack %s.\nirq stack area: %08x-%08x, warning offset: %x", + OSi_CheckIrqStack_mesg[(int)st - 1], + OSi_IRQ_STACK_TOP, OSi_IRQ_STACK_BOTTOM, OSi_IrqStackWarningOffset); + +} +#endif +#endif \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_irqHandler.c b/subprojects/NitroSDK/libraries/os/src/os_irqHandler.c new file mode 100644 index 0000000000..d64432296a --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_irqHandler.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include + +#ifdef SDK_ARM9 +#include +#include +#else +#include +#include +#endif + +#ifdef SDK_ARM9 +#include +#endif + +#ifndef SDK_THREAD_INFINITY +OSThreadQueue OSi_IrqThreadQueue = 0; +#else +OSThreadQueue OSi_IrqThreadQueue = { NULL, NULL }; +#endif + +#ifdef SDK_ARM9 +#include +#include +#endif + +asm void OS_IrqHandler (void) +{ +#ifdef SDK_NO_THREAD +#else + stmfd sp !, { lr } +#endif + mov r12, #HW_REG_BASE + add r12, r12, #REG_IE_OFFSET + ldr r1, [r12, #REG_IME_ADDR - REG_IE_ADDR] + cmp r1, #0 +#ifdef SDK_NO_THREAD + beq @bxeq1 + b @bxeq2 +@bxeq1: + bx lr +@bxeq2: +#else + beq @ldmeqfd3 + b @ldmeqfd4 +@ldmeqfd3: + ldmfd sp !, { pc } +@ldmeqfd4: +#endif + ldmia r12, { r1 - r2 } + ands r1, r1, r2 + +#ifdef SDK_NO_THREAD + beq @bxeq5 + b @bxeq6 +@bxeq5: + bx lr +@bxeq6: +#else + beq @ldmeqfd7 + b @ldmeqfd8 +@ldmeqfd7: + ldmfd sp !, { pc } +@ldmeqfd8: +#endif + +#if defined(SDK_ARM9) && !defined(SDK_CWBUG_PROC_OPT) + mov r3, #1 << 31 + @1 : clz r0, r1 + bics r1, r1, r3, LSR r0 + bne @1 + mov r1, r3, LSR r0 + str r1, [r12, #REG_IF_ADDR - REG_IE_ADDR] + rsbs r0, r0, #31 + +#else + mov r3, #1 + mov r0, #0 + @1: ands r2, r1, r3, LSL r0 + beq @addeq9 + b @addeq10 +@addeq9: + add r0, r0, #1 +@addeq10: + beq @1 + str r2, [r12, #REG_IF_ADDR - REG_IE_ADDR] +#endif + +#ifdef SDK_DEBUG + cmp r0, #OS_IRQ_TABLE_MAX + @2: bge @2 +#endif + ldr r1, = OS_IRQTable + ldr r0, [r1, r0, LSL #2] + +#ifdef SDK_NO_THREAD + bx r0 +#else + ldr lr, = OS_IrqHandler_ThreadSwitch + bx r0 +#endif +} + +asm void OS_IrqHandler_ThreadSwitch (void) +{ +#ifdef SDK_NO_THREAD +#else +#ifndef SDK_THREAD_INFINITY + ldr r12, = OSi_IrqThreadQueue +#if (OS_THREAD_MAX_NUM <= 16) + ldrh r3, [r12] + mov r0, #0 + cmp r3, #0 + beq @thread_switch + strh r0, [r12] +#else + ldr r3, [r12] + mov r0, #0 + cmp r3, #0 + beq @thread_switch + str r0, [r12] +#endif + ldr r12, = OSi_ThreadInfo + mov r1, #1 + strh r1, [r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING] + ldr r12, [r12, #OS_THREADINFO_OFFSET_LIST] + mov r2, #OS_THREAD_STATE_READY + @1 : + cmp r12, #0 + beq @thread_switch + ldr r0, [r12, #OS_THREAD_OFFSET_ID] + tst r3, r1, LSL r0 + bne @strne1 + b @strne2 +@strne1: + str r2, [r12, #OS_THREAD_OFFSET_STATE] +@strne2: + ldr r12, [r12, #OS_THREAD_OFFSET_NEXT] + b @1 +#else + ldr r12, = OSi_IrqThreadQueue + mov r3, #0 + ldr r12, [r12, #OSThreadQueue.head] + mov r2, #OS_THREAD_STATE_READY + cmp r12, #0 + beq @thread_switch + @1: str r2, [r12, #OSThread.state] + str r3, [r12, #OSThread.queue] + str r3, [r12, #OSThread.link.prev] + ldr r0, [r12, #OSThread.link.next] + str r3, [r12, #OSThread.link.next] + mov r12, r0 + cmp r12, #0 + bne @1 + ldr r12, = OSi_IrqThreadQueue + str r3, [r12, #OSThreadQueue.head] + str r3, [r12, #OSThreadQueue.tail] + ldr r12, = OSi_ThreadInfo + mov r1, #1 + strh r1, [r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING] +#endif + +@thread_switch: + ldr r12, = OSi_ThreadInfo + ldrh r1, [r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING] + cmp r1, #0 + beq @ldreq3 + b @ldreq4 +@ldreq3: + ldr pc, [sp], #4 +@ldreq4: + mov r1, #0 + strh r1, [r12, #OS_THREADINFO_OFFSET_ISNEEDRESCHEDULING] + mov r3, #HW_PSR_IRQ_MODE | HW_PSR_FIQ_DISABLE | HW_PSR_IRQ_DISABLE | HW_PSR_ARM_STATE + msr cpsr_c, r3 + add r2, r12, #OS_THREADINFO_OFFSET_LIST + ldr r1, [r2] + @11 : + cmp r1, #0 + bne @ldrneh5 + b @ldrneh6 +@ldrneh5: + ldrh r0, [r1, #OS_THREAD_OFFSET_STATE] +@ldrneh6: + bne @cmpne7 + b @cmpne8 +@cmpne7: + cmp r0, #OS_THREAD_STATE_READY +@cmpne8: + bne @ldrne9 + b @ldrne10 +@ldrne9: + ldr r1, [r1, #OS_THREAD_OFFSET_NEXT] +@ldrne10: + bne @11 + cmp r1, #0 + bne @12 + +_dont_switched_: + mov r3, #HW_PSR_IRQ_MODE | HW_PSR_IRQ_DISABLE | HW_PSR_ARM_STATE + msr cpsr_c, r3 + ldr pc, [sp], #4 + + @12 : + ldr r0, [r12, #OS_THREADINFO_OFFSET_CURRENT] + cmp r1, r0 + beq _dont_switched_ + ldr r3, [r12, #OS_THREADINFO_OFFSET_SWITCHCALLBACK] + cmp r3, #0 + beq @13 + stmfd sp !, { r0, r1, r12 } + mov lr, pc + bx r3 + ldmfd sp !, { r0, r1, r12 } + + @13: + str r1, [r12, #OS_THREADINFO_OFFSET_CURRENT] + mrs r2, SPSR + str r2, [r0, #OS_THREAD_OFFSET_CONTEXT] ! + +#if defined(SDK_ARM9) + stmfd sp !, { r0, r1 } + add r0, r0, #OS_THREAD_OFFSET_CONTEXT + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, = CP_SaveContext + blx r1 + ldmfd sp !, { r0, r1 } +#endif + ldmib sp !, { r2, r3 } + stmib r0 !, { r2, r3 } + ldmib sp !, { r2, r3, r12, r14 } + stmib r0 !, { r2 - r14 }^ + stmib r0 !, { r14 } +#ifdef SDK_CONTEXT_HAS_SP_SVC + mov r3, #HW_PSR_SVC_MODE | HW_PSR_FIQ_DISABLE | HW_PSR_IRQ_DISABLE | HW_PSR_ARM_STATE + msr cpsr_c, r3 + stmib r0 !, { sp } +#endif + +#if defined(SDK_ARM9) + stmfd sp !, { r1 } + add r0, r1, #OS_THREAD_OFFSET_CONTEXT + add r0, r0, #OS_CONTEXT_CP_CONTEXT + ldr r1, = CPi_RestoreContext + blx r1 + ldmfd sp !, { r1 } +#endif + +#ifdef SDK_CONTEXT_HAS_SP_SVC + ldr sp, [r1, #OS_THREAD_OFFSET_CONTEXT + OS_CONTEXT_SP_SVC] + mov r3, #HW_PSR_IRQ_MODE | HW_PSR_FIQ_DISABLE | HW_PSR_IRQ_DISABLE | HW_PSR_ARM_STATE + msr cpsr_c, r3 +#endif + ldr r2, [r1, #OS_THREAD_OFFSET_CONTEXT] ! + msr SPSR, r2 + ldr r14, [r1, #OS_CONTEXT_PC_PLUS4 - OS_CONTEXT_CPSR] + ldmib r1, { r0 - r14 }^ + nop + stmda sp !, { r0 - r3, r12, r14 } + ldmfd sp !, { pc } +#endif +} + +#ifdef SDK_ARM9 +#include +#endif + +void OS_WaitIrq (BOOL clear, OSIrqMask irqFlags) +{ +#ifdef SDK_NO_THREAD + OS_WaitInterrupt(clear, irqFlags); + +#else + OSIntrMode enabled = OS_DisableInterrupts(); + + if (clear) { + (void)OS_ClearIrqCheckFlag(irqFlags); + } + + (void)OS_RestoreInterrupts(enabled); + + while (!(OS_GetIrqCheckFlag() & irqFlags)) { + OS_SleepThread(&OSi_IrqThreadQueue); + } +#endif +} + +void OS_WaitAnyIrq (void) +{ +#ifdef SDK_NO_THREAD + OS_Halt(); +#else + OS_SleepThread(&OSi_IrqThreadQueue); +#endif +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_irqTable.c b/subprojects/NitroSDK/libraries/os/src/os_irqTable.c new file mode 100644 index 0000000000..91a9900542 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_irqTable.c @@ -0,0 +1,173 @@ +#include + +void OSi_IrqCallback(int dmaNo); +void OSi_IrqTimer0(void); +void OSi_IrqTimer1(void); +void OSi_IrqTimer2(void); +void OSi_IrqTimer3(void); +void OSi_IrqDma0(void); +void OSi_IrqDma1(void); +void OSi_IrqDma2(void); +void OSi_IrqDma3(void); + +#ifdef SDK_ARM7 +void OSi_IrqVBlank(void); +#endif + +#ifdef SDK_ARM9 +#include +#endif +OSIrqFunction OS_IRQTable[OS_IRQ_TABLE_MAX] = { +#ifdef SDK_ARM9 + OS_IrqDummy, +#else + OSi_IrqVBlank, +#endif + OS_IrqDummy, + OS_IrqDummy, + OSi_IrqTimer0, + OSi_IrqTimer1, + OSi_IrqTimer2, + OSi_IrqTimer3, + OS_IrqDummy, + OSi_IrqDma0, + OSi_IrqDma1, + OSi_IrqDma2, + OSi_IrqDma3, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, +#ifdef SDK_ARM9 + OS_IrqDummy, +#else + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy, + OS_IrqDummy +#endif +}; +#ifdef SDK_ARM9 +#include +#endif + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +OSIrqCallbackInfo OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NUM] = { + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, + { NULL, 0, 0, }, +#ifdef SDK_ARM7 + {NULL, 0, 0, } +#endif +}; + +static u16 OSi_IrqCallbackInfoIndex[OSi_IRQCALLBACK_NUM] = { + REG_OS_IE_D0_SHIFT, REG_OS_IE_D1_SHIFT, REG_OS_IE_D2_SHIFT, REG_OS_IE_D3_SHIFT, + REG_OS_IE_T0_SHIFT, REG_OS_IE_T1_SHIFT, REG_OS_IE_T2_SHIFT, REG_OS_IE_T3_SHIFT, +#ifdef SDK_ARM7 + REG_OS_IE_VB_SHIFT +#endif +}; +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +void OS_IrqDummy (void) +{ + +} + +void OSi_IrqCallback (int index) +{ + OSIrqMask imask = (1UL << OSi_IrqCallbackInfoIndex[index]); + void (*callback) (void *) = OSi_IrqCallbackInfo[index].func; + + OSi_IrqCallbackInfo[index].func = NULL; + + if (callback) { + (callback) (OSi_IrqCallbackInfo[index].arg); + } + + OS_SetIrqCheckFlag(imask); + + if (!OSi_IrqCallbackInfo[index].enable) { + (void)OS_DisableIrqMask(imask); + } +} + +void OSi_IrqDma0 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA0); +} + +void OSi_IrqDma1 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA1); +} + +void OSi_IrqDma2 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA2); +} + +void OSi_IrqDma3 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_DMA3); +} + +void OSi_IrqTimer0 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER0); +} + +void OSi_IrqTimer1 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER1); +} + +void OSi_IrqTimer2 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER2); +} + +void OSi_IrqTimer3 (void) +{ + OSi_IrqCallback(OSi_IRQCALLBACK_NO_TIMER3); +} + +#if defined(SDK_TCM_APPLY) && defined(SDK_ARM9) +#include +#endif + +#ifdef SDK_ARM7 +void OSi_IrqVBlank (void) +{ + void (*callback) (void) = + (void (*)(void)) OSi_IrqCallbackInfo[OSi_IRQCALLBACK_NO_VBLANK].func; + + (*(u32 *)HW_VBLANK_COUNT_BUF)++; + + if (callback) { + (callback) (); + } + + OS_SetIrqCheckFlag(1UL << REG_OS_IE_VB_SHIFT); +} +#endif \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_message.c b/subprojects/NitroSDK/libraries/os/src/os_message.c new file mode 100644 index 0000000000..cecbdd0bec --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_message.c @@ -0,0 +1,113 @@ +#include +#include + +void OS_InitMessageQueue (OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount) +{ + OS_InitThreadQueue(&mq->queueSend); + OS_InitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +BOOL OS_SendMessage (OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled; + s32 lastIndex; + + enabled = OS_DisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } else { + OS_SleepThread(&mq->queueSend); + } + } + + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + OS_WakeupThread(&mq->queueReceive); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +BOOL OS_ReceiveMessage (OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = OS_DisableInterrupts(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } else { + OS_SleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + OS_WakeupThread(&mq->queueSend); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +BOOL OS_JamMessage (OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = OS_DisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) { + if (!(flags & OS_MESSAGE_BLOCK)) { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } else { + OS_SleepThread(&mq->queueSend); + } + } + + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + + OS_WakeupThread(&mq->queueReceive); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +BOOL OS_ReadMessage (OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = OS_DisableInterrupts(); + + while (mq->usedCount == 0) { + if (!(flags & OS_MESSAGE_BLOCK)) { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } else { + OS_SleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) { + *msg = mq->msgArray[mq->firstIndex]; + } + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_mutex.c b/subprojects/NitroSDK/libraries/os/src/os_mutex.c new file mode 100644 index 0000000000..6527fcc227 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_mutex.c @@ -0,0 +1,227 @@ +#include +#include + +void OSi_EnqueueTail(OSThread *thread, OSMutex *mutex); +void OSi_DequeueItem(OSThread *thread, OSMutex *mutex); +OSMutex *OSi_DequeueHead(OSThread *thread); + +void OS_InitMutex (OSMutex *mutex) +{ + SDK_ASSERT(mutex); + + OS_InitThreadQueue(&mutex->queue); + mutex->thread = NULL; + mutex->count = 0; +} + +void OS_LockMutex (OSMutex *mutex) +{ + OSIntrMode saved; + OSThread *currentThread; + OSThread *ownerThread; + + SDK_ASSERT(mutex); + + saved = OS_DisableInterrupts(); + currentThread = OS_GetCurrentThread(); + + for (;;) { + ownerThread = ((volatile OSMutex *)mutex)->thread; + + if (ownerThread == NULL) { + mutex->thread = currentThread; + mutex->count++; + OSi_EnqueueTail(currentThread, mutex); + break; + } else if (ownerThread == currentThread) { + mutex->count++; + break; + } else { + currentThread->mutex = mutex; + OS_SleepThread(&mutex->queue); + currentThread->mutex = NULL; + } + } + + (void)OS_RestoreInterrupts(saved); +} + +void OS_UnlockMutex (OSMutex *mutex) +{ + OSIntrMode saved; + OSThread *currentThread; + + SDK_ASSERT(mutex); + + saved = OS_DisableInterrupts(); + currentThread = OS_GetCurrentThread(); + + if (mutex->thread == currentThread && --mutex->count == 0) { + OSi_DequeueItem(currentThread, mutex); + mutex->thread = NULL; + + OS_WakeupThread(&mutex->queue); + } + + (void)OS_RestoreInterrupts(saved); +} + +void OSi_UnlockAllMutex (OSThread *thread) +{ + OSMutex *mutex; + + SDK_ASSERT(thread); + +#ifndef SDK_THREAD_INFINITY + while (thread->mutexQueueHead) { + mutex = OSi_DequeueHead(thread); + SDK_ASSERT(mutex->thread == thread); + + mutex->count = 0; + mutex->thread = NULL; + OS_WakeupThread(&(mutex->queue)); + } +#else + while (thread->mutexQueue.head) { + mutex = OSi_RemoveMutexLinkFromQueue(&thread->mutexQueue); + + SDK_ASSERT(mutex->thread == thread); + mutex->count = 0; + mutex->thread = NULL; + OS_WakeupThread(&mutex->queue); + + } +#endif +} + +BOOL OS_TryLockMutex (OSMutex *mutex) +{ + OSIntrMode saved; + OSThread *currentThread; + BOOL locked; + + SDK_ASSERT(mutex); + + saved = OS_DisableInterrupts(); + currentThread = OS_GetCurrentThread(); + + if (mutex->thread == NULL) { + mutex->thread = currentThread; + mutex->count++; + OSi_EnqueueTail(currentThread, mutex); + locked = TRUE; + } else if (mutex->thread == currentThread) { + mutex->count++; + locked = TRUE; + } else { + locked = FALSE; + } + + (void)OS_RestoreInterrupts(saved); + return locked; +} + +void OSi_EnqueueTail (OSThread *thread, OSMutex *mutex) +{ +#ifndef SDK_THREAD_INFINITY + OSMutex *prev = thread->mutexQueueTail; + + SDK_ASSERT(thread && mutex); + + if (!prev) { + thread->mutexQueueHead = mutex; + } else { + prev->next = mutex; + } + + mutex->prev = prev; + mutex->next = NULL; + thread->mutexQueueTail = mutex; +#else + OSMutex *prev = thread->mutexQueue.tail; + + SDK_ASSERT(thread && mutex); + + if (!prev) { + thread->mutexQueue.head = mutex; + } else { + prev->link.next = mutex; + } + + mutex->link.prev = prev; + mutex->link.next = NULL; + thread->mutexQueue.tail = mutex; +#endif +} + +void OSi_DequeueItem (OSThread *thread, OSMutex *mutex) +{ +#ifndef SDK_THREAD_INFINITY + OSMutex *next = mutex->next; + OSMutex *prev = mutex->prev; + + SDK_ASSERT(thread && mutex); + + if (!next) { + thread->mutexQueueTail = prev; + } else { + next->prev = prev; + } + + if (!prev) { + thread->mutexQueueHead = next; + } else { + prev->next = next; + } +#else + OSMutex *next = mutex->link.next; + OSMutex *prev = mutex->link.prev; + + SDK_ASSERT(thread && mutex); + + if (!next) { + thread->mutexQueue.tail = prev; + } else { + next->link.prev = prev; + } + + if (!prev) { + thread->mutexQueue.head = next; + } else { + prev->link.next = next; + } +#endif +} + +OSMutex *OSi_DequeueHead (OSThread *thread) +{ +#ifndef SDK_THREAD_INFINITY + OSMutex *mutex = thread->mutexQueueHead; + OSMutex *next = mutex->next; + + SDK_ASSERT(thread); + + if (!next) { + thread->mutexQueueTail = NULL; + } else { + next->prev = NULL; + } + + thread->mutexQueueHead = next; +#else + OSMutex *mutex = thread->mutexQueue.head; + OSMutex *next = mutex->link.next; + + SDK_ASSERT(thread); + + if (!next) { + thread->mutexQueue.tail = NULL; + } else { + next->link.prev = NULL; + } + + thread->mutexQueue.head = next; +#endif + + return mutex; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_ownerInfo.c b/subprojects/NitroSDK/libraries/os/src/os_ownerInfo.c new file mode 100644 index 0000000000..338f2e431e --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_ownerInfo.c @@ -0,0 +1,71 @@ +#include +#include + +void OS_GetMacAddress (u8 *macAddress) +{ + u8 *src; + + src = + (u8 *)((u32)(OS_GetSystemWork()->nvramUserInfo) + + ((sizeof(NVRAMConfig) + 3) & ~0x00000003)); + MI_CpuCopy8(src, macAddress, 6); +} + +#ifdef SDK_TS +#if (SDK_TS_VERSION >= 200 || SDK_NVRAM_FORMAT >= 100) + +void OS_GetOwnerInfo (OSOwnerInfo *info) +{ + NVRAMConfig *src; + + src = (NVRAMConfig *)(OS_GetSystemWork()->nvramUserInfo); + info->language = (u8)(src->ncd.option.language); + info->favoriteColor = (u8)(src->ncd.owner.favoriteColor); + info->birthday.month = (u8)(src->ncd.owner.birthday.month); + info->birthday.day = (u8)(src->ncd.owner.birthday.day); + info->nickNameLength = (u16)(src->ncd.owner.nickname.length); + info->commentLength = (u16)(src->ncd.owner.comment.length); + MI_CpuCopy16(src->ncd.owner.nickname.str, + info->nickName, OS_OWNERINFO_NICKNAME_MAX * sizeof(u16)); + MI_CpuCopy16(src->ncd.owner.comment.str, info->comment, OS_OWNERINFO_COMMENT_MAX * sizeof(u16)); + info->nickName[OS_OWNERINFO_NICKNAME_MAX] = 0; + info->comment[OS_OWNERINFO_COMMENT_MAX] = 0; +} + +#endif + +s64 OS_GetOwnerRtcOffset (void) +{ + NVRAMConfig *src = (NVRAMConfig *)(OS_GetSystemWork()->nvramUserInfo); + +#if (SDK_TS_VERSION >= 200 || SDK_NVRAM_FORMAT >= 100) + return src->ncd.option.rtcOffset; +#else + return src->ncd.rtcOffset; +#endif +} + +#endif + +const GXRgb *OS_GetFavoriteColorTable (void) +{ + static const GXRgb col_table[OS_FAVORITE_COLOR_MAX] = { + OS_FAVORITE_COLOR_VALUE_GRAY, + OS_FAVORITE_COLOR_VALUE_BROWN, + OS_FAVORITE_COLOR_VALUE_RED, + OS_FAVORITE_COLOR_VALUE_PINK, + OS_FAVORITE_COLOR_VALUE_ORANGE, + OS_FAVORITE_COLOR_VALUE_YELLOW, + OS_FAVORITE_COLOR_VALUE_LIME_GREEN, + OS_FAVORITE_COLOR_VALUE_GREEN, + OS_FAVORITE_COLOR_VALUE_DARK_GREEN, + OS_FAVORITE_COLOR_VALUE_SEA_GREEN, + OS_FAVORITE_COLOR_VALUE_TURQUOISE, + OS_FAVORITE_COLOR_VALUE_BLUE, + OS_FAVORITE_COLOR_VALUE_DARK_BLUE, + OS_FAVORITE_COLOR_VALUE_PURPLE, + OS_FAVORITE_COLOR_VALUE_VIOLET, + OS_FAVORITE_COLOR_VALUE_MAGENTA, + }; + return col_table; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_printf.c b/subprojects/NitroSDK/libraries/os/src/os_printf.c new file mode 100644 index 0000000000..a6795472cd --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_printf.c @@ -0,0 +1,885 @@ +#include + +#ifdef SDK_LINK_ISD +# pragma warn_extracomma off +# include +# pragma warn_extracomma reset +#else +void ISDPrint(const char *); +#endif + +#ifndef SDK_FINALROM +static char common_buffer[256]; +#endif + +#if !defined(SDK_FINALROM) && defined(SDK_NO_MESSAGE) +#undef OSi_Warning +#undef OSi_TWarning +#undef OSi_Panic +#undef OSi_TPanic +void OSi_Warning(const char *file, int line, const char *fmt, ...); +void OSi_TWarning(const char *file, int line, const char *fmt, ...); +void OSi_Panic(const char *file, int line, const char *fmt, ...); +void OSi_TPanic(const char *file, int line, const char *fmt, ...); +#endif + +#ifndef SDK_FINALROM +SDK_WEAK_SYMBOL void OS_PutChar (char c) +{ + char str[2]; + + str[0] = c; + str[1] = '\0'; + + OS_PutString(str); +} +#endif + +static void OS_PutStringInit(const char *str); + +#ifndef SDK_FINALROM +static void OS_PutStringAris(const char *str); +static void OS_PutStringISD(const char *str); +#ifdef SDK_ARM7 +static void OS_PutStringPrnSrv(const char *str); +#endif +#endif + +#ifndef SDK_FINALROM +void (*OS_PutString) (const char *str) = OS_PutStringInit; +#endif + +static void OS_PutStringInit (const char *str) +{ +#ifndef SDK_FINALROM + OSIntrMode intr = OS_DisableInterrupts(); + +#ifdef SDK_ARM9 + if (OS_IsRunOnEmulator()) { + OS_PutString = OS_PutStringAris; + } else +#endif + { +#ifdef SDK_ARM7 + OS_PutString = OS_PutStringPrnSrv; +#else + OS_PutString = OS_PutStringISD; +#endif + } + + OS_PutString(str); + + (void)OS_RestoreInterrupts(intr); + +#else + (void)str; +#endif +} + +#ifndef SDK_FINALROM +#ifdef SDK_CW_WARNOFF_SAFESTRB +#include +#endif +static void OS_PutStringAris (const char *str) +{ + char c; + + while ('\0' != (c = *str)) { + reg_OS_EMU_CONSOLE_OUT = (u8)c; + str++; + } +} + +#ifdef SDK_CW_WARNOFF_SAFESTRB +#include +#endif +#endif + +#ifndef SDK_FINALROM +static void OS_PutStringISD (const char *str) +{ + OS_InitLock(); + + OS_PutString = ISDPrint; + OS_PutString(str); +} +#endif + +#ifndef SDK_FINALROM +#if defined(SDK_ARM9) || defined(SDK_USE_VSNPRINTF) +SDK_WEAK_SYMBOL void OS_VPrintf (const char *fmt, va_list vlist) +{ + (void)vsnprintf(common_buffer, sizeof(common_buffer), fmt, vlist); + OS_PutString(common_buffer); +} +#else +SDK_WEAK_SYMBOL void OS_VPrintf (const char *fmt, va_list vlist) +{ + OS_TVPrintf(fmt, vlist); +} +#endif +SDK_WEAK_SYMBOL void OS_TVPrintf (const char *fmt, va_list vlist) +{ + (void)OS_VSNPrintf(common_buffer, sizeof(common_buffer), fmt, vlist); + OS_PutString(common_buffer); +} +SDK_WEAK_SYMBOL void OS_TVPrintfEx (const char *fmt, va_list vlist) +{ + (void)OS_VSNPrintfEx(common_buffer, sizeof(common_buffer), fmt, vlist); + OS_PutString(common_buffer); +} +#endif + +#ifndef SDK_FINALROM +SDK_WEAK_SYMBOL void OS_Printf (const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + OS_VPrintf(fmt, vlist); + va_end(vlist); +} + +SDK_WEAK_SYMBOL void OS_TPrintf (const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + OS_TVPrintf(fmt, vlist); + va_end(vlist); +} + +SDK_WEAK_SYMBOL void OS_TPrintfEx (const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + OS_TVPrintfEx(fmt, vlist); + va_end(vlist); +} +#endif + +#ifndef SDK_FINALROM +SDK_WEAK_SYMBOL void OSi_Warning (const char *file, int line, const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + OS_Printf("%s:%d Warning:", file, line); + OS_VPrintf(fmt, vlist); + OS_Printf("\n"); + va_end(vlist); +} + +SDK_WEAK_SYMBOL void OSi_TWarning (const char *file, int line, const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + OS_TPrintf("%s:%d Warning:", file, line); + OS_TVPrintf(fmt, vlist); + OS_TPrintf("\n"); + va_end(vlist); +} +#endif + +#ifndef SDK_FINALROM +void (*OSi_FuncTerminate) (void) = OS_Terminate; + +SDK_WEAK_SYMBOL void OSi_Panic (const char *file, int line, const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + (void)OS_DisableInterrupts(); + OS_Printf("%s:%d Panic:", file, line); + OS_VPrintf(fmt, vlist); + OS_Printf("\n"); + OSi_FuncTerminate(); +} + +SDK_WEAK_SYMBOL void OSi_TPanic (const char *file, int line, const char *fmt, ...) +{ + va_list vlist; + + va_start(vlist, fmt); + (void)OS_DisableInterrupts(); + OS_TPrintf("%s:%d Panic:", file, line); + OS_TVPrintf(fmt, vlist); + OS_TPrintf("\n"); + OSi_FuncTerminate(); +} +#endif + +#ifdef SDK_ARM9 +#ifndef SDK_FINALROM +void OS_InitPrintServer (void) +{ + OSPrintServerBuffer *p; + + OS_InitArena(); + p = OS_AllocFromSharedArenaHi(sizeof(OSPrintServerBuffer), 4); + p->in = p->out = 0UL; + PXI_SetComponentParam((u32)p); +} +#endif +#endif + +#ifdef SDK_ARM9 +#ifndef SDK_FINALROM +#include +void OS_PrintServer (void) +{ + OSPrintServerBuffer *p; + register OSPrintWChar word; + + u32 in, out; + int i; + + p = (OSPrintServerBuffer *)PXI_GetComponentParam(); + + if (!p) { + return; + } + + out = p->out; + in = p->in; + + while (in != out) { + i = 0; + + while (in != out && i < sizeof(common_buffer) - 3) { + word.s = p->buffer[out].s; + if (word.c[0]) { + common_buffer[i++] = word.c[0]; + + if (word.c[1]) { + common_buffer[i++] = word.c[1]; + } + } + out++; + if (out >= OS_PRINTSRV_WCHARSIZE) + out = 0; + } + common_buffer[i] = '\0'; + OS_PutString(common_buffer); + } + + p->out = out; +} + +#include +#endif +#endif + +#ifdef SDK_ARM7 +static void OS_PutStringPrnSrv (const char *str) +{ +#ifndef SDK_FINALROM + OSPrintServerBuffer *p; + register OSPrintWChar word; + + u32 in, in_tmp, out; + u32 isOdd; + + p = (OSPrintServerBuffer *)PXI_GetComponentParam(); + in = p->in; + out = p->out; + isOdd = ((u32)str) & 1; + + while (1) { + in_tmp = in + 1; + if (in_tmp >= OS_PRINTSRV_WCHARSIZE) + in_tmp = 0; + if (out == in_tmp) + break; + + if (isOdd) { + p->buffer[in].s = word.s = (u16)((*(u16 *)(str - 1)) & 0xff00); + str++; + isOdd = 0UL; + if (!word.c[1]) + break; + in = in_tmp; + } else { + p->buffer[in].s = word.s = *(u16 *)str; + str += 2; + if (!word.c[0]) + break; + in = in_tmp; + if (!word.c[1]) + break; + } + } + p->in = in; +#else + (void)str; +#endif +} +#endif + +#if defined(SDK_CW_WARNOFF_SAFESTRB) +#include +#endif + +typedef struct dst_string_tag { + size_t len; + char *cur; + char *base; +} +dst_string; + +static void string_put_char (dst_string *p, char c) +{ + if (p->len > 0) + *p->cur = c, --p->len; + ++p->cur; +} + +static void string_fill_char (dst_string *p, char c, int n) +{ + if (n > 0) { + size_t i, k = p->len; + if (k > (size_t) n) + k = (size_t) n; + for (i = 0; i < k; ++i) + p->cur[i] = c; + p->len -= k; + p->cur += n; + } +} + +static void string_put_string (dst_string *p, const char *s, int n) +{ + if (n > 0) { + size_t i, k = p->len; + if (k > (size_t) n) + k = (size_t) n; + for (i = 0; i < k; ++i) + p->cur[i] = s[i]; + p->len -= k; + p->cur += n; + } +} + +SDK_WEAK_SYMBOL int OS_SPrintf (char *dst, const char *fmt, ...) +{ + int ret; + va_list va; + va_start(va, fmt); + ret = OS_VSPrintf(dst, fmt, va); + va_end(va); + return ret; +} + +SDK_WEAK_SYMBOL int OS_VSPrintf (char *dst, const char *fmt, va_list vlist) +{ + return OS_VSNPrintf(dst, 0x7FFFFFFF, fmt, vlist); +} + +SDK_WEAK_SYMBOL int OS_SNPrintf (char *dst, size_t len, const char *fmt, ...) +{ + int ret; + va_list va; + va_start(va, fmt); + ret = OS_VSNPrintf(dst, len, fmt, va); + va_end(va); + return ret; +} + +SDK_WEAK_SYMBOL int OS_VSNPrintf (char *dst, size_t len, const char *fmt, va_list vlist) +{ + return STD_TVSNPrintf(dst, len, fmt, vlist); +} + +SDK_WEAK_SYMBOL int OS_VSNPrintfEx (char *dst, size_t len, const char *fmt, va_list vlist) +{ + char buf[24]; + int n_buf; + char prefix[2]; + int n_prefix; + + const char *s = fmt; + + dst_string str; + str.len = len, str.cur = str.base = dst; + + while (*s) { + if ((unsigned int)(((unsigned char)*s ^ 0x20) - 0xA1) < 0x3C) { + + string_put_char(&str, *s++); + if (*s) + string_put_char(&str, *s++); + } else if (*s != '%') { + + string_put_char(&str, *s++); + } else { + + enum { + flag_blank = 000001, + flag_plus = 000002, + flag_sharp = 000004, + flag_minus = 000010, + flag_zero = 000020, + flag_l1 = 000040, + flag_h1 = 000100, + flag_l2 = 000200, + flag_h2 = 000400, + flag_unsigned = 010000, + flag_binary = 020000, + flag_colon = 040000, + flag_end + }; + int flag = 0, width = 0, precision = -1, radix = 10; + char hex_char = 'a' - 10; + const char *p_start = s; + + for (;;) { + switch (*++s) { + case '+': + if (s[-1] != ' ') + break; + flag |= flag_plus; + continue; + case ' ': + flag |= flag_blank; + continue; + case '-': + flag |= flag_minus; + continue; + case '0': + flag |= flag_zero; + continue; + case ':': + flag |= flag_colon; + continue; + } + break; + } + + if (*s == '*') { + ++s, width = va_arg(vlist, int); + if (width < 0) + width = -width, flag |= flag_minus; + } else { + while ((*s >= '0') && (*s <= '9')) + width = (width * 10) + *s++ - '0'; + } + + if (*s == '.') { + ++s, precision = 0; + if (*s == '*') { + ++s, precision = va_arg(vlist, int); + if (precision < 0) + precision = -1; + } else { + while ((*s >= '0') && (*s <= '9')) + precision = (precision * 10) + *s++ - '0'; + } + } + + switch (*s) { + case 'h': + if (*++s != 'h') + flag |= flag_h1; + else + ++s, flag |= flag_h2; + break; + case 'l': + if (*++s != 'l') + flag |= flag_l1; + else + ++s, flag |= flag_l2; + break; + } + + switch (*s) { + case 'd': + case 'i': + goto put_integer; + case 'o': + radix = 8; + flag |= flag_unsigned; + goto put_integer; + case 'u': + flag |= flag_unsigned; + goto put_integer; + case 'X': + hex_char = 'A' - 10; + goto put_hexadecimal; + case 'x': + goto put_hexadecimal; + case 'p': + + flag |= flag_sharp; + precision = 8; + goto put_hexadecimal; + + case 'C': + flag |= flag_l1; + case 'c': + if (precision >= 0) + goto put_invalid; + { + int c = va_arg(vlist, int); + width -= 1; + if (flag & flag_minus) { + if (flag & flag_l1) { + char dst[2]; + + if (STD_ConvertCharUnicodeToSjis(dst, (u16)c) == 1) { + string_put_char(&str, dst[0]); + } else { + string_put_string(&str, dst, 2); + } + } else { + string_put_char(&str, (char)c); + } + string_fill_char(&str, ' ', width); + } else { + char pad = (char)((flag & flag_zero) ? '0' : ' '); + string_fill_char(&str, pad, width); + + if (flag & flag_l1) { + char dst[2]; + + if (STD_ConvertCharUnicodeToSjis(dst, (u16)c) == 1) { + string_put_char(&str, dst[0]); + } else { + string_put_string(&str, dst, 2); + } + } else { + string_put_char(&str, (char)c); + } + } + ++s; + } + break; + + case 'S': + flag |= flag_l1; + case 's': + { + int n_buf = 0; + const char *p_buf = va_arg(vlist, const char *); + + if (precision < 0) { + while (p_buf[n_buf]) { + if (flag & flag_l1) { + n_buf += 2; + } else { + ++n_buf; + } + } + } else { + while ((n_buf < precision) && p_buf[n_buf]) { + if (flag & flag_l1) { + n_buf += 2; + } else { + ++n_buf; + } + } + } + if (flag & flag_l1) { + n_buf /= 2; + } + width -= n_buf; + if (flag & flag_minus) { + if (flag & flag_l1) { + u16 *w_buf = (u16 *)p_buf; + char dst[2]; + + while (n_buf--) { + if (STD_ConvertCharUnicodeToSjis(dst, *w_buf) == 1) { + string_put_char(&str, dst[0]); + } else { + string_put_string(&str, dst, 2); + } + w_buf++; + } + } else { + string_put_string(&str, p_buf, n_buf); + } + string_fill_char(&str, ' ', width); + } else { + char pad = (char)((flag & flag_zero) ? '0' : ' '); + string_fill_char(&str, pad, width); + + if (flag & flag_l1) { + u16 *w_buf = (u16 *)p_buf; + char dst[2]; + + while (n_buf--) { + if (STD_ConvertCharUnicodeToSjis(dst, *w_buf) == 1) { + string_put_char(&str, dst[0]); + } else { + string_put_string(&str, dst, 2); + } + w_buf++; + } + } else { + string_put_string(&str, p_buf, n_buf); + } + } + ++s; + } + break; + + case 'B': + hex_char = 'A' - 10; + case 'b': + { + int n_buf = width; + int count = 0; + char c = 0; + char *p_buf = va_arg(vlist, char *); + + if (n_buf <= 0) { + n_buf = 1; + } + width = 0; + + if (flag & flag_minus) { + while (1) { + + char left_char, right_char; + int left = ((p_buf[count] & 0xF0) >> 4); + int right = (p_buf[count] & 0x0F); + + left_char = (char)((left < 10) ? (left + '0') : (left + hex_char)); + right_char = (char)((right < 10) ? (right + '0') : (right + hex_char)); + + string_put_char(&str, left_char); + string_put_char(&str, right_char); + + count++; + + if (count >= n_buf) + break; + + if (count == precision) { + string_put_char(&str, '\n'); + } else if (flag & flag_colon) { + string_put_char(&str, ':'); + } else if (flag & flag_blank) { + string_put_char(&str, ' '); + } + } + string_fill_char(&str, ' ', width); + } else { + char pad = (char)((flag & flag_zero) ? '0' : ' '); + string_fill_char(&str, pad, width); + + while (1) { + char left_char, right_char; + int left = ((p_buf[count] & 0xF0) >> 4); + int right = (p_buf[count] & 0x0F); + + left_char = (char)((left < 10) ? (left + '0') : (left + hex_char)); + right_char = (char)((right < 10) ? (right + '0') : (right + hex_char)); + + string_put_char(&str, left_char); + string_put_char(&str, right_char); + + count++; + + if (count >= n_buf) + break; + + if (count == precision) { + string_put_char(&str, '\n'); + } else if (flag & flag_colon) { + string_put_char(&str, ':'); + } + if (flag & flag_blank) { + string_put_char(&str, ' '); + } + } + } + ++s; + } + break; + + case 'n': + { + int pos = str.cur - str.base; + if (flag & flag_h2) + ; + else if (flag & flag_h1) + *va_arg(vlist, signed short *) = (signed short)pos; + else if (flag & flag_l2) + *va_arg(vlist, u64 *) = (u64)pos; + else + *va_arg(vlist, signed int *) = (signed int)pos; + } + ++s; + break; + + case '%': + if (p_start + 1 != s) + goto put_invalid; + string_put_char(&str, *s++); + break; + + default: + goto put_invalid; + +put_invalid: + string_put_string(&str, p_start, s - p_start); + break; + +put_hexadecimal: + radix = 16; + flag |= flag_unsigned; +put_integer: + { + u64 val = 0; + n_prefix = 0; + + if (flag & flag_minus) + flag &= ~flag_zero; + if (precision < 0) + precision = 1; + else + flag &= ~flag_zero; + + if (flag & flag_unsigned) { + if (flag & flag_h2) + val = va_arg(vlist, unsigned char); + else if (flag & flag_h1) + val = va_arg(vlist, unsigned short); + else if (flag & flag_l2) + val = va_arg(vlist, u64); + else + val = va_arg(vlist, unsigned long); + flag &= ~(flag_plus | flag_blank); + if (flag & flag_sharp) { + if (radix == 16) { + if (val != 0) { + prefix[0] = (char)(hex_char + (10 + 'x' - 'a')); + prefix[1] = '0'; + n_prefix = 2; + } + } else if (radix == 8) { + prefix[0] = '0'; + n_prefix = 1; + } + } + } else { + if (flag & flag_h2) + val = va_arg(vlist, char); + else if (flag & flag_h1) + val = va_arg(vlist, short); + else if (flag & flag_l2) + val = va_arg(vlist, u64); + else + val = va_arg(vlist, long); + if ((val >> 32) & 0x80000000) { + val = ~val + 1; + prefix[0] = '-'; + n_prefix = 1; + } else { + if (val || precision) { + if (flag & flag_plus) { + prefix[0] = '+'; + n_prefix = 1; + } else if (flag & flag_blank) { + prefix[0] = ' '; + n_prefix = 1; + } + } + } + } + n_buf = 0; + switch (radix) { + case 8: + while (val != 0) { + int d = (int)(val & 0x07); + val >>= 3; + buf[n_buf++] = (char)(d + '0'); + } + break; + case 10: + if ((val >> 32) == 0) { +#if defined(SDK_CW) || defined(__MWERKS__) +#pragma optimize_for_size off +#endif + u32 v = (u32)val; + while (v != 0) { + + u32 r = v / 10; + int d = (int)(v - (r * 10)); + v = r; + buf[n_buf++] = (char)(d + '0'); + } + } else { + while (val != 0) { + u64 r = val / 10; + int d = (int)(val - (r * 10)); + val = r; + buf[n_buf++] = (char)(d + '0'); + } + } + break; + case 16: + while (val != 0) { + int d = (int)(val & 0x0f); + val >>= 4; + buf[n_buf++] = (char)((d < 10) ? (d + '0') : (d + hex_char)); + } + break; + } + if ((n_prefix > 0) && (prefix[0] == '0')) { + n_prefix = 0; + buf[n_buf++] = '0'; + } + } + goto put_to_stream; + +put_to_stream: + { + int n_pad = precision - n_buf; + if (flag & flag_zero) { + if (n_pad < width - n_buf - n_prefix) + n_pad = width - n_buf - n_prefix; + } + if (n_pad > 0) + width -= n_pad; + width -= n_prefix + n_buf; + if (!(flag & flag_minus)) + string_fill_char(&str, ' ', width); + while (n_prefix > 0) + string_put_char(&str, prefix[--n_prefix]); + string_fill_char(&str, '0', n_pad); + while (n_buf > 0) + string_put_char(&str, buf[--n_buf]); + if (flag & flag_minus) + string_fill_char(&str, ' ', width); + ++s; + } + break; + } + } + } + + if (str.len > 0) + *str.cur = '\0'; + else if (len > 0) + str.base[len - 1] = '\0'; + return str.cur - str.base; +} + +#if defined(SDK_CW_WARNOFF_SAFESTRB) +#include +#endif + +#ifdef SDK_FINALROM +#ifdef OS_Printf +#undef OS_Printf +#endif +void OS_Printf(const char *fmt, ...); +void OS_Printf (const char *fmt, ...) +{ +#pragma unused( fmt ) +} +#endif \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_protectionRegion.c b/subprojects/NitroSDK/libraries/os/src/os_protectionRegion.c new file mode 100644 index 0000000000..c457ff7153 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_protectionRegion.c @@ -0,0 +1,196 @@ +#include +#include + +asm void OS_EnableICacheForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c2, c0, 1 + orr r1, r1, r0 + mcr p15, 0, r1, c2, c0, 1 + bx lr +} + +asm void OS_DisableICacheForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c2, c0, 1 + bic r1, r1, r0 + mcr p15, 0, r1, c2, c0, 1 + bx lr +} + +asm u32 OS_GetICacheEnableFlagsForProtectionRegion (void) +{ + mrc p15, 0, r0, c2, c0, 1 + bx lr +} + +asm void OS_SetIPermissionsForProtectionRegion (register u32 setMask, register u32 flags) +{ + mrc p15, 0, r2, c5, c0, 3 + bic r2, r2, r0 + orr r2, r2, r1 + mcr p15, 0, r2, c5, c0, 3 + bx lr +} + +asm u32 OS_GetIPermissionsForProtectionRegion (void) +{ + mrc p15, 0, r0, c5, c0, 3 + bx lr +} + +asm void OS_EnableDCacheForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c2, c0, 0 + orr r1, r1, r0 + mcr p15, 0, r1, c2, c0, 0 + bx lr +} + +asm void OS_DisableDCacheForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c2, c0, 0 + bic r1, r1, r0 + mcr p15, 0, r1, c2, c0, 0 + bx lr +} + +asm u32 OS_GetDCacheEnableFlagsForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r0, c2, c0, 0 + bx lr +} + +asm void OS_SetDPermissionsForProtectionRegion (register u32 setMask, register u32 flags) +{ + mrc p15, 0, r2, c5, c0, 2 + bic r2, r2, r0 + orr r2, r2, r1 + mcr p15, 0, r2, c5, c0, 2 + bx lr +} + +asm u32 OS_GetDPermissionsForProtectionRegion (void) +{ + mrc p15, 0, r0, c5, c0, 2 + bx lr +} + +asm void OS_EnableWriteBufferForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c3, c0, 0 + orr r1, r1, r0 + mcr p15, 0, r1, c3, c0, 0 + bx lr +} + +asm void OS_DisableWriteBufferForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r1, c3, c0, 0 + bic r1, r1, r0 + mcr p15, 0, r1, c3, c0, 0 + bx lr +} + +asm u32 OS_GetWriteBufferEnableFlagsForProtectionRegion (register u32 flags) +{ + mrc p15, 0, r0, c3, c0, 0 + bx lr +} + +asm void OS_SetProtectionRegion0 (u32 param) +{ + mcr p15, 0, r0, c6, c0, 0 + bx lr +} + +asm void OS_SetProtectionRegion1 (u32 param) +{ + mcr p15, 0, r0, c6, c1, 0 + bx lr +} + +asm void OS_SetProtectionRegion2 (u32 param) +{ + mcr p15, 0, r0, c6, c2, 0 + bx lr +} + +asm void OS_SetProtectionRegion3 (u32 param) +{ + mcr p15, 0, r0, c6, c3, 0 + bx lr +} + +asm void OS_SetProtectionRegion4 (u32 param) +{ + mcr p15, 0, r0, c6, c4, 0 + bx lr +} + +asm void OS_SetProtectionRegion5 (u32 param) +{ + mcr p15, 0, r0, c6, c5, 0 + bx lr +} + +asm void OS_SetProtectionRegion6 (u32 param) +{ + mcr p15, 0, r0, c6, c6, 0 + bx lr +} + +asm void OS_SetProtectionRegion7 (u32 param) +{ + mcr p15, 0, r0, c6, c7, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion0 (void) +{ + mrc p15, 0, r0, c6, c0, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion1 (void) +{ + mrc p15, 0, r0, c6, c1, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion2 (void) +{ + mrc p15, 0, r0, c6, c2, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion3 (void) +{ + mrc p15, 0, r0, c6, c3, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion4 (void) +{ + mrc p15, 0, r0, c6, c4, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion5 (void) +{ + mrc p15, 0, r0, c6, c5, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion6 (void) +{ + mrc p15, 0, r0, c6, c6, 0 + bx lr +} + +asm u32 OS_GetProtectionRegion7 (void) +{ + mrc p15, 0, r0, c6, c7, 0 + bx lr +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_protectionUnit.c b/subprojects/NitroSDK/libraries/os/src/os_protectionUnit.c new file mode 100644 index 0000000000..b7a4ac3afa --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_protectionUnit.c @@ -0,0 +1,20 @@ +#include +#include + +asm void OS_EnableProtectionUnit (void) +{ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #HW_C1_PROTECT_UNIT_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_DisableProtectionUnit (void) +{ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #HW_C1_PROTECT_UNIT_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_reset.c b/subprojects/NitroSDK/libraries/os/src/os_reset.c new file mode 100644 index 0000000000..9545f25c55 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_reset.c @@ -0,0 +1,398 @@ +#include +#include +#include +#include + +#include + +extern void SDK_IRQ_STACKSIZE(void); + +#define OS_PXI_COMMAND_RESET 0x10 + +#define OS_PXI_COMMAND_MASK 0x00007f00 +#define OS_PXI_COMMAND_SHIFT 8 +#define OS_PXI_DATA_MASK 0x000000ff +#define OS_PXI_DATA_SHIFT 0 + +#ifdef SDK_ARM9 +#define OSi_HW_DTCM SDK_AUTOLOAD_DTCM_START +#endif + +#ifdef SDK_ARM9 +static void OSi_CpuClear32(register u32 data, register void *destp, register u32 size); +static void OSi_ReloadRomData(void); +static void OSi_ReadCardRom32(u32 src, void *dst, int len); +#endif + +static void OSi_CommonCallback(PXIFifoTag tag, u32 data, BOOL err); +static void OSi_DoResetSystem(void); +static void OSi_DoBoot(void); +static void OSi_SendToPxi(u16 data); + +static u16 OSi_IsInitReset = FALSE; +static vu16 OSi_IsResetOccurred = FALSE; + +void OS_InitReset (void) +{ + if (OSi_IsInitReset) { + return; + } + OSi_IsInitReset = TRUE; + +#ifdef SDK_ARM9 + + PXI_Init(); + while (!PXI_IsCallbackReady(PXI_FIFO_TAG_OS, PXI_PROC_ARM7)) { + } +#endif + + PXI_SetFifoRecvCallback(PXI_FIFO_TAG_OS, OSi_CommonCallback); +} + +BOOL OS_IsResetOccurred (void) +{ + return OSi_IsResetOccurred; +} + +static void OSi_CommonCallback (PXIFifoTag tag, u32 data, BOOL err) +{ +#pragma unused( tag, err ) + u16 command; + u16 commandArg; + + command = (u16)((data & OS_PXI_COMMAND_MASK) >> OS_PXI_COMMAND_SHIFT); + commandArg = (u16)((data & OS_PXI_DATA_MASK) >> OS_PXI_DATA_SHIFT); + +#ifdef SDK_ARM9 + if (command == OS_PXI_COMMAND_RESET) { + OSi_IsResetOccurred = TRUE; + } else { +#ifndef SDK_FINALROM + OS_Panic("unknown command"); +#else + OS_Panic(""); +#endif + } + +#else + if (command == OS_PXI_COMMAND_RESET) { + OSi_IsResetOccurred = TRUE; + } else { +#ifndef SDK_FINALROM + OS_Panic("unknown command"); +#else + OS_Panic(""); +#endif + } +#endif +} + +static void OSi_SendToPxi (u16 data) +{ + u32 pxi_send_data; + + pxi_send_data = ((u32)data) << OS_PXI_COMMAND_SHIFT; + while (PXI_SendWordByFifo(PXI_FIFO_TAG_OS, pxi_send_data, FALSE) != PXI_FIFO_SUCCESS) { + } +} + +#define RESET_HW_DTCM_IRQ_STACK_END SDK_AUTOLOAD_DTCM_START + 0x00003fc0 - HW_SVC_STACK_SIZE + +#ifdef SDK_ARM9 +void OS_ResetSystem (u32 parameter) +{ + + if (MB_IsMultiBootChild()) { +#ifndef SDK_FINALROM + OS_Panic("cannot reset from MB child"); +#else + OS_Panic(""); +#endif + } + + { + u16 id = (u16)OS_GetLockID(); + CARD_LockRom(id); + } + + MI_StopDma(0); + MI_StopDma(1); + MI_StopDma(2); + MI_StopDma(3); + + (void)OS_SetIrqMask(OS_IE_FIFO_RECV); + (void)OS_ResetRequestIrqMask(0xffffffff); + + *(u32 *)HW_RESET_PARAMETER_BUF = parameter; + + OSi_SendToPxi(OS_PXI_COMMAND_RESET); + + asm + { + + ldr r0, = RESET_HW_DTCM_IRQ_STACK_END; + ldr r1, = SDK_IRQ_STACKSIZE; + sub r0, r0, r1; + mov sp, r0; + + bl OSi_DoResetSystem; + } + +} + +#else +void OS_ResetSystem (void) +{ + MI_StopDma(0); + MI_StopDma(1); + MI_StopDma(2); + MI_StopDma(3); + + (void)OS_SetIrqMask(OS_IE_FIFO_RECV); + (void)OS_ResetRequestIrqMask(0xffffffff); + + SND_Shutdown(); + + OSi_SendToPxi(OS_PXI_COMMAND_RESET); + OSi_DoResetSystem(); +} +#endif + +#ifdef SDK_ARM9 +#include +static void OSi_DoResetSystem (void) +{ + while (!(vu16)OSi_IsResetOccurred) { + } + + reg_OS_IME = 0; + + OSi_ReloadRomData(); + + OSi_DoBoot(); +} + +#include + +#else +#include +static void OSi_DoResetSystem (void) +{ + reg_OS_IME = 0; + OSi_DoBoot(); +} + +#include +#endif + +#ifdef SDK_ARM9 +#include +asm void OSi_DoBoot (void) +{ + mov r12, #HW_REG_BASE + str r12, [r12, #REG_IME_OFFSET] + ldr r1, = OSi_HW_DTCM + add r1, r1, #0x3fc0 + add r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR + mov r0, #0 + str r0, [r1, #0] + ldr r1, = REG_SUBPINTF_ADDR + @1: + ldrh r0, [r1] + and r0, r0, #0x000f + cmp r0, #0x0001 + bne @1 + mov r0, #0x0100 + strh r0, [r1] + mov r0, #0 + ldr r3, = HW_EXCP_VECTOR_MAIN + ldr r4, [r3] + ldr r1, = HW_BIOS_EXCP_STACK_MAIN + mov r2, #0x80 + bl OSi_CpuClear32 + str r4, [r3] + ldr r1, = HW_PXI_SIGNAL_PARAM_ARM9 + mov r2, #0x18 + bl OSi_CpuClear32 + ldr r1, = HW_WM_RSSI_POOL + strh r0, [r1] + ldr r1, = HW_COMPONENT_PARAM + mov r2, #0x64 + bl OSi_CpuClear32 + ldr r1, = REG_SUBPINTF_ADDR + @2: + ldrh r0, [r1] + and r0, r0, #0x000f + cmp r0, #0x0001 + beq @2 + mov r0, #0 + strh r0, [r1] + ldr r3, = HW_ROM_HEADER_BUF + ldr r12, [r3, #0x24] + mov lr, r12 + ldr r11, = HW_PXI_SIGNAL_PARAM_ARM9 + ldmia r11, {r0 - r10} + mov r11, #0 + bx r12 +} + +#include +#else +#include +asm void OSi_DoBoot (void) +{ + mov r12, #HW_REG_BASE + str r12, [r12, #REG_IME_OFFSET] + ldr r1, = HW_INTR_VECTOR_BUF + mov r0, #0 + str r0, [r1, #0] + ldr r1, = REG_MAINPINTF_ADDR + mov r0, #0x0100 + strh r0, [r1] + @1: + ldrh r0, [r1] + and r0, r0, #0x000f + cmp r0, #0x0001 + bne @1 + ldr r1, = REG_MAINPINTF_ADDR + mov r0, #0 + strh r0, [r1] + @2 : + ldrh r0, [r1] + cmp r0, #0x0001 + beq @2 + ldr r3, = HW_ROM_HEADER_BUF + ldr r12, [r3, #0x34] + mov lr, r12 + mov r0, #0 + mov r1, #0 + mov r2, #0 + mov r3, #0 + bx r12 +} +#include +#endif + +#ifdef SDK_ARM9 +#include + +static asm void OSi_CpuClear32 (register u32 data, register void *destp, register u32 size) +{ + add r12, r1, r2 + @1: + cmp r1, r12 + blt @stmltia1 + b @stmltia2 +@stmltia1: + stmia r1 !, {r0} +@stmltia2: + blt @1 + bx lr +} + +static void OSi_ReloadRomData (void) +{ + u32 p = (u32)HW_ROM_HEADER_BUF; + const u32 rom_base = *(u32 *)HW_ROM_BASE_OFFSET_BUF; + + if (rom_base >= 0x8000) + OSi_ReadCardRom32(rom_base, (void *)p, 0x160); + + { + u32 src_arm9 = *(u32 *)(p + 0x20); + u32 dst_arm9 = *(u32 *)(p + 0x28); + u32 len_arm9 = *(u32 *)(p + 0x2c); + u32 src_arm7 = *(u32 *)(p + 0x30); + u32 dst_arm7 = *(u32 *)(p + 0x38); + u32 len_arm7 = *(u32 *)(p + 0x3c); + + { + OSIntrMode bak_cpsr = OS_DisableInterrupts(); + DC_StoreAll(); + DC_InvalidateAll(); + (void)OS_RestoreInterrupts(bak_cpsr); + } + IC_InvalidateAll(); + DC_WaitWriteBufferEmpty(); + + src_arm9 += rom_base; + src_arm7 += rom_base; + + if (src_arm9 < 0x8000) { + u32 diff = 0x8000 - src_arm9; + src_arm9 = 0x8000; + dst_arm9 += diff; + len_arm9 -= diff; + } + OSi_ReadCardRom32(src_arm9, (void *)dst_arm9, (int)len_arm9); + + OSi_ReadCardRom32(src_arm7, (void *)dst_arm7, (int)len_arm7); + } +} + +static void OSi_ReadCardRom32 (u32 src, void *dst, int len) +{ + vu8 *const reg_CARD_MASTERCNT = (vu8 *)(HW_REG_BASE + 0x1a1); + vu8 *const reg_CARD_CMD = (vu8 *)(HW_REG_BASE + 0x1a8); + vu32 *const reg_CARD_CNT = (vu32 *)(HW_REG_BASE + 0x1a4); + vu32 *const reg_CARD_DATA = (vu32 *)(HW_REG_BASE + 0x100010); + vu32 *const hdr_GAME_BUF = (vu32 *)(HW_ROM_HEADER_BUF + 0x60); + + enum { + CARD_MASTER_SELECT_ROM = 0x00, + CARD_MASTER_ENABLE = 0x80, + CARD_CMD_READ_PAGE = 0xb7, + CARD_CTRL_CMD_MASK = 0x07000000, + CARD_CTRL_CMD_PAGE = 0x01000000, + CARD_CTRL_READ = 0x00000000, + CARD_CTRL_RESET_HI = 0x20000000, + CARD_CTRL_START = 0x80000000, + CARD_CTRL_READY = 0x00800000, + CARD_ENUM_END + }; + + const u32 ctrl_start = (u32)((*hdr_GAME_BUF & ~CARD_CTRL_CMD_MASK) + | (CARD_CTRL_CMD_PAGE | CARD_CTRL_READ + | CARD_CTRL_START | CARD_CTRL_RESET_HI)); + + int pos = -(int)(src & (512 - 1)); + + while ((*reg_CARD_CNT & CARD_CTRL_START) != 0) { + } + *reg_CARD_MASTERCNT = (u32)(CARD_MASTER_SELECT_ROM | CARD_MASTER_ENABLE); + + for (src = (u32)(src + pos); pos < len; src += 512) { + + reg_CARD_CMD[0] = (u8)(CARD_CMD_READ_PAGE); + reg_CARD_CMD[1] = (u8)(src >> 24); + reg_CARD_CMD[2] = (u8)(src >> 16); + reg_CARD_CMD[3] = (u8)(src >> 8); + reg_CARD_CMD[4] = (u8)(src >> 0); + reg_CARD_CMD[5] = (u8)(0); + reg_CARD_CMD[6] = (u8)(0); + reg_CARD_CMD[7] = (u8)(0); + + *reg_CARD_CNT = ctrl_start; + for (;;) { + u32 ctrl = *reg_CARD_CNT; + + if ((ctrl & CARD_CTRL_READY) != 0) { + + const u32 data = *reg_CARD_DATA; + + if ((pos >= 0) && (pos < len)) { + *(u32 *)((u32)dst + pos) = data; + } + + pos += sizeof(u32); + } + + if (!(ctrl & CARD_CTRL_START)) { + break; + } + } + } +} + +#include +#endif \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_spinLock.c b/subprojects/NitroSDK/libraries/os/src/os_spinLock.c new file mode 100644 index 0000000000..dc54fd9379 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_spinLock.c @@ -0,0 +1,451 @@ +#include + +void _ISDbgLib_Initialize(void); +void _ISDbgLib_AllocateEmualtor(void); +void _ISDbgLib_FreeEmulator(void); +s32 OS_LockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)); +s32 OS_UnlockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)); +s32 OS_TryLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*crtlFuncp)(void)); +static s32 OSi_DoLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), BOOL disableFiq); +static s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), BOOL disableFIQ); +static s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), BOOL disableFIQ); +static void OSi_AllocateCartridgeBus(void); +static void OSi_FreeCartridgeBus(void); +static void OSi_AllocateCardBus(void); +static void OSi_FreeCardBus(void); +static void OSi_WaitByLoop(void); + +#ifdef SDK_ARM9 +#define OSi_ASSERT_ID(id) SDK_ASSERTMSG(id >= OS_MAINP_LOCK_ID_START && id <= OS_MAINP_SYSTEM_LOCK_ID, \ + "lock ID %d is out of bounds", id) +#else +#define OSi_ASSERT_ID(id) SDK_ASSERTMSG(id >= OS_SUBP_LOCK_ID_START && id <= OS_SUBP_SYSTEM_LOCK_ID, \ + "lock ID %d is out of bounds", id) +#endif + +#define OSi_LOCKID_INITIAL_FLAG_0 0xffffffff +#define OSi_LOCKID_INITIAL_FLAG_1 0xffff0000 + +#ifdef SDK_ARM9 +#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_MAIN +#define OSi_ANYP_LOCK_ID_START OS_MAINP_LOCK_ID_START +#else +#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_SUB +#define OSi_ANYP_LOCK_ID_START OS_SUBP_LOCK_ID_START +#endif + +static inline void OSi_WaitByLoop (void) +{ + SVC_WaitByLoop(0x1000 / 4); +} + +void OS_InitLock (void) +{ + static BOOL isInitialized = FALSE; + OSLockWord *lockp; + + if (isInitialized) + return; + isInitialized = TRUE; + + lockp = (OSLockWord *)HW_INIT_LOCK_BUF; + +#ifdef SDK_ARM9 + { + lockp->lockFlag = 0; + (void)OS_LockByWord(OS_MAINP_SYSTEM_LOCK_ID - 1, lockp, NULL); + + while (lockp->extension != 0) { + OSi_WaitByLoop(); + } + + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0; + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1; + + MI_CpuClear32((void *)HW_SHARED_LOCK_BUF, HW_CTRDG_LOCK_BUF - HW_SHARED_LOCK_BUF); + MIi_SetCardProcessor(MI_PROCESSOR_ARM7); + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7); + +#ifndef SDK_FINALROM + _ISDbgLib_Initialize(); +#endif + + (void)OS_UnlockByWord(OS_MAINP_SYSTEM_LOCK_ID - 1, lockp, NULL); + (void)OS_LockByWord(OS_MAINP_SYSTEM_LOCK_ID, lockp, NULL); + } + +#else + { + lockp->extension = 0; + while (lockp->ownerID != OS_MAINP_SYSTEM_LOCK_ID) { + OSi_WaitByLoop(); + } + +#ifndef SDK_FINALROM + _ISDbgLib_Initialize(); +#endif + + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0; + ((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1; + + lockp->extension = OS_SUBP_SYSTEM_LOCK_ID; + } +#endif +} + +static s32 OSi_DoLockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), + BOOL disableFiq) +{ + s32 lastLockFlag; + + while ((lastLockFlag = + OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, disableFiq)) > OS_LOCK_SUCCESS) { + OSi_WaitByLoop(); + } + + return lastLockFlag; +} + +s32 OS_LockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoLockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +s32 OS_LockByWord_IrqAndFiq (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoLockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + +static s32 OSi_DoUnlockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), + BOOL disableFIQ) +{ + OSIntrMode lastInterrupts; + + OSi_ASSERT_ID(lockID); + + if (lockID != lockp->ownerID) { + return OS_UNLOCK_ERROR; + } + + lastInterrupts = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts(); + + lockp->ownerID = 0; + if (ctrlFuncp) { + ctrlFuncp(); + } + lockp->lockFlag = 0; + + if (disableFIQ) { + (void)OS_RestoreInterrupts_IrqAndFiq(lastInterrupts); + } else { + (void)OS_RestoreInterrupts(lastInterrupts); + } + + return OS_UNLOCK_SUCCESS; +} + +s32 OS_UnlockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +s32 OS_UnLockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +s32 OS_UnlockByWord_IrqAndFiq (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + +static s32 OSi_DoTryLockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void), + BOOL disableFIQ) +{ + s32 lastLockFlag; + OSIntrMode lastInterrupts; + + OSi_ASSERT_ID(lockID); + + lastInterrupts = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts(); + + lastLockFlag = (s32)MI_SwapWord(lockID, &lockp->lockFlag); + + if (lastLockFlag == OS_LOCK_SUCCESS) { + if (ctrlFuncp) { + ctrlFuncp(); + } + lockp->ownerID = lockID; + } + + if (disableFIQ) { + (void)OS_RestoreInterrupts_IrqAndFiq(lastInterrupts); + } else { + (void)OS_RestoreInterrupts(lastInterrupts); + } + + return lastLockFlag; +} + +s32 OS_TryLockByWord (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +s32 OS_TryLockByWord_IrqAndFiq (u16 lockID, OSLockWord *lockp, void (*ctrlFuncp)(void)) +{ + return OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, TRUE); +} + +s32 OS_LockCartridge (u16 lockID) +{ + s32 lastLockFlag; + + OSi_ASSERT_ID(lockID); + + lastLockFlag = + OSi_DoLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE); + +#ifndef SDK_FINALROM + _ISDbgLib_AllocateEmualtor(); +#endif + + return lastLockFlag; +} + +s32 OS_UnlockCartridge (u16 lockID) +{ + s32 lastLockFlag; + + OSi_ASSERT_ID(lockID); + +#ifndef SDK_FINALROM + _ISDbgLib_FreeEmulator(); +#endif + + lastLockFlag = + OSi_DoUnlockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_FreeCartridgeBus, TRUE); + + return lastLockFlag; +} + +asm s32 OS_UnLockCartridge (u16 lockID) +{ + ldr r1, = OS_UnlockCartridge + bx r1 +} + +s32 OS_TryLockCartridge (u16 lockID) +{ + s32 lastLockFlag; + + lastLockFlag = + OSi_DoTryLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, + TRUE); + +#ifndef SDK_FINALROM + if (lastLockFlag == OS_LOCK_SUCCESS) { + _ISDbgLib_AllocateEmualtor(); + } +#endif + + return lastLockFlag; +} + +static void OSi_AllocateCartridgeBus (void) +{ +#ifdef SDK_ARM9 + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM9); +#endif +} + +static void OSi_FreeCartridgeBus (void) +{ +#ifdef SDK_ARM9 + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7); +#endif +} + +#if defined(SDK_TEG) + +static u32 osi_card_lock = OS_LOCK_ID_ERROR; + +static s32 OSi_LockCardID (u16 lockID, BOOL blocking) +{ + s32 ret = OS_LOCK_ID_ERROR; + for (;;) { + OSIntrMode bak_psr = OS_DisableInterrupts(); + ret = osi_card_lock; + if (ret == OS_LOCK_ID_ERROR) { + osi_card_lock = lockID; + ret = OS_LOCK_SUCCESS; + } + (void)OS_RestoreInterrupts(bak_psr); + if ((ret != OS_LOCK_SUCCESS) && blocking) { + OSi_WaitByLoop(); + continue; + } + break; + } + return ret; +} + +static s32 OSi_UnlockCardID (u16 lockID) +{ + if (osi_card_lock != lockID) + return OS_UNLOCK_ERROR; + osi_card_lock = OS_LOCK_ID_ERROR; + return OS_UNLOCK_SUCCESS; +} + +#endif + +s32 OS_LockCard (u16 lockID) +{ + OSi_ASSERT_ID(lockID); + +#if defined(SDK_TEG) + return OSi_LockCardID(lockID, TRUE); +#else + return OS_LockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus); +#endif +} + +s32 OS_UnlockCard (u16 lockID) +{ + OSi_ASSERT_ID(lockID); + +#if defined(SDK_TEG) + return OSi_UnlockCardID(lockID); +#else + return OS_UnlockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_FreeCardBus); +#endif +} + +asm s32 OS_UnLockCard (u16 lockID) +{ + ldr r1, = OS_UnlockCard + bx r1 +} + +s32 OS_TryLockCard (u16 lockID) +{ +#if defined(SDK_TEG) + return OSi_LockCardID(lockID, FALSE); +#else + return OS_TryLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus); +#endif +} + +static void OSi_AllocateCardBus (void) +{ +#ifdef SDK_ARM9 + MIi_SetCardProcessor(MI_PROCESSOR_ARM9); +#endif +} + +static void OSi_FreeCardBus (void) +{ +#ifdef SDK_ARM9 + MIi_SetCardProcessor(MI_PROCESSOR_ARM7); +#endif +} + +u16 OS_ReadOwnerOfLockWord (OSLockWord *lockp) +{ + return lockp->ownerID; +} + +#include +asm s32 OS_GetLockID (void) +{ + ldr r3, = OSi_ANYP_LOCK_ID_FLAG + ldr r1, [r3, #0] + +#ifdef SDK_ARM9 + clz r2, r1 +#else + mov r2, #0 + mov r0, #0x80000000 +_lp1: + tst r1, r0 + bne _ex1 + add r2, r2, #1 + cmp r2, #32 + beq _ex1 + mov r0, r0, lsr #1 + b _lp1 +_ex1: +#endif + cmp r2, #32 + bne @movne1 + b @movne2 +@movne1: + mov r0, #OSi_ANYP_LOCK_ID_START +@movne2: + bne _1 + add r3, r3, #4 + ldr r1, [r3, #0] +#ifdef SDK_ARM9 + clz r2, r1 +#else + mov r2, #0 + mov r0, #0x80000000 +_lp2: + tst r1, r0 + bne _ex2 + add r2, r2, #1 + cmp r2, #32 + beq _ex2 + mov r0, r0, lsr #1 + b _lp2 +_ex2: +#endif + cmp r2, #32 + ldr r0, = OS_LOCK_ID_ERROR + beq @bxeq1 + b @bxeq2 +@bxeq1: + bx lr +@bxeq2: + mov r0, #OSi_ANYP_LOCK_ID_START + 32 +_1: + add r0, r0, r2 + mov r1, #0x80000000 + mov r1, r1, lsr r2 + ldr r2, [r3, #0] + bic r2, r2, r1 + str r2, [r3, #0] + bx lr +} + +asm void OS_ReleaseLockID (register u16 lockID) +{ +#pragma unused( lockID ) + + ldr r3, = OSi_ANYP_LOCK_ID_FLAG + cmp r0, #OSi_ANYP_LOCK_ID_START + 32 + bpl @addpl1 + b @addpl2 +@addpl1: + add r3, r3, #4 +@addpl2: + bpl @subpl1 + b @subpl2 +@subpl1: + sub r0, r0, #OSi_ANYP_LOCK_ID_START + 32 +@subpl2: + bmi @submi1 + b @submi2 +@submi1: + sub r0, r0, #OSi_ANYP_LOCK_ID_START +@submi2: + mov r1, #0x80000000 + mov r1, r1, lsr r0 + ldr r2, [r3, #0] + orr r2, r2, r1 + str r2, [r3, #0] + bx lr +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_system.c b/subprojects/NitroSDK/libraries/os/src/os_system.c new file mode 100644 index 0000000000..04bab6b877 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_system.c @@ -0,0 +1,120 @@ +#include +#include + +asm OSIntrMode OS_EnableInterrupts (void) +{ + mrs r0, cpsr + bic r1, r0, #HW_PSR_IRQ_DISABLE + msr cpsr_c, r1 + and r0, r0, #HW_PSR_IRQ_DISABLE + bx lr +} + +asm OSIntrMode OS_DisableInterrupts (void) +{ + 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 (register 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 OSIntrMode OS_EnableInterrupts_IrqAndFiq (void) +{ + mrs r0, cpsr + bic r1, r0, #HW_PSR_IRQ_FIQ_DISABLE + msr cpsr_c, r1 + and r0, r0, #HW_PSR_IRQ_FIQ_DISABLE + bx lr +} + +asm OSIntrMode OS_DisableInterrupts_IrqAndFiq (void) +{ + mrs r0, cpsr + orr r1, r0, #HW_PSR_IRQ_FIQ_DISABLE + msr cpsr_c, r1 + and r0, r0, #HW_PSR_IRQ_FIQ_DISABLE + bx lr +} + +asm OSIntrMode OS_RestoreInterrupts_IrqAndFiq (register OSIntrMode state) +{ + mrs r1, cpsr + bic r2, r1, #HW_PSR_IRQ_FIQ_DISABLE + orr r2, r2, r0 + msr cpsr_c, r2 + and r0, r1, #HW_PSR_IRQ_FIQ_DISABLE + bx lr +} + +asm OSIntrMode_Irq OS_GetCpsrIrq (void) +{ + mrs r0, cpsr + and r0, r0, #HW_PSR_IRQ_DISABLE + bx lr +} + +asm OSProcMode OS_GetProcMode (void) +{ + mrs r0, cpsr + and r0, r0, #HW_PSR_CPU_MODE_MASK + bx lr +} + +#include + +#ifdef SDK_ARM9 +#include +asm void OS_SpinWait (u32 cycle) +{ +_1: subs r0, r0, #4 + bcs _1 + bx lr +} +#include +#else +void OS_SpinWait (u32 cycle) +{ + SVC_WaitByLoop((s32)cycle / 4); +} +#endif + +void OS_WaitInterrupt (BOOL clear, OSIrqMask irqFlags) +{ + OSIntrMode cpsrIrq = OS_DisableInterrupts(); + BOOL ime = OS_EnableIrq(); + + if (clear) { + (void)OS_ClearIrqCheckFlag(irqFlags); + } + + while (!(OS_GetIrqCheckFlag() & irqFlags)) { + OS_Halt(); + (void)OS_EnableInterrupts(); + (void)OS_DisableInterrupts(); + } + + (void)OS_ClearIrqCheckFlag(irqFlags); + (void)OS_RestoreIrq(ime); + (void)OS_RestoreInterrupts(cpsrIrq); +} + +void OS_WaitVBlankIntr (void) +{ + SVC_WaitByLoop(1); +#if defined(SDK_ENABLE_ARM7_PRINT) && defined(SDK_ARM9) + + OS_PrintServer(); +#endif + OS_WaitIrq(TRUE, OS_IE_V_BLANK); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_tcm.c b/subprojects/NitroSDK/libraries/os/src/os_tcm.c new file mode 100644 index 0000000000..8eb15a7c00 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_tcm.c @@ -0,0 +1,88 @@ +#include +#include + +asm void OS_EnableITCM (void) +{ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #HW_C1_ITCM_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_DisableITCM (void) +{ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #HW_C1_ITCM_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_SetITCMParam (register u32 param) +{ + and r0, r0, #HW_C9_TCMR_SIZE_MASK + mcr p15, 0, r0, c9, c1, 1 + bx lr +} + +asm u32 OS_GetITCMParam (void) +{ + mrc p15, 0, r0, c9, c1, 1 + and r0, r0, #HW_C9_TCMR_SIZE_MASK + bx lr +} + +asm void OS_EnableDTCM (void) +{ + mrc p15, 0, r0, c1, c0, 0 + orr r0, r0, #HW_C1_DTCM_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_DisableDTCM (void) +{ + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #HW_C1_DTCM_ENABLE + mcr p15, 0, r0, c1, c0, 0 + bx lr +} + +asm void OS_SetDTCMParam (register u32 param) +{ + ldr r1, = HW_C9_TCMR_BASE_MASK | HW_C9_TCMR_SIZE_MASK + and r0, r0, r1 + mcr p15, 0, r0, c9, c1, 0 + bx lr +} + +asm u32 OS_GetDTCMParam (void) +{ + mrc p15, 0, r0, c9, c1, 0 + ldr r1, = HW_C9_TCMR_BASE_MASK | HW_C9_TCMR_SIZE_MASK + and r0, r0, r1 + bx lr +} + +#define OSi_TCM_REGION_SIZE_MASK HW_C9_TCMR_SIZE_MASK +#define OSi_TCM_REGION_BASE_MASK HW_C9_TCMR_BASE_MASK + +asm void OS_SetDTCMAddress (register u32 address) +{ + mrc p15, 0, r2, c9, c1, 0 + and r2, r2, #OSi_TCM_REGION_SIZE_MASK + ldr r1, = OSi_TCM_REGION_BASE_MASK + and r0, r0, r1 + orr r0, r0, r2 + mcr p15, 0, r0, c9, c1, 0 + bx lr +} + +asm u32 OS_GetDTCMAddress (void) +{ + mrc p15, 0, r0, c9, c1, 0 + ldr r1, = OSi_TCM_REGION_BASE_MASK + and r0, r0, r1 + bx lr +} + +#include \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_terminate_proc.c b/subprojects/NitroSDK/libraries/os/src/os_terminate_proc.c new file mode 100644 index 0000000000..1c6a991139 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_terminate_proc.c @@ -0,0 +1,28 @@ +#include + +SDK_WEAK_SYMBOL void OS_Terminate (void) +{ + while (1) { + (void)OS_DisableInterrupts(); + OS_Halt(); + } +} + +#include +SDK_WEAK_SYMBOL asm void OS_Halt (void) +{ + mov r0, #0 + mcr p15, 0, r0, c7, c0, 4 + bx lr +} +#include + +SDK_WEAK_SYMBOL void OS_Exit (int status) +{ +#ifdef SDK_FINALROM +#pragma unused( status ) +#endif + (void)OS_DisableInterrupts(); + OS_Printf("\n" OS_EXIT_STRING, status); + OS_Terminate(); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_thread.c b/subprojects/NitroSDK/libraries/os/src/os_thread.c new file mode 100644 index 0000000000..087321671c --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_thread.c @@ -0,0 +1,1293 @@ +#include +#include +#include + +extern void SDK_SYS_STACKSIZE(void); +extern void SDK_IRQ_STACKSIZE(void); +#define OSi_SYS_STACKSIZE ((s32)SDK_SYS_STACKSIZE) +#define OSi_IRQ_STACKSIZE ((s32)SDK_IRQ_STACKSIZE) + +#ifdef SDK_ARM9 + #define OSi_STACK_CHECKNUM_BOTTOM 0xfddb597dUL + #define OSi_STACK_CHECKNUM_TOP 0x7bf9dd5bUL + #define OSi_STACK_CHECKNUM_WARN 0x597dfbd9UL +#else + #define OSi_STACK_CHECKNUM_BOTTOM 0xd73bfdf7UL + #define OSi_STACK_CHECKNUM_TOP 0xfbdd37bbUL + #define OSi_STACK_CHECKNUM_WARN 0xbdf7db3dUL +#endif + +#ifdef SDK_ARM9 +extern void SDK_SECTION_ARENA_DTCM_START(void); +void SDK_AUTOLOAD_DTCM_END(void); + #define OSi_LAUNCHER_STACK_LO_DEFAULT SDK_SECTION_ARENA_DTCM_START + #define OSi_LAUNCHER_STACK_HI_MAX (HW_DTCM_SVC_STACK - OSi_IRQ_STACKSIZE) + #define OSi_LAUNCHER_STACK_BOTTOM (HW_DTCM_SVC_STACK - OSi_IRQ_STACKSIZE) +#else + #define OSi_LAUNCHER_STACK_LO_DEFAULT HW_WRAM + #define OSi_LAUNCHER_STACK_HI_MAX (HW_PRV_WRAM_IRQ_STACK_END - OSi_IRQ_STACKSIZE) + #define OSi_LAUNCHER_STACK_BOTTOM (HW_PRV_WRAM_IRQ_STACK_END - OSi_IRQ_STACKSIZE) +#endif + +#ifdef SDK_CONTEXT_HAS_SP_SVC +#define OSi_IDLE_CHECKNUM_SIZE (sizeof(u32) * 2 + HW_SVC_STACK_SIZE) +#else +#define OSi_IDLE_CHECKNUM_SIZE (sizeof(u32) * 2) +#endif + +#ifdef SDK_ARM9 +#define OSi_IDLE_SVC_SIZE (sizeof(u32) * 32) +#else +#define OSi_IDLE_SVC_SIZE (sizeof(u32) * 16) +#endif + +#define OSi_IDLE_THREAD_STACK_SIZE (OSi_IDLE_CHECKNUM_SIZE + OSi_IDLE_SVC_SIZE) + +OSThread OSi_LauncherThread; +OSThread OSi_IdleThread; + +OSThreadInfo OSi_ThreadInfo; + +OSThread **OSi_CurrentThreadPtr; +#define OSi_GetCurrentThread() (*OSi_CurrentThreadPtr) + +BOOL OSi_IsThreadInitialized = FALSE; + +u32 OSi_IdleThreadStack[OSi_IDLE_THREAD_STACK_SIZE / sizeof(u32)]; + +void *OSi_SystemCallbackInSwitchThread = NULL; + +u32 OSi_RescheduleCount = 0; + +#ifdef SDK_THREAD_INFINITY +static int OSi_ThreadIdCount = 0; +#endif + +void *OSi_StackForDestructor = NULL; + +#ifndef SDK_THREAD_INFINITY +static int OSi_SearchFreeEntry(void); +#endif +static void OSi_CancelThreadAlarmForSleep(OSThread *thread); +static void OSi_InsertThreadToList(OSThread *thread); +static void OSi_RemoveThreadFromList(OSThread *thread); +static void OSi_SleepAlarmCallback(void *arg); +static void OSi_IdleThreadProc(void *); +void OSi_SetSystemCallbackInSwitchThread(void *callback); + +static void OSi_ExitThread_ArgSpecified(OSThread *thread, void *arg); +static void OSi_ExitThread(void *arg); +static void OSi_ExitThread_Destroy(void); + +static void OSi_RescheduleThread(void); + +#ifdef SDK_THREAD_INFINITY + +static int OSi_GetUnusedThreadId (void) +{ + ++OSi_ThreadIdCount; + SDK_ASSERT(OSi_ThreadIdCount > 0); + return OSi_ThreadIdCount; +} +#endif + +#ifdef SDK_THREAD_INFINITY + +static void OSi_InsertLinkToQueue (OSThreadQueue *queue, OSThread *thread) +{ + OSThread *next = queue->head; + + while (next && next->priority <= thread->priority) { + if (next == thread) { + return; + } + next = next->link.next; + } + + if (!next) { + OSThread *prev = queue->tail; + + if (!prev) { + queue->head = thread; + } else { + prev->link.next = thread; + } + + thread->link.prev = prev; + thread->link.next = NULL; + queue->tail = thread; + } else { + OSThread *prev = next->link.prev; + + if (!prev) { + queue->head = thread; + } else { + prev->link.next = thread; + } + + thread->link.prev = prev; + thread->link.next = next; + next->link.prev = thread; + } +} + +static OSThread *OSi_RemoveLinkFromQueue (OSThreadQueue *queue) +{ + OSThread *t = queue->head; + + if (t) { + OSThread *next = t->link.next; + + queue->head = next; + + if (next) { + next->link.prev = NULL; + } else { + queue->tail = NULL; + t->queue = NULL; + } + } + + return t; +} + +static OSThread *OSi_RemoveSpecifiedLinkFromQueue (OSThreadQueue *queue, OSThread *thread) +{ + OSThread *t = queue->head; + OSThread *next; + OSThread *prev; + + while (t) { + next = t->link.next; + + if (t == thread) { + prev = t->link.prev; + + if (queue->head == t) { + queue->head = next; + } else { + prev->link.next = next; + } + + if (queue->tail == t) { + queue->tail = prev; + } else { + next->link.prev = prev; + } + + break; + } + + t = next; + } + + return t; +} + +OSMutex *OSi_RemoveMutexLinkFromQueue (OSMutexQueue *queue) +{ + OSMutex *t = queue->head; + + if (t) { + OSMutex *next = t->link.next; + + queue->head = next; + + if (next) { + next->link.prev = NULL; + } else { + queue->tail = NULL; + } + } + + return t; +} + +#endif + +void OSi_SetSystemCallbackInSwitchThread (void *callback) +{ + OSi_SystemCallbackInSwitchThread = callback; +} + +#ifndef SDK_THREAD_INFINITY + +static int OSi_SearchFreeEntry (void) +{ + int i; + + for (i = 0; i < OS_THREAD_MAX_NUM; i++) { + if (!OSi_ThreadInfo.entry[i]) { + return i; + } + } + return -1; +} +#endif + +static void OSi_InsertThreadToList (OSThread *thread) +{ + OSThread *t = OSi_ThreadInfo.list; + OSThread *pre = NULL; + + while (t && t->priority < thread->priority) { + pre = t; + t = t->next; + } + + if (!pre) { + thread->next = OSi_ThreadInfo.list; + OSi_ThreadInfo.list = thread; + } else { + thread->next = pre->next; + pre->next = thread; + } +} + +static void OSi_RemoveThreadFromList (OSThread *thread) +{ + OSThread *t = OSi_ThreadInfo.list; + OSThread *pre = NULL; + + while (t && t != thread) { + pre = t; + t = t->next; + } + + SDK_ASSERTMSG(t, "Cannot remove thread from list."); + + if (!pre) { + OSi_ThreadInfo.list = thread->next; + } else { + pre->next = thread->next; + } +} + +static void OSi_RescheduleThread (void) +{ + if (OSi_RescheduleCount <= 0) { + OSThreadInfo *info = &OSi_ThreadInfo; + if (info->irqDepth > 0 || OS_GetProcMode() == OS_PROCMODE_IRQ) { + + info->isNeedRescheduling = TRUE; + } else { + OSThread *currentThread, *nextThread; + currentThread = OSi_GetCurrentThread(); + nextThread = OS_SelectThread(); + + if (currentThread == nextThread || !nextThread) { + return; + } + + if (currentThread->state != OS_THREAD_STATE_TERMINATED + && OS_SaveContext(¤tThread->context)) { + return; + } + + if (OSi_SystemCallbackInSwitchThread) { + ((OSSwitchThreadCallback)OSi_SystemCallbackInSwitchThread)(currentThread, + nextThread); + } + + if (info->switchCallback) { + ((OSSwitchThreadCallback)info->switchCallback)(currentThread, nextThread); + } + + OS_SetCurrentThread(nextThread); + OS_LoadContext(&nextThread->context); + + } + } +} + +void OS_InitThread (void) +{ + void *stackLo; +#ifndef SDK_THREAD_INFINITY + int i; +#endif + + if (OSi_IsThreadInitialized) { + return; + } + OSi_IsThreadInitialized = TRUE; + +#ifndef SDK_THREAD_INFINITY + + for (i = 0; i < OS_THREAD_MAX_NUM; i++) { + OSi_ThreadInfo.entry[i] = NULL; + } +#endif + + OSi_CurrentThreadPtr = &(OSi_ThreadInfo.current); + + OSi_LauncherThread.priority = OS_THREAD_LAUNCHER_PRIORITY; + OSi_LauncherThread.id = 0; + OSi_LauncherThread.state = OS_THREAD_STATE_READY; + OSi_LauncherThread.next = NULL; + + OSi_LauncherThread.profiler = NULL; + +#ifndef SDK_THREAD_INFINITY + OSi_ThreadInfo.entry[0] = &OSi_LauncherThread; +#endif + OSi_ThreadInfo.list = &OSi_LauncherThread; + + OS_SetCurrentThread(&OSi_LauncherThread); + + stackLo = (OSi_SYS_STACKSIZE <= 0) ? + (void *)((u32)OSi_LAUNCHER_STACK_LO_DEFAULT - OSi_SYS_STACKSIZE) : + (void *)((u32)OSi_LAUNCHER_STACK_HI_MAX - OSi_SYS_STACKSIZE); + SDK_ASSERT((u32)OSi_LAUNCHER_STACK_LO_DEFAULT <= (u32)stackLo + && (u32)stackLo <= (u32)OSi_LAUNCHER_STACK_HI_MAX); + + OSi_LauncherThread.stackBottom = (u32)OSi_LAUNCHER_STACK_BOTTOM; + OSi_LauncherThread.stackTop = (u32)stackLo; + OSi_LauncherThread.stackWarningOffset = 0; + + *(u32 *)(OSi_LauncherThread.stackBottom - sizeof(u32)) = OSi_STACK_CHECKNUM_BOTTOM; + *(u32 *)OSi_LauncherThread.stackTop = OSi_STACK_CHECKNUM_TOP; + + OS_InitThreadQueue(&OSi_LauncherThread.joinQueue); + +#ifndef SDK_THREAD_INFINITY + + OSi_ThreadInfo.max_entry = OS_THREAD_MAX_NUM; +#endif + + OSi_ThreadInfo.isNeedRescheduling = FALSE; + OSi_ThreadInfo.irqDepth = 0; + SDK_ASSERTMSG(OSi_IRQ_STACKSIZE > 0, "IRQ STACKSIZE must be >0"); + +#ifdef SDK_ARM9 + OS_GetSystemWork()->threadinfo_mainp = &OSi_ThreadInfo; +#else + OS_GetSystemWork()->threadinfo_subp = &OSi_ThreadInfo; +#endif + + (void)OS_SetSwitchThreadCallback(NULL); + +#ifdef SDK_ARM9 + OS_CreateThread(&OSi_IdleThread, + OSi_IdleThreadProc, + (void *)NULL, + OSi_IdleThreadStack + OSi_IDLE_THREAD_STACK_SIZE / sizeof(u32), + OSi_IDLE_THREAD_STACK_SIZE, + OS_THREAD_PRIORITY_MAX); + OSi_IdleThread.priority = OS_THREAD_PRIORITY_MAX + 1; + OSi_IdleThread.state = OS_THREAD_STATE_READY; +#endif +} + +asm BOOL OS_IsThreadAvailable (void) +{ + ldr r0, = OSi_IsThreadInitialized + ldr r0, [r0, #0] + bx lr +} + +void OS_CreateThread (OSThread *thread, void (*func)(void *), void *arg, void *stack, u32 stackSize, u32 prio) +{ +#define STACK_ALIGN 4 + OSIntrMode enable; + int index; + + SDK_ASSERTMSG(OSi_GetCurrentThread(), "thread system were not initialized"); + SDK_ASSERTMSG(OS_THREAD_PRIORITY_MIN <= prio + && prio <= OS_THREAD_PRIORITY_MAX, "invalid priority"); + SDK_ASSERTMSG(stackSize % STACK_ALIGN == 0, "stack size must be aligned by %d", STACK_ALIGN); + SDK_ASSERTMSG((u32)stack % STACK_ALIGN == 0, "stack must be aligned by %d", STACK_ALIGN); + + enable = OS_DisableInterrupts(); + +#ifndef SDK_THREAD_INFINITY + if ((index = OSi_SearchFreeEntry()) < 0) { + SDK_ASSERTMSG(index >= 0, "OS_CreateThread: thread entry not allocated"); + (void)OS_RestoreInterrupts(enable); + return; + } +#else + index = OSi_GetUnusedThreadId(); +#endif + + thread->priority = prio; + thread->id = (u32)index; + thread->state = OS_THREAD_STATE_WAITING; + thread->profiler = NULL; + +#ifndef SDK_THREAD_INFINITY + OSi_ThreadInfo.entry[index] = thread; +#endif + OSi_InsertThreadToList(thread); + + thread->stackBottom = (u32)stack; + thread->stackTop = (u32)stack - stackSize; + thread->stackWarningOffset = 0; + + *(u32 *)(thread->stackBottom - sizeof(u32)) = OSi_STACK_CHECKNUM_BOTTOM; + *(u32 *)thread->stackTop = OSi_STACK_CHECKNUM_TOP; + + OS_InitThreadQueue(&thread->joinQueue); + OS_InitContext(&thread->context, (u32)func, (u32)stack - sizeof(u32)); + + thread->context.r[0] = (u32)arg; + thread->context.lr = (u32)OS_ExitThread; + + MI_CpuClear32((void *)((u32)stack - stackSize + sizeof(u32)), stackSize - sizeof(u32) * 2); + + thread->mutex = NULL; +#ifndef SDK_THREAD_INFINITY + thread->mutexQueueHead = NULL; + thread->mutexQueueTail = NULL; +#else + thread->mutexQueue.head = NULL; + thread->mutexQueue.tail = NULL; +#endif + +#ifdef SDK_THREAD_INFINITY + OS_SetThreadDestructor(thread, NULL); +#endif + +#ifdef SDK_THREAD_INFINITY + thread->queue = NULL; + thread->link.prev = thread->link.next = NULL; + MI_CpuClear32(&thread->specific[0], sizeof(void *) * OS_THREAD_SPECIFIC_MAX); +#endif + thread->alarmForSleep = NULL; + (void)OS_RestoreInterrupts(enable); +} + +void OS_ExitThread (void) +{ + (void)OS_DisableInterrupts(); + +#ifdef SDK_THREAD_INFINITY + OSi_ExitThread_ArgSpecified(OS_GetCurrentThread(), 0); +#else + OSi_ExitThread_Destroy(); +#endif +} + +#ifdef SDK_THREAD_INFINITY + +static void OSi_ExitThread_ArgSpecified (OSThread *thread, void *arg) +{ + if (OSi_StackForDestructor) { + OS_InitContext(&thread->context, (u32)OSi_ExitThread, (u32)OSi_StackForDestructor); + thread->context.r[0] = (u32)arg; + thread->context.cpsr |= HW_PSR_IRQ_DISABLE; + thread->state = OS_THREAD_STATE_READY; + OS_LoadContext(&thread->context); + + } else { + OSi_ExitThread(arg); + } +} +#endif + +#ifdef SDK_THREAD_INFINITY +static void OSi_ExitThread (void *arg) +{ + OSThread *currentThread = OSi_GetCurrentThread(); + OSThreadDestructor destructor; + + SDK_ASSERT(currentThread); + + destructor = currentThread->destructor; + if (destructor) { + currentThread->destructor = NULL; + destructor(arg); + (void)OS_DisableInterrupts(); + } + + OSi_ExitThread_Destroy(); +} +#endif + +static void OSi_ExitThread_Destroy (void) +{ + OSThread *currentThread = OSi_GetCurrentThread(); + SDK_ASSERT(currentThread); + +#ifdef SDK_THREAD_INFINITY + (void)OS_DisableScheduler(); +#endif + +#ifndef SDK_THREAD_INFINITY + SDK_ASSERT(OSi_ThreadInfo.entry[currentThread->id] == currentThread); +#endif + + OSi_UnlockAllMutex(currentThread); + + if (currentThread->queue) { + (void)OSi_RemoveSpecifiedLinkFromQueue(currentThread->queue, currentThread); + } + + OSi_RemoveThreadFromList(currentThread); + +#ifndef SDK_THREAD_INFINITY + OSi_ThreadInfo.entry[currentThread->id] = NULL; +#endif + currentThread->state = OS_THREAD_STATE_TERMINATED; + +#ifndef SDK_THREAD_INFINITY + OS_WakeupThread(¤tThread->joinQueue); +#else + OS_WakeupThread(¤tThread->joinQueue); +#endif + +#ifdef SDK_THREAD_INFINITY + (void)OS_EnableScheduler(); +#endif + + OS_RescheduleThread(); + OS_Terminate(); +} + +static vu32 exitThreadStatus = 0; + +static void exitThreadFunc (void *arg) +{ + exitThreadStatus = 1; + (void)arg; +} + +void UTEST_OS_ExitThread(void); + +void UTEST_OS_ExitThread (void) +{ + OSThread thread; + u32 stack[1024]; + + OS_Init(); + OS_InitThread(); + + OS_CreateThread(&thread, + exitThreadFunc, + NULL, + stack + 1024, sizeof(stack), OS_GetThreadPriority(OS_GetCurrentThread()) - 1); + OS_WakeupThreadDirect(&thread); + OS_JoinThread(&thread); + UT_AssertEq(exitThreadStatus, 1); +} + +void OS_DestroyThread (OSThread *thread) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERT(thread); + + if (OS_GetCurrentThread() == thread) { + OSi_ExitThread_Destroy(); + } + +#ifdef SDK_THREAD_INFINITY + (void)OS_DisableScheduler(); +#endif + + OSi_UnlockAllMutex(thread); + OSi_CancelThreadAlarmForSleep(thread); + + if (thread->queue) { + (void)OSi_RemoveSpecifiedLinkFromQueue(thread->queue, thread); + } + + OSi_RemoveThreadFromList(thread); + +#ifndef SDK_THREAD_INFINITY + OSi_ThreadInfo.entry[thread->id] = NULL; +#endif + thread->state = OS_THREAD_STATE_TERMINATED; + + OS_WakeupThread(&thread->joinQueue); + +#ifdef SDK_THREAD_INFINITY + (void)OS_EnableScheduler(); +#endif + (void)OS_RestoreInterrupts(enabled); + + OS_RescheduleThread(); +} + +#ifdef SDK_THREAD_INFINITY + +static inline void OSi_KillThreadWithPriority(OSThread *thread, void *arg, u32 prio); +static inline void OSi_KillThreadWithPriority (OSThread *thread, void *arg, u32 prio) +{ + SDK_ASSERT(thread); + + { + u32 stack = (OSi_StackForDestructor) ? (u32)OSi_StackForDestructor : thread->stackBottom - sizeof(u32); + OS_InitContext(&thread->context, (u32)OSi_ExitThread, stack); + } + thread->context.r[0] = (u32)arg; + thread->context.cpsr |= HW_PSR_IRQ_DISABLE; + + thread->state = OS_THREAD_STATE_READY; + + (void)OS_DisableScheduler(); + (void)OS_SetThreadPriority(thread, prio); + (void)OS_EnableScheduler(); +} + +void OS_KillThread (OSThread *thread, void *arg) +{ + OS_KillThreadWithPriority(thread, arg, OS_GetThreadPriority(thread)); +} + +void OS_KillThreadWithPriority (OSThread *thread, void *arg, u32 prio) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + if (thread == OS_GetCurrentThread()) { + OSi_ExitThread_ArgSpecified(thread, arg); + + } + + OSi_CancelThreadAlarmForSleep(thread); + OSi_KillThreadWithPriority(thread, arg, prio); + OSi_RescheduleThread(); + + (void)OS_RestoreInterrupts(enabled); +} + +void UTEST_OS_KillThread_1(void); +void UTEST_OS_KillThread_1 (void) +{ + OSThread thread; + OSThread *t = &thread; + u32 flag; + + OS_Init(); + OS_InitThread(); + + t->stackBottom = 0x6789abcd; + t->state = OS_THREAD_STATE_TERMINATED; + OSi_KillThreadWithPriority(t, (void *)0x12345678, 16); + + UT_AssertEq(t->context.pc_plus4, (u32)OSi_ExitThread + 4); + UT_AssertEq(t->context.r[0], (u32)0x12345678); + flag = ((u32)OS_ExitThread & 1) ? (u32)HW_PSR_THUMB_STATE : (u32)HW_PSR_ARM_STATE; + UT_AssertEq(t->context.cpsr, (u32)HW_PSR_IRQ_DISABLE | HW_PSR_SYS_MODE | flag); + UT_AssertEq(t->context.sp, (u32)0x6789abcd - HW_SVC_STACK_SIZE); + + UT_AssertEq(t->state, OS_THREAD_STATE_READY); + UT_AssertAsserted(OSi_KillThreadWithPriority(0, 0, 16)); +} + +static vu32 killThreadStatus = 0; + +static void killThreadDtor (void *arg) +{ + killThreadStatus = 666; + (void)arg; +} + +static void killThreadFunc (void *arg) +{ + OS_SetThreadDestructor(OS_GetCurrentThread(), killThreadDtor); + + killThreadStatus = 1; + while (1) { + OS_SleepThread(NULL); + killThreadStatus++; + } + (void)arg; +} + +void UTEST_OS_KillThread_2(void); +void UTEST_OS_KillThread_2 (void) +{ + OSThread thread; + u32 stack[1024]; + + OS_Init(); + OS_InitThread(); + + OS_CreateThread(&thread, + killThreadFunc, + NULL, + stack + 1024, sizeof(stack), OS_GetThreadPriority(OS_GetCurrentThread()) - 1); + UT_AssertEq(killThreadStatus, 0); + + OS_WakeupThreadDirect(&thread); + UT_AssertEq(killThreadStatus, 1); + UT_AssertEq(thread.destructor, killThreadDtor); + + OS_WakeupThreadDirect(&thread); + UT_AssertEq(killThreadStatus, 2); + + OS_KillThread(&thread, 0); + OS_JoinThread(&thread); + UT_AssertEq(killThreadStatus, 666); +} + +#endif + +static void OSi_CancelThreadAlarmForSleep (OSThread *thread) +{ + OSAlarm *alarm = thread->alarmForSleep; + + if (alarm) { + OS_CancelAlarm(alarm); + } +} + +void OS_JoinThread (OSThread *thread) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + SDK_ASSERT(thread); + + if (thread->state != OS_THREAD_STATE_TERMINATED) { + OS_SleepThread(&thread->joinQueue); + } + + (void)OS_RestoreInterrupts(enabled); +} + +BOOL OS_IsThreadTerminated (const OSThread *thread) +{ + return (thread->state == OS_THREAD_STATE_TERMINATED) ? TRUE : FALSE; +} + +void OS_SleepThreadDirect (OSThread *thread, OSThreadQueue *queue) +{ + SDK_ASSERT(thread); + SDK_ASSERT(thread->state != OS_THREAD_STATE_TERMINATED); + + { + OSIntrMode bak_intr = OS_DisableInterrupts(); + if (queue) { +#ifndef SDK_THREAD_INFINITY + *queue |= (OSThreadQueue)(1UL << thread->id); +#else + thread->queue = queue; + OSi_InsertLinkToQueue(queue, thread); +#endif + } + thread->state = OS_THREAD_STATE_WAITING; + OSi_RescheduleThread(); + (void)OS_RestoreInterrupts(bak_intr); + } +} + +void OS_SleepThread (OSThreadQueue *queue) +{ + OSIntrMode enable; + OSThread *currentThread; + + enable = OS_DisableInterrupts(); +#ifndef SDK_THREAD_INFINITY + { + currentThread = OSi_GetCurrentThread(); + SDK_ASSERT(currentThread); + + if (queue) { + *queue |= (OSThreadQueue)(1UL << currentThread->id); + } + + currentThread->state = OS_THREAD_STATE_WAITING; + OSi_RescheduleThread(); + } +#else + { + currentThread = OSi_GetCurrentThread(); + SDK_ASSERT(currentThread); + + if (queue) { + currentThread->queue = queue; + OSi_InsertLinkToQueue(queue, currentThread); + } + + currentThread->state = OS_THREAD_STATE_WAITING; + OSi_RescheduleThread(); + } +#endif + (void)OS_RestoreInterrupts(enable); + +} + +void OS_WakeupThread (OSThreadQueue *queue) +{ + OSIntrMode enable; +#ifndef SDK_THREAD_INFINITY + u32 mask; +#else + BOOL isNeedRescheduling = FALSE; +#endif + SDK_ASSERT(queue); + enable = OS_DisableInterrupts(); + +#ifndef SDK_THREAD_INFINITY + mask = (u32) * queue; + if (mask) { + + OSThread *t = OSi_ThreadInfo.list; + while (t) { + if (mask & (1UL << t->id)) { + t->state = OS_THREAD_STATE_READY; + } + + t = t->next; + } + + OS_InitThreadQueue(queue); + OSi_RescheduleThread(); + } +#else + if (queue->head) { + while (queue->head) { + OSThread *thread = OSi_RemoveLinkFromQueue(queue); + + thread->state = OS_THREAD_STATE_READY; + thread->queue = NULL; + thread->link.prev = thread->link.next = NULL; + } + + OS_InitThreadQueue(queue); + OSi_RescheduleThread(); + } +#endif + + (void)OS_RestoreInterrupts(enable); +} + +void OS_WakeupThreadDirect (OSThread *thread) +{ + OSIntrMode enable; + + SDK_ASSERT(thread); + SDK_ASSERT(thread->state != OS_THREAD_STATE_TERMINATED); + enable = OS_DisableInterrupts(); + { + thread->state = OS_THREAD_STATE_READY; + OSi_RescheduleThread(); + + } + (void)OS_RestoreInterrupts(enable); +} + +OSThread *OS_SelectThread (void) +{ + OSThread *t = OSi_ThreadInfo.list; + + while (t && !OS_IsThreadRunnable(t)) { + t = t->next; + } + + return t; +} + +void OS_RescheduleThread (void) +{ + OSIntrMode bak_intr = OS_DisableInterrupts(); + OSi_RescheduleThread(); + (void)OS_RestoreInterrupts(bak_intr); +} + +void OS_YieldThread (void) +{ + OSThread *current = OS_GetCurrentThread(); + OSThread *pre = NULL; + OSThread *lastThread = NULL; + int samePriorityThread = 0; + OSIntrMode enable = OS_DisableInterrupts(); + + { + OSThread *t = OSi_ThreadInfo.list; + OSThread *tPre = NULL; + + while (t) { + if (t == current) { + pre = tPre; + } + + if (current->priority == t->priority) { + lastThread = t; + samePriorityThread++; + } + + tPre = t; + t = t->next; + } + } + + if (samePriorityThread <= 1 || lastThread == current) { + (void)OS_RestoreInterrupts(enable); + return; + } + + if (!pre) { + OSi_ThreadInfo.list = current->next; + } else { + pre->next = current->next; + } + + current->next = lastThread->next; + lastThread->next = current; + + OSi_RescheduleThread(); + + (void)OS_RestoreInterrupts(enable); +} + +void OS_DumpThreadList (void) +{ +#ifndef SDK_FINALROM +#ifndef SDK_THREAD_INFINITY + int i; +#endif + + OS_Printf("----------------\n"); + OS_Printf("thread list top %08x\n", OSi_ThreadInfo.list); + +#ifndef SDK_THREAD_INFINITY + OS_Printf("No: address prio next\n"); + for (i = 0; i < OS_THREAD_MAX_NUM; i++) { + OSThread *thread = OSi_ThreadInfo.entry[i]; + OS_Printf("%02d: %08x %5d %08x\n", i, thread, (thread) ? thread->priority : 0, + (thread) ? thread->next : 0); + } +#else + + OS_Printf("Id: address prio next st queue.h queue.t link.p link.n\n"); + { + OSThread *thread = OSi_ThreadInfo.list; + while (thread) { + + OS_Printf("%02d: %08x %5d %08x %d %8x %8x %8x %8x\n", thread->id, thread, + thread->priority, thread->next, thread->state, + (thread->queue) ? thread->queue->head : (OSThread *)1, + (thread->queue) ? thread->queue->tail : (OSThread *)1, thread->link.prev, + thread->link.next); + thread = thread->next; + + } + } +#endif +#endif +} + +int OS_GetNumberOfThread (void) +{ + int threads = 0; + +#ifndef SDK_THREAD_INFINITY + int i; + + for (i = 0; i < OS_THREAD_MAX_NUM; i++) { + if (OSi_ThreadInfo.entry[i]) { + threads++; + } + } +#else + OSThread *thread = OSi_ThreadInfo.list; + while (thread) { + threads++; + thread = thread->next; + } +#endif + + return threads; +} + +OSStackStatus OS_GetStackStatus (const OSThread *thread) +{ + if (*(u32 *)(thread->stackTop) != OSi_STACK_CHECKNUM_TOP) { + return OS_STACK_OVERFLOW; + } else if (thread->stackWarningOffset + && *(u32 *)(thread->stackTop + thread->stackWarningOffset) != OSi_STACK_CHECKNUM_WARN) { + return OS_STACK_ABOUT_TO_OVERFLOW; + } else if (*(u32 *)(thread->stackBottom - sizeof(u32)) != OSi_STACK_CHECKNUM_BOTTOM) { + return OS_STACK_UNDERFLOW; + } else { + return OS_STACK_NO_ERROR; + } +} + +static char *OSi_CheckStack_mesg[] = { + "overflow", "about to overflow", "underflow" +}; + +#ifndef SDK_FINALROM +#ifndef SDK_NO_MESSAGE +void OSi_CheckStack (const char *file, int line, const OSThread *thread) +{ + OSStackStatus st; + + if ((st = OS_GetStackStatus(thread)) == OS_STACK_NO_ERROR) { + return; + } + + OSi_Panic(file, line, " stack %x(id:%d) %s.\nstack area: %08x-%08x, warning offset: %x", + thread, + thread->id, + OSi_CheckStack_mesg[(int)st - 1], + thread->stackTop, thread->stackBottom, thread->stackWarningOffset); + +} +#endif +#endif + +static u32 OSi_SystemStackBuffer; + +#include +asm u32 OSi_GetSystemStackPointer (void) +{ + ldr r0, = OSi_SystemStackBuffer + stmia r0, { sp } ^ + ldr r0, [r0] + bx lr +} +#include + +asm u32 OSi_GetCurrentStackPointer (void) +{ + mov r0, sp + bx lr +} + +void OS_SetThreadStackWarningOffset (OSThread *thread, u32 offset) +{ + SDK_ASSERTMSG((offset & 3) == 0, "Offset must be aligned by 4"); + SDK_ASSERTMSG(offset > 0, "Cannot set warning level to stack top."); + SDK_ASSERTMSG(OS_GetThreadContext(thread)->sp > thread->stackTop + offset, + "Cannot set warning level below current sp."); + + thread->stackWarningOffset = offset; + + if (offset != 0) { + *(u32 *)(thread->stackTop + offset) = OSi_STACK_CHECKNUM_WARN; + } +} + +BOOL OS_SetThreadPriority (OSThread *thread, u32 prio) +{ + OSThread *t = OSi_ThreadInfo.list; + OSThread *pre = NULL; + OSIntrMode enable; + + SDK_ASSERTMSG(OS_THREAD_PRIORITY_MIN <= prio + && prio <= OS_THREAD_PRIORITY_MAX, "invalid priority"); + SDK_ASSERTMSG(thread != &OSi_IdleThread, "cannot change idle thread priority."); + + enable = OS_DisableInterrupts(); + + while (t && t != thread) { + pre = t; + t = t->next; + } + + if (!t || t == &OSi_IdleThread) { + (void)OS_RestoreInterrupts(enable); + return FALSE; + } + + if (t->priority != prio) { + + if (!pre) { + OSi_ThreadInfo.list = thread->next; + } else { + pre->next = thread->next; + } + + thread->priority = prio; + + OSi_InsertThreadToList(thread); + OSi_RescheduleThread(); + } + + (void)OS_RestoreInterrupts(enable); + return TRUE; +} + +u32 OS_GetThreadPriority (const OSThread *thread) +{ + SDK_ASSERTMSG(thread, "OS_GetThreadPriority: bad thread"); + return thread->priority; +} + +void OS_Sleep (u32 msec) +{ + OSAlarm alarm; + + SDK_ASSERTMSG(OS_IsTickAvailable() + && OS_IsAlarmAvailable(), "OS_Sleep: need to start Tick and Alarm beforehand."); + SDK_ASSERTMSG(OSi_IsThreadInitialized, "OS_Sleep: thread system not initialized."); + + OS_CreateAlarm(&alarm); + { + OSThread *volatile p_thread = OSi_GetCurrentThread(); + OSIntrMode bak_cpsr = OS_DisableInterrupts(); + + p_thread->alarmForSleep = &alarm; + + OS_SetAlarm(&alarm, OS_MilliSecondsToTicks(msec), &OSi_SleepAlarmCallback, + (void *)&p_thread); + while (p_thread != NULL) { + OS_SleepThread(NULL); + } + (void)OS_RestoreInterrupts(bak_cpsr); + } +} + +static void OSi_SleepAlarmCallback (void *arg) +{ + OSThread **pp_thread = (OSThread **)arg; + OSThread *p_thread = *pp_thread; + *pp_thread = NULL; + + p_thread->alarmForSleep = NULL; + + OS_WakeupThreadDirect(p_thread); +} + +OSSwitchThreadCallback OS_SetSwitchThreadCallback (OSSwitchThreadCallback callback) +{ + OSSwitchThreadCallback prev; + OSIntrMode enabled; + + enabled = OS_DisableInterrupts(); + prev = OSi_ThreadInfo.switchCallback; + OSi_ThreadInfo.switchCallback = callback; + + (void)OS_RestoreInterrupts(enabled); + return prev; +} + +static void OSi_IdleThreadProc (void *) +{ + (void)OS_EnableInterrupts(); + while (1) { + OS_Halt(); + } + +} + +OSThread *OSi_GetIdleThread (void) +{ + OSThread *t = NULL; + if (OSi_IsThreadInitialized) { + t = &OSi_IdleThread; + } + return t; +} + +u32 OS_DisableScheduler (void) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + u32 count; + + if (OSi_RescheduleCount < (u32)(0 - 1)) { + count = OSi_RescheduleCount++; + } + (void)OS_RestoreInterrupts(enabled); + + return count; +} + +u32 OS_EnableScheduler (void) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + u32 count = 0; + + if (OSi_RescheduleCount > 0) { + count = OSi_RescheduleCount--; + } + (void)OS_RestoreInterrupts(enabled); + + return count; +} + +#ifdef SDK_THREAD_INFINITY + +OSThread *OS_GetThread (u32 id) +{ + OSThread *retval = NULL; + OSThread *t = OSi_ThreadInfo.list; + + while (t) { + if (t->id == id) { + retval = t; + break; + } + + t = t->next; + } + + return retval; +} +#endif + +#ifdef SDK_THREAD_INFINITY + +void OS_SetThreadDestructor (OSThread *thread, OSThreadDestructor dtor) +{ + SDK_ASSERT(thread); + thread->destructor = dtor; +} + +OSThreadDestructor OS_GetThreadDestructor (const OSThread *thread) +{ + SDK_ASSERT(thread); + return thread->destructor; +} + +void OS_SetThreadParameter (OSThread *thread, void *parameter) +{ + SDK_ASSERT(thread); + thread->userParameter = parameter; +} + +void *OS_GetThreadParameter (const OSThread *thread) +{ + SDK_ASSERT(thread); + return thread->userParameter; +} + +void OSi_SetSystemErrno (OSThread *thread, int errno) +{ + SDK_ASSERT(thread); + thread->systemErrno = errno; +} + +int OSi_GetSystemErrno (const OSThread *thread) +{ + SDK_ASSERT(thread); + return thread->systemErrno; +} + +int OS_GetErrno (void) +{ + OSThread *thread = OSi_GetCurrentThread(); + return OSi_GetSystemErrno(thread); +} +#endif + +BOOL OS_IsThreadInList (const OSThread *thread) +{ + BOOL r = FALSE; + OSThread *t = OSi_ThreadInfo.list; + OSIntrMode enabled = OS_DisableInterrupts(); + + while (t) { + if (t == thread) { + r = TRUE; + break; + } + + t = t->next; + } + + (void)OS_RestoreInterrupts(enabled); + return r; +} + +void OS_SetThreadDestructorStack (void *stack) +{ + SDK_ASSERT(stack); + SDK_ASSERT((u32)stack % STACK_ALIGN == 0); + + OSi_StackForDestructor = stack; +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_tick.c b/subprojects/NitroSDK/libraries/os/src/os_tick.c new file mode 100644 index 0000000000..6360577358 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_tick.c @@ -0,0 +1,129 @@ +#include + +#define OSi_TICK_TIMERCONTROL (REG_OS_TM0CNT_H_E_MASK | REG_OS_TM0CNT_H_I_MASK | OS_TIMER_PRESCALER_64) + +#define OSi_TICK_TIMER OS_TIMER_0 + +#define OSi_TICK_IE_TIMER OS_IE_TIMER0 + +static u16 OSi_UseTick = FALSE; + +vu64 OSi_TickCounter; + +BOOL OSi_NeedResetTimer = FALSE; + +extern u16 OSi_IsTimerReserved(int timerNum); +extern void OSi_SetTimerReserved(int timerNum); + +static void OSi_CountUpTick(void); +u32 OSi_GetTick_noProfile(void); + +void OS_InitTick (void) +{ + if (!OSi_UseTick) { + OSi_UseTick = TRUE; + + SDK_ASSERT(!OSi_IsTimerReserved(OSi_TICK_TIMER)); + OSi_SetTimerReserved(OSi_TICK_TIMER); + + OSi_TickCounter = 0; + OS_SetTimerControl(OSi_TICK_TIMER, 0); + OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)0); + OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL); + + OS_SetIrqFunction(OSi_TICK_IE_TIMER, OSi_CountUpTick); + + (void)OS_EnableIrqMask(OSi_TICK_IE_TIMER); + + OSi_NeedResetTimer = FALSE; + } +} + +BOOL OS_IsTickAvailable (void) +{ + return OSi_UseTick; +} + +static void OSi_CountUpTick (void) +{ + OSi_TickCounter++; + + if (OSi_NeedResetTimer) { + OS_SetTimerControl(OSi_TICK_TIMER, 0); + OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)0); + OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL); + + OSi_NeedResetTimer = FALSE; + } + + OSi_EnterTimerCallback(OSi_TICK_TIMER, (void (*)(void *)) OSi_CountUpTick, 0); +} + +OSTick OS_GetTick (void) +{ + vu16 countL; + vu64 countH; + + OSIntrMode prev = OS_DisableInterrupts(); + SDK_ASSERT(OSi_UseTick); + + countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4); + countH = OSi_TickCounter & 0xffffffffffffULL; + + if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000)) { + countH++; + } + + (void)OS_RestoreInterrupts(prev); + + return (countH << 16) | countL; +} + +#pragma profile off +u32 OSi_GetTick_noProfile (void) +{ + vu16 countL; + vu16 countH; + + OSIntrMode prev = OS_DisableInterrupts(); + SDK_ASSERT(OSi_UseTick); + + countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4); + countH = (u16)OSi_TickCounter; + + if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000)) { + countH++; + } + + (void)OS_RestoreInterrupts(prev); + + return (u32)(countH << 16) | countL; +} + +#pragma profile reset + +u16 OS_GetTickLo (void) +{ + SDK_ASSERT(OSi_UseTick); + return *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4); +} + +void OS_SetTick (OSTick count) +{ + OSIntrMode prev; + + SDK_ASSERT(OSi_UseTick); + prev = OS_DisableInterrupts(); + + reg_OS_IF = OSi_TICK_IE_TIMER; + + OSi_NeedResetTimer = TRUE; + + OSi_TickCounter = (u64)(count >> 16); + + OS_SetTimerControl(OSi_TICK_TIMER, 0); + OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)(count & 0xffff)); + OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL); + + (void)OS_RestoreInterrupts(prev); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_timer.c b/subprojects/NitroSDK/libraries/os/src/os_timer.c new file mode 100644 index 0000000000..c1e42d9c6d --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_timer.c @@ -0,0 +1,143 @@ +#include + +#define REG_OS_TMCNT_H_E_MASK REG_OS_TM0CNT_H_E_MASK +#define REG_OS_TMCNT_H_I_MASK REG_OS_TM0CNT_H_I_MASK +#define REG_OS_TMCNT_H_CH_MASK REG_OS_TM1CNT_H_CH_MASK + +static u16 OSi_TimerReserved = 0; + +#define OSi_TIMER_RESERVED_0 1 +#define OSi_TIMER_RESERVED_1 2 +#define OSi_TIMER_RESERVED_2 4 +#define OSi_TIMER_RESERVED_3 8 + +u16 OSi_IsTimerReserved(int timerNum); +void OSi_SetTimerReserved(int timerNum); +void OSi_UnsetTimerReserved(int timerNum); + +u16 OSi_IsTimerReserved (int timerNum) +{ + return (u16)(OSi_TimerReserved & (1 << timerNum)); +} + +void OSi_SetTimerReserved (int timerNum) +{ + OSi_TimerReserved |= (1 << timerNum); +} + +void OSi_UnsetTimerReserved (int timerNum) +{ + OSi_TimerReserved &= ~(1 << timerNum); +} + +void OS_StartTimer (OSTimer id, u16 count, OSTimerPrescaler preScale) +{ + SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3); + SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024); + + SDK_ASSERT(!OSi_IsTimerReserved(id)); + + OS_SetTimerCount(id, (u16) ~count); + OS_SetTimerControl(id, (u16)(REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | preScale)); +} + +void OS_StartTimer32 (OSTimer32 id, u32 count, OSTimerPrescaler preScale) +{ + SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23); + SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024); + + SDK_ASSERT(!OSi_IsTimerReserved(id)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 1)); + + OS_SetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff)); + OS_SetTimerCount((OSTimer)id, (u16)(~count & 0xffff)); + + OS_SetTimerControl((OSTimer)((int)id + 1), + REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale)); +} + +void OS_StartTimer48 (OSTimer48 id, u64 count, OSTimerPrescaler preScale) +{ + SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123); + SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024); + + SDK_ASSERT(!OSi_IsTimerReserved(id)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 1)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 2)); + + OS_SetTimerCount((OSTimer)((int)id + 2), (u16)((~count >> 32) & 0xffff)); + OS_SetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff)); + OS_SetTimerCount((OSTimer)id, (u16)(~count & 0xffff)); + + OS_SetTimerControl((OSTimer)((int)id + 2), + REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl((OSTimer)((int)id + 1), REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl((OSTimer)id, (u16)(REG_OS_TMCNT_H_E_MASK | preScale)); +} + +void OS_StartTimer64 (u64 count, OSTimerPrescaler preScale) +{ + SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024); + + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_0)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_1)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_2)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_3)); + + OS_SetTimerCount(OS_TIMER_3, (u16)((~count >> 48) & 0xffff)); + OS_SetTimerCount(OS_TIMER_2, (u16)((~count >> 32) & 0xffff)); + OS_SetTimerCount(OS_TIMER_1, (u16)((~count >> 16) & 0xffff)); + OS_SetTimerCount(OS_TIMER_0, (u16)(~count & 0xffff)); + + OS_SetTimerControl(OS_TIMER_3, + REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_I_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl(OS_TIMER_2, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl(OS_TIMER_1, REG_OS_TMCNT_H_E_MASK | REG_OS_TMCNT_H_CH_MASK); + OS_SetTimerControl(OS_TIMER_0, (u16)(REG_OS_TMCNT_H_E_MASK | preScale)); +} + +void OS_StopTimer (OSTimer id) +{ + SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3); + SDK_ASSERT(!OSi_IsTimerReserved(id)); + + OS_SetTimerControl(id, 0); +} + +void OS_StopTimer32 (OSTimer32 id) +{ + SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23); + + SDK_ASSERT(!OSi_IsTimerReserved(id)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 1)); + + OS_StopTimer((OSTimer)((int)id + 1)); + OS_StopTimer((OSTimer)id); +} + +void OS_StopTimer48 (OSTimer48 id) +{ + SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123); + + SDK_ASSERT(!OSi_IsTimerReserved(id)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 1)); + SDK_ASSERT(!OSi_IsTimerReserved(id + 2)); + + OS_StopTimer((OSTimer)((int)id + 2)); + OS_StopTimer((OSTimer)((int)id + 1)); + OS_StopTimer((OSTimer)id); +} + +void OS_StopTimer64 (void) +{ + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_0)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_1)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_2)); + SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_3)); + + OS_StopTimer(OS_TIMER_3); + OS_StopTimer(OS_TIMER_2); + OS_StopTimer(OS_TIMER_1); + OS_StopTimer(OS_TIMER_0); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_valarm.c b/subprojects/NitroSDK/libraries/os/src/os_valarm.c new file mode 100644 index 0000000000..7c711215c0 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_valarm.c @@ -0,0 +1,447 @@ +#include + +#define OSi_VHIGHT HW_LCD_LINES + +#define OSi_VALARM_LATER 0 +#define OSi_VALARM_NOW 1 +#define OSi_VALARM_TIMEOUT 2 + +static struct OSiVAlarmQueue { + OSVAlarm *head; + OSVAlarm *tail; +} +OSi_VAlarmQueue; + +static u16 OSi_UseVAlarm = FALSE; + +static s32 OSi_VFrameCount; +static s32 OSi_PreviousVCount; + +static void OSi_InsertVAlarm(OSVAlarm *alarm); +static void OSi_SetNextVAlarm(OSVAlarm *alarm); +static void OSi_AppendVAlarm(OSVAlarm *alarm); +static void OSi_VAlarmHandler(void *arg); +static int OSi_CompareVCount(OSVAlarm *alarm, s32 currentVCount, s32 currentVFrame); +static s32 OSi_GetVFrame(s32 vcount); + +static int OSi_VCountArr (int count) +{ + while (count < 0) { + count += OSi_VHIGHT; + } + while (count >= OSi_VHIGHT) { + count -= OSi_VHIGHT; + } + return count; +} + +#define OSi_VCountSub(a, b) OSi_VCountArr((int)((a) - (b))) + +#define OSi_IsNearVCount(a, b, c) ((OSi_VCountSub((a), (c)) < OSi_VCountSub((b), (c)))? TRUE: FALSE) + +void OS_InitVAlarm (void) +{ + if (!OSi_UseVAlarm) { + OSi_UseVAlarm = TRUE; + + OSi_VAlarmQueue.head = NULL; + OSi_VAlarmQueue.tail = NULL; + + (void)OS_DisableIrqMask(OS_IE_V_COUNT); + + OSi_VFrameCount = 0; + OSi_PreviousVCount = 0; + } +} + +void OS_EndVAlarm (void) +{ + OSIntrMode enabled; + + SDK_ASSERT(OSi_UseVAlarm); + enabled = OS_DisableInterrupts(); + + if (OSi_UseVAlarm) { + SDK_ASSERTMSG(!OSi_VAlarmQueue.head, + "OS_EndVAlarm: Cannot end v-alarm system while using v-alarm."); + OSi_UseVAlarm = FALSE; + } + + (void)OS_RestoreInterrupts(enabled); +} + +BOOL OS_IsVAlarmAvailable (void) +{ + return OSi_UseVAlarm; +} + +static void OSi_InsertVAlarm (OSVAlarm *alarm) +{ + OSVAlarm *prev; + OSVAlarm *next; + + for (next = OSi_VAlarmQueue.head; next; next = next->next) { + + if ((next->frame < alarm->frame) || + (next->frame == alarm->frame) && (next->fire <= alarm->fire)) { + continue; + } + + prev = next->prev; + + alarm->prev = prev; + alarm->next = next; + + next->prev = alarm; + + if (prev) { + prev->next = alarm; + } else { + OSi_VAlarmQueue.head = alarm; + OSi_SetNextVAlarm(alarm); + } + + return; + } + + OSi_AppendVAlarm(alarm); +} + +static void OSi_AppendVAlarm (OSVAlarm *alarm) +{ + OSVAlarm *prev = OSi_VAlarmQueue.tail; + + alarm->prev = prev; + alarm->next = NULL; + + OSi_VAlarmQueue.tail = alarm; + + if (prev) { + prev->next = alarm; + } else { + OSi_VAlarmQueue.head = alarm; + OSi_SetNextVAlarm(alarm); + } +} + +static void OSi_DetachVAlarm (OSVAlarm *alarm) +{ + OSVAlarm *prev; + OSVAlarm *next; + + if (!alarm) { + return; + } + + prev = alarm->prev; + next = alarm->next; + + if (next) { + next->prev = prev; + } else { + OSi_VAlarmQueue.tail = prev; + } + + if (prev) { + prev->next = next; + } else { + OSi_VAlarmQueue.head = next; + } +} + +void OS_CreateVAlarm (OSVAlarm *alarm) +{ + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERT(alarm); + + alarm->handler = 0; + alarm->tag = 0; + + alarm->finish = FALSE; +} + +void OS_SetVAlarm (OSVAlarm *alarm, s16 count, s16 delay, OSVAlarmHandler handler, void *arg) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + s32 currentVCount; + s32 currentVFrame; + + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERTMSG(handler, "OS_SetVAlarm: handler must not be NULL."); + if (!alarm || alarm->handler) { +#ifndef SDK_FINALROM + OS_Panic("v-alarm could be already used."); +#else + OS_Panic(""); +#endif + } + + currentVCount = GX_GetVCount(); + currentVFrame = OSi_GetVFrame(currentVCount); + + alarm->period = FALSE; + + alarm->fire = count; + alarm->frame = (u32)((count > currentVCount) ? currentVFrame : (currentVFrame + 1)); + + alarm->delay = delay; + + alarm->handler = handler; + alarm->arg = arg; + + alarm->canceled = FALSE; + + OSi_InsertVAlarm(alarm); + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_SetPeriodicVAlarm (OSVAlarm *alarm, s16 count, s16 delay, OSVAlarmHandler handler, void *arg) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + s32 currentVCount; + s32 currentVFrame; + + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERTMSG(handler, "OS_SetPeriodicVAlarm: handler must not be NULL\n"); + SDK_ASSERTMSG(0 <= delay + && delay <= OSi_VHIGHT, + "OS_SetPeriodicVAlarm: illegal permissible range of delay."); + if (!alarm || alarm->handler) { +#ifndef SDK_FINALROM + OS_Panic("v-alarm could be already used."); +#else + OS_Panic(""); +#endif + } + + currentVCount = GX_GetVCount(); + currentVFrame = OSi_GetVFrame(currentVCount); + + alarm->period = TRUE; + + alarm->fire = count; + alarm->frame = (u32)((count > currentVCount) ? currentVFrame : (currentVFrame + 1)); + + alarm->delay = delay; + + alarm->handler = handler; + alarm->arg = arg; + + alarm->canceled = FALSE; + + OSi_InsertVAlarm(alarm); + + (void)OS_RestoreInterrupts(enabled); +} + +static void OSi_SetNextVAlarm (OSVAlarm *alarm) +{ + + OS_SetIrqFunction(OS_IE_V_COUNT, (void (*)()) OSi_VAlarmHandler); + + GX_SetVCountEqVal(alarm->fire); + + GX_VCountEqIntr(TRUE); + (void)OS_EnableIrqMask(OS_IE_V_COUNT); +} + +void OS_SetVAlarmTag (OSVAlarm *alarm, u32 tag) +{ +#ifdef SDK_DEBUG + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERT(alarm); + SDK_ASSERTMSG(tag > 0, "OSSetVAlarmTag: Tag must be >0."); +#else + if (tag == 0) { + OS_Panic(""); + } +#endif + + if (alarm) { + alarm->tag = tag; + } +} + +void OS_CancelVAlarm (OSVAlarm *alarm) +{ + OSIntrMode enabled = OS_DisableInterrupts();; + + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERT(alarm); + + alarm->canceled = TRUE; + if (alarm->handler == NULL) { + (void)OS_RestoreInterrupts(enabled); + return; + } + + OSi_DetachVAlarm(alarm); + + alarm->handler = NULL; + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_CancelAllVAlarms (void) +{ + OSIntrMode enabled; + OSVAlarm *alarm; + OSVAlarm *next; + + SDK_ASSERT(OSi_UseVAlarm); + enabled = OS_DisableInterrupts(); + + for (alarm = OSi_VAlarmQueue.head, next = alarm ? alarm->next : NULL; + alarm; alarm = next, next = alarm ? alarm->next : NULL) { + + OS_CancelVAlarm(alarm); + } + + (void)OS_RestoreInterrupts(enabled); +} + +void OS_CancelVAlarms (u32 tag) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + OSVAlarm *alarm; + OSVAlarm *next; + +#ifdef SDK_DEBUG + SDK_ASSERT(OSi_UseVAlarm); + SDK_ASSERTMSG(tag > 0, "OSCancelVAlarms: Tag must be >0."); +#else + if (tag == 0) { + OS_Panic(""); + } +#endif + + for (alarm = OSi_VAlarmQueue.head, next = alarm ? alarm->next : NULL; + alarm; alarm = next, next = alarm ? alarm->next : NULL) { + if (alarm->tag == tag) { + + OS_CancelVAlarm(alarm); + } + } + + (void)OS_RestoreInterrupts(enabled); +} + +static void OSi_VAlarmHandler (void *) +{ + OSVAlarm *alarm; + OSVAlarmHandler handler; + int check; + s32 currentVCount; + s32 currentVFrame; + + (void)OS_DisableIrqMask(OS_IE_V_COUNT); + GX_VCountEqIntr(FALSE); + + OS_SetIrqCheckFlag(OS_IE_V_COUNT); + + currentVCount = GX_GetVCountEqVal(); + currentVFrame = OSi_GetVFrame(currentVCount - 1); + + while (NULL != (alarm = OSi_VAlarmQueue.head)) { + + currentVCount = GX_GetVCount(); + currentVFrame = OSi_GetVFrame(currentVCount); + + check = OSi_CompareVCount(alarm, currentVFrame, currentVCount); + +#ifdef DEBUGPRINT + OS_Printf("[%d:%d %d] %d %d check=%d \n", + alarm->arg, alarm->frame, alarm->fire, currentVFrame, currentVCount, check); +#endif + + switch (check) { + case OSi_VALARM_LATER: + + OSi_SetNextVAlarm(alarm); + + if (alarm->fire != GX_GetVCount() || alarm->frame != currentVFrame) { + return; + } + + (void)OS_DisableIrqMask(OS_IE_V_COUNT); + GX_VCountEqIntr(FALSE); + (void)OS_ResetRequestIrqMask(OS_IE_V_COUNT); + + case OSi_VALARM_NOW: + + handler = alarm->handler; + OSi_DetachVAlarm(alarm); + alarm->handler = NULL; + + if (handler) { + (handler) (alarm->arg); + } + + if (alarm->period && !alarm->canceled) { + alarm->handler = handler; + alarm->frame = (u32)OSi_VFrameCount + 1; + OSi_InsertVAlarm(alarm); + } + break; + + case OSi_VALARM_TIMEOUT: + + OSi_DetachVAlarm(alarm); + alarm->frame = (u32)OSi_VFrameCount + 1; + OSi_InsertVAlarm(alarm); + break; + + } + } +} + +static int OSi_CompareVCount (OSVAlarm *alarm, s32 currentVFrame, s32 currentVCount) +{ + s32 delayVFrame; + s32 delayVCount; + + delayVFrame = currentVFrame - (s32)alarm->frame; + delayVCount = currentVCount - (s32)alarm->fire; + + if (delayVFrame < 0 || (delayVFrame == 0 && delayVCount < 0)) { + return OSi_VALARM_LATER; + } + + if (delayVCount < 0) { + delayVCount += OSi_VHIGHT; + } + + return (delayVCount <= alarm->delay) ? OSi_VALARM_NOW : OSi_VALARM_TIMEOUT; +} + +static s32 OSi_GetVFrame (s32 vcount) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + if (vcount < OSi_PreviousVCount) { + OSi_VFrameCount++; + } + OSi_PreviousVCount = vcount; + + (void)OS_RestoreInterrupts(enabled); + return OSi_VFrameCount; +} + +void OS_DumpVAlarm(void); +void OS_DumpVAlarm (void) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + OSVAlarm *alarm; + OSVAlarm *next; + + OS_Printf("---------------- current vcount = %d\n", (s16)GX_GetVCount()); + for (alarm = OSi_VAlarmQueue.head; alarm; alarm = next) { + next = alarm->next; + + OS_Printf("%08x fire=%d:%d delay=%d arg=%2d prev=%08x next=%08x\n", alarm, + alarm->frame, alarm->fire, alarm->delay, alarm->arg, alarm->prev, alarm->next); + } + + (void)OS_RestoreInterrupts(enabled); +} \ No newline at end of file diff --git a/subprojects/NitroSDK/libraries/os/src/os_vramExclusive.c b/subprojects/NitroSDK/libraries/os/src/os_vramExclusive.c new file mode 100644 index 0000000000..42bebf49a1 --- /dev/null +++ b/subprojects/NitroSDK/libraries/os/src/os_vramExclusive.c @@ -0,0 +1,81 @@ +#include +#include + +static u32 OSi_vramExclusive; +static u16 OSi_vramLockId[OS_VRAM_BANK_KINDS]; + +#include +static asm u32 +OsCountZeroBits (u32 bitmap) +{ + clz r0, r0 + bx lr +} + +#include + +void OSi_InitVramExclusive (void) +{ + s32 i; + + OSi_vramExclusive = 0x0000; + for(i = 0 ; i < OS_VRAM_BANK_KINDS ; i++) { + OSi_vramLockId[i] = 0; + } +} + +BOOL OSi_TryLockVram (u16 bank, u16 lockId) +{ + u32 workMap; + s32 zeroBits; + OSIntrMode enabled = OS_DisableInterrupts(); + + workMap = (u32)(bank & OSi_vramExclusive); + while (TRUE) { + zeroBits = (s32)(31 - OsCountZeroBits(workMap)); + if (zeroBits < 0) { + break; + } + workMap &= ~(0x00000001 << zeroBits); + if (OSi_vramLockId[zeroBits] != lockId) { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } + } + + workMap = (u32)(bank & OS_VRAM_BANK_ID_ALL); + while (TRUE) { + zeroBits = (s32)(31 - OsCountZeroBits(workMap)); + if (zeroBits < 0) { + break; + } + workMap &= ~(0x00000001 << zeroBits); + OSi_vramLockId[zeroBits] = lockId; + OSi_vramExclusive |= (0x00000001 << zeroBits); + } + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +void OSi_UnlockVram (u16 bank, u16 lockId) +{ + u32 workMap; + s32 zeroBits; + OSIntrMode enabled = OS_DisableInterrupts(); + + workMap = (u32)(bank & OSi_vramExclusive & OS_VRAM_BANK_ID_ALL); + while (TRUE) { + zeroBits = (s32)(31 - OsCountZeroBits((u32)workMap)); + if (zeroBits < 0) { + break; + } + workMap &= ~(0x00000001 << zeroBits); + if (OSi_vramLockId[zeroBits] == lockId) { + OSi_vramLockId[zeroBits] = 0; + OSi_vramExclusive &= ~(0x00000001 << zeroBits); + } + } + + (void)OS_RestoreInterrupts(enabled); +} \ No newline at end of file