summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/MI_exMemory.h14
-rw-r--r--arm9/lib/include/OS_init.h1
-rw-r--r--arm9/lib/include/OS_spinLock.h29
-rw-r--r--arm9/lib/include/mmap.h5
-rw-r--r--arm9/lib/src/OS_init.c1
-rw-r--r--arm9/lib/src/OS_spinLock.c217
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
+}