diff options
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/MI_exMemory.h | 14 | ||||
-rw-r--r-- | arm9/lib/include/OS_init.h | 1 | ||||
-rw-r--r-- | arm9/lib/include/OS_spinLock.h | 29 | ||||
-rw-r--r-- | arm9/lib/include/mmap.h | 5 | ||||
-rw-r--r-- | arm9/lib/src/OS_init.c | 1 | ||||
-rw-r--r-- | arm9/lib/src/OS_spinLock.c | 217 |
6 files changed, 266 insertions, 1 deletions
diff --git a/arm9/lib/include/MI_exMemory.h b/arm9/lib/include/MI_exMemory.h index 4a8a10a8..8bd355ac 100644 --- a/arm9/lib/include/MI_exMemory.h +++ b/arm9/lib/include/MI_exMemory.h @@ -1,9 +1,23 @@ #ifndef NITRO_MI_EXMEMORY_H_ #define NITRO_MI_EXMEMORY_H_ +#include "consts.h" + typedef enum { MI_PROCESSOR_ARM9 = 0, MI_PROCESSOR_ARM7 = 1 } MIProcessor; +static inline void MIi_SetCardProcessor(MIProcessor proc) +{ + reg_MI_EXMEMCNT = + (u16)((reg_MI_EXMEMCNT & ~0x0800) | (proc << 11)); +} + +static inline void MIi_SetCartridgeProcessor(MIProcessor proc) +{ + reg_MI_EXMEMCNT = + (u16)((reg_MI_EXMEMCNT & ~0x0080) | (proc << 7)); +} + #endif //NITRO_MI_EXMEMORY_H_ diff --git a/arm9/lib/include/OS_init.h b/arm9/lib/include/OS_init.h index a998b45e..69d21213 100644 --- a/arm9/lib/include/OS_init.h +++ b/arm9/lib/include/OS_init.h @@ -23,6 +23,7 @@ #include "OS_terminate_proc.h" #include "OS_interrupt.h" #include "OS_reset.h" +#include "OS_spinLock.h" void OS_Init(); diff --git a/arm9/lib/include/OS_spinLock.h b/arm9/lib/include/OS_spinLock.h index 3bb8a1c2..eccc502b 100644 --- a/arm9/lib/include/OS_spinLock.h +++ b/arm9/lib/include/OS_spinLock.h @@ -5,12 +5,41 @@ #ifndef POKEDIAMOND_OS_SPINLOCK_H #define POKEDIAMOND_OS_SPINLOCK_H +#include "types.h" +#include "syscall.h" + typedef volatile struct OSLockWord { u32 lockFlag; u16 ownerID; u16 extension; } OSLockWord; +static inline void OSi_WaitByLoop(void) +{ + SVC_WaitByLoop(0x1000 / 4); +} + +void OS_InitLock(void); +s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFiq); +s32 OS_TryLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ); +s32 OS_UnlockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void)); +s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFiq); +s32 OS_LockCartridge(u16 lockID); +s32 OS_UnlockCartridge(u16 lockID); +s32 OS_TryLockCartridge(u16 lockID); +void OSi_AllocateCartridgeBus(void); +void OSi_FreeCartridgeBus(void); +s32 OS_TryLockCard(u16 lockID); +s32 OS_UnlockCard(u16 lockID); +void OSi_AllocateCardBus(void); +void OSi_FreeCardBus(void); +u16 OS_ReadOwnerOfLockWord(OSLockWord * lock); +s32 OS_UnLockCartridge(u16 lockID); s32 OS_GetLockID(void); +void OS_ReleaseLockID(register u16 lockID); #endif //POKEDIAMOND_OS_SPINLOCK_H diff --git a/arm9/lib/include/mmap.h b/arm9/lib/include/mmap.h index 27255115..207e0509 100644 --- a/arm9/lib/include/mmap.h +++ b/arm9/lib/include/mmap.h @@ -39,6 +39,11 @@ extern u32 SDK_AUTOLOAD_DTCM_START[]; #define HW_DTCM_SVC_STACK (HW_DTCM_SVC_STACK_END - HW_SVC_STACK_SIZE) #define HW_DTCM_IRQ_STACK_END (HW_DTCM_SVC_STACK) +#define HW_LOCK_ID_FLAG_MAIN (HW_MAIN_MEM + 0x007fffb0) +#define HW_SHARED_LOCK_BUF (HW_MAIN_MEM + 0x007fffc0) +#define HW_CARD_LOCK_BUF (HW_MAIN_MEM + 0x007fffe0) +#define HW_CTRDG_LOCK_BUF (HW_MAIN_MEM + 0x007fffe8) + #define HW_BUTTON_XY_BUF (HW_MAIN_MEM + 0x007fffa8) #define OSi_MAIN_ARENA_HI_DEFAULT (HW_MAIN_MEM_MAIN_END) diff --git a/arm9/lib/src/OS_init.c b/arm9/lib/src/OS_init.c index a1db8788..a34196f4 100644 --- a/arm9/lib/src/OS_init.c +++ b/arm9/lib/src/OS_init.c @@ -6,7 +6,6 @@ #include "OS_init.h" extern void PXI_Init(); -extern void OS_InitLock(); extern void OS_InitException(); extern void MI_Init(); extern void OS_InitVAlarm(); diff --git a/arm9/lib/src/OS_spinLock.c b/arm9/lib/src/OS_spinLock.c new file mode 100644 index 00000000..5050a7bd --- /dev/null +++ b/arm9/lib/src/OS_spinLock.c @@ -0,0 +1,217 @@ +// +// Created by red031000 on 2020-05-21. +// + +#include "OS_spinLock.h" +#include "OS_system.h" +#include "function_target.h" +#include "consts.h" +#include "MI_exMemory.h" + +extern void MIi_CpuClear32(u32 param1, void * addr, u32 length); //not too sure about names +extern u32 MI_SwapWord(u32 data, volatile u32* destp); + +ARM_FUNC void OS_InitLock(void) +{ + static BOOL isInitialized = FALSE; + + if (isInitialized) + { + return; + } + isInitialized = TRUE; + + OSLockWord* lockp = (OSLockWord *)0x027FFFF0; + + lockp->lockFlag = 0; + + (void)OS_TryLockByWord(0x7e, lockp, NULL); + + while (lockp->extension) + { + OSi_WaitByLoop(); + } + + ((u32 *)HW_LOCK_ID_FLAG_MAIN)[0] = 0xffffffff; + ((u32 *)HW_LOCK_ID_FLAG_MAIN)[1] = 0xffff0000; + + MIi_CpuClear32(0x0, (void *)HW_SHARED_LOCK_BUF, 0x28); + + MIi_SetCardProcessor(MI_PROCESSOR_ARM7); + + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7); + + (void)OS_UnlockByWord(0x7e, lockp, NULL); + (void)OS_TryLockByWord(0x7f, lockp, NULL); +} + +ARM_FUNC s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void), //should be static + BOOL disableFiq) +{ + s32 lastLockFlag; + while ((lastLockFlag = OSi_DoTryLockByWord(lockId, lockp, ctrlFuncp, disableFiq)) > 0) { + OSi_WaitByLoop(); + } + + return lastLockFlag; +} + +ARM_FUNC s32 OS_TryLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void)) +{ + return OSi_DoLockByWord(lockId, lockp, ctrlFuncp, FALSE); +} + +ARM_FUNC s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFIQ) +{ + if (lockID != lockp->ownerID) + { + return -2; + } + + OSIntrMode lastIntrMode = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts(); + lockp->ownerID = 0; + if (ctrlFuncp) + { + ctrlFuncp(); + } + lockp->lockFlag = 0; + if (disableFIQ) + { + (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode); + } + else + { + (void)OS_RestoreInterrupts(lastIntrMode); + } + return 0; +} + +ARM_FUNC s32 OS_UnlockByWord(u16 lockID, OSLockWord* lockp, void (*ctrlFuncp) (void)) +{ + return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE); +} + +ARM_FUNC s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void), + BOOL disableFiq) +{ + OSIntrMode lastIntrMode = (disableFiq) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts(); + + s32 lastLockFlag = (s32)MI_SwapWord(lockID, &lockp->lockFlag); + + if (!lastLockFlag) + { + if (ctrlFuncp) + { + ctrlFuncp(); + } + lockp->ownerID = lockID; + } + + if (disableFiq) + { + (void)OS_RestoreInterrupts_IrqAndFiq(lastIntrMode); + } + else + { + (void)OS_RestoreInterrupts(lastIntrMode); + } + + return lastLockFlag; +} + +ARM_FUNC s32 OS_LockCartridge(u16 lockID) +{ + return OSi_DoLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE); +} + +ARM_FUNC s32 OS_UnlockCartridge(u16 lockID) +{ + return OSi_DoUnlockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_FreeCartridgeBus, TRUE); +} + +ARM_FUNC s32 OS_TryLockCartridge(u16 lockID) +{ + return OSi_DoTryLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE); +} + +ARM_FUNC void OSi_AllocateCartridgeBus(void) +{ + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM9); +} + +ARM_FUNC void OSi_FreeCartridgeBus(void) +{ + MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7); +} + +ARM_FUNC s32 OS_TryLockCard(u16 lockID) +{ + return OS_TryLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus); +} + +ARM_FUNC s32 OS_UnlockCard(u16 lockID) +{ + return OS_UnlockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_FreeCardBus); +} + +ARM_FUNC void OSi_AllocateCardBus(void) +{ + MIi_SetCardProcessor(MI_PROCESSOR_ARM9); +} + +ARM_FUNC void OSi_FreeCardBus(void) +{ + MIi_SetCardProcessor(MI_PROCESSOR_ARM7); +} + +ARM_FUNC u16 OS_ReadOwnerOfLockWord(OSLockWord * lock) +{ + return lock->ownerID; +} + +ARM_FUNC asm s32 OS_UnLockCartridge(u16 lockID) +{ + ldr r1, =OS_UnlockCartridge + bx r1 +} + +ARM_FUNC asm s32 OS_GetLockID(void) +{ + ldr r3, =HW_LOCK_ID_FLAG_MAIN + ldr r1, [r3, #0x0] + clz r2, r1 + cmp r2, #0x20 + movne r0, #0x40 + bne _020CA0D4 + add r3, r3, #0x4 + ldr r1, [r3, #0x0] + clz r2, r1 + cmp r2, #0x20 + ldr r0, =0xFFFFFFFD + bxeq lr + mov r0, #0x60 +_020CA0D4: + add r0, r0, r2 + mov r1, #0x80000000 + mov r1, r1, lsr r2 + ldr r2, [r3, #0x0] + bic r2, r2, r1 + str r2, [r3, #0x0] + bx lr +} + +ARM_FUNC asm void OS_ReleaseLockID(register u16 lockID) +{ + ldr r3, =HW_LOCK_ID_FLAG_MAIN + cmp r0, #0x60 + addpl r3, r3, #0x4 + subpl r0, r0, #0x60 + submi r0, r0, #0x40 + mov r1, #0x80000000 + mov r1, r1, lsr r0 + ldr r2, [r3, #0x0] + orr r2, r2, r1 + str r2, [r3, #0x0] + bx lr +} |