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