1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - CARD - libraries
3   File:     card_common.h
4 
5   Copyright 2007-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-26#$
14   $Rev: 10827 $
15   $Author: yosizaki $
16 
17  *---------------------------------------------------------------------------*/
18 #ifndef NITRO_LIBRARIES_CARD_COMMON_H__
19 #define NITRO_LIBRARIES_CARD_COMMON_H__
20 
21 
22 #include <nitro/card/common.h>
23 #include <nitro/card/backup.h>
24 
25 
26 #include "../include/card_utility.h"
27 #include "../include/card_task.h"
28 #include "../include/card_command.h"
29 
30 
31 
32 #ifdef __cplusplus
33 extern  "C"
34 {
35 #endif
36 
37 
38 /*---------------------------------------------------------------------------*/
39 /* Constants */
40 
41 // CARD internal state
42 enum
43 {
44     // Initialized
45     CARD_STAT_INIT = (1 << 0),
46 
47     // PXI command initialized (ARM9)
48     CARD_STAT_INIT_CMD = (1 << 1),
49 
50     // A command was issued but has not completed. (ARM9)
51     // This also includes the state before processing in the WaitForTask function.
52     CARD_STAT_BUSY = (1 << 2),
53 
54     // There is a transferred task (ARM9/ARM7)
55     CARD_STAT_TASK = (1 << 3),
56 
57     // Waiting to be notified that a request from the ARM7 has completed (ARM9)
58     CARD_STAT_WAITFOR7ACK = (1 << 5),
59 
60     // Currently requesting cancellation
61     CARD_STAT_CANCEL = (1 << 6)
62 };
63 
64 #define CARD_UNSYNCHRONIZED_BUFFER  (void*)0x80000000
65 
66 typedef enum
67 {
68     CARD_TARGET_NONE,
69     CARD_TARGET_ROM,
70     CARD_TARGET_BACKUP,
71     CARD_TARGET_RW
72 }
73 CARDTargetMode;
74 
75 typedef u32 CARDAccessLevel;
76 #define CARD_ACCESS_LEVEL_NONE      0x0000UL
77 #define CARD_ACCESS_LEVEL_BACKUP_R  0x0001UL
78 #define CARD_ACCESS_LEVEL_BACKUP_W  0x0002UL
79 #define CARD_ACCESS_LEVEL_BACKUP    (u32)(CARD_ACCESS_LEVEL_BACKUP_R | CARD_ACCESS_LEVEL_BACKUP_W)
80 #define CARD_ACCESS_LEVEL_ROM       0x0004UL
81 #define CARD_ACCESS_LEVEL_FULL      (u32)(CARD_ACCESS_LEVEL_BACKUP | CARD_ACCESS_LEVEL_ROM)
82 
83 
84 /*---------------------------------------------------------------------------*/
85 /* Declarations */
86 
87 typedef s32 CARDiOwner;
88 
89 // CARD common parameters
90 typedef struct CARDiCommon
91 {
92     // Common memory for request communications
93     CARDiCommandArg *cmd;
94 
95     // Status flag
96     volatile u32    flag;
97 
98     // Default task priority
99     u32             priority;
100 
101 #if	defined(SDK_ARM9)
102     // Threshold value for invalidating the entire cache when reading from a ROM.
103     // FlushAll is more efficient than FlushRange past a fixed size.
104     u32     flush_threshold_ic;
105     u32     flush_threshold_dc;
106 #endif
107 
108     // Card access rights management.
109     // Take exclusive control of the card/backup in the processor.
110     // This is necessary because multiple asynchronous functions (Rom and Backup) that use card access may be called from the same thread.
111     //
112     //
113     // This follows a lock-ID because OSMutex follows a thread
114     volatile CARDiOwner lock_owner;    // ==s32 with Error status
115     volatile int        lock_ref;
116     OSThreadQueue       lock_queue[1];
117     CARDTargetMode      lock_target;
118 
119     // Task thread information
120     struct
121     {
122         OSThread    context[1];
123         u8          stack[0x400];
124     }
125     thread;
126 
127 #if defined(SDK_ARM7)
128     // New task procedure format
129     CARDTask        task[1];
130     CARDTaskQueue   task_q[1];
131     // The most recent command from the ARM9
132     int             command;
133     u8              padding[20];
134 #else
135     // Old task procedure format
136     void          (*task_func) (struct CARDiCommon *);
137     // User callback and arguments
138     MIDmaCallback   callback;
139     void           *callback_arg;
140     // Thread that waits for tasks to complete
141     OSThreadQueue   busy_q[1];
142     // API task parameters
143     u32                     src;
144     u32                     dst;
145     u32                     len;
146     u32                     dma;
147     const CARDDmaInterface *DmaCall;
148     // Information for managing backup commands
149     CARDRequest             req_type;
150     int                     req_retry;
151     CARDRequestMode         req_mode;
152     OSThread               *current_thread_9;
153 //    u8      padding[32];
154 #endif
155 
156 }
157 CARDiCommon;
158 
159 
160 SDK_COMPILER_ASSERT(sizeof(CARDiCommon) % 32 == 0);
161 
162 
163 /*---------------------------------------------------------------------------*/
164 /* Variables */
165 
166 extern CARDiCommon cardi_common;
167 extern u32  cardi_rom_base;
168 
169 
170 /*---------------------------------------------------------------------------*/
171 /* functions */
172 
173 /*---------------------------------------------------------------------------*
174   Name:         CARDi_ExecuteOldTypeTask
175 
176   Description:  Gives asynchronous processing over to a worker thread, and runs synchronous processing here.
177                 (It is up to this function's caller to guarantee that the task thread has already been locked for exclusive control by the CARDi_WaitForTask function)
178 
179 
180   Arguments:    task       Task function to set
181                 async      TRUE if asynchronous processing is desired.
182 
183   Returns:      None.
184  *---------------------------------------------------------------------------*/
185 BOOL CARDi_ExecuteOldTypeTask(void (*task) (CARDiCommon *), BOOL async);
186 
187 /*---------------------------------------------------------------------------*
188   Name:         CARDi_WaitForTask
189 
190   Description:  Waits until the task thread's usage rights are available.
191                 (It is up to this function's caller to guarantee that the designated bus is locked)
192 
193   Arguments:    p            The library's work buffer
194                 restart      TRUE if the next task should be started
195                 callback     Callback function after completion of access
196                 callback_arg  Argument of callback function
197 
198   Returns:      None.
199  *---------------------------------------------------------------------------*/
200 BOOL CARDi_WaitForTask(CARDiCommon *p, BOOL restart, MIDmaCallback callback, void *callback_arg);
201 
202 /*---------------------------------------------------------------------------*
203   Name:         CARDi_EndTask
204 
205   Description:  Sends a notification that a task is complete and releases the usage rights of the task thread.
206 
207   Arguments:    p            Library's work buffer (passed by argument for efficiency)
208 
209   Returns:      None.
210  *---------------------------------------------------------------------------*/
211 void CARDi_EndTask(CARDiCommon *p);
212 
213 void CARDi_OldTypeTaskThread(void *arg);
214 
215 
216 /*---------------------------------------------------------------------------*
217   Name:         CARDi_GetTargetMode
218 
219   Description:  Gets the current lock target of the CARD bus.
220 
221   Arguments:    None.
222 
223   Returns:      One of the three states indicated by CARDTargetMode.
224  *---------------------------------------------------------------------------*/
CARDi_GetTargetMode(void)225 SDK_INLINE CARDTargetMode CARDi_GetTargetMode(void)
226 {
227     return cardi_common.lock_target;
228 }
229 
230 /*---------------------------------------------------------------------------*
231   Name:         CARDi_LockResource
232 
233   Description:  Resource exclusive lock
234 
235   Arguments:    owner      lock-ID indicating the owner of the lock
236                 target     Resource target on the card bus to be locked
237 
238   Returns:      None.
239  *---------------------------------------------------------------------------*/
240 void CARDi_LockResource(CARDiOwner owner, CARDTargetMode target);
241 
242 /*---------------------------------------------------------------------------*
243   Name:         CARDi_UnlockResource
244 
245   Description:  Unlocks exclusive control of the resource.
246 
247   Arguments:    owner      lock-ID indicating the owner of the lock
248                 target     Resource target on the card bus to be unlocked
249 
250   Returns:      None.
251  *---------------------------------------------------------------------------*/
252 void CARDi_UnlockResource(CARDiOwner owner, CARDTargetMode target);
253 
254 /*---------------------------------------------------------------------------*
255   Name:         CARDi_GetAccessLevel
256 
257   Description:  Gets the permitted ROM access level.
258 
259   Arguments:    None.
260 
261   Returns:      Permitted ROM access level.
262  *---------------------------------------------------------------------------*/
263 CARDAccessLevel CARDi_GetAccessLevel(void);
264 
265 /*---------------------------------------------------------------------------*
266   Name:         CARDi_WaitAsync
267 
268   Description:  Waits for asynchronous completion.
269 
270   Arguments:    None.
271 
272   Returns:      TRUE if the latest processing result is CARD_RESULT_SUCCESS.
273  *---------------------------------------------------------------------------*/
274 BOOL    CARDi_WaitAsync(void);
275 
276 /*---------------------------------------------------------------------------*
277   Name:         CARDi_TryWaitAsync
278 
279   Description:  Attempts to wait for asynchronous completion and returns control immediately whether it succeeds or fails.
280 
281   Arguments:    None.
282 
283   Returns:      TRUE if the most recent asynchronous process has completed.
284  *---------------------------------------------------------------------------*/
285 BOOL    CARDi_TryWaitAsync(void);
286 
287 void CARDi_InitResourceLock(void);
288 
289 
290 
291 void CARDi_InitCommand(void);
292 
293 
294 #ifdef __cplusplus
295 } // extern "C"
296 #endif
297 
298 
299 
300 #endif // NITRO_LIBRARIES_CARD_COMMON_H__
301