summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm9/asm/CARD_common.s328
-rw-r--r--arm9/asm/CARD_rom.s5
-rw-r--r--arm9/lib/include/CARD_common.h173
-rw-r--r--arm9/lib/include/CARD_rom.h3
-rw-r--r--arm9/lib/include/MI_memory.h5
-rw-r--r--arm9/lib/include/OS_spinLock.h2
-rw-r--r--arm9/lib/include/mmap.h1
-rw-r--r--arm9/lib/src/CARD_common.c184
-rw-r--r--arm9/lib/src/OS_reset.c2
-rw-r--r--include-mw/function_target.h2
10 files changed, 346 insertions, 359 deletions
diff --git a/arm9/asm/CARD_common.s b/arm9/asm/CARD_common.s
deleted file mode 100644
index 42bce178..00000000
--- a/arm9/asm/CARD_common.s
+++ /dev/null
@@ -1,328 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .section .bss
-
- .global UNK_021D555C
-UNK_021D555C: ; 0x021D555C
- .space 0x4
-
- .global UNK_021D5560
-UNK_021D5560: ; 0x021D5560
- .space 0x60
-
- .global cardi_common
-cardi_common: ; 0x021D55C0
- .space 0x620
-
- .global UNK_021D5BE0
-UNK_021D5BE0: ; 0x021D5BE0
- .space 0x20
-
- .text
-
- arm_func_start CARD_UnlockBackup
-CARD_UnlockBackup: ; 0x020D66A0
- ldr ip, _020D66AC ; =CARDi_UnlockResource
- mov r1, #0x2
- bx r12
- .balign 4
-_020D66AC: .word CARDi_UnlockResource
-
- arm_func_start CARD_LockBackup
-CARD_LockBackup: ; 0x020D66B0
- ldr ip, _020D66BC ; =CARDi_LockResource
- mov r1, #0x2
- bx r12
- .balign 4
-_020D66BC: .word CARDi_LockResource
-
- arm_func_start CARD_UnlockRom
-CARD_UnlockRom: ; 0x020D66C0
- stmdb sp!, {r4,lr}
- mov r4, r0
- bl OS_UnlockCard
- mov r0, r4
- mov r1, #0x1
- bl CARDi_UnlockResource
- ldmia sp!, {r4,lr}
- bx lr
-
- arm_func_start CARD_LockRom
-CARD_LockRom: ; 0x020D66E0
- stmdb sp!, {r4,lr}
- mov r4, r0
- mov r1, #0x1
- bl CARDi_LockResource
- mov r0, r4
- bl OS_TryLockCard
- ldmia sp!, {r4,lr}
- bx lr
-
- arm_func_start CARD_GetResultCode
-CARD_GetResultCode: ; 0x020D6700
- ldr r0, _020D6710 ; =cardi_common
- ldr r0, [r0, #0x0]
- ldr r0, [r0, #0x0]
- bx lr
- .balign 4
-_020D6710: .word cardi_common
-
- arm_func_start CARDi_TryWaitAsync
-CARDi_TryWaitAsync: ; 0x020D6714
- ldr r0, _020D672C ; =cardi_common
- ldr r0, [r0, #0x114]
- ands r0, r0, #0x4
- moveq r0, #0x1
- movne r0, #0x0
- bx lr
- .balign 4
-_020D672C: .word cardi_common
-
- arm_func_start CARDi_WaitAsync
-CARDi_WaitAsync: ; 0x020D6730
- stmdb sp!, {r4-r6,lr}
- ldr r6, _020D6788 ; =cardi_common
- bl OS_DisableInterrupts
- ldr r1, [r6, #0x114]
- mov r5, r0
- ands r0, r1, #0x4
- beq _020D6764
- add r4, r6, #0x10c
-_020D6750:
- mov r0, r4
- bl OS_SleepThread
- ldr r0, [r6, #0x114]
- ands r0, r0, #0x4
- bne _020D6750
-_020D6764:
- mov r0, r5
- bl OS_RestoreInterrupts
-_020D676C: ; 0x020D676C
- ldr r0, [r6, #0x0]
- ldr r0, [r0, #0x0]
- cmp r0, #0x0
- moveq r0, #0x1
- movne r0, #0x0
- ldmia sp!, {r4-r6,lr}
- bx lr
- .balign 4
-_020D6788: .word cardi_common
-
- arm_func_start CARD_Enable
-CARD_Enable: ; 0x020D678C
- ldr r1, _020D6798 ; =UNK_021D555C
- str r0, [r1, #0x0]
- bx lr
- .balign 4
-_020D6798: .word UNK_021D555C
-
- arm_func_start CARD_CheckEnabled
-CARD_CheckEnabled: ; 0x020D679C
- stmdb sp!, {lr}
- sub sp, sp, #0x4
- bl CARD_IsEnabled
-_020D67A8: ; 0x020D67A8
- cmp r0, #0x0
- addne sp, sp, #0x4
- ldmneia sp!, {lr}
- bxne lr
- bl OS_Terminate
- add sp, sp, #0x4
- ldmia sp!, {lr}
- bx lr
-
- arm_func_start CARD_IsEnabled
-CARD_IsEnabled:
- ldr r0, _020D67D4 ; =UNK_021D555C
- ldr r0, [r0, #0x0]
- bx lr
- .balign 4
-_020D67D4: .word UNK_021D555C
-
- arm_func_start CARDi_InitCommon
-CARDi_InitCommon: ; 0x020D67D8
- stmdb sp!, {r4,lr}
- sub sp, sp, #0x8
- ldr r4, _020D68B8 ; =cardi_common
- ldr r1, _020D68BC ; =UNK_021D5560
- mvn r2, #0x2
- mov r0, #0x0
- str r2, [r4, #0x8]
- mov r2, #0x60
- str r0, [r4, #0xc]
- str r0, [r4, #0x18]
- str r1, [r4, #0x0]
- bl MIi_CpuClearFast
- ldr r0, _020D68BC ; =UNK_021D5560
- mov r1, #0x60
- bl DC_FlushRange
- ldr r0, _020D68C0 ; =0x027FFC40
- ldrh r0, [r0, #0x0]
- cmp r0, #0x2
- beq _020D6834
- ldr r0, _020D68C4 ; =0x027FFE00
- ldr r1, _020D68C8 ; =0x027FFA80
- mov r2, #0x160
- bl MI_CpuCopy8
-_020D6834:
- mov r2, #0x0
- str r2, [r4, #0x14]
- ldr r0, [r4, #0x14]
- mov r1, #0x4
- str r0, [r4, #0x10]
- str r2, [r4, #0x110]
- ldr r3, [r4, #0x110]
- mov r0, #0x400
- str r3, [r4, #0x10c]
- str r1, [r4, #0x108]
- str r0, [sp, #0x0]
- ldr r12, [r4, #0x108]
- ldr r1, _020D68CC ; =CARDi_TaskThread
- ldr r3, _020D68D0 ; =UNK_021D5BE0
- add r0, r4, #0x44
- str r12, [sp, #0x4]
- bl OS_CreateThread
- add r0, r4, #0x44
- bl OS_WakeupThreadDirect
- ldr r1, _020D68D4 ; =CARDi_OnFifoRecv
- mov r0, #0xb
- bl PXI_SetFifoRecvCallback
- ldr r0, _020D68C0 ; =0x027FFC40
- ldrh r0, [r0, #0x0]
- cmp r0, #0x2
- addeq sp, sp, #0x8
- ldmeqia sp!, {r4,lr}
- bxeq lr
- mov r0, #0x1
- bl CARD_Enable
- add sp, sp, #0x8
- ldmia sp!, {r4,lr}
- bx lr
- .balign 4
-_020D68B8: .word cardi_common
-_020D68BC: .word UNK_021D5560
-_020D68C0: .word 0x027FFC40
-_020D68C4: .word 0x027FFE00
-_020D68C8: .word 0x027FFA80
-_020D68CC: .word CARDi_TaskThread
-_020D68D0: .word UNK_021D5BE0
-_020D68D4: .word CARDi_OnFifoRecv
-
- arm_func_start CARDi_UnlockResource
-CARDi_UnlockResource: ; 0x020D68D8
- stmdb sp!, {r4-r7,lr}
- sub sp, sp, #0x4
- ldr r5, _020D6978 ; =cardi_common
- mov r7, r0
- mov r6, r1
- bl OS_DisableInterrupts
- mov r1, r5
- mov r4, r0
- ldr r0, [r1, #0x8]
- cmp r0, r7
- bne _020D6910
- ldr r0, [r5, #0xc]
- cmp r0, #0x0
- bne _020D6918
-_020D6910:
- bl OS_Terminate
- b _020D6958
-_020D6918:
- ldr r0, [r5, #0x18]
- cmp r0, r6
- beq _020D6928
- bl OS_Terminate
-_020D6928:
- ldr r0, [r5, #0xc]
- sub r0, r0, #0x1
- str r0, [r5, #0xc]
- ldr r0, [r5, #0xc]
- cmp r0, #0x0
- bne _020D6958
- mvn r0, #0x2
- str r0, [r5, #0x8]
- mov r1, #0x0
- add r0, r5, #0x10
- str r1, [r5, #0x18]
- bl OS_WakeupThread
-_020D6958:
- ldr r1, [r5, #0x0]
- mov r2, #0x0
- mov r0, r4
- str r2, [r1, #0x0]
- bl OS_RestoreInterrupts
- add sp, sp, #0x4
- ldmia sp!, {r4-r7,lr}
- bx lr
- .balign 4
-_020D6978: .word cardi_common
-
- arm_func_start CARDi_LockResource
-CARDi_LockResource: ; 0x020D697C
- stmdb sp!, {r4-r9,lr}
- sub sp, sp, #0x4
- ldr r5, _020D6A14 ; =cardi_common
- mov r7, r0
- mov r6, r1
- bl OS_DisableInterrupts
- ldr r1, [r5, #0x8]
- mov r4, r0
- cmp r1, r7
- bne _020D69B8
- ldr r0, [r5, #0x18]
- cmp r0, r6
- beq _020D69E8
- bl OS_Terminate
- b _020D69E8
-_020D69B8:
- ldr r0, [r5, #0x8]
- mvn r8, #0x2
- cmp r0, r8
- beq _020D69E0
- add r9, r5, #0x10
-_020D69CC:
- mov r0, r9
- bl OS_SleepThread
- ldr r0, [r5, #0x8]
- cmp r0, r8
- bne _020D69CC
-_020D69E0:
- str r7, [r5, #0x8]
- str r6, [r5, #0x18]
-_020D69E8:
- ldr r1, [r5, #0xc]
- mov r0, r4
- add r1, r1, #0x1
- str r1, [r5, #0xc]
- ldr r1, [r5, #0x0]
- mov r2, #0x0
- str r2, [r1, #0x0]
- bl OS_RestoreInterrupts
- add sp, sp, #0x4
- ldmia sp!, {r4-r9,lr}
- bx lr
- .balign 4
-_020D6A14: .word cardi_common
-
- arm_func_start CARDi_SetTask
-CARDi_SetTask: ; 0x020D6A18
- stmdb sp!, {r4-r5,lr}
- sub sp, sp, #0x4
- ldr r4, _020D6A5C ; =cardi_common
- mov r5, r0
- ldr r1, [r4, #0x108]
- add r0, r4, #0x44
- bl OS_SetThreadPriority
- add r0, r4, #0x44
- str r0, [r4, #0x104]
- str r5, [r4, #0x40]
- ldr r1, [r4, #0x114]
- orr r1, r1, #0x8
- str r1, [r4, #0x114]
- bl OS_WakeupThreadDirect
- add sp, sp, #0x4
- ldmia sp!, {r4-r5,lr}
- bx lr
- .balign 4
-_020D6A5C: .word cardi_common
diff --git a/arm9/asm/CARD_rom.s b/arm9/asm/CARD_rom.s
index 53163039..77fe7534 100644
--- a/arm9/asm/CARD_rom.s
+++ b/arm9/asm/CARD_rom.s
@@ -2,7 +2,6 @@
.include "global.inc"
.extern OSi_ThreadInfo
- .extern UNK_021D5BE0
.extern cardi_common
.section .data
@@ -13,6 +12,10 @@ UNK_02106A50: ; 0x02106A50
.section .bss
+ .global UNK_021D5BE0
+UNK_021D5BE0: ; 0x021D5BE0
+ .space 0x20
+
.global UNK_021D5C00
UNK_021D5C00: ; 0x021D5C00
.space 0x220
diff --git a/arm9/lib/include/CARD_common.h b/arm9/lib/include/CARD_common.h
index 9cedac4f..051923ce 100644
--- a/arm9/lib/include/CARD_common.h
+++ b/arm9/lib/include/CARD_common.h
@@ -1,5 +1,34 @@
-#ifndef NITRO_CARD_COMMON_H_
-#define NITRO_CARD_COMMON_H_
+#ifndef POKEDIAMOND_CARD_COMMON_H
+#define POKEDIAMOND_CARD_COMMON_H
+
+#include "nitro/types.h"
+#include "OS_thread.h"
+#include "MI_dma.h"
+
+#define CARD_THREAD_PRIORITY_DEFAULT 4
+
+#define CARD_BACKUP_TYPE_DEVICE_SHIFT 0
+#define CARD_BACKUP_TYPE_DEVICE_EEPROM 1
+#define CARD_BACKUP_TYPE_DEVICE_FLASH 2
+#define CARD_BACKUP_TYPE_DEVICE_FRAM 3
+#define CARD_BACKUP_TYPE_SIZEBIT_SHIFT 8
+#define CARD_BACKUP_TYPE_VENDER_SHIFT 16
+#define CARD_BACKUP_TYPE_DEFINE(type, size, vender) \
+ (((CARD_BACKUP_TYPE_DEVICE_ ## type) << CARD_BACKUP_TYPE_DEVICE_SHIFT) | \
+ ((size) << CARD_BACKUP_TYPE_SIZEBIT_SHIFT) | \
+ ((vender) << CARD_BACKUP_TYPE_VENDER_SHIFT))
+
+typedef enum
+{
+ CARD_BACKUP_TYPE_EEPROM_4KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 9, 0),
+ CARD_BACKUP_TYPE_EEPROM_64KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 13, 0),
+ CARD_BACKUP_TYPE_EEPROM_512KBITS = CARD_BACKUP_TYPE_DEFINE(EEPROM, 16, 0),
+ CARD_BACKUP_TYPE_FLASH_2MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 18, 0),
+ CARD_BACKUP_TYPE_FLASH_4MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 19, 0),
+ CARD_BACKUP_TYPE_FLASH_8MBITS = CARD_BACKUP_TYPE_DEFINE(FLASH, 20, 0),
+ CARD_BACKUP_TYPE_FRAM_256KBITS = CARD_BACKUP_TYPE_DEFINE(FRAM, 15, 0),
+ CARD_BACKUP_TYPE_NOT_USE = 0
+} CARDBackupType;
typedef enum
{
@@ -11,41 +40,133 @@ typedef enum
CARD_RESULT_ERROR,
CARD_RESULT_NO_RESPONSE,
CARD_RESULT_CANCELED
-}
-CARDResult;
+} CARDResult;
typedef enum
{
- CARD_REQ_INIT = 0, /* initialize (setting from ARM9)*/
- CARD_REQ_ACK, /* request done (acknowledge from ARM7)*/
- CARD_REQ_IDENTIFY, /* CARD_IdentifyBackup*/
- CARD_REQ_READ_ID, /* CARD_ReadRomID (TEG && ARM9)*/
- CARD_REQ_READ_ROM, /* CARD_ReadRom (TEG && ARM9)*/
- CARD_REQ_WRITE_ROM, /* (reserved)*/
- CARD_REQ_READ_BACKUP, /* CARD_ReadBackup*/
- CARD_REQ_WRITE_BACKUP, /* CARD_WriteBackup*/
- CARD_REQ_PROGRAM_BACKUP, /* CARD_ProgramBackup*/
- CARD_REQ_VERIFY_BACKUP, /* CARD_VerifyBackup*/
- CARD_REQ_ERASE_PAGE_BACKUP, /* CARD_EraseBackupPage*/
- CARD_REQ_ERASE_SECTOR_BACKUP, /* CARD_EraseBackupSector*/
- CARD_REQ_ERASE_CHIP_BACKUP, /* CARD_EraseBackupChip*/
+ CARD_TARGET_NONE,
+ CARD_TARGET_ROM,
+ CARD_TARGET_BACKUP
+} CARDTargetMode;
+
+typedef enum
+{
+ CARD_REQ_INIT = 0,
+ CARD_REQ_ACK,
+ CARD_REQ_IDENTIFY,
+ CARD_REQ_READ_ID,
+ CARD_REQ_READ_ROM,
+ CARD_REQ_WRITE_ROM,
+ CARD_REQ_READ_BACKUP,
+ CARD_REQ_WRITE_BACKUP,
+ CARD_REQ_PROGRAM_BACKUP,
+ CARD_REQ_VERIFY_BACKUP,
+ CARD_REQ_ERASE_PAGE_BACKUP,
+ CARD_REQ_ERASE_SECTOR_BACKUP,
+ CARD_REQ_ERASE_CHIP_BACKUP,
CARD_REQ_MAX
-}
-CARDRequest;
+} CARDRequest;
typedef enum
{
- CARD_REQUEST_MODE_RECV, /* Data reception*/
- CARD_REQUEST_MODE_SEND, /* Send data (Including single verify)*/
- CARD_REQUEST_MODE_SEND_VERIFY, /* Send data + verify*/
- CARD_REQUEST_MODE_SPECIAL /* special operations like sector deletion*/
-}
-CARDRequestMode;
+ CARD_REQUEST_MODE_RECV,
+ CARD_REQUEST_MODE_SEND,
+ CARD_REQUEST_MODE_SEND_VERIFY,
+ CARD_REQUEST_MODE_SPECIAL
+} CARDRequestMode;
+
+enum
+{
+ CARD_STAT_INIT = (1 << 0),
+ CARD_STAT_INIT_CMD = (1 << 1),
+ CARD_STAT_BUSY = (1 << 2),
+ CARD_STAT_TASK = (1 << 3),
+ CARD_STAT_RECV = (1 << 4),
+ CARD_STAT_REQ = (1 << 5),
+ CARD_STAT_CANCEL = (1 << 6)
+};
+
+typedef s32 CARDiOwner;
+
+typedef struct CARDiCommandArg
+{
+ CARDResult result;
+ CARDBackupType type;
+ u32 id;
+ u32 src;
+ u32 dest;
+ u32 len;
+
+ struct
+ {
+ u32 total_size;
+ u32 sect_size;
+ u32 page_size;
+ u32 addr_width;
+ u32 program_page;
+ u32 write_page;
+ u32 write_page_total;
+ u32 erase_chip;
+ u32 erase_chip_total;
+ u32 erase_sector;
+ u32 erase_sector_total;
+ u32 erase_page;
+ u8 initial_status;
+ u8 padding1[3];
+ u32 caps;
+ u8 padding2[16];
+ } spec;
+} CARDiCommandArg;
+
+typedef struct CARDiCommon
+{
+ CARDiCommandArg *cmd;
+ s32 command;
+
+ volatile CARDiOwner lock_owner;
+ volatile s32 lock_ref;
+ OSThreadQueue lock_queue[1];
+ CARDTargetMode lock_target;
+
+ u32 src;
+ u32 dst;
+ u32 len;
+ u32 dma;
+ CARDRequest req_type;
+ s32 req_retry;
+ CARDRequestMode req_mode;
+ MIDmaCallback callback;
+ void *callback_arg;
+ void (*task_func) (struct CARDiCommon *);
+
+ OSThread thread[1];
+ OSThread *cur_th;
+
+ u32 priority;
+ OSThreadQueue busy_q[1];
+
+ volatile u32 flag;
+
+ u8 dummy[8];
+
+ u8 backup_cache_page_buf[256] ALIGN(32);
+} CARDiCommon;
+void CARDi_SetTask(void (*task) (CARDiCommon *));
+void CARDi_InitCommon(void);
+BOOL CARD_IsEnabled(void);
+void CARD_CheckEnabled(void);
+void CARD_Enable(BOOL enable);
+BOOL CARDi_WaitAsync(void);
+BOOL CARDi_TryWaitAsync(void);
CARDResult CARD_GetResultCode(void);
+void CARD_LockRom(u16 lock_id);
+void CARD_UnlockRom(u16 lock_id);
+void CARD_LockBackup(u16 lock_id);
+void CARD_UnlockBackup(u16 lock_id);
#define CARD_RETRY_COUNT_MAX 10
void CARD_Init(void);
-#endif //NITRO_CARD_COMMON_H_
+#endif //POKEDIAMOND_CARD_COMMON_H
diff --git a/arm9/lib/include/CARD_rom.h b/arm9/lib/include/CARD_rom.h
index 3d7bbb77..b96c527b 100644
--- a/arm9/lib/include/CARD_rom.h
+++ b/arm9/lib/include/CARD_rom.h
@@ -26,9 +26,6 @@ static inline void CARD_ReadRomAsync(u32 dma, const void * src, void * dst, u32
CARDi_ReadRom(dma, src, dst, len, callback, arg, TRUE);
}
-void CARD_LockRom(u16 lock_id);
-void CARD_UnlockRom(u16 lock_id);
-
static inline const CARDRomRegion * CARD_GetRomRegionFNT() {
return (const CARDRomRegion *)((const u8 *)HW_ROM_HEADER_BUF + 0x40);
}
diff --git a/arm9/lib/include/MI_memory.h b/arm9/lib/include/MI_memory.h
index 01c12f86..450e5e58 100644
--- a/arm9/lib/include/MI_memory.h
+++ b/arm9/lib/include/MI_memory.h
@@ -45,4 +45,9 @@ static inline void MI_CpuCopy16(const void *src, void *dest, u32 size)
MIi_CpuCopy16(src, dest, size);
}
+static inline void MI_CpuFillFast(void *dest, u32 data, u32 size)
+{
+ MIi_CpuClearFast(data, dest, size);
+}
+
#endif //POKEDIAMOND_ARM9_MI_MEMORY_H
diff --git a/arm9/lib/include/OS_spinLock.h b/arm9/lib/include/OS_spinLock.h
index a5d27585..c26e3b9f 100644
--- a/arm9/lib/include/OS_spinLock.h
+++ b/arm9/lib/include/OS_spinLock.h
@@ -5,6 +5,8 @@
#include "nitro/OS_spinLock_shared.h"
#include "syscall.h"
+#define OS_LOCK_ID_ERROR (-3)
+
static inline void OSi_WaitByLoop(void)
{
SVC_WaitByLoop(0x1000 / 4);
diff --git a/arm9/lib/include/mmap.h b/arm9/lib/include/mmap.h
index c56b1dfe..027259ad 100644
--- a/arm9/lib/include/mmap.h
+++ b/arm9/lib/include/mmap.h
@@ -29,6 +29,7 @@ extern u32 SDK_AUTOLOAD_DTCM_START[];
#define HW_CARD_ROM_HEADER_SIZE 0x00000160
#define HW_DOWNLOAD_PARAMETER_SIZE 0x00000020
+#define HW_CARD_ROM_HEADER (HW_MAIN_MEM + 0x007ffa80)
#define HW_RESET_PARAMETER_BUF (HW_MAIN_MEM + 0x007ffc20)
#define HW_ROM_BASE_OFFSET_BUF (HW_MAIN_MEM + 0x007ffc2c)
#define HW_ROM_HEADER_BUF (HW_MAIN_MEM + 0x007ffe00) // ROM registration area data buffer
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);
diff --git a/include-mw/function_target.h b/include-mw/function_target.h
index 3834419c..84b7e1cd 100644
--- a/include-mw/function_target.h
+++ b/include-mw/function_target.h
@@ -8,4 +8,6 @@
#define ENUMS_ALWAYS_INT_OFF _Pragma("enumsalwaysint off")
#define ENUMS_ALWAYS_INT_RESET _Pragma("enumsalwaysint reset")
+#define ALIGN(num) __attribute__ ((aligned(num)))
+
#endif //GUARD_FUNCTION_TARGET_H