1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS - include
3   File:     spinLock.h
4 
5   Copyright 2003-2009 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-06-04#$
14   $Rev: 10698 $
15   $Author: okubata_ryoma $
16 
17  *---------------------------------------------------------------------------*/
18 
19 #ifndef NITRO_OS_SPINLOCK_H_
20 #define NITRO_OS_SPINLOCK_H_
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #include <nitro/types.h>
27 
28 #ifndef SDK_TWL
29 #ifdef	SDK_ARM9
30 #include	<nitro/hw/ARM9/mmap_global.h>
31 #else  //SDK_ARM7
32 #include	<nitro/hw/ARM7/mmap_global.h>
33 #endif
34 #else // SDK_TWL
35 #include    <twl/hw/common/mmap_shared.h>
36 #ifdef	SDK_ARM9
37 #include	<twl/hw/ARM9/mmap_global.h>
38 #else  //SDK_ARM7
39 #include	<twl/hw/ARM7/mmap_global.h>
40 #endif
41 #endif //SDK_TWL
42 
43 //======================================================================
44 //                      Lock Functions
45 //
46 //- 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
47 //
48 //
49 //======================================================================
50 
51 // Lock ID
52 
53 #define OS_UNLOCK_ID            0      // ID when lock variable is not locked
54 #define OS_MAINP_LOCKED_FLAG    0x40   // Main processor lock verification flag
55 #define OS_MAINP_LOCK_ID_START  0x40   // Starting number of lock ID assignments, for main processor use
56 #define OS_MAINP_LOCK_ID_END    0x6f   //                               Assignment completion number
57 #define OS_MAINP_DBG_LOCK_ID    0x70   //                               Debugger reservation number
58 #define OS_MAINP_SYSTEM_LOCK_ID 0x7f   //                               System reservation number
59 #define OS_SUBP_LOCKED_FLAG     0x80   //   Lock verification flag by sub-processor
60 #define OS_SUBP_LOCK_ID_START   0x80   //   Starting number of lock ID assignments, for sub-processor use
61 #define OS_SUBP_LOCK_ID_END     0xaf   //                               Assignment completion number
62 #define OS_SUBP_DBG_LOCK_ID     0xb0   //                               Debugger reservation number
63 #define OS_SUBP_SYSTEM_LOCK_ID  0xbf   //                               System reservation number
64 
65 #define OS_LOCK_SUCCESS         0      // Lock success
66 #define OS_LOCK_ERROR           (-1)   // Lock error
67 
68 #define OS_UNLOCK_SUCCESS       0      // Unlock success
69 #define OS_UNLOCK_ERROR         (-2)   // Unlock error
70 
71 #define OS_LOCK_FREE            0      // Unlocking
72 
73 #define OS_LOCK_ID_ERROR        (-3)   // Lock ID error
74 
75 
76 //---- Structure of Lock Variable
77 typedef volatile struct OSLockWord
78 {
79     u32     lockFlag;
80     u16     ownerID;
81     u16     extension;
82 }
83 OSLockWord;
84 
85 /*---------------------------------------------------------------------------*
86   Name:         OS_InitLock
87 
88   Description:  Initializes access rights to system lock variables and shared resources.
89 
90 
91                 The region used for cartridge mutexes will be cleared.
92                 (because that region is used by the debugger)
93 
94   Arguments:    None.
95 
96   Returns:      None.
97  *---------------------------------------------------------------------------*/
98 void    OS_InitLock(void);
99 
100 /*---------------------------------------------------------------------------*
101   Name:         OS_LockByWord
102                 OS_LockCartridge
103                 OS_LockCard
104 
105   Description:  Spinlock functions.
106 
107                 These use spinlocks on lock variables for mutually exclusive control of resources shared between processors and between modules.
108                 It will keep trying until the lock succeeds.
109                 Lock resources shared between processors before using them.
110                 If you can adjust the timing for resources owned by a single processor, you do not need to lock them.
111                 It's also possible to lock exclusive-use resources just for debugging.
112 
113 
114 
115   Arguments:    lockID: Lock ID
116                 lockp: Lock variable's pointer
117 
118   Returns:      >0: A locked value
119                 OS_LOCK_SUCCESS (=0): Successful lock
120  *---------------------------------------------------------------------------*/
121 s32     OS_LockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
122 s32     OS_LockCartridge(u16 lockID);
123 s32     OS_LockCard(u16 lockID);
124 
125 /*---------------------------------------------------------------------------*
126   Name:         OS_UnlockByWord
127                 OS_UnlockCartridge
128                 OS_UnlockCard
129 
130   Description:  Unlocks.
131                 This unlocks and passes the access rights of a shared resource to the subprocessor.
132                 If an unlocked module is run, it is not unlocked and OS_UNLOCK_ERROR is returned.
133 
134 
135   Arguments:    lockID: Lock ID
136                 lockp: Lock variable's pointer
137 
138   Returns:      OS_UNLOCK_SUCCESS: Unlock success.
139                 OS_UNLOCK_ERROR: Unlock error.
140  *---------------------------------------------------------------------------*/
141 s32     OS_UnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
142 s32     OS_UnlockCartridge(u16 lockID);
143 s32     OS_UnlockCard(u16 lockID);
144 
145 //---- The previous names have also been left for compatibility. ('UnLock' <-> 'Unlock')
146 //     The ISD library calls these functions. They are not inline.
147 s32     OS_UnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
148 s32     OS_UnLockCartridge(u16 lockID);
149 s32     OS_UnLockCard(u16 lockID);
150 
151 /*---------------------------------------------------------------------------*
152   Name:         OS_TryLockByWord
153                 OS_TryLockCartridge
154                 OS_TryLockCard
155 
156   Description:  Attempts to lock.
157 
158                 Attempts only a single spinlock.
159                 Lock resources shared between processors before using them.
160                 If you can adjust the timing for resources owned by a single processor, you do not need to lock them.
161                 It's also possible to lock exclusive-use resources just for debugging.
162 
163 
164   Arguments:    lockID: Lock ID
165                 lockp: Lock variable's pointer
166                 CtrlFuncp: Resource control functions pointer
167 
168   Returns:      >0: Locked (the previously stored ID).
169                 OS_LOCK_SUCCESS: Lock success
170  *---------------------------------------------------------------------------*/
171 s32     OS_TryLockByWord(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void));
172 s32     OS_TryLockCartridge(u16 lockID);
173 s32     OS_TryLockCard(u16 lockID);
174 
175 /*---------------------------------------------------------------------------*
176   Name:         OS_ReadOwnerOfLockWord
177                 OS_ReadOwnerOfLockCartridge
178                 OS_ReadOwnerOfLockCard
179 
180   Description:  Reads the lock variable's owner module ID.
181 
182                 Reads a lock variable's owner module ID.
183                 You can check which processor has ownership now if the module ID is nonzero.
184                 For a shared resource, prohibiting interrupts can maintain only the main processor's ownership rights.
185                 In other states, it might be changed by subprocessors.
186                 The lock variable may not necessarily be unlocked even if the owner module ID is 0.
187 
188 
189 
190                 Note: Be aware that byte access to main memory is not possible unless it is through a cache.
191 
192                 Thus, as a basic rule, you should use the OS_ReadOwnerOfLockWord function for main memory.
193 
194   Arguments:    lockp: Lock variable's pointer
195 
196   Returns:      Owner module ID.
197  *---------------------------------------------------------------------------*/
198 u16     OS_ReadOwnerOfLockWord(OSLockWord *lockp);
199 #define OS_ReadOwnerOfLockCartridge()  OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CTRDG_LOCK_BUF )
200 #define OS_ReadOwnerOfLockCard()       OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CARD_LOCK_BUF  )
201 
202 /*---------------------------------------------------------------------------*
203   Name:         OS_GetLockID
204 
205   Description:  Gets the lock ID.
206 
207   Arguments:    None.
208 
209   Returns:      OS_LOCK_ID_ERROR: Failed to get the ID
210                 (for the ARM9)
211                 0x40-0x6f: lock ID
212                 (for the ARM7)
213                 0x80-0xaf: lock ID
214 
215                 Only up to 48 kinds of IDs can be assigned.
216                 When managing multiple lock variables in a module, use a single ID whenever possible.
217 
218  *---------------------------------------------------------------------------*/
219 s32     OS_GetLockID(void);
220 
221 
222 /*---------------------------------------------------------------------------*
223   Name:         OS_ReleaseLockID
224 
225   Description:  Releases a lock ID.
226 
227   Arguments:    lockID: Lock ID to attempt to release.
228 
229   Returns:      None.
230  *---------------------------------------------------------------------------*/
231 void    OS_ReleaseLockID(u16 lockID);
232 
233 
234 #ifdef SDK_TWL
235 //================================================================
236 //   Private Functions
237 //   The following are internal functions. Do not use them from an application.
238 #define OSi_SYNCTYPE_SENDER 0
239 #define OSi_SYNCTYPE_RECVER 1
240 
241 #define OSi_SYNCVAL_NOT_READY 0
242 #define OSi_SYNCVAL_READY     1
243 
244 void OSi_SyncWithOtherProc( int type, void* syncBuf );
245 
OSi_SetSyncValue(u8 n)246 static inline void OSi_SetSyncValue( u8 n )
247 {
248 	*(vu8*)(HW_INIT_LOCK_BUF+4) = n;
249 }
OSi_GetSyncValue(void)250 static inline u8 OSi_GetSyncValue( void )
251 {
252 	return *(vu8*)(HW_INIT_LOCK_BUF+4);
253 }
254 
255 #endif
256 
257 
258 //--------------------------------------------------------------------------------
259 #ifdef __cplusplus
260 } /* extern "C" */
261 #endif
262 
263 /* NITRO_OS_SPINLOCK_H_ */
264 #endif
265