1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - CTRDG - libraries - ARM9
3 File: ctrdg_proc.c
4
5 Copyright 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:: 2007-11-15#$
14 $Rev: 2414 $
15 $Author: hatamoto_minoru $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 #include <../include/ctrdg_work.h>
19
20 extern void CTRDGi_InitCommon(void);
21 extern void CTRDGi_SendtoPxi(u32 data);
22
23 //---- PXI callbacks
24 static void CTRDGi_CallbackForInitModuleInfo(PXIFifoTag tag, u32 data, BOOL err);
25 static void CTRDGi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err);
26 static void CTRDGi_CallbackForSetPhi(PXIFifoTag tag, u32 data, BOOL err);
27
28 extern CTRDGWork CTRDGi_Work;
29
30 //---- Lock for pxi
31 static int CTRDGi_Lock = FALSE;
32
33 //---- User callback
34 CTRDGPulledOutCallback CTRDG_UserCallback = NULL;
35
36 /* Game Pak removal callback is not called twice */
37 static BOOL isCartridgePullOut = FALSE;
38 static BOOL skipCheck = FALSE;
39 static BOOL ctrdg_already_pullout = FALSE;
40
41 #ifndef SDK_TWLLTD
42 //---- initialized flag
43 static BOOL isInitialized = FALSE;
44 #endif
45
46 //================================================================================
47 // INIT
48 //================================================================================
49 /*---------------------------------------------------------------------------*
50 Name: CTRDGi_IsInitialized
51
52 Description: check weather ctrdg library is initialized
53 (for internal use)
54
55 Arguments: None
56
57 Returns: TRUE ... initialized already
58 FALSE... not initialized
59 *---------------------------------------------------------------------------*/
60 #ifndef SDK_TWLLTD
CTRDGi_IsInitialized(void)61 BOOL CTRDGi_IsInitialized(void)
62 {
63 return isInitialized;
64 }
65 #endif
66
67 /*---------------------------------------------------------------------------*
68 Name: CTRDG_Init
69
70 Description: initialize cartridge functions
71
72 Arguments: None
73
74 Returns: None
75 *---------------------------------------------------------------------------*/
76 #ifndef SDK_TWLLTD
CTRDG_Init(void)77 SDK_WEAK_SYMBOL void CTRDG_Init(void)
78 {
79 if (isInitialized)
80 {
81 return;
82 }
83 isInitialized = TRUE;
84
85 CTRDGi_InitCommon();
86
87 /* So that the Game Pak removal callback cannot be called two or more times */
88 ctrdg_already_pullout = FALSE;
89
90 #ifndef SDK_SMALL_BUILD
91 //---- Setting PXI
92 PXI_Init();
93 while (!PXI_IsCallbackReady(PXI_FIFO_TAG_CTRDG, PXI_PROC_ARM7))
94 {
95 }
96 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG, CTRDGi_CallbackForInitModuleInfo);
97
98 CTRDGi_InitModuleInfo();
99
100 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG, NULL); // To avoid warning by overriding
101 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG, CTRDGi_PulledOutCallback);
102
103 //---- Init user callback
104 CTRDG_UserCallback = NULL;
105
106 // Create a TaskThread to use the asynchronous version of the AGBBackup access function
107 {
108 static CTRDGiTaskWork CTRDGTaskList;
109 CTRDGi_InitTaskThread(&CTRDGTaskList);
110 }
111
112 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG_PHI, CTRDGi_CallbackForSetPhi);
113
114 /*
115 * Access is disabled, as long as the user has not explicitly specified 'enable'.
116 * (If it is not an option Game Pak, writing is also not allowed)
117 */
118 #if defined(SDK_ARM9)
119 CTRDG_Enable(FALSE);
120 #endif
121 #endif // SDK_SMALL_BUILD
122 }
123 #endif // SDK_TWLLTD
124
125 /*---------------------------------------------------------------------------*
126 Name: CTRDGi_InitModuleInfo
127
128 Description: Initialize the information of peripheral device around cartridge.
129
130 Because try lock cartridge, in case another processor had locked,
131 wait until it was released.
132
133 To avoid other bus master interrupts,
134 DMA1 is used for accessing cartridge.
135 This is a compatibility in future.
136
137 Arguments: None.
138
139 Returns: None.
140 *---------------------------------------------------------------------------*/
141 static CTRDGHeader headerBuf ATTRIBUTE_ALIGN(32);
142
CTRDGi_InitModuleInfo(void)143 void CTRDGi_InitModuleInfo(void)
144 {
145 #ifndef SDK_SMALL_BUILD
146
147 static BOOL isInfoInitialized;
148 CTRDGLockByProc lockInfo;
149 OSIrqMask lastIE;
150 BOOL lastIME;
151
152 if (isInfoInitialized)
153 {
154 return;
155 }
156 isInfoInitialized = TRUE;
157
158 if (!(reg_OS_PAUSE & REG_OS_PAUSE_CHK_MASK))
159 {
160 return;
161 }
162
163 lastIE = OS_SetIrqMask(OS_IE_SPFIFO_RECV);
164 lastIME = OS_EnableIrq();
165
166 //---- Get privilege for accessing cartridge
167 CTRDGi_LockByProcessor(CTRDGi_Work.lockID, &lockInfo);
168
169 //---- Read information of peripheral devices
170 {
171 MIProcessor proc = MI_GetMainMemoryPriority();
172 CTRDGRomCycle rc;
173
174 // Set the latest access cycle
175 CTRDGi_ChangeLatestAccessCycle(&rc);
176
177 // Set main memory priority for avoiding DMA stole by ARM7 access
178 MI_SetMainMemoryPriority(MI_PROCESSOR_ARM9);
179
180 // 16-bit access to have much enough access interval
181 DC_InvalidateRange(&((u8 *)&headerBuf)[0x80], sizeof(headerBuf) - 0x80);
182 MI_DmaCopy16(1, (void *)(HW_CTRDG_ROM + 0x80),
183 &((u8 *)&headerBuf)[0x80], sizeof(headerBuf) - 0x80);
184
185 // Restore main memory priority
186 MI_SetMainMemoryPriority(proc);
187
188 // Restore access cycle
189 CTRDGi_RestoreAccessCycle(&rc);
190 }
191
192 //---- Release privilege for accessing Game Pak
193 CTRDGi_UnlockByProcessor(CTRDGi_Work.lockID, &lockInfo);
194
195 // Update Game Pak data only if a Game Pak was inserted during the previous check or if a software reset has not even been executed once
196 //
197 if ((*(u8 *)HW_IS_CTRDG_EXIST) || !(*(u8 *)HW_SET_CTRDG_MODULE_INFO_ONCE))
198 {
199 //---- Copy the information of peripheral devices to system area
200 int i;
201 CTRDGHeader *chb = &headerBuf;
202 CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
203
204 cip->moduleID.raw = chb->moduleID;
205 for (i = 0; i < 3; i++)
206 {
207 cip->exLsiID[i] = chb->exLsiID[i];
208 }
209 cip->makerCode = chb->makerCode;
210 cip->gameCode = chb->gameCode;
211
212 // Check whether or not a Game Pak is inserted
213 *(u8 *)HW_IS_CTRDG_EXIST = (u8)((CTRDG_IsExisting())? 1 : 0);
214 // TRUE if the Game Pak information has been updated even once
215 (*(u8 *)HW_SET_CTRDG_MODULE_INFO_ONCE) = TRUE;
216 }
217
218 //---- Copy Nintendo logo data in the ARM9 system ROM to main memory
219 MI_CpuCopy32((void *)CTRDG_SYSROM9_NINLOGO_ADR, &headerBuf.nintendoLogo,
220 sizeof(headerBuf.nintendoLogo));
221 DC_FlushAll();
222
223 //---- Send message to ARM7
224 CTRDGi_SendtoPxi(CTRDG_PXI_COMMAND_INIT_MODULE_INFO |
225 (((u32)&headerBuf - HW_MAIN_MEM) >> 5) << CTRDG_PXI_COMMAND_PARAM_SHIFT);
226
227 //---- Wait until ARM7 finishes initializing
228 while (CTRDGi_Work.subpInitialized != TRUE)
229 {
230 SVC_WaitByLoop(1);
231 }
232
233 (void)OS_RestoreIrq(lastIME);
234 (void)OS_SetIrqMask(lastIE);
235
236 #endif // SDK_SMALL_BUILD
237 }
238
239 /*---------------------------------------------------------------------------*
240 Name: CTRDGi_CallbackForInitModuleInfo
241
242 Description: Callback to receive data from PXI.
243
244 Arguments: tag: Tag from PXI (unused)
245 data: Data from PXI
246 err: Error bit (unused)
247
248 Returns: None.
249 *---------------------------------------------------------------------------*/
CTRDGi_CallbackForInitModuleInfo(PXIFifoTag tag,u32 data,BOOL err)250 static void CTRDGi_CallbackForInitModuleInfo(PXIFifoTag tag, u32 data, BOOL err)
251 {
252 #pragma unused( tag, err )
253
254 if ((data & CTRDG_PXI_COMMAND_MASK) == CTRDG_PXI_COMMAND_INIT_MODULE_INFO)
255 {
256 CTRDGi_Work.subpInitialized = TRUE;
257 }
258 else
259 {
260 #ifndef SDK_FINALROM
261 OS_Panic("illegal Cartridge pxi command.");
262 #else
263 OS_Panic("");
264 #endif
265 }
266 }
267
268 /*---------------------------------------------------------------------------*
269 Name: CTRDG_DummyInit
270
271 Description: Initialize for smaller CTRDG.
272 Called from user defined CTRDG_Init.
273
274 Arguments: None
275
276 Returns: None
277 *---------------------------------------------------------------------------*/
278 #ifndef SDK_TWLLTD
279 static void CTRDGi_DummyCallback(PXIFifoTag tag, u32 data, BOOL err);
CTRDG_DummyInit(void)280 void CTRDG_DummyInit(void)
281 {
282 CTRDGi_InitCommon();
283
284 //---- set dummy callback
285 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG, NULL); // to avoid warning by overriding
286 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_CTRDG, CTRDGi_DummyCallback);
287
288 //---- send INIT_MODULE_INFO for sync with ARM7
289 CTRDGi_SendtoPxi(CTRDG_PXI_COMMAND_INIT_MODULE_INFO);
290 }
291
292 //---- dummy callback for smaller CTRDG.
CTRDGi_DummyCallback(PXIFifoTag tag,u32 data,BOOL err)293 static void CTRDGi_DummyCallback(PXIFifoTag tag, u32 data, BOOL err)
294 {
295 #pragma unused( tag, data, err )
296 // do nothing
297 }
298 #endif // ifndef SDK_TWLLTD
299
300 //================================================================================
301 // PULLOUT PROCS
302 //================================================================================
303 /*---------------------------------------------------------------------------*
304 Name: CTRDGi_PulledOutCallback
305
306 Description: Callback to receive data from PXI.
307
308 Arguments: tag: Tag from PXI (unused)
309 data: Data from PXI
310 err: Error bit (unused)
311
312 Returns: None.
313 *---------------------------------------------------------------------------*/
CTRDGi_PulledOutCallback(PXIFifoTag tag,u32 data,BOOL err)314 static void CTRDGi_PulledOutCallback(PXIFifoTag tag, u32 data, BOOL err)
315 {
316 #pragma unused( tag, err )
317
318 //---- Receive message 'pulled out'
319 if ((data & CTRDG_PXI_COMMAND_MASK) == CTRDG_PXI_COMMAND_PULLED_OUT)
320 {
321 if (ctrdg_already_pullout == FALSE)
322 {
323 BOOL isTerminateImm = FALSE;
324
325 //---- Call user callback
326 if (CTRDG_UserCallback)
327 {
328 isTerminateImm = CTRDG_UserCallback();
329 }
330
331 //---- Terminate
332 if (isTerminateImm)
333 {
334 CTRDG_TerminateForPulledOut();
335 }
336 /* If called once, it is not called again */
337 ctrdg_already_pullout = TRUE;
338 }
339 }
340 else
341 {
342 #ifndef SDK_FINALROM
343 OS_Panic("illegal Cartridge pxi command.");
344 #else
345 OS_Panic("");
346 #endif
347 }
348 }
349
350 /*---------------------------------------------------------------------------*
351 Name: CTRDG_SetPulledOutCallback
352
353 Description: Set user callback for being pulled-out Game Pak.
354
355 Arguments: callback: Callback
356
357 Returns: None.
358 *---------------------------------------------------------------------------*/
CTRDG_SetPulledOutCallback(CTRDGPulledOutCallback callback)359 void CTRDG_SetPulledOutCallback(CTRDGPulledOutCallback callback)
360 {
361 #ifndef SDK_TWLLTD
362 SDK_ASSERT(CTRDGi_IsInitialized());
363 #endif
364 CTRDG_UserCallback = callback;
365 }
366
367 /*---------------------------------------------------------------------------*
368 Name: CTRDG_TerminateForPulledOut
369
370 Description: Terminate for pulling out Game Pak.
371 Send message to do termination to ARM7.
372
373 Arguments: None.
374
375 Returns: None.
376 *---------------------------------------------------------------------------*/
CTRDG_TerminateForPulledOut(void)377 void CTRDG_TerminateForPulledOut(void)
378 {
379 #ifndef SDK_TWLLTD
380 SDK_ASSERT(CTRDGi_IsInitialized());
381 #endif
382
383 //---- Send 'TERMINATE' command to ARM7 and terminate itself immediately
384 CTRDGi_SendtoPxi(CTRDG_PXI_COMMAND_TERMINATE);
385
386 OS_Terminate();
387 }
388
389 /*---------------------------------------------------------------------------*
390 Name: CTRDG_SendToARM7
391
392 Description: Send data to ARM7.
393
394 Arguments: arg: Data to send
395
396 Returns: None.
397 *---------------------------------------------------------------------------*/
CTRDG_SendToARM7(void * arg)398 void CTRDG_SendToARM7(void *arg)
399 {
400 (void)PXI_SendWordByFifo(PXI_FIFO_TAG_CTRDG_Ex, (u32)arg, FALSE);
401 }
402
403 /*---------------------------------------------------------------------------*
404 Name: CTRDG_CheckPulledOut
405
406 Description: Game Pak is pulled out.
407
408 Arguments: None.
409
410 Returns: None.
411 *---------------------------------------------------------------------------*/
CTRDG_CheckPulledOut(void)412 void CTRDG_CheckPulledOut(void)
413 {
414 #ifndef SDK_TWLLTD
415 SDK_ASSERT(CTRDGi_IsInitialized());
416 #endif
417
418 //---- If skip flag or Game Pak already pulled out.
419 if (skipCheck || isCartridgePullOut)
420 {
421 return;
422 }
423
424 //---------------- Check Game Pak pulled out
425 //---- Check Game Pak
426 isCartridgePullOut = CTRDG_IsPulledOut();
427
428 //---- If no Game Pak...
429 if (!CTRDG_IsExisting())
430 {
431 if (!isCartridgePullOut)
432 {
433 skipCheck = TRUE;
434 return;
435 }
436 }
437
438 //---------------- If Game Pak pulled out, tell that to ARM9
439 if (isCartridgePullOut)
440 {
441 /* Call in the same way as functions that are called by PXI from ARM7. */
442 /* Arguments forcibly set to those used when processing occurs. */
443 CTRDGi_PulledOutCallback(PXI_FIFO_TAG_CTRDG, CTRDG_PXI_COMMAND_PULLED_OUT, NULL);
444 }
445 }
446
447 /*---------------------------------------------------------------------------*
448 Name: CTRDG_SetPhiClock
449
450 Description: Set ARM9 and ARM7 PHI output clock.
451
452 Arguments: clock: PHI clock to set (MIPhiClock value)
453
454 Returns: None.
455 *---------------------------------------------------------------------------*/
CTRDG_SetPhiClock(CTRDGPhiClock clock)456 void CTRDG_SetPhiClock(CTRDGPhiClock clock)
457 {
458 u32 data = ((u32)clock << CTRDG_PXI_COMMAND_PARAM_SHIFT) | CTRDG_PXI_COMMAND_SET_PHI;
459
460 #ifndef SDK_TWLLTD
461 SDK_ASSERT(CTRDGi_IsInitialized());
462 #endif
463
464 //---- Check parameter range
465 SDK_ASSERT((u32)clock <= CTRDG_PHI_CLOCK_16MHZ);
466
467 //---- Set ARM9 PHI output clock
468 MIi_SetPhiClock((MIiPhiClock) clock);
469
470 //---- Send command to set ARM7 phi clock
471 CTRDGi_Lock = TRUE;
472 while (PXI_SendWordByFifo(PXI_FIFO_TAG_CTRDG_PHI, data, FALSE) != PXI_FIFO_SUCCESS)
473 {
474 SVC_WaitByLoop(1);
475 }
476
477 //---- Wait response
478 while (CTRDGi_Lock)
479 {
480 SVC_WaitByLoop(1);
481 }
482 }
483
484 /*---------------------------------------------------------------------------*
485 Name: CTRDG_CallbackForSetPhi
486
487 Description: Callback from ARM7 to receive PHI clock setting.
488
489 Arguments: tag: Tag from PXI (unused)
490 data: Data from PXI
491 err: Error bit (unused)
492
493 Returns: None.
494 *---------------------------------------------------------------------------*/
CTRDGi_CallbackForSetPhi(PXIFifoTag tag,u32 data,BOOL err)495 static void CTRDGi_CallbackForSetPhi(PXIFifoTag tag, u32 data, BOOL err)
496 {
497 #pragma unused(tag, data, err)
498 CTRDGi_Lock = FALSE;
499 }
500