1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - CARD - libraries
3   File:     card_pullOut.c
4 
5   Copyright 2007-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 
20 #include <nitro/card/rom.h>
21 #include <nitro/card/pullOut.h>
22 
23 #include "card_rom.h"
24 
25 //---- User callback for card pulled out
26 static CARDPulledOutCallback CARD_UserCallback;
27 
28 //---- Flag to be pulled out
29 static u32 CARDiSlotResetCount;
30 static BOOL CARDi_IsPulledOutFlag = FALSE;
31 
32 static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err);
33 static void CARDi_SendtoPxi(u32 data, u32 wait);
34 
35 /*---------------------------------------------------------------------------*
36   Name:         CARD_InitPulledOutCallback
37 
38   Description:  Initialize callback setting.
39 
40   Arguments:    None.
41 
42   Returns:      None.
43  *---------------------------------------------------------------------------*/
CARD_InitPulledOutCallback(void)44 void CARD_InitPulledOutCallback(void)
45 {
46     PXI_Init();
47 
48     CARDiSlotResetCount = 0;
49     CARDi_IsPulledOutFlag = FALSE;
50 
51     //---- Set PXI callback
52     PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CARD, CARDi_PulledOutCallback);
53 
54     //---- Init user callback
55     CARD_UserCallback = NULL;
56 }
57 
58 /*---------------------------------------------------------------------------*
59   Name:         CARDi_PulledOutCallback
60 
61   Description:  Callback to receive data from PXI.
62 
63   Arguments:    tag: Tag from PXI (unused)
64                 data: Data from PXI
65                 err: Error bit (unused)
66 
67   Returns:      None.
68  *---------------------------------------------------------------------------*/
CARDi_PulledOutCallback(PXIFifoTag tag,u32 data,BOOL err)69 static void CARDi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err)
70 {
71 #pragma unused( tag, err )
72 
73     u32     command = data & CARD_PXI_COMMAND_MASK;
74 
75     //---- Receive message 'pulled out'
76     if (command == CARD_PXI_COMMAND_PULLED_OUT)
77     {
78         if (CARDi_IsPulledOutFlag == FALSE)
79         {
80             BOOL    isTerminateImm = TRUE;
81 
82             CARDi_IsPulledOutFlag = TRUE;
83             CARDi_NotifyEvent(CARD_EVENT_PULLEDOUT, NULL);
84 
85             //---- Call user callback
86             if (CARD_UserCallback)
87             {
88                 isTerminateImm = CARD_UserCallback();
89             }
90 
91             //---- Terminate
92             if (isTerminateImm)
93             {
94                 CARD_TerminateForPulledOut();
95             }
96         }
97     }
98     else if (command == CARD_PXI_COMMAND_RESET_SLOT)
99     {
100         CARDiSlotResetCount += 1;
101         CARDi_IsPulledOutFlag = FALSE;
102         CARDi_NotifyEvent(CARD_EVENT_SLOTRESET, NULL);
103     }
104     else
105     {
106 #ifndef SDK_FINALROM
107         OS_Panic("illegal card pxi command.");
108 #else
109         OS_Panic("");
110 #endif
111     }
112 }
113 
114 /*---------------------------------------------------------------------------*
115   Name:         CARD_SetPulledOutCallback
116 
117   Description:  Set user callback for card being pulled out.
118 
119   Arguments:    callback: Callback
120 
121   Returns:      None.
122  *---------------------------------------------------------------------------*/
CARD_SetPulledOutCallback(CARDPulledOutCallback callback)123 void CARD_SetPulledOutCallback(CARDPulledOutCallback callback)
124 {
125     CARD_UserCallback = callback;
126 }
127 
128 /*---------------------------------------------------------------------------*
129   Name:         CARD_IsPulledOut
130 
131   Description:  Return if have detected card pulled out.
132 
133   Arguments:    None.
134 
135   Returns:      TRUE if detected.
136  *---------------------------------------------------------------------------*/
CARD_IsPulledOut(void)137 BOOL CARD_IsPulledOut(void)
138 {
139     return CARDi_IsPulledOutFlag;
140 }
141 
142 //================================================================================
143 //         TERMINATION
144 //================================================================================
145 /*---------------------------------------------------------------------------*
146   Name:         CARD_TerminateForPulledOut
147 
148   Description:  Terminate for pulling out card.
149                 Send message to do termination to ARM7.
150 
151   Arguments:    None.
152 
153   Returns:      None.
154  *---------------------------------------------------------------------------*/
CARD_TerminateForPulledOut(void)155 void CARD_TerminateForPulledOut(void)
156 {
157     //---- If folding, power off
158     if (PAD_DetectFold())
159     {
160         (void)PM_ForceToPowerOff();
161         //---- Power off is always successful so this point is never reached
162     }
163 
164     // When the cover is not closed, send Terminate command because the ARM7 processor must be stopped
165 #ifdef SDK_TWL
166     if ( OS_IsRunOnTwl() )
167     {
168         // End processing
169         // If making an ARM7 processor request, wait for the callback function to complete
170         PMi_ExecutePostExitCallbackList();
171     }
172 #endif // SDK_TWL
173     //---- Send 'TERMINATE' command to ARM7, and terminate itself immediately
174     CARDi_SendtoPxi(CARD_PXI_COMMAND_TERMINATE, 1);
175 
176     //---- Stop all dma
177     MI_StopAllDma();
178 #ifdef SDK_TWL
179 	if ( OS_IsRunOnTwl() )
180 	{
181 		MI_StopAllNDma();
182 	}
183 #endif
184 
185     OS_Terminate();
186 }
187 
188 /*---------------------------------------------------------------------------*
189   Name:         CARDi_CheckPulledOutCore
190 
191   Description:  Main processing for the card removal detection function.
192                 The card bus must be locked.
193 
194   Arguments:    id: ROM-ID read from the card
195 
196   Returns:      None.
197  *---------------------------------------------------------------------------*/
CARDi_CheckPulledOutCore(u32 id)198 void CARDi_CheckPulledOutCore(u32 id)
199 {
200     //---- Card ID IPL had read
201     vu32    iplCardID = *(vu32 *)(HW_BOOT_CHECK_INFO_BUF);
202     //---- If card removal has been detected, simulate PXI-notification from ARM7
203     if (id != (u32)iplCardID)
204     {
205         OSIntrMode bak_cpsr = OS_DisableInterrupts();
206         CARDi_PulledOutCallback(PXI_FIFO_TAG_CARD, CARD_PXI_COMMAND_PULLED_OUT, FALSE);
207         (void)OS_RestoreInterrupts(bak_cpsr);
208     }
209 }
210 
211 /*---------------------------------------------------------------------------*
212   Name:         CARD_CheckPulledOut
213 
214   Description:  Get whether system has detected pulled out card
215                 by comparing IPL cardID with current cardID
216                 (notice that once a card is pulled out, IDs are absolutely different)
217 
218   Arguments:    None.
219 
220   Returns:      TRUE if current cardID is equal to IPL cardID.
221  *---------------------------------------------------------------------------*/
CARD_CheckPulledOut(void)222 void CARD_CheckPulledOut(void)
223 {
224     CARDi_CheckPulledOutCore(CARDi_ReadRomID());
225 }
226 
227 //================================================================================
228 //         SEND PXI COMMAND
229 //================================================================================
230 /*---------------------------------------------------------------------------*
231   Name:         CARDi_SendtoPxi
232 
233   Description:  Send data via PXI.
234 
235   Arguments:    data: Data to send
236 
237   Returns:      None.
238  *---------------------------------------------------------------------------*/
CARDi_SendtoPxi(u32 data,u32 wait)239 static void CARDi_SendtoPxi(u32 data, u32 wait)
240 {
241     while (PXI_SendWordByFifo(PXI_FIFO_TAG_CARD, data, FALSE) != PXI_FIFO_SUCCESS)
242     {
243         SVC_WaitByLoop((s32)wait);
244     }
245 }
246 
247 
248 /*---------------------------------------------------------------------------*
249  * Internal functions
250  *---------------------------------------------------------------------------*/
251 
252 /*---------------------------------------------------------------------------*
253   Name:         CARDi_GetSlotResetCount
254 
255   Description:  Get the number of times the slot detects reinsertion.
256                 Simply return the number of times the CARDi_ResetSlotStatus function was called.
257 
258   Arguments:    None.
259 
260   Returns:      Number of times slot detects reinsertion. Initial value was 0.
261  *---------------------------------------------------------------------------*/
CARDi_GetSlotResetCount(void)262 u32     CARDi_GetSlotResetCount(void)
263 {
264     return CARDiSlotResetCount;
265 }
266 
267 /*---------------------------------------------------------------------------*
268   Name:         CARDi_IsPulledOutEx
269 
270   Description:  Determines whether the card was pulled from the slot.
271 
272   Arguments:    count: The number of times the slot was reinserted as confirmed last time.
273                        Get using the CARDi_GetSlotResetCount function.
274 
275   Returns:      If the specified number of times the slot detected reinsertion is the same as the current and the card is currently pulled out, TRUE.
276 
277  *---------------------------------------------------------------------------*/
CARDi_IsPulledOutEx(u32 count)278 BOOL    CARDi_IsPulledOutEx(u32 count)
279 {
280     BOOL    result = FALSE;
281     OSIntrMode  bak = OS_DisableInterrupts();
282     {
283         result = ((count == CARDi_GetSlotResetCount()) && !CARD_IsPulledOut());
284     }
285     (void)OS_RestoreInterrupts(bak);
286     return result;
287 }
288