/*---------------------------------------------------------------------------* Project: TwlSDK - OS - include File: spinLock.h Copyright 2003-2009 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. $Date:: 2009-06-04#$ $Rev: 10698 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ #ifndef NITRO_OS_SPINLOCK_H_ #define NITRO_OS_SPINLOCK_H_ #ifdef __cplusplus extern "C" { #endif #include #ifndef SDK_TWL #ifdef SDK_ARM9 #include #else //SDK_ARM7 #include #endif #else // SDK_TWL #include #ifdef SDK_ARM9 #include #else //SDK_ARM7 #include #endif #endif //SDK_TWL //====================================================================== // Lock Functions // //- Use these functions for mutually exclusive control of dedicated resources, such as the inter-CPU transfer FIFO, and common resources between CPUs, such as internal work RAM and VRAM-C/D shared by Game Cards, Game Paks, and CPUs // // //====================================================================== // Lock ID #define OS_UNLOCK_ID 0 // ID when lock variable is not locked #define OS_MAINP_LOCKED_FLAG 0x40 // Main processor lock verification flag #define OS_MAINP_LOCK_ID_START 0x40 // Starting number of lock ID assignments, for main processor use #define OS_MAINP_LOCK_ID_END 0x6f // Assignment completion number #define OS_MAINP_DBG_LOCK_ID 0x70 // Debugger reservation number #define OS_MAINP_SYSTEM_LOCK_ID 0x7f // System reservation number #define OS_SUBP_LOCKED_FLAG 0x80 // Lock verification flag by sub-processor #define OS_SUBP_LOCK_ID_START 0x80 // Starting number of lock ID assignments, for sub-processor use #define OS_SUBP_LOCK_ID_END 0xaf // Assignment completion number #define OS_SUBP_DBG_LOCK_ID 0xb0 // Debugger reservation number #define OS_SUBP_SYSTEM_LOCK_ID 0xbf // System reservation number #define OS_LOCK_SUCCESS 0 // Lock success #define OS_LOCK_ERROR (-1) // Lock error #define OS_UNLOCK_SUCCESS 0 // Unlock success #define OS_UNLOCK_ERROR (-2) // Unlock error #define OS_LOCK_FREE 0 // Unlocking #define OS_LOCK_ID_ERROR (-3) // Lock ID error //---- Structure of Lock Variable typedef volatile struct OSLockWord { u32 lockFlag; u16 ownerID; u16 extension; } OSLockWord; /*---------------------------------------------------------------------------* Name: OS_InitLock Description: Initializes access rights to system lock variables and shared resources. The region used for cartridge mutexes will be cleared. (because that region is used by the debugger) Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void OS_InitLock(void); /*---------------------------------------------------------------------------* Name: OS_LockByWord OS_LockCartridge OS_LockCard Description: Spinlock functions. These use spinlocks on lock variables for mutually exclusive control of resources shared between processors and between modules. It will keep trying until the lock succeeds. Lock resources shared between processors before using them. If you can adjust the timing for resources owned by a single processor, you do not need to lock them. It's also possible to lock exclusive-use resources just for debugging. Arguments: lockID: Lock ID lockp: Lock variable's pointer Returns: >0: A locked value OS_LOCK_SUCCESS (=0): Successful lock *---------------------------------------------------------------------------*/ s32 OS_LockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); s32 OS_LockCartridge(u16 lockID); s32 OS_LockCard(u16 lockID); /*---------------------------------------------------------------------------* Name: OS_UnlockByWord OS_UnlockCartridge OS_UnlockCard Description: Unlocks. This unlocks and passes the access rights of a shared resource to the subprocessor. If an unlocked module is run, it is not unlocked and OS_UNLOCK_ERROR is returned. Arguments: lockID: Lock ID lockp: Lock variable's pointer Returns: OS_UNLOCK_SUCCESS: Unlock success. OS_UNLOCK_ERROR: Unlock error. *---------------------------------------------------------------------------*/ s32 OS_UnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); s32 OS_UnlockCartridge(u16 lockID); s32 OS_UnlockCard(u16 lockID); //---- The previous names have also been left for compatibility. ('UnLock' <-> 'Unlock') // The ISD library calls these functions. They are not inline. s32 OS_UnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void)); s32 OS_UnLockCartridge(u16 lockID); s32 OS_UnLockCard(u16 lockID); /*---------------------------------------------------------------------------* Name: OS_TryLockByWord OS_TryLockCartridge OS_TryLockCard Description: Attempts to lock. Attempts only a single spinlock. Lock resources shared between processors before using them. If you can adjust the timing for resources owned by a single processor, you do not need to lock them. It's also possible to lock exclusive-use resources just for debugging. Arguments: lockID: Lock ID lockp: Lock variable's pointer CtrlFuncp: Resource control functions pointer Returns: >0: Locked (the previously stored ID). OS_LOCK_SUCCESS: Lock success *---------------------------------------------------------------------------*/ s32 OS_TryLockByWord(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void)); s32 OS_TryLockCartridge(u16 lockID); s32 OS_TryLockCard(u16 lockID); /*---------------------------------------------------------------------------* Name: OS_ReadOwnerOfLockWord OS_ReadOwnerOfLockCartridge OS_ReadOwnerOfLockCard Description: Reads the lock variable's owner module ID. Reads a lock variable's owner module ID. You can check which processor has ownership now if the module ID is nonzero. For a shared resource, prohibiting interrupts can maintain only the main processor's ownership rights. In other states, it might be changed by subprocessors. The lock variable may not necessarily be unlocked even if the owner module ID is 0. Note: Be aware that byte access to main memory is not possible unless it is through a cache. Thus, as a basic rule, you should use the OS_ReadOwnerOfLockWord function for main memory. Arguments: lockp: Lock variable's pointer Returns: Owner module ID. *---------------------------------------------------------------------------*/ u16 OS_ReadOwnerOfLockWord(OSLockWord *lockp); #define OS_ReadOwnerOfLockCartridge() OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CTRDG_LOCK_BUF ) #define OS_ReadOwnerOfLockCard() OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CARD_LOCK_BUF ) /*---------------------------------------------------------------------------* Name: OS_GetLockID Description: Gets the lock ID. Arguments: None. Returns: OS_LOCK_ID_ERROR: Failed to get the ID (for the ARM9) 0x40-0x6f: lock ID (for the ARM7) 0x80-0xaf: lock ID Only up to 48 kinds of IDs can be assigned. When managing multiple lock variables in a module, use a single ID whenever possible. *---------------------------------------------------------------------------*/ s32 OS_GetLockID(void); /*---------------------------------------------------------------------------* Name: OS_ReleaseLockID Description: Releases a lock ID. Arguments: lockID: Lock ID to attempt to release. Returns: None. *---------------------------------------------------------------------------*/ void OS_ReleaseLockID(u16 lockID); #ifdef SDK_TWL //================================================================ // Private Functions // The following are internal functions. Do not use them from an application. #define OSi_SYNCTYPE_SENDER 0 #define OSi_SYNCTYPE_RECVER 1 #define OSi_SYNCVAL_NOT_READY 0 #define OSi_SYNCVAL_READY 1 void OSi_SyncWithOtherProc( int type, void* syncBuf ); static inline void OSi_SetSyncValue( u8 n ) { *(vu8*)(HW_INIT_LOCK_BUF+4) = n; } static inline u8 OSi_GetSyncValue( void ) { return *(vu8*)(HW_INIT_LOCK_BUF+4); } #endif //-------------------------------------------------------------------------------- #ifdef __cplusplus } /* extern "C" */ #endif /* NITRO_OS_SPINLOCK_H_ */ #endif