1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - CTRDG - include
3   File:     ctrdg.c
4 
5   Copyright 2008-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-01-28#$
14   $Rev: 9923 $
15   $Author: yada $
16  *---------------------------------------------------------------------------*/
17 #include <nitro/ctrdg.h>
18 #include <../include/ctrdg_work.h>
19 #include <nitro/os/ARM9/cache.h>
20 
21 //----------------------------------------------------------------------------
22 
23 CTRDGWork CTRDGi_Work;
24 
25 /* cartridge permission */
26 static BOOL CTRDGi_EnableFlag = FALSE;
27 
28 
29 /*---------------------------------------------------------------------------*
30   Name:         CTRDG_IsExistedAtInit
31 
32   Description:  get whether cartridge existed
33 
34   Arguments:    None
35 
36   Returns:      TRUE if existing
37  *---------------------------------------------------------------------------*/
CTRDG_IsExistedAtInit(void)38 static BOOL CTRDG_IsExistedAtInit(void)
39 {
40 #ifdef SDK_TWLLTD
41     return FALSE;
42 #else
43     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
44 
45     return cip->moduleID.raw != 0xffff ? TRUE : FALSE;
46 #endif
47 }
48 
49 /*---------------------------------------------------------------------------*
50   Name:         CTRDGi_InitCommon
51 
52   Description:  common routine called from CTRDG_Init.
53                 keep lockID for cartridge functions.
54 
55   Arguments:    None
56 
57   Returns:      None
58  *---------------------------------------------------------------------------*/
CTRDGi_InitCommon(void)59 void CTRDGi_InitCommon(void)
60 {
61     SVC_CpuClear(0, &CTRDGi_Work, sizeof(CTRDGi_Work), 32);     // use SVC_* intentionally.
62 
63     CTRDGi_Work.lockID = (u16)OS_GetLockID();
64 }
65 
66 /*---------------------------------------------------------------------------*
67   Name:         CTRDG_IsBitID
68 
69   Description:  return whether peripheral device which is specified by bitID exists
70                 in cartridge
71 
72   Arguments:    bitID  bit ID
73 
74   Returns:      TRUE if existed
75  *---------------------------------------------------------------------------*/
76 
CTRDG_IsBitID(u8 bitID)77 BOOL CTRDG_IsBitID(u8 bitID)
78 {
79     return (CTRDG_IsExisting() && CTRDGi_IsBitIDAtInit(bitID));
80 }
81 
82 /*---------------------------------------------------------------------------*
83   Name:         CTRDGi_IsBitIDAtInit
84 
85   Description:  return whether peripheral device which is specified by bitID existed
86                 in cartridge at boot time
87 
88   Arguments:    bitID  bit ID
89 
90   Returns:      TRUE if existed
91  *---------------------------------------------------------------------------*/
CTRDGi_IsBitIDAtInit(u8 bitID)92 BOOL CTRDGi_IsBitIDAtInit(u8 bitID)
93 {
94     BOOL    retval = FALSE;
95 
96     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
97 
98     if (cip->moduleID.raw != 0xffff && cip->moduleID.raw != 0x0000 && ~cip->moduleID.bitID & bitID)
99     {
100         retval = TRUE;
101     }
102 
103     return retval;
104 }
105 
106 /*---------------------------------------------------------------------------*
107   Name:         CTRDG_IsNumberID
108 
109   Description:  return whether peripheral device which is specified by numberID exists
110                 in cartridge
111 
112   Arguments:    numberID  number ID
113 
114   Returns:      TRUE if existed
115  *---------------------------------------------------------------------------*/
CTRDG_IsNumberID(u8 numberID)116 BOOL CTRDG_IsNumberID(u8 numberID)
117 {
118     return (CTRDG_IsExisting() && CTRDGi_IsNumberIDAtInit(numberID));
119 }
120 
121 /*---------------------------------------------------------------------------*
122   Name:         CTRDGi_IsNumberIDAtInit
123 
124   Description:  return whether peripheral device which is specified by numberID existed
125                 in cartridge at boot time
126 
127   Arguments:    numberID  number ID
128 
129   Returns:      TRUE if existed
130  *---------------------------------------------------------------------------*/
CTRDGi_IsNumberIDAtInit(u8 numberID)131 BOOL CTRDGi_IsNumberIDAtInit(u8 numberID)
132 {
133     BOOL    retval = FALSE;
134 
135     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
136 
137     if (cip->moduleID.raw != 0xffff && cip->moduleID.raw != 0x0000)
138     {
139         if (cip->moduleID.numberID == numberID)
140         {
141             retval = TRUE;
142         }
143         else if (!cip->moduleID.disableExLsiID)
144         {
145             if (cip->exLsiID[0] == numberID
146                 || cip->exLsiID[1] == numberID || cip->exLsiID[2] == numberID)
147             {
148                 retval = TRUE;
149             }
150         }
151     }
152 
153     return retval;
154 }
155 
156 /*---------------------------------------------------------------------------*
157   Name:         CTRDG_IsAgbCartridge
158 
159   Description:  return whether AGB cartridge exists
160 
161   Arguments:    None
162 
163   Returns:      TRUE if existed
164  *---------------------------------------------------------------------------*/
CTRDG_IsAgbCartridge(void)165 BOOL CTRDG_IsAgbCartridge(void)
166 {
167     return (CTRDG_IsExisting() && CTRDGi_IsAgbCartridgeAtInit());
168 }
169 
170 /*---------------------------------------------------------------------------*
171   Name:         CTRDG_IsOptionCartridge
172 
173   Description:  return whether option cartridge exists
174 
175   Arguments:    None
176 
177   Returns:      TRUE if existed
178  *---------------------------------------------------------------------------*/
CTRDG_IsOptionCartridge(void)179 BOOL CTRDG_IsOptionCartridge(void)
180 {
181     return (CTRDG_IsExisting() && !CTRDGi_IsAgbCartridgeAtInit());
182 }
183 
184 /*---------------------------------------------------------------------------*
185   Name:         CTRDGi_IsAgbCartridgeAtInit
186 
187   Description:  return whether AGB cartridge existed at boot time
188 
189   Arguments:    None
190 
191   Returns:      TRUE if existed
192  *---------------------------------------------------------------------------*/
CTRDGi_IsAgbCartridgeAtInit(void)193 BOOL CTRDGi_IsAgbCartridgeAtInit(void)
194 {
195     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
196 
197     return cip->isAgbCartridge;
198 }
199 
200 /*---------------------------------------------------------------------------*
201   Name:         CTRDG_GetAgbGameCode
202 
203   Description:  get game code in AGB cartridge
204 
205   Arguments:    None
206 
207   Returns:      Game code if exist, FALSE if cartridge not exist
208  *---------------------------------------------------------------------------*/
CTRDG_GetAgbGameCode(void)209 u32 CTRDG_GetAgbGameCode(void)
210 {
211     u32     retval = FALSE;
212 
213     if (CTRDG_IsExisting())
214     {
215         retval = CTRDGi_GetAgbGameCodeAtInit();
216     }
217 
218     return retval;
219 }
220 
221 /*---------------------------------------------------------------------------*
222   Name:         CTRDGi_GetAgbGameCodeAtInit
223 
224   Description:  get game code in AGB cartridge read at boot time
225 
226   Arguments:    None
227 
228   Returns:      Game code if exist, FALSE if cartridge did not exist
229  *---------------------------------------------------------------------------*/
CTRDGi_GetAgbGameCodeAtInit(void)230 u32 CTRDGi_GetAgbGameCodeAtInit(void)
231 {
232     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
233     u32     retval = FALSE;
234 
235     if (CTRDGi_IsAgbCartridgeAtInit())
236     {
237         retval = cip->gameCode;
238     }
239 
240     return retval;
241 }
242 
243 /*---------------------------------------------------------------------------*
244   Name:         CTRDG_GetAgbMakerCode
245 
246   Description:  get maker code in AGB cartridge
247 
248   Arguments:    None
249 
250   Returns:      Maker code if exist, FALSE if cartridge not exist
251  *---------------------------------------------------------------------------*/
CTRDG_GetAgbMakerCode(void)252 u16 CTRDG_GetAgbMakerCode(void)
253 {
254     u16     retval = FALSE;
255 
256     if (CTRDG_IsExisting())
257     {
258         retval = CTRDGi_GetAgbMakerCodeAtInit();
259     }
260 
261     return retval;
262 }
263 
264 /*---------------------------------------------------------------------------*
265   Name:         CTRDGi_GetAgbMakerCodeAtInit
266 
267   Description:  get maker code in AGB cartridge read at boot time
268 
269   Arguments:    None
270 
271   Returns:      Maker code if exist, FALSE if not exist
272  *---------------------------------------------------------------------------*/
CTRDGi_GetAgbMakerCodeAtInit(void)273 u16 CTRDGi_GetAgbMakerCodeAtInit(void)
274 {
275     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
276     u16     retval = FALSE;
277 
278     if (CTRDGi_IsAgbCartridgeAtInit())
279     {
280         retval = cip->makerCode;
281     }
282 
283     return retval;
284 }
285 
286 
287 /*---------------------------------------------------------------------------*
288   Name:         CTRDG_IsPulledOut
289 
290   Description:  get whether system has detected pulled out cartridge
291 
292   Arguments:    None
293 
294   Returns:      TRUE if detect pull out
295  *---------------------------------------------------------------------------*/
CTRDG_IsPulledOut(void)296 BOOL CTRDG_IsPulledOut(void)
297 {
298     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
299 
300 #ifndef SDK_TWLLTD
301     SDK_ASSERT(CTRDGi_IsInitialized());
302 #endif
303 
304     //---- cartridge not exist at boot time
305     if (!CTRDG_IsExistedAtInit())
306     {
307         return FALSE;
308     }
309 
310     //---- check existing when not detect pulled out
311     if (!cip->detectPullOut)
312     {
313         (void)CTRDG_IsExisting();
314     }
315 
316     return cip->detectPullOut;
317 }
318 
319 /*---------------------------------------------------------------------------*
320   Name:         CTRDG_IsAgbCartridgePulledOut
321 
322   Description:  get whether system has detected pulled out AGB cartridge
323 
324   Arguments:    None
325 
326   Returns:      TRUE if detect pull out
327  *---------------------------------------------------------------------------*/
CTRDG_IsAgbCartridgePulledOut(void)328 BOOL CTRDG_IsAgbCartridgePulledOut(void)
329 {
330     return (CTRDG_IsPulledOut() && CTRDGi_IsAgbCartridgeAtInit());
331 }
332 
333 /*---------------------------------------------------------------------------*
334   Name:         CTRDG_IsOptionCartridgePulledOut
335 
336   Description:  get whether system has detected pulled out option cartridge
337 
338   Arguments:    None
339 
340   Returns:      TRUE if detect pull out
341  *---------------------------------------------------------------------------*/
CTRDG_IsOptionCartridgePulledOut(void)342 BOOL CTRDG_IsOptionCartridgePulledOut(void)
343 {
344     return (CTRDG_IsPulledOut() && !CTRDGi_IsAgbCartridgeAtInit());
345 }
346 
347 /*---------------------------------------------------------------------------*
348   Name:         CTRDG_IsExisting
349 
350   Description:  get whether cartridge exists
351 
352   Arguments:    None
353 
354   Returns:      TRUE if existing
355  *---------------------------------------------------------------------------*/
CTRDG_IsExisting(void)356 BOOL CTRDG_IsExisting(void)
357 {
358 #ifdef SDK_TWLLTD
359     return FALSE;
360 #else
361     BOOL    retval = TRUE;
362     CTRDGLockByProc lockInfo;
363 
364     CTRDGHeader *chp = CTRDGi_GetHeaderAddr();
365     CTRDGModuleInfo *cip = CTRDGi_GetModuleInfoAddr();
366 
367     SDK_ASSERT(CTRDGi_IsInitialized());
368 
369     //---- if cartridge not exist at boot time.
370     if (!CTRDG_IsExistedAtInit())
371     {
372         return FALSE;
373     }
374 
375     //---- if detect cartirdge pulled out
376     if (cip->detectPullOut == TRUE)
377     {
378         return FALSE;
379     }
380 #if defined(SDK_ARM7)
381     //---- get privilege for accessing cartridge
382     if (CTRDGi_LockByProcessor(CTRDGi_Work.lockID, &lockInfo) == FALSE)
383     {
384         (void)OS_RestoreInterrupts(lockInfo.irq);
385         return TRUE;
386     }
387 #else
388     //---- get privilege for accessing cartridge
389     CTRDGi_LockByProcessor(CTRDGi_Work.lockID, &lockInfo);
390 #endif
391 
392     //---- check if cartridge exists
393     {
394         CTRDGRomCycle rc;
395         u8      isRomCode;
396 
397         // set the lastest access cycle
398         CTRDGi_ChangeLatestAccessCycle(&rc);
399         isRomCode = chp->isRomCode;
400 
401         // ( please observe comparison order to the following )
402         if ((isRomCode == CTRDG_IS_ROM_CODE && cip->moduleID.raw != chp->moduleID)      // memory loaded
403             || (isRomCode != CTRDG_IS_ROM_CODE && cip->moduleID.raw != *CTRDGi_GetModuleIDImageAddr())  // memory not loaded
404             || ((cip->gameCode != chp->gameCode) && cip->isAgbCartridge))       // AGB cartridge comparison
405         {
406             cip->detectPullOut = TRUE;
407             retval = FALSE;
408         }
409 
410         //---- restore access cycle
411         CTRDGi_RestoreAccessCycle(&rc);
412     }
413 
414     //---- release privilege for accessing cartridge
415     CTRDGi_UnlockByProcessor(CTRDGi_Work.lockID, &lockInfo);
416 
417     return retval;
418 #endif // SDK_TWLLTD
419 }
420 
421 /*---------------------------------------------------------------------------*
422   Name:         CTRDGi_ChangeLatestAccessCycle
423 
424   Description:  set access cycle to cartridge to latest setting
425 
426   Arguments:    r :  Cartridge ROM access cycle
427 
428   Returns:      None.
429  *---------------------------------------------------------------------------*/
CTRDGi_ChangeLatestAccessCycle(CTRDGRomCycle * r)430 void CTRDGi_ChangeLatestAccessCycle(CTRDGRomCycle *r)
431 {
432     r->c1 = MI_GetCartridgeRomCycle1st();
433     r->c2 = MI_GetCartridgeRomCycle2nd();
434 
435     MI_SetCartridgeRomCycle1st(MI_CTRDG_ROMCYCLE1_18);
436     MI_SetCartridgeRomCycle2nd(MI_CTRDG_ROMCYCLE2_6);
437 }
438 
439 /*---------------------------------------------------------------------------*
440   Name:         CTRDGi_RestoreAccessCycle
441 
442   Description:  set access cycle to cartridge to the original setting
443 
444   Arguments:    r :  Cartridge ROM access cycle
445 
446   Returns:      None.
447  *---------------------------------------------------------------------------*/
CTRDGi_RestoreAccessCycle(CTRDGRomCycle * r)448 void CTRDGi_RestoreAccessCycle(CTRDGRomCycle *r)
449 {
450     MI_SetCartridgeRomCycle1st(r->c1);
451     MI_SetCartridgeRomCycle2nd(r->c2);
452 }
453 
454 
455 /*---------------------------------------------------------------------------*
456   Name:         CTRDGi_LockByProcessor
457 
458   Description:  get privilege for accessing cartridge to specified processor
459 
460                 Because try lock cartridge, in case another processor had locked,
461                 wait till its was released.
462 
463                 Status of interrupt in return is disable.
464 
465   Arguments:    lockID : lock ID for cartridge
466                 info   : info for lock by my processor
467 
468   Returns:      None.
469  *---------------------------------------------------------------------------*/
470 #if defined(SDK_ARM7)
CTRDGi_LockByProcessor(u16 lockID,CTRDGLockByProc * info)471 BOOL CTRDGi_LockByProcessor(u16 lockID, CTRDGLockByProc *info)
472 #else
473 void CTRDGi_LockByProcessor(u16 lockID, CTRDGLockByProc *info)
474 #endif
475 {
476     while (1)
477     {
478         info->irq = OS_DisableInterrupts();
479 
480         if (((info->locked = OS_ReadOwnerOfLockCartridge() & CTRDG_LOCKED_BY_MYPROC_FLAG) != 0)
481             || (OS_TryLockCartridge(lockID) == OS_LOCK_SUCCESS))
482         {
483 #if defined(SDK_ARM7)
484             return TRUE;
485 #else
486             break;
487 #endif
488         }
489 #if defined(SDK_ARM7)
490         return FALSE;
491 #endif
492         (void)OS_RestoreInterrupts(info->irq);
493 
494         SVC_WaitByLoop(1);
495     }
496 }
497 
498 /*---------------------------------------------------------------------------*
499   Name:         CTRDGi_UnlockByProcessor
500 
501   Description:  release privilege for accessing cartirige
502 
503   Arguments:    lockID : lock ID for cartridge
504                 info   : info for lock by my processor
505                          it must be the value got in CTRDGi_LockCartridgeByProccesser.
506 
507   Returns:      None.
508  *---------------------------------------------------------------------------*/
CTRDGi_UnlockByProcessor(u16 lockID,CTRDGLockByProc * info)509 void CTRDGi_UnlockByProcessor(u16 lockID, CTRDGLockByProc *info)
510 {
511     if (!info->locked)
512     {
513         (void)OS_UnLockCartridge(lockID);
514     }
515 
516     (void)OS_RestoreInterrupts(info->irq);
517 }
518 
519 /*---------------------------------------------------------------------------*
520   Name:         CTRDGi_SendtoPxi
521 
522   Description:  send data via PXI
523 
524   Arguments:    data : data to send
525 
526   Returns:      None
527  *---------------------------------------------------------------------------*/
CTRDGi_SendtoPxi(u32 data)528 void CTRDGi_SendtoPxi(u32 data)
529 {
530     while (PXI_SendWordByFifo(PXI_FIFO_TAG_CTRDG, data, FALSE) != PXI_FIFO_SUCCESS)
531     {
532         SVC_WaitByLoop(1);
533     }
534 }
535 
536 //================================================================================
537 //       READ DATA FROM CARTRIDGE
538 //================================================================================
539 /*---------------------------------------------------------------------------*
540   Name:         CTRDG_DmaCopy16 / 32
541 
542   Description:  read cartridge data via DMA
543 
544   Arguments:    dmaNo : DMA No.
545                 src   : source address (in cartridge)
546                 dest  : destination address (in memory)
547                 size  : forwarding size
548 
549   Returns:      TRUE if success.
550                 FALSE if fail. ( no cartridge )
551  *---------------------------------------------------------------------------*/
CTRDG_DmaCopy16(u32 dmaNo,const void * src,void * dest,u32 size)552 BOOL CTRDG_DmaCopy16(u32 dmaNo, const void *src, void *dest, u32 size)
553 {
554 #ifndef SDK_TWLLTD
555     SDK_ASSERT(CTRDGi_IsInitialized());
556 #endif
557     return CTRDGi_CopyCommon(dmaNo, src, dest, size, CTRDGi_FORWARD_DMA16);
558 }
CTRDG_DmaCopy32(u32 dmaNo,const void * src,void * dest,u32 size)559 BOOL CTRDG_DmaCopy32(u32 dmaNo, const void *src, void *dest, u32 size)
560 {
561 #ifndef SDK_TWLLTD
562     SDK_ASSERT(CTRDGi_IsInitialized());
563 #endif
564     return CTRDGi_CopyCommon(dmaNo, src, dest, size, CTRDGi_FORWARD_DMA32);
565 }
566 
567 /*---------------------------------------------------------------------------*
568   Name:         CTRDG_CpuCopy8 / 16 / 32
569 
570   Description:  read cartridge data by CPU access
571 
572   Arguments:    src   : source address (in cartridge)
573                 dest  : destination address (in memory)
574                 size  : forwarding size
575 
576   Returns:      TRUE if success.
577                 FALSE if fail. ( no cartridge )
578  *---------------------------------------------------------------------------*/
CTRDG_CpuCopy8(const void * src,void * dest,u32 size)579 BOOL CTRDG_CpuCopy8(const void *src, void *dest, u32 size)
580 {
581 #ifndef SDK_TWLLTD
582     SDK_ASSERT(CTRDGi_IsInitialized());
583 #endif
584     if (HW_CTRDG_ROM <= (u32)dest && (u32)dest < HW_CTRDG_RAM_END)
585     {
586         return CTRDGi_CopyCommon(0 /*dummy */ , (const void *)dest, (void *)src, size,
587                                  CTRDGi_FORWARD_CPU8);
588     }
589     else
590     {
591         return CTRDGi_CopyCommon(0 /*dummy */ , src, dest, size, CTRDGi_FORWARD_CPU8);
592     }
593 }
CTRDG_CpuCopy16(const void * src,void * dest,u32 size)594 BOOL CTRDG_CpuCopy16(const void *src, void *dest, u32 size)
595 {
596 #ifndef SDK_TWLLTD
597     SDK_ASSERT(CTRDGi_IsInitialized());
598 #endif
599     return CTRDGi_CopyCommon(0 /*dummy */ , src, dest, size, CTRDGi_FORWARD_CPU16);
600 }
CTRDG_CpuCopy32(const void * src,void * dest,u32 size)601 BOOL CTRDG_CpuCopy32(const void *src, void *dest, u32 size)
602 {
603 #ifndef SDK_TWLLTD
604     SDK_ASSERT(CTRDGi_IsInitialized());
605 #endif
606     return CTRDGi_CopyCommon(0 /*dummy */ , src, dest, size, CTRDGi_FORWARD_CPU32);
607 }
608 
609 /*---------------------------------------------------------------------------*
610   Name:         CTRDGi_CopyCommon
611 
612   Description:  read/write cartridge data.
613                 subroutine of CTRDG_CpuCopy*(), CTRDG_DmaCopy*() and CTRDG_WriteStream8().
614 
615   Arguments:    dmaNo       : DMA No.
616                 src         : source address
617                 dest        : destination address
618                 size        : forwarding size
619                 forwardType : action flag
620 
621   Returns:      TRUE if success.
622                 FALSE if fail. ( no cartridge )
623  *---------------------------------------------------------------------------*/
CTRDGi_CopyCommon(u32 dmaNo,const void * src,void * dest,u32 size,u32 forwardType)624 BOOL CTRDGi_CopyCommon(u32 dmaNo, const void *src, void *dest, u32 size, u32 forwardType)
625 {
626     //---- check cartridge existence
627     if (!CTRDG_IsExisting())
628     {
629         return FALSE;
630     }
631 
632     /* confirm whether application has certainly judged AGB-cartridge */
633     CTRDG_CheckEnabled();
634 
635     (void)OS_LockCartridge(CTRDGi_Work.lockID);
636 
637     if ((forwardType & CTRDGi_FORWARD_TYPE_MASK) == CTRDGi_FORWARD_TYPE_DMA)
638     {
639         MI_StopDma(dmaNo);
640         DC_FlushRange(dest, size);
641     }
642 
643     switch (forwardType)
644     {
645     case CTRDGi_FORWARD_DMA16:
646         MI_DmaCopy16(dmaNo, src, dest, size);
647         break;
648     case CTRDGi_FORWARD_DMA32:
649         MI_DmaCopy32(dmaNo, src, dest, size);
650         break;
651     case CTRDGi_FORWARD_CPU16:
652         MI_CpuCopy16(src, dest, size);
653         break;
654     case CTRDGi_FORWARD_CPU32:
655         MI_CpuCopy32(src, dest, size);
656         break;
657 
658     case CTRDGi_FORWARD_CPU8:
659         {
660             int     n;
661             u8     *dest8 = (u8 *)dest;
662             u8     *src8 = (u8 *)src;
663             for (n = 0; n < size; n++)
664             {
665                 *dest8++ = *src8++;
666             }
667         }
668         break;
669     }
670 
671     (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
672 
673     //---- check to remove cartridge in the middle of reading
674     if (!CTRDG_IsExisting())
675     {
676         return FALSE;
677     }
678 
679     return TRUE;
680 }
681 
682 /*---------------------------------------------------------------------------*
683   Name:         CTRDG_Read8 / 16 / 32
684 
685   Description:  read cartridge data by CPU access
686 
687   Arguments:    address  : source address (in cartridge)
688                 rdata    : address to store read data
689 
690   Returns:      TRUE if success.
691                 FALSE if fail. ( no cartridge )
692  *---------------------------------------------------------------------------*/
CTRDG_Read8(const u8 * address,u8 * rdata)693 BOOL CTRDG_Read8(const u8 *address, u8 *rdata)
694 {
695 #ifndef SDK_TWLLTD
696     SDK_ASSERT(CTRDGi_IsInitialized());
697 #endif
698     return CTRDGi_AccessCommon((void *)address, 0 /*dummy */ , rdata, CTRDGi_ACCESS_READ8);
699 }
CTRDG_Read16(const u16 * address,u16 * rdata)700 BOOL CTRDG_Read16(const u16 *address, u16 *rdata)
701 {
702 #ifndef SDK_TWLLTD
703     SDK_ASSERT(CTRDGi_IsInitialized());
704 #endif
705     return CTRDGi_AccessCommon((void *)address, 0 /*dummy */ , rdata, CTRDGi_ACCESS_READ16);
706 }
CTRDG_Read32(const u32 * address,u32 * rdata)707 BOOL CTRDG_Read32(const u32 *address, u32 *rdata)
708 {
709 #ifndef SDK_TWLLTD
710     SDK_ASSERT(CTRDGi_IsInitialized());
711 #endif
712     return CTRDGi_AccessCommon((void *)address, 0 /*dummy */ , rdata, CTRDGi_ACCESS_READ32);
713 }
714 
715 /*---------------------------------------------------------------------------*
716   Name:         CTRDG_Write8 / 16 / 32
717 
718   Description:  write data to cartridge
719 
720   Arguments:    address  : destination address (in cartridge)
721                 data     : data to write
722 
723   Returns:      TRUE if success.
724                 FALSE if fail. ( no cartridge )
725  *---------------------------------------------------------------------------*/
CTRDG_Write8(u8 * address,u8 data)726 BOOL CTRDG_Write8(u8 *address, u8 data)
727 {
728 #ifndef SDK_TWLLTD
729     SDK_ASSERT(CTRDGi_IsInitialized());
730 #endif
731     return CTRDGi_AccessCommon(address, data, 0 /*dummy */ , CTRDGi_ACCESS_WRITE8);
732 }
CTRDG_Write16(u16 * address,u16 data)733 BOOL CTRDG_Write16(u16 *address, u16 data)
734 {
735 #ifndef SDK_TWLLTD
736     SDK_ASSERT(CTRDGi_IsInitialized());
737 #endif
738     return CTRDGi_AccessCommon(address, data, 0 /*dummy */ , CTRDGi_ACCESS_WRITE16);
739 }
CTRDG_Write32(u32 * address,u32 data)740 BOOL CTRDG_Write32(u32 *address, u32 data)
741 {
742 #ifndef SDK_TWLLTD
743     SDK_ASSERT(CTRDGi_IsInitialized());
744 #endif
745     return CTRDGi_AccessCommon(address, data, 0 /*dummy */ , CTRDGi_ACCESS_WRITE32);
746 }
747 
748 /*---------------------------------------------------------------------------*
749   Name:         CTRDGi_AccessCommon
750 
751   Description:  read/write cartridge data.
752                 subroutine of CTRDG_Read*() and CTRDG_Write*().
753 
754   Arguments:    address    : address to access
755                 data       : data to write (in write mode)
756                 rdata      : address to store read data (in read mode)
757                 accessType : action flag
758 
759   Returns:      TRUE if success.
760                 FALSE if fail. ( no cartridge )
761  *---------------------------------------------------------------------------*/
CTRDGi_AccessCommon(void * address,u32 data,void * rdata,u32 accessType)762 BOOL CTRDGi_AccessCommon(void *address, u32 data, void *rdata, u32 accessType)
763 {
764     //---- check cartridge existence
765     if (!CTRDG_IsExisting())
766     {
767         return FALSE;
768     }
769 
770     /* confirm whether application has certainly judged AGB-cartridge */
771     CTRDG_CheckEnabled();
772 
773     (void)OS_LockCartridge(CTRDGi_Work.lockID);
774 
775     switch (accessType)
776     {
777     case CTRDGi_ACCESS_READ8:
778         if (rdata)
779         {
780             *(u8 *)rdata = *(u8 *)address;
781         }
782         break;
783     case CTRDGi_ACCESS_READ16:
784         if (rdata)
785         {
786             *(u16 *)rdata = *(u16 *)address;
787         }
788         break;
789     case CTRDGi_ACCESS_READ32:
790         if (rdata)
791         {
792             *(u32 *)rdata = *(u32 *)address;
793         }
794         break;
795     case CTRDGi_ACCESS_WRITE8:
796         *(u8 *)address = (u8)data;
797         break;
798     case CTRDGi_ACCESS_WRITE16:
799         *(u16 *)address = (u16)data;
800         break;
801     case CTRDGi_ACCESS_WRITE32:
802         *(u32 *)address = (u32)data;
803         break;
804     }
805 
806     (void)OS_UnLockCartridge(CTRDGi_Work.lockID);
807 
808     //---- check to remove cartridge in the middle of reading
809     if (!CTRDG_IsExisting())
810     {
811         return FALSE;
812     }
813 
814     return TRUE;
815 }
816 
817 /*---------------------------------------------------------------------------*
818   Name:         CTRDG_IsEnabled
819 
820   Description:  check if CTRDG is accessable
821 
822   Arguments:    None.
823 
824   Returns:      Return cartridge access permission.
825  *---------------------------------------------------------------------------*/
CTRDG_IsEnabled(void)826 BOOL CTRDG_IsEnabled(void)
827 {
828 #if !defined(SDK_TWLLTD) && defined(SDK_ARM9)
829     SDK_ASSERT(CTRDGi_IsInitialized());
830 #endif
831     return CTRDGi_EnableFlag;
832 }
833 
834 /*---------------------------------------------------------------------------*
835   Name:         CTRDG_Enable
836 
837   Description:  Set cartridge access permission mode.
838 
839   Arguments:    enable       permission mode to be set.
840 
841   Returns:      None.
842  *---------------------------------------------------------------------------*/
CTRDG_Enable(BOOL enable)843 void CTRDG_Enable(BOOL enable)
844 {
845     OSIntrMode bak_cpsr = OS_DisableInterrupts();
846     CTRDGi_EnableFlag = enable;
847 #if defined(SDK_ARM9)
848 #ifndef SDK_TWLLTD
849     SDK_ASSERT(CTRDGi_IsInitialized());
850 #endif
851     if (CTRDG_IsExistedAtInit())
852     {
853         u32 dacc = (u32)(enable ? OS_PR3_ACCESS_RW : OS_PR3_ACCESS_RO);
854         (void)OS_SetDPermissionsForProtectionRegion(OS_PR3_ACCESS_MASK, dacc);
855         if ( enable )
856         {
857             // for CTRDG
858             DC_FlushAll();
859             DC_WaitWriteBufferEmpty();
860             OS_DisableICacheForProtectionRegion(1<<3);
861             OS_DisableDCacheForProtectionRegion(1<<3);
862             OS_DisableWriteBufferForProtectionRegion(1<<3);
863         }
864         else
865         {
866             // for HW_TWL_MAIN_MEM_EX
867             OS_EnableICacheForProtectionRegion(1<<3);
868             OS_EnableDCacheForProtectionRegion(1<<3);
869             OS_EnableWriteBufferForProtectionRegion(1<<3);
870         }
871     }
872 #endif /* defined(SDK_ARM9) */
873     (void)OS_RestoreInterrupts(bak_cpsr);
874 }
875 
876 /*---------------------------------------------------------------------------*
877   Name:         CTRDG_CheckEnabled
878 
879   Description:  Terminate program if CTRDG is not accessable
880 
881   Arguments:    None.
882 
883   Returns:      None.
884  *---------------------------------------------------------------------------*/
CTRDG_CheckEnabled(void)885 void CTRDG_CheckEnabled(void)
886 {
887 #ifdef SDK_ARM9
888 #ifndef SDK_TWLLTD
889     SDK_ASSERT(CTRDGi_IsInitialized());
890 #endif
891     if (!CTRDG_IsOptionCartridge() && !CTRDG_IsEnabled())
892     {
893         OS_TPanic
894             ("cartridge permission denied. (you must call CTRDG_Enable() under the guideline.)");
895     }
896 #endif
897 }
898