diff options
author | red031000 <rubenru09@aol.com> | 2020-09-16 18:18:33 +0100 |
---|---|---|
committer | red031000 <rubenru09@aol.com> | 2020-09-16 18:21:28 +0100 |
commit | 1e3c383ff53842cd2fe2134278b448fffebb15e9 (patch) | |
tree | 3a0c1dc4ce85764c1a6761d2bde821752231a889 /arm9/lib/src | |
parent | a013685f0bd75d8070971d96b79e4c146d5fbcaf (diff) |
arm9 CARD_common
Diffstat (limited to 'arm9/lib/src')
-rw-r--r-- | arm9/lib/src/CARD_common.c | 184 | ||||
-rw-r--r-- | arm9/lib/src/OS_reset.c | 2 |
2 files changed, 185 insertions, 1 deletions
diff --git a/arm9/lib/src/CARD_common.c b/arm9/lib/src/CARD_common.c new file mode 100644 index 00000000..f02d10e2 --- /dev/null +++ b/arm9/lib/src/CARD_common.c @@ -0,0 +1,184 @@ +#include "CARD_common.h" +#include "consts.h" +#include "function_target.h" +#include "MI_memory.h" +#include "OS_system.h" +#include "OS_terminate_proc.h" +#include "OS_spinLock.h" +#include "OS_cache.h" +#include "MB_mb.h" +#include "PXI_fifo.h" + +CARDiCommon cardi_common ALIGN(32); +static CARDiCommandArg cardi_arg ALIGN(32); + +u8 cardi_thread_stack[0x400] ALIGN(4); + +extern void CARDi_TaskThread(void *arg); +extern void PXI_SetFifoRecvCallback(u32 param1, void* callback); +extern void CARDi_OnFifoRecv(PXIFifoTag tag, u32 data, BOOL err); + +static void CARDi_LockResource(CARDiOwner owner, CARDTargetMode target); +static void CARDi_UnlockResource(CARDiOwner owner, CARDTargetMode target); + +ARM_FUNC void CARDi_SetTask(void (*task) (CARDiCommon *)) +{ + CARDiCommon *const p = &cardi_common; + + (void)OS_SetThreadPriority(p->thread, p->priority); + + p->cur_th = p->thread; + p->task_func = task; + p->flag |= CARD_STAT_TASK; + OS_WakeupThreadDirect(p->thread); +} + +ARM_FUNC static void CARDi_LockResource(CARDiOwner owner, CARDTargetMode target) +{ + CARDiCommon *const p = &cardi_common; + OSIntrMode bak_psr = OS_DisableInterrupts(); + if (p->lock_owner == owner) + { + if (p->lock_target != target) + { + OS_Terminate(); + } + } + else + { + while (p->lock_owner != OS_LOCK_ID_ERROR) + { + OS_SleepThread(p->lock_queue); + } + p->lock_owner = owner; + p->lock_target = target; + } + ++p->lock_ref; + p->cmd->result = CARD_RESULT_SUCCESS; + (void)OS_RestoreInterrupts(bak_psr); +} + +ARM_FUNC static void CARDi_UnlockResource(CARDiOwner owner, CARDTargetMode target) +{ + CARDiCommon *p = &cardi_common; + OSIntrMode bak_psr = OS_DisableInterrupts(); + if ((p->lock_owner != owner) || !p->lock_ref) + { + OS_Terminate(); + } + else + { + if (p->lock_target != target) + { + OS_Terminate(); + } + if (!--p->lock_ref) + { + p->lock_owner = OS_LOCK_ID_ERROR; + p->lock_target = CARD_TARGET_NONE; + OS_WakeupThread(p->lock_queue); + } + } + p->cmd->result = CARD_RESULT_SUCCESS; + (void)OS_RestoreInterrupts(bak_psr); +} + +ARM_FUNC void CARDi_InitCommon(void) +{ + CARDiCommon *p = &cardi_common; + + p->lock_owner = OS_LOCK_ID_ERROR; + p->lock_ref = 0; + p->lock_target = CARD_TARGET_NONE; + + p->cmd = &cardi_arg; + MI_CpuFillFast(&cardi_arg, 0x00, sizeof(cardi_arg)); + DC_FlushRange(&cardi_arg, sizeof(cardi_arg)); + + if (!MB_IsMultiBootChild()) + { + MI_CpuCopy8((const void *)HW_ROM_HEADER_BUF, (void *)HW_CARD_ROM_HEADER, HW_CARD_ROM_HEADER_SIZE); + } + OS_InitThreadQueue(p->lock_queue); + OS_InitThreadQueue(p->busy_q); + p->priority = CARD_THREAD_PRIORITY_DEFAULT; + OS_CreateThread(p->thread, CARDi_TaskThread, NULL, cardi_thread_stack + sizeof(cardi_thread_stack), + sizeof(cardi_thread_stack), p->priority); + OS_WakeupThreadDirect(p->thread); + + PXI_SetFifoRecvCallback(PXI_FIFO_TAG_FS, CARDi_OnFifoRecv); + + if (!MB_IsMultiBootChild()) + { + CARD_Enable(TRUE); + } +} + +static BOOL CARDi_EnableFlag = FALSE; + +ARM_FUNC BOOL CARD_IsEnabled(void) +{ + return CARDi_EnableFlag; +} + +ARM_FUNC void CARD_CheckEnabled(void) +{ + if (!CARD_IsEnabled()) + { + OS_Terminate(); + } +} + +ARM_FUNC void CARD_Enable(BOOL enable) +{ + CARDi_EnableFlag = enable; +} + +ARM_FUNC BOOL CARDi_WaitAsync(void) +{ + CARDiCommon *const p = &cardi_common; + + OSIntrMode bak_psr = OS_DisableInterrupts(); + while ((p->flag & CARD_STAT_BUSY) != 0) + { + OS_SleepThread(p->busy_q); + } + (void)OS_RestoreInterrupts(bak_psr); + return (p->cmd->result == CARD_RESULT_SUCCESS); +} + +ARM_FUNC BOOL CARDi_TryWaitAsync(void) +{ + CARDiCommon *const p = &cardi_common; + + return !(p->flag & CARD_STAT_BUSY); +} + +ARM_FUNC CARDResult CARD_GetResultCode(void) +{ + CARDiCommon *const p = &cardi_common; + + return p->cmd->result; +} + +ARM_FUNC void CARD_LockRom(u16 lock_id) +{ + CARDi_LockResource(lock_id, CARD_TARGET_ROM); + (void)OS_TryLockCard(lock_id); +} + +ARM_FUNC void CARD_UnlockRom(u16 lock_id) +{ + (void)OS_UnlockCard(lock_id); + CARDi_UnlockResource(lock_id, CARD_TARGET_ROM); +} + +ARM_FUNC void CARD_LockBackup(u16 lock_id) +{ + CARDi_LockResource(lock_id, CARD_TARGET_BACKUP); +} + +ARM_FUNC void CARD_UnlockBackup(u16 lock_id) +{ + CARDi_UnlockResource(lock_id, CARD_TARGET_BACKUP); +} diff --git a/arm9/lib/src/OS_reset.c b/arm9/lib/src/OS_reset.c index 03781947..2e333bb8 100644 --- a/arm9/lib/src/OS_reset.c +++ b/arm9/lib/src/OS_reset.c @@ -8,6 +8,7 @@ #include "OS_cache.h" #include "sections.h" #include "MI_dma.h" +#include "CARD_common.h" static u16 OSi_IsInitReset = 0; vu16 OSi_IsResetOccurred = 0; @@ -16,7 +17,6 @@ extern void PXI_Init(void); extern u32 PXI_IsCallbackReady(u32 param1, u32 param2); extern void PXI_SetFifoRecvCallback(u32 param1, void* callback); extern u32 PXI_SendWordByFifo(u32 param1, u32 data, u32 param2); -extern void CARD_LockRom(u16 lockId); static void OSi_CommonCallback(PXIFifoTag tag, u32 data, BOOL err); static void OSi_SendToPxi(u16 data); |