1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS - include
3   File:     spinLock.h
4 
5   Copyright 2003-2008 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:: 2008-09-17#$
14   $Rev: 8556 $
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 #ifdef SDK_NITRO
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_NITRO
42 
43 //======================================================================
44 //                      Lock Functions
45 //
46 //Use these functions to exclusively control 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:  Initialize system lock variable
89                 and privilege to access shared resources.
90 
91                 * cartridge exclusive control area is not cleared
92                   because debugger uses.
93 
94   Arguments:    None.
95 
96   Returns:      None.
97  *---------------------------------------------------------------------------*/
98 void    OS_InitLock(void);
99 
100 //----------------------------------------------------------------------
101 //          Spinlock
102 //
103 //- This conducts spinlock of the lock variables for exclusive control of resources shared between processors and between modules.
104 //
105 //- Trials continue until lock succeeds.
106 //- Be sure to lock resources shared between processors before using them.
107 //If the timing of resources exclusively used by one processor can be adjusted, it is okay not to lock them.
108 //
109 //  It's also possible to lock exclusive-use resources just for debugging.
110 //
111 //Arguments:
112 //  lockID:              Lock ID
113 //  lockp:       Lock variable's pointer
114 //
115 //Return values:
116 //  OS_LOCK_SUCCESS:     Lock success
117 //----------------------------------------------------------------------
118 s32     OS_LockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
119 s32     OS_LockCartridge(u16 lockID);
120 s32     OS_LockCard(u16 lockID);
121 
122 //----------------------------------------------------------------------
123 //          Unlock
124 //
125 //- This unlocks and passes access rights of shared resources to the subprocessor.
126 //- In the case of running a module that is not locked, it will not be unlocked, and OS_UNLOCK_ERROR will be returned.
127 //
128 //
129 //Arguments:
130 //  lockID:              Lock ID
131 //  lockp:       Lock variable's pointer
132 //
133 //Return values:
134 //  OS_UNLOCK_SUCCESS:   Unlock success
135 //  OS_UNLOCK_ERROR:     Unlock error
136 //----------------------------------------------------------------------
137 s32     OS_UnlockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
138 s32     OS_UnlockCartridge(u16 lockID);
139 s32     OS_UnlockCard(u16 lockID);
140 
141 //---- for compatibility with old name ('UnLock' <-> 'Unlock')
142 //     Because isd lib calls OS_UnLock*, these cannot be inlined.
143 s32     OS_UnLockByWord(u16 lockID, OSLockWord *lockp, void (*ctrlFuncp) (void));
144 s32     OS_UnLockCartridge(u16 lockID);
145 s32     OS_UnLockCard(u16 lockID);
146 
147 //----------------------------------------------------------------------
148 //          Lock trials
149 //
150 //- Try spinlock once only.
151 //- Be sure to lock resources shared between processors before using them.
152 //If the timing of resources exclusively used by one processor can be adjusted, it is okay not to lock them.
153 //
154 //  It's also possible to lock exclusive-use resources just for debugging.
155 //
156 //Arguments:
157 //  lockID:              Lock ID
158 //  lockp:       Lock variable's pointer
159 //  CtrlFuncp:           Resource control functions pointer
160 //
161 //Return values:
162 //  TRUE:                  Locked (the previously stored ID)
163 //  OS_LOCK_SUCCESS:     Lock success
164 //----------------------------------------------------------------------
165 s32     OS_TryLockByWord(u16 lockID, OSLockWord *lockp, void (*crtlFuncp) (void));
166 s32     OS_TryLockCartridge(u16 lockID);
167 s32     OS_TryLockCard(u16 lockID);
168 
169 //----------------------------------------------------------------------
170 //          Read the lock variable's owner module ID
171 //
172 //- This reads the lock variable's owner module ID.
173 //- You can check which processor has ownership rights if the module ID is non-zero.
174 //
175 //In the case of a shared resource, only the state of the main processor side having ownership rights can be maintained by disabling interrupts.
176 //
177 //  In other states, it might be changed by the sub processor.
178 //- The lock variable may not necessarily be unlocked even if owner module ID is 0.
179 //
180 //Arguments:
181 //  lockp:       Lock variable's pointer
182 //
183 //Return values:    Owner module ID
184 //
185 //*Note: Be aware that byte access cannot be performed to the main memory unless it is through a cache.
186 //
187 //  Thus, as a basic rule, you should use OS_ReadOwnerOfLockWord() for main memory.
188 //----------------------------------------------------------------------
189 u16     OS_ReadOwnerOfLockWord(OSLockWord *lockp);
190 #define OS_ReadOwnerOfLockCartridge()  OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CTRDG_LOCK_BUF )
191 #define OS_ReadOwnerOfLockCard()       OS_ReadOwnerOfLockWord( (OSLockWord *)HW_CARD_LOCK_BUF  )
192 
193 
194 
195 /*---------------------------------------------------------------------------*
196   Name:         OS_GetLockID
197 
198   Description:  Get lock ID.
199 
200   Arguments:    None.
201 
202   Returns:      OS_LOCK_ID_ERROR, if fail to get ID
203 
204                 if ARM9
205                    0x40-0x6f:       lockID
206                 else if ARM7
207                    0x80-0xaf:       lockID
208                 endif
209 
210                 *Notice:  ID is allocated only 48 pattern at a highest.
211 
212  *---------------------------------------------------------------------------*/
213 s32     OS_GetLockID(void);
214 
215 
216 /*---------------------------------------------------------------------------*
217   Name:         OS_ReleaseLockID
218 
219   Description:  Release lock ID.
220 
221   Arguments:    lockID: id to tend to release.
222 
223   Returns:      None.
224  *---------------------------------------------------------------------------*/
225 void    OS_ReleaseLockID(u16 lockID);
226 
227 
228 
229 #ifdef SDK_TWL
230 //================================================================
231 //   Private Functions
232 //   These functions are for internal use. Never call them from the application.
233 #define OSi_SYNCTYPE_SENDER 0
234 #define OSi_SYNCTYPE_RECVER 1
235 
236 #define OSi_SYNCVAL_NOT_READY 0
237 #define OSi_SYNCVAL_READY     1
238 
239 void OSi_SyncWithOtherProc( int type, void* syncBuf );
240 
OSi_SetSyncValue(u8 n)241 static inline void OSi_SetSyncValue( u8 n )
242 {
243 	*(vu8*)(HW_INIT_LOCK_BUF+4) = n;
244 }
OSi_GetSyncValue(void)245 static inline u8 OSi_GetSyncValue( void )
246 {
247 	return *(vu8*)(HW_INIT_LOCK_BUF+4);
248 }
249 
250 #endif
251 
252 
253 //--------------------------------------------------------------------------------
254 #ifdef __cplusplus
255 } /* extern "C" */
256 #endif
257 
258 /* NITRO_OS_SPINLOCK_H_ */
259 #endif
260