Files
pokediamond/arm7/lib/src/OS_spinLock.c
T
2020-06-14 17:34:02 +01:00

193 lines
3.9 KiB
C

#include "function_target.h"
#include "OS_spinLock.h"
#include "OS_system.h"
#include "MI_swap.h"
ARM_FUNC void OS_InitLock(void)
{
static BOOL isInitialized = FALSE;
if (isInitialized)
return;
isInitialized = TRUE;
OSLockWord *lockp = (OSLockWord *)HW_INIT_LOCK_BUF;
lockp->extension = 0;
while (lockp->ownerID != 0x7f)
{
OSi_WaitByLoop();
}
((u32 *)HW_LOCK_ID_FLAG_SUB)[0] = 0xffffffff;
((u32 *)HW_LOCK_ID_FLAG_SUB)[1] = 0xffff0000;
lockp->extension = 0xbf;
}
ARM_FUNC void FUN_037F8CB4(s32 ct)
{
SVC_WaitByLoop((u32)ct); //todo this should be linker generated, figure out why it broke
}
ARM_FUNC s32 OSi_DoLockByWord(u16 lockId, OSLockWord *lockp, void (*ctrlFuncp) (void),
BOOL disableFiq)
{
s32 lastLockFlag;
while ((lastLockFlag = OSi_DoTryLockByWord(lockId, lockp, ctrlFuncp, disableFiq)) > 0) {
OSi_WaitByLoop();
}
return lastLockFlag;
}
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 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, (u32 *)&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)
{
//noop
}
ARM_FUNC void OSi_FreeCartridgeBus(void)
{
//noop
}
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_SUB
ldr r1, [r3]
mov r2, #0
mov r0, #0x80000000
_037F8A34:
tst r1, r0
bne _037F8A50
add r2, r2, #1
cmp r2, #32
beq _037F8A50
mov r0, r0, lsr #1
b _037F8A34
_037F8A50:
cmp r2, #32
movne r0, #0x80
bne _037F8A98
add r3, r3, #4
ldr r1, [r3]
mov r2, #0
mov r0, #0x80000000
_037F8A6C:
tst r1, r0
bne _037F8A88
add r2, r2, #1
cmp r2, #32
beq _037F8A88
mov r0, r0, lsr #1
b _037F8A6C
_037F8A88:
cmp r2, #32
ldr r0, =0xFFFFFFFD
bxeq lr
mov r0, #160
_037F8A98:
add r0, r0, r2
mov r1, #0x80000000
mov r1, r1, lsr r2
ldr r2, [r3]
bic r2, r2, r1
str r2, [r3]
bx lr
}
ARM_FUNC asm void OS_ReleaseLockID(register u16 lockID)
{
ldr r3, =HW_LOCK_ID_FLAG_SUB
cmp r0, #0xa0
addpl r3, r3, #0x4
subpl r0, r0, #0xa0
submi r0, r0, #0x80
mov r1, #0x80000000
mov r1, r1, lsr r0
ldr r2, [r3, #0x0]
orr r2, r2, r1
str r2, [r3, #0x0]
bx lr
}