mirror of
https://github.com/rvtr/twl_wrapsdk.git
synced 2025-06-18 14:25:43 -04:00
933 lines
27 KiB
C
933 lines
27 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: NitroSDK - OS -
|
||
File: os_spinLock.c
|
||
|
||
Copyright 2003-2006 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Log: os_spinLock.c,v $
|
||
Revision 1.40 2006/01/18 02:11:30 kitase_hirotake
|
||
do-indent
|
||
|
||
Revision 1.39 2005/11/21 05:42:31 yasu
|
||
OSi_WaitByLoop を inline 化
|
||
|
||
Revision 1.38 2005/11/17 10:11:36 yasu
|
||
OS_SpinWait を SVC_WaitByLoop で行なうように修正
|
||
|
||
Revision 1.37 2005/03/04 10:06:01 yasu
|
||
過剰な volatile を削除
|
||
|
||
Revision 1.36 2005/03/01 01:57:00 yosizaki
|
||
copyright の年を修正.
|
||
|
||
Revision 1.35 2005/02/28 05:26:29 yosizaki
|
||
do-indent.
|
||
|
||
Revision 1.34 2004/07/23 04:27:47 yada
|
||
OS_UnLock* restored for compatibility
|
||
|
||
Revision 1.33 2004/07/23 00:57:17 yada
|
||
rename OS_UnLock* -> OS_Unlock*
|
||
|
||
Revision 1.32 2004/07/22 08:21:17 yada
|
||
change some lockID's type u32->u16
|
||
|
||
Revision 1.31 2004/07/08 07:56:14 yosizaki
|
||
change around OS_LockCard in (TEG && ARM9)
|
||
|
||
Revision 1.30 2004/07/06 04:45:28 yosizaki
|
||
add assertion (TEG && ARM9)
|
||
|
||
Revision 1.29 2004/06/21 11:03:25 yada
|
||
fix comment. incorrect about return value.
|
||
|
||
Revision 1.28 2004/05/20 06:37:03 yasu
|
||
fix in Wait
|
||
|
||
Revision 1.27 2004/04/30 07:37:44 yada
|
||
HW_LOCKIDFLAG_MAIN/SUB -> HW_LOCK_ID_FLAG_MAIN/SUB
|
||
|
||
Revision 1.26 2004/04/30 00:18:00 yada
|
||
put HW_LOCKID_FLAG_MAIN/SUB
|
||
|
||
Revision 1.25 2004/04/20 06:56:11 yada
|
||
OS_TryLockCartridge() が、無条件に _ISDbgLib_AllocateEmualtor() を
|
||
呼んでいたのを修正。
|
||
|
||
Revision 1.24 2004/03/30 06:09:29 yada
|
||
ldconst や lda を ldr = を使用する記述にした。
|
||
|
||
Revision 1.23 2004/03/26 10:37:23 yada
|
||
OS_GetLockID(), OS_ReleaseLockID() 追加
|
||
|
||
Revision 1.22 2004/03/25 09:44:24 yada
|
||
カードのunlock, tryLock 関数の定数修正。ウェイトでARM7はSVC呼ぶように。
|
||
|
||
Revision 1.21 2004/03/25 09:22:39 yada
|
||
内部ロック関数等で引数のFIQフラグの順序を変え効率をよくした。
|
||
Cardのロック・アンロック修正
|
||
|
||
Revision 1.20 2004/03/25 07:25:05 yada
|
||
OS_LockCard() 等カードのロックについて追加
|
||
|
||
Revision 1.19 2004/03/25 02:38:30 yada
|
||
MI_SetMainMemoryPriority(), MI_SetCardProcessor(),MI_SetCartridgeProcessor()
|
||
を、MI_~からMIi_~ に変更し内部関数にするようにした。
|
||
|
||
Revision 1.18 2004/03/04 09:47:50 yada
|
||
カートリッジのロックに限りIRQ/FIQ禁止にした。
|
||
|
||
Revision 1.17 2004/02/13 08:58:52 yasu
|
||
nitro_sp.h -> nitro.h
|
||
|
||
Revision 1.16 2004/02/13 01:33:58 yada
|
||
ARM9とAMR7 でインクルードファイル場合わけ
|
||
|
||
Revision 1.15 2004/02/10 02:04:23 yada
|
||
subp 用にinclude修正
|
||
|
||
Revision 1.14 2004/02/10 01:25:06 yada
|
||
UTL_* を MI_ に取り込んだことによる修正
|
||
|
||
Revision 1.13 2004/02/05 07:09:02 yasu
|
||
change SDK prefix iris -> nitro
|
||
|
||
Revision 1.12 2004/02/05 02:00:37 yada
|
||
UTL_SwapWord を os_utility.c に移行
|
||
|
||
Revision 1.11 2004/01/18 02:25:37 yada
|
||
インデント等の整形
|
||
|
||
Revision 1.10 2004/01/14 01:44:01 yada
|
||
lockやunlockの途中実行関数を設定出来るようにしたことへの対応
|
||
|
||
Revision 1.9 2003/12/25 07:31:26 yada
|
||
型ルール統一による変更
|
||
|
||
Revision 1.8 2003/12/22 13:40:59 yasu
|
||
memorymap.h の明示的読み込み
|
||
|
||
Revision 1.7 2003/12/22 01:37:27 yada
|
||
WRAM, VRAM-c,d の設定をコメントアウト
|
||
|
||
Revision 1.6 2003/12/18 07:17:09 yada
|
||
red-sdk 仕様から変更
|
||
|
||
Revision 1.5 2003/12/17 08:21:56 yasu
|
||
ARM7 との共用コード化
|
||
|
||
Revision 1.4 2003/12/12 05:04:22 yasu
|
||
_ISDbgLib_* 関数の追加
|
||
|
||
Revision 1.3 2003/12/10 10:56:18 yasu
|
||
ISDPrint で必要な SpinLock 関数のみの移植
|
||
OS_LockWord() -> OS_LockByWord()
|
||
volatile LockWord -> OS_LockWord などの変更
|
||
|
||
Revision 1.2 2003/12/08 12:20:43 yada
|
||
12/3 REDSDK への変更対応
|
||
|
||
Revision 1.1 2003/11/29 01:25:46 yada
|
||
ファイル名称変更
|
||
|
||
Revision 1.2 2003/11/28 01:56:22 yada
|
||
REDSDKの03-11-27反映
|
||
但し殆どをコメントアウト
|
||
|
||
Revision 1.1 2003/11/06 09:30:39 yada
|
||
暫定版
|
||
|
||
$NoKeywords: $
|
||
*---------------------------------------------------------------------------*/
|
||
#include <nitro.h>
|
||
|
||
void _ISDbgLib_Initialize(void);
|
||
void _ISDbgLib_AllocateEmualtor(void);
|
||
void _ISDbgLib_FreeEmulator(void);
|
||
|
||
s32 OS_LockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
|
||
s32 OS_UnlockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
|
||
s32 OS_TryLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void));
|
||
|
||
static s32 OSi_DoLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFiq);
|
||
static s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFIQ);
|
||
static s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFIQ);
|
||
|
||
static void OSi_AllocateCartridgeBus(void);
|
||
static void OSi_FreeCartridgeBus(void);
|
||
|
||
static void OSi_AllocateCardBus(void);
|
||
static void OSi_FreeCardBus(void);
|
||
|
||
static void OSi_WaitByLoop(void);
|
||
|
||
|
||
#ifdef SDK_ARM9
|
||
#define OSi_ASSERT_ID( id ) SDK_ASSERTMSG( id >= OS_MAINP_LOCK_ID_START && id <= OS_MAINP_SYSTEM_LOCK_ID, \
|
||
"lock ID %d is out of bounds", id )
|
||
#else
|
||
#define OSi_ASSERT_ID( id ) SDK_ASSERTMSG( id >= OS_SUBP_LOCK_ID_START && id <= OS_SUBP_SYSTEM_LOCK_ID, \
|
||
"lock ID %d is out of bounds", id )
|
||
#endif
|
||
|
||
|
||
#define OSi_LOCKID_INITIAL_FLAG_0 0xffffffff
|
||
#define OSi_LOCKID_INITIAL_FLAG_1 0xffff0000
|
||
|
||
|
||
#ifdef SDK_ARM9
|
||
#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_MAIN
|
||
#define OSi_ANYP_LOCK_ID_START OS_MAINP_LOCK_ID_START
|
||
#else
|
||
#define OSi_ANYP_LOCK_ID_FLAG HW_LOCK_ID_FLAG_SUB
|
||
#define OSi_ANYP_LOCK_ID_START OS_SUBP_LOCK_ID_START
|
||
#endif
|
||
|
||
//======================================================================
|
||
// DUMMY LOOP
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OSi_WaitByLoop
|
||
|
||
Description: wait by for() loop
|
||
|
||
Arguments: None.
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
static inline void OSi_WaitByLoop(void)
|
||
{
|
||
#ifdef SDK_DEBUGGER_ARM
|
||
OS_SpinWait(0x1000);
|
||
#else
|
||
SVC_WaitByLoop(0x1000 / 4);
|
||
#endif
|
||
}
|
||
|
||
//======================================================================
|
||
// INITIALIZE
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_InitLock
|
||
|
||
Description: initialize system lock variable
|
||
and privilege to access shared resources
|
||
|
||
* cartridge exclusive control area is not cleared
|
||
because debugger uses.
|
||
|
||
Arguments: None.
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
void OS_InitLock(void)
|
||
{
|
||
static BOOL isInitialized = FALSE;
|
||
OSLockWord *lockp;
|
||
|
||
if (isInitialized)
|
||
return; // do it only once
|
||
isInitialized = TRUE;
|
||
|
||
lockp = (OSLockWord *)HW_INIT_LOCK_BUF;
|
||
|
||
#ifdef SDK_ARM9
|
||
{
|
||
//
|
||
// Code for MAIN PROCESSOR
|
||
//
|
||
|
||
lockp->lockFlag = 0;
|
||
(void)OS_LockByWord(OS_MAINP_SYSTEM_LOCK_ID - 1, lockp, NULL);
|
||
|
||
// サブプロセッサによる共有リソース未使用チェック
|
||
while (lockp->extension != 0)
|
||
{
|
||
OSi_WaitByLoop();
|
||
}
|
||
|
||
// ロックIDカウンタ用フラグ 初期化
|
||
((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0;
|
||
((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1;
|
||
|
||
// ロックバッファ クリア(カートリッジ領域以外)
|
||
MI_CpuClear32((void *)HW_SHARED_LOCK_BUF, HW_CTRDG_LOCK_BUF - HW_SHARED_LOCK_BUF);
|
||
|
||
// NITRO カードアクセス権 → サブプロセッサ
|
||
MIi_SetCardProcessor(MI_PROCESSOR_ARM7);
|
||
|
||
// カートリッジアクセス権 → サブプロセッサ
|
||
MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7);
|
||
|
||
#ifndef SDK_FINALROM
|
||
_ISDbgLib_Initialize();
|
||
#endif
|
||
|
||
(void)OS_UnlockByWord(OS_MAINP_SYSTEM_LOCK_ID - 1, lockp, NULL);
|
||
(void)OS_LockByWord(OS_MAINP_SYSTEM_LOCK_ID, lockp, NULL);
|
||
}
|
||
|
||
#else // SDK_ARM7
|
||
{
|
||
//
|
||
// Code for SUB PROCESSOR
|
||
//
|
||
|
||
lockp->extension = 0;
|
||
while (lockp->ownerID != OS_MAINP_SYSTEM_LOCK_ID)
|
||
{
|
||
OSi_WaitByLoop();
|
||
}
|
||
|
||
#ifndef SDK_FINALROM
|
||
_ISDbgLib_Initialize();
|
||
#endif
|
||
|
||
// ロックIDカウンタ用フラグ 初期化
|
||
((u32 *)OSi_ANYP_LOCK_ID_FLAG)[0] = OSi_LOCKID_INITIAL_FLAG_0;
|
||
((u32 *)OSi_ANYP_LOCK_ID_FLAG)[1] = OSi_LOCKID_INITIAL_FLAG_1;
|
||
|
||
// メインプロセッサとの初期化終了の同期
|
||
lockp->extension = OS_SUBP_SYSTEM_LOCK_ID;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// LOCK
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OSi_DoLockByWord
|
||
|
||
Description: do spinlock. keep to try till success
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to lock variable
|
||
ctrlFuncp function
|
||
disableFiq whether do disable fiq
|
||
|
||
Returns: OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
static s32 OSi_DoLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFiq)
|
||
{
|
||
s32 lastLockFlag;
|
||
|
||
while ((lastLockFlag =
|
||
OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, disableFiq)) > OS_LOCK_SUCCESS)
|
||
{
|
||
OSi_WaitByLoop();
|
||
}
|
||
|
||
return lastLockFlag;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_LockByWord
|
||
|
||
Description: do spinlock. keep to try till success.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to lock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_LockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoLockByWord(lockID, lockp, ctrlFuncp, FALSE);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_LockByWord_IrqAndFiq
|
||
|
||
Description: do spinlock. keep to try till success.
|
||
disable irq and fiq
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to lock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_LockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoLockByWord(lockID, lockp, ctrlFuncp, TRUE);
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// UNLOCK
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OSi_DoUnlockByWord
|
||
|
||
Description: do unlock lock.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to unlock variable
|
||
ctrlFuncp function
|
||
disableFiq whether do disable fiq
|
||
|
||
Returns: OS_UNLOCK_SUCCESS success
|
||
OS_UNLOCK_ERROR error of unlocking lock
|
||
*---------------------------------------------------------------------------*/
|
||
static s32 OSi_DoUnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFIQ)
|
||
{
|
||
OSIntrMode lastInterrupts;
|
||
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
if (lockID != lockp->ownerID)
|
||
{
|
||
return OS_UNLOCK_ERROR;
|
||
}
|
||
|
||
//---- Disable irq/fiq or irq
|
||
lastInterrupts = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
|
||
|
||
lockp->ownerID = 0;
|
||
if (ctrlFuncp)
|
||
{
|
||
ctrlFuncp();
|
||
}
|
||
lockp->lockFlag = 0;
|
||
|
||
//---- Restore irq/fiq or irq
|
||
if (disableFIQ)
|
||
{
|
||
(void)OS_RestoreInterrupts_IrqAndFiq(lastInterrupts);
|
||
}
|
||
else
|
||
{
|
||
(void)OS_RestoreInterrupts(lastInterrupts);
|
||
}
|
||
|
||
return OS_UNLOCK_SUCCESS;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_UnlockByWord
|
||
|
||
Description: do unlock lock.
|
||
disable irq and fiq
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to unlock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: OS_UNLOCK_SUCCESS success
|
||
OS_UNLOCK_ERROR error of unlocking lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_UnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE);
|
||
}
|
||
|
||
//---- for compatibility to old name ('UnLock' <-> 'Unlock')
|
||
s32 OS_UnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, FALSE);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_UnlockByWord_IrqAndFiq
|
||
|
||
Description: do unlock lock.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to unlock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: OS_UNLOCK_SUCCESS success
|
||
OS_UNLOCK_ERROR error of unlocking lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_UnlockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoUnlockByWord(lockID, lockp, ctrlFuncp, TRUE);
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// TRY LOCK
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OSi_DoTryLockByWord
|
||
|
||
Description: try to lock spinlock only once.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to trying to lock variable
|
||
ctrlFuncp function
|
||
disableFiq whether do disable fiq
|
||
|
||
Returns: >0 value previous locked id
|
||
OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
static s32 OSi_DoTryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void),
|
||
BOOL disableFIQ)
|
||
{
|
||
s32 lastLockFlag;
|
||
OSIntrMode lastInterrupts;
|
||
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
//---- Disable irq/fiq or irq
|
||
lastInterrupts = (disableFIQ) ? OS_DisableInterrupts_IrqAndFiq() : OS_DisableInterrupts();
|
||
|
||
lastLockFlag = (s32)MI_SwapWord(lockID, &lockp->lockFlag);
|
||
|
||
if (lastLockFlag == OS_LOCK_SUCCESS)
|
||
{
|
||
if (ctrlFuncp)
|
||
{
|
||
ctrlFuncp();
|
||
}
|
||
lockp->ownerID = lockID;
|
||
}
|
||
|
||
//---- Restore irq/fiq or irq
|
||
if (disableFIQ)
|
||
{
|
||
(void)OS_RestoreInterrupts_IrqAndFiq(lastInterrupts);
|
||
}
|
||
else
|
||
{
|
||
(void)OS_RestoreInterrupts(lastInterrupts);
|
||
}
|
||
|
||
return lastLockFlag;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_TryLockByWord
|
||
|
||
Description: try to lock spinlock only once.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to trying to lock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: >0 value previous locked id
|
||
OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_TryLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, FALSE);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_TryLockByWord_IrqAndFiq
|
||
|
||
Description: try to lock spinlock only once.
|
||
|
||
Arguments: lockID lock ID
|
||
lockp pointer to trying to lock variable
|
||
ctrlFuncp function
|
||
|
||
Returns: >0 value previous locked id
|
||
OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_TryLockByWord_IrqAndFiq(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void))
|
||
{
|
||
return OSi_DoTryLockByWord(lockID, lockp, ctrlFuncp, TRUE);
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// CARTRIDGE
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_LockCartridge
|
||
|
||
Description: lock cartridge
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_LockCartridge(u16 lockID)
|
||
{
|
||
s32 lastLockFlag;
|
||
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
lastLockFlag =
|
||
OSi_DoLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus, TRUE);
|
||
|
||
#ifndef SDK_FINALROM
|
||
_ISDbgLib_AllocateEmualtor();
|
||
#endif
|
||
|
||
return lastLockFlag;
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_UnlockCartridge
|
||
|
||
Description: unlock cartridge
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: OS_UNLOCK_SUCCESS success
|
||
OS_UNLOCK_ERROR error of unlocking lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_UnlockCartridge(u16 lockID)
|
||
{
|
||
s32 lastLockFlag;
|
||
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
#ifndef SDK_FINALROM
|
||
_ISDbgLib_FreeEmulator();
|
||
#endif
|
||
|
||
lastLockFlag =
|
||
OSi_DoUnlockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_FreeCartridgeBus, TRUE);
|
||
|
||
return lastLockFlag;
|
||
}
|
||
|
||
//---- for compatibility to old name ('UnLock' <-> 'Unlock')
|
||
asm s32 OS_UnLockCartridge( u16 lockID )
|
||
{
|
||
ldr r1, =OS_UnlockCartridge
|
||
bx r1
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_TryLockCartridge
|
||
|
||
Description: try to lock cartridge
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: >0 value previous locked id
|
||
OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_TryLockCartridge(u16 lockID)
|
||
{
|
||
s32 lastLockFlag;
|
||
|
||
lastLockFlag =
|
||
OSi_DoTryLockByWord(lockID, (OSLockWord *)HW_CTRDG_LOCK_BUF, OSi_AllocateCartridgeBus,
|
||
TRUE);
|
||
|
||
#ifndef SDK_FINALROM
|
||
if (lastLockFlag == OS_LOCK_SUCCESS)
|
||
{
|
||
_ISDbgLib_AllocateEmualtor();
|
||
}
|
||
#endif
|
||
|
||
return lastLockFlag;
|
||
}
|
||
|
||
//----------------
|
||
static void OSi_AllocateCartridgeBus(void)
|
||
{
|
||
#ifdef SDK_ARM9
|
||
MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM9); // Cartridge for MAIN
|
||
#endif
|
||
}
|
||
|
||
//----------------
|
||
static void OSi_FreeCartridgeBus(void)
|
||
{
|
||
#ifdef SDK_ARM9
|
||
MIi_SetCartridgeProcessor(MI_PROCESSOR_ARM7); // Cartridge for SUB
|
||
#endif
|
||
}
|
||
|
||
//======================================================================
|
||
// CARD
|
||
//======================================================================
|
||
|
||
/*
|
||
* 20040708:yosizaki
|
||
* TEG では ARM9 がロックした後 ARM7 へ転送要求する必要がある.
|
||
* このときロックが共有だと ARM9 のロック中で ARM 7 がロックできない.
|
||
* ので, 単に個々のロック ID によってプロセッサ内での排他制御を行う.
|
||
*/
|
||
#if defined(SDK_TEG)
|
||
|
||
static u32 osi_card_lock = OS_LOCK_ID_ERROR;
|
||
|
||
static s32 OSi_LockCardID(u16 lockID, BOOL blocking)
|
||
{
|
||
s32 ret = OS_LOCK_ID_ERROR;
|
||
for (;;)
|
||
{
|
||
OSIntrMode bak_psr = OS_DisableInterrupts();
|
||
ret = osi_card_lock;
|
||
if (ret == OS_LOCK_ID_ERROR)
|
||
{
|
||
osi_card_lock = lockID;
|
||
ret = OS_LOCK_SUCCESS;
|
||
}
|
||
(void)OS_RestoreInterrupts(bak_psr);
|
||
if ((ret != OS_LOCK_SUCCESS) && blocking)
|
||
{
|
||
OSi_WaitByLoop();
|
||
continue;
|
||
}
|
||
break;
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
static s32 OSi_UnlockCardID(u16 lockID)
|
||
{
|
||
if (osi_card_lock != lockID)
|
||
return OS_UNLOCK_ERROR;
|
||
osi_card_lock = OS_LOCK_ID_ERROR;
|
||
return OS_UNLOCK_SUCCESS;
|
||
}
|
||
|
||
#endif
|
||
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_LockCard
|
||
|
||
Description: lock card
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_LockCard(u16 lockID)
|
||
{
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
#if defined(SDK_TEG)
|
||
return OSi_LockCardID(lockID, TRUE);
|
||
#else
|
||
return OS_LockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus);
|
||
#endif
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_UnlockCard
|
||
|
||
Description: unlock card
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: OS_UNLOCK_SUCCESS success
|
||
OS_UNLOCK_ERROR error of unlocking lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_UnlockCard(u16 lockID)
|
||
{
|
||
OSi_ASSERT_ID(lockID);
|
||
|
||
#if defined(SDK_TEG)
|
||
return OSi_UnlockCardID(lockID);
|
||
#else
|
||
return OS_UnlockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_FreeCardBus);
|
||
#endif
|
||
}
|
||
|
||
//---- for compatibility to old name ('UnLock' <-> 'Unlock')
|
||
asm s32 OS_UnLockCard( u16 lockID )
|
||
{
|
||
ldr r1, =OS_UnlockCard
|
||
bx r1
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_TryLockCard
|
||
|
||
Description: try to lock card
|
||
|
||
Arguments: lockID lock ID
|
||
|
||
Returns: >0 value previous locked id
|
||
OS_LOCK_SUCCESS success to lock
|
||
*---------------------------------------------------------------------------*/
|
||
s32 OS_TryLockCard(u16 lockID)
|
||
{
|
||
#if defined(SDK_TEG)
|
||
return OSi_LockCardID(lockID, FALSE);
|
||
#else
|
||
return OS_TryLockByWord(lockID, (OSLockWord *)HW_CARD_LOCK_BUF, OSi_AllocateCardBus);
|
||
#endif
|
||
}
|
||
|
||
//----------------
|
||
static void OSi_AllocateCardBus(void)
|
||
{
|
||
#ifdef SDK_ARM9
|
||
MIi_SetCardProcessor(MI_PROCESSOR_ARM9); // Card for MAIN
|
||
#endif
|
||
}
|
||
|
||
//----------------
|
||
static void OSi_FreeCardBus(void)
|
||
{
|
||
#ifdef SDK_ARM9
|
||
MIi_SetCardProcessor(MI_PROCESSOR_ARM7); // Card for SUB
|
||
#endif
|
||
}
|
||
|
||
|
||
//======================================================================
|
||
// READ OWNER
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_ReadOwnerOfLockWord
|
||
|
||
Description: read owner id of lock
|
||
|
||
・モジュールID が非0 の場合はその時点でどちらのプロセッサ側が
|
||
所有権を持っているのかを確認できます。
|
||
・共有リソースの場合は「メインプロセッサ側が所有権を持っている状態」
|
||
のみを割り込みを禁止することによって維持することができます。
|
||
その他の状態はサブプロセッサが変化させてしまう可能性があります。
|
||
・所有モジュールID が 0 であってもロック変数が解除されているとは限りません。
|
||
|
||
Arguments: lockp pointer to lock
|
||
|
||
Returns: owner id
|
||
*---------------------------------------------------------------------------*/
|
||
u16 OS_ReadOwnerOfLockWord(OSLockWord *lockp)
|
||
{
|
||
return lockp->ownerID;
|
||
}
|
||
|
||
//======================================================================
|
||
// LOCK ID
|
||
//======================================================================
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_GetLockID
|
||
|
||
Description: get lock ID
|
||
|
||
Arguments: None.
|
||
|
||
Returns: OS_LOCK_ID_ERROR, if fail to get ID
|
||
|
||
if ARM9
|
||
0x40~0x6f lockID
|
||
else if ARM7
|
||
0x80~0xaf lockID
|
||
endif
|
||
|
||
*Notice: ID is allocated only 48 pattern at a highest.
|
||
|
||
IDは48種類までしか割り当てることができません。
|
||
モジュール内にて複数のロック変数を制御する場合は
|
||
できるだけ1つのIDを使用するようにして下さい。
|
||
*---------------------------------------------------------------------------*/
|
||
#include <nitro/code32.h>
|
||
asm s32 OS_GetLockID( void )
|
||
{
|
||
//---- フラグの前32ビットに立っているフラグ(空きID)があるか
|
||
ldr r3, =OSi_ANYP_LOCK_ID_FLAG
|
||
ldr r1, [r3, #0]
|
||
|
||
#ifdef SDK_ARM9
|
||
clz r2, r1
|
||
#else
|
||
mov r2, #0
|
||
mov r0, #0x80000000
|
||
_lp1:
|
||
tst r1, r0
|
||
bne _ex1
|
||
add r2, r2, #1
|
||
cmp r2, #32
|
||
beq _ex1
|
||
|
||
mov r0, r0, lsr #1
|
||
b _lp1
|
||
_ex1:
|
||
#endif
|
||
cmp r2, #32
|
||
|
||
//---- 空きIDがあるとき
|
||
movne r0, #OSi_ANYP_LOCK_ID_START
|
||
bne _1
|
||
|
||
//---- 後ろ323ビットに立っているフラグ(空きID)があるか
|
||
add r3, r3, #4
|
||
ldr r1, [r3, #0]
|
||
#ifdef SDK_ARM9
|
||
clz r2, r1
|
||
#else
|
||
mov r2, #0
|
||
mov r0, #0x80000000
|
||
_lp2:
|
||
tst r1, r0
|
||
bne _ex2
|
||
add r2, r2, #1
|
||
cmp r2, #32
|
||
beq _ex2
|
||
|
||
mov r0, r0, lsr #1
|
||
b _lp2
|
||
_ex2:
|
||
#endif
|
||
cmp r2, #32
|
||
|
||
//---- 空きIDがない
|
||
ldr r0, =OS_LOCK_ID_ERROR
|
||
bxeq lr
|
||
|
||
//---- 空きIDがあるとき
|
||
mov r0, #OSi_ANYP_LOCK_ID_START+32
|
||
|
||
_1:
|
||
add r0, r0, r2
|
||
mov r1, #0x80000000
|
||
mov r1, r1, lsr r2
|
||
|
||
ldr r2, [r3, #0]
|
||
bic r2, r2, r1
|
||
str r2, [r3, #0]
|
||
|
||
bx lr
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
Name: OS_ReleaseLockID
|
||
|
||
Description: release lock ID
|
||
|
||
Arguments: id to tend to release
|
||
|
||
Returns: None.
|
||
*---------------------------------------------------------------------------*/
|
||
asm void OS_ReleaseLockID( register u16 lockID )
|
||
{
|
||
#pragma unused( lockID )
|
||
|
||
ldr r3, =OSi_ANYP_LOCK_ID_FLAG
|
||
|
||
cmp r0, #OSi_ANYP_LOCK_ID_START+32
|
||
addpl r3, r3, #4
|
||
|
||
subpl r0, r0, #OSi_ANYP_LOCK_ID_START+32
|
||
submi r0, r0, #OSi_ANYP_LOCK_ID_START
|
||
|
||
mov r1, #0x80000000
|
||
mov r1, r1, lsr r0
|
||
|
||
ldr r2, [r3, #0]
|
||
orr r2, r2, r1
|
||
str r2, [r3, #0]
|
||
|
||
bx lr
|
||
}
|
||
#include <nitro/codereset.h>
|