1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS
3 File: os_reset.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:: 2009-06-08#$
14 $Rev: 10706 $
15 $Author: yosizaki $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 #include <nitro/mb.h>
19 #include <nitro/snd/common/global.h>
20 #include <nitro/card.h>
21
22 #include <nitro/code32.h>
23
24 //---- autoload start
25 #ifdef SDK_ARM9
26 #define OSi_HW_DTCM SDK_AUTOLOAD_DTCM_START
27 #endif
28
29 //---------------- local functions
30 #ifdef SDK_ARM9
31 static void OSi_CpuClear32(register u32 data, register void *destp, register u32 size);
32 static void OSi_ReloadRomData(void);
33 static void OSi_ReadCardRom32(u32 src, void *dst, int len);
34 #endif // ifdef SDK_ARM9
35
36 void OSi_DoResetSystem(void);
37 static void OSi_DoBoot(void);
38
39 #ifdef SDK_TWL
40 static void OSi_ReloadTwlRomData(void);
41 #ifdef SDK_ARM7
42 extern void SDK_LTDAUTOLOAD_LTDMAIN_START(void);
43 void* const OSi_LtdMainParams[] =
44 {
45 (void*)SDK_LTDAUTOLOAD_LTDMAIN_START,
46 };
47 #endif
48 #endif
49
50 //---------------- local variables
51 static u16 OSi_IsInitReset = FALSE;
52
53 //================================================================================
54 /*---------------------------------------------------------------------------*
55 Name: OS_InitReset
56
57 Description: init reset system
58
59 Arguments: None.
60
61 Returns: None.
62 *---------------------------------------------------------------------------*/
OS_InitReset(void)63 void OS_InitReset(void)
64 {
65 if (OSi_IsInitReset)
66 {
67 return;
68 }
69 OSi_IsInitReset = TRUE;
70
71 //---------------- ARM9
72 #ifdef SDK_ARM9
73 //---- wait ARM7 PXI library start
74 PXI_Init();
75 while (!PXI_IsCallbackReady(PXI_FIFO_TAG_OS, PXI_PROC_ARM7))
76 {
77 }
78 #endif
79
80 //---- set PXI receive callback
81 PXI_SetFifoRecvCallback(PXI_FIFO_TAG_OS, OSi_CommonCallback);
82 }
83
84 /*---------------------------------------------------------------------------*
85 Name: OS_ResetSystem
86
87 Description: Start reset sequence.
88 To decrease code in itcm or wram,
89 separate this function from OSi_DoResetSystem()
90
91 Arguments: (ARM9) parameter : reset parameter
92 (ARM7) None
93
94 Returns: None.
95 *---------------------------------------------------------------------------*/
96 //---------------- ARM9
97 #ifdef SDK_ARM9
OS_ResetSystem(u32 parameter)98 void OS_ResetSystem(u32 parameter)
99 {
100 #ifdef SDK_TWL
101 //---- stop if reset from non-card application
102 if ((MB_IsMultiBootChild() == TRUE) ||
103 ((OS_IsRunOnTwl() == TRUE) && ((*((u32*)(HW_TWL_ROM_HEADER_BUF + 0x234)) & 0x00000004) != 0)))
104 {
105 #ifndef SDK_FINALROM
106 OS_Panic("Only card booted application can execute software reset.\nSee OS_ResetSystem() reference manual.");
107 #else
108 OS_Panic("");
109 #endif
110 }
111 #else
112 //---- stop if reset from multiboot child
113 if (MB_IsMultiBootChild())
114 {
115 #ifndef SDK_FINALROM
116 OS_Panic("Cannot reset from MB child.\nSee OS_ResetSystem() reference manual.");
117 #else
118 OS_Panic("");
119 #endif
120 }
121 #endif
122 //---- stop if reset on TWL-mode
123 #ifdef SDK_TWL
124 if (OS_IsRunOnTwl())
125 {
126 #ifndef SDK_FINALROM
127 OS_Panic("Cannot reset on TWL-mode.\nSee OS_ResetSystem() reference manual.");
128 #else
129 OS_Panic("");
130 #endif
131 }
132 #endif
133
134 #ifdef SDK_TWL
135 if ( OS_IsRunOnTwl() )
136 {
137 // End processing
138 // If making an ARM7 processor request, wait for the callback function to complete
139 PMi_ExecutePostExitCallbackList();
140 }
141 #endif
142
143 //---- wait while card is locked
144 {
145 u16 id = (u16)OS_GetLockID();
146 CARD_LockRom(id);
147 }
148
149 //---- set only pxi interrupt available
150 (void)OS_SetIrqMask(OS_IE_FIFO_RECV);
151 (void)OS_ResetRequestIrqMask(0xffffffff /*all request */ );
152
153 //---- stop all dma
154 MI_StopAllDma();
155 #ifdef SDK_TWL
156 if (OS_IsRunOnTwl())
157 {
158 MI_StopAllNDma();
159 }
160 #endif
161
162 //---- save parameter
163 *(u32 *)HW_RESET_PARAMETER_BUF = parameter;
164
165 //---- send reset command to ARM7
166 OSi_SendToPxi(OS_PXI_COMMAND_RESET);
167
168 //---- reset
169 OSi_DoResetSystem();
170
171 // Doesn't reach here
172 }
173
174 //---------------- ARM7
175 #else // ifdef SDK_ARM9
176 #pragma dont_inline on
OS_ResetSystem(void)177 void OS_ResetSystem(void)
178 {
179 //---- set only pxi interrupt available
180 (void)OS_SetIrqMask(OS_IE_FIFO_RECV);
181 (void)OS_ResetRequestIrqMask(0xffffffff /*all request */ );
182
183 //---- stop all dma
184 {
185 u32 n;
186 for( n=0; n<4; n++ )
187 {
188 MI_StopDma(n);
189 #ifdef SDK_TWL
190 if (OS_IsRunOnTwl())
191 {
192 MI_StopNDma(n);
193 }
194 #endif
195 }
196 }
197
198 //---- sound stop
199 SND_Shutdown();
200
201 //---- send reset command to ARM9
202 OSi_SendToPxi(OS_PXI_COMMAND_RESET);
203
204 //---- reset
205 OSi_DoResetSystem();
206 }
207 #pragma dont_inline reset
208 #endif // ifdef SDK_ARM9
209
210 #if defined(SDK_TWL) && defined(SDK_ARM9)
211 #include <twl/itcm_begin.h>
212 #define OSi_TCM_REGION_BASE_MASK HW_C9_TCMR_BASE_MASK // 0xfffff000
OSi_GetDTCMAddress(void)213 static asm u32 OSi_GetDTCMAddress(void)
214 {
215 mrc p15, 0, r0, c9, c1, 0
216 ldr r1, =OSi_TCM_REGION_BASE_MASK
217 and r0, r0, r1
218 bx lr
219 }
220 /*---------------------------------------------------------------------------*
221 Name: OSi_VerifyStaticSegments
222
223 Description: Verifies 4 static segments before rebooting.
224
225 Arguments: None.
226
227 Returns: None.
228 *---------------------------------------------------------------------------*/
OSi_VerifyStaticSegments(void)229 static void OSi_VerifyStaticSegments(void)
230 {
231 BOOL result = TRUE;
232 const CARDRomHeaderTWL *header = (const CARDRomHeaderTWL *)HW_TWL_ROM_HEADER_BUF;
233 if ((((const u8 *)header)[0x1C] & 0x01) != 0)
234 {
235 int i;
236 // use DTCM as workarea
237 u8 *work = (u8 *)OSi_GetDTCMAddress();
238 SVCHMACSHA1Context *context = (SVCHMACSHA1Context *)&work[0];
239 u8 *digest = &work[sizeof(SVCHMACSHA1Context)];
240 // calculate and verify HMAC-SHA1 of the static segments
241 enum { SEGMENT_TOTAL = 4 };
242 struct Segment { u8 *address; u32 size; } *(table[SEGMENT_TOTAL]);
243 const void *(compareDigests[SEGMENT_TOTAL]);
244 table[0] = (struct Segment *)&header->ntr.main_ram_address;
245 table[1] = (struct Segment *)&header->ntr.sub_ram_address;
246 table[2] = (struct Segment *)&header->main_ltd_ram_address;
247 table[3] = (struct Segment *)&header->sub_ltd_ram_address;
248 compareDigests[0] = &((const u8 *)header)[0x3A0];
249 compareDigests[1] = header->sub_static_digest;
250 compareDigests[2] = header->main_ltd_static_digest;
251 compareDigests[3] = header->sub_ltd_static_digest;
252 for (i = 0; i < SEGMENT_TOTAL; ++i)
253 {
254 static const u8 hmacKey[] =
255 {
256 0x21, 0x06, 0xc0, 0xde, 0xba, 0x98, 0xce, 0x3f,
257 0xa6, 0x92, 0xe3, 0x9d, 0x46, 0xf2, 0xed, 0x01,
258 0x76, 0xe3, 0xcc, 0x08, 0x56, 0x23, 0x63, 0xfa,
259 0xca, 0xd4, 0xec, 0xdf, 0x9a, 0x62, 0x78, 0x34,
260 0x8f, 0x6d, 0x63, 0x3c, 0xfe, 0x22, 0xca, 0x92,
261 0x20, 0x88, 0x97, 0x23, 0xd2, 0xcf, 0xae, 0xc2,
262 0x32, 0x67, 0x8d, 0xfe, 0xca, 0x83, 0x64, 0x98,
263 0xac, 0xfd, 0x3e, 0x37, 0x87, 0x46, 0x58, 0x24,
264 };
265 const u8 *address = table[i]->address;
266 u32 size = table[i]->size;
267 if (i == 0)
268 {
269 address += 0x4000;
270 size -= 0x4000;
271 }
272 SVC_HMACSHA1Init(context, hmacKey, sizeof(hmacKey));
273 SVC_HMACSHA1Update(context, address, size);
274 SVC_HMACSHA1GetHash(context, digest);
275 result &= (SVC_CompareSHA1(digest, compareDigests[i]) != FALSE);
276 }
277 }
278 // if any segment is invalid, enter the endless-loop
279 while (result == FALSE)
280 {
281 }
282 }
283 #include <twl/itcm_end.h>
284 #endif // defined(SDK_TWL) && defined(SDK_ARM9)
285
286 /*---------------------------------------------------------------------------*
287 Name: OSi_DoResetSystem
288
289 Description: Start reset sequence.
290 Subroutine of OS_ResetSystem().
291 This part is put in itcm/wram because rom data will be
292 Loaded anew.
293
294 Arguments: None.
295
296 Returns: None.
297 *---------------------------------------------------------------------------*/
298 //---------------- ARM9
299 #ifdef SDK_ARM9
300 #ifdef SDK_TWL
301 #include <twl/itcm_begin.h>
302 #else
303 #include <nitro/itcm_begin.h>
304 #endif
305 SDK_WEAK_SYMBOL
OSi_DoResetSystem(void)306 void OSi_DoResetSystem(void)
307 __attribute__((never_inline))
308 {
309 //---- wait to receive reset command from ARM7
310 while (!OS_IsResetOccurred())
311 {
312 }
313
314 //---- set IME = 0
315 reg_OS_IME = 0;
316
317 //---- reload ROM data
318 #ifdef SDK_TWL
319 if (OS_IsRunOnTwl() == TRUE)
320 {
321 OSi_ReloadTwlRomData();
322 OSi_VerifyStaticSegments();
323 }
324 else
325 #endif
326 {
327 OSi_ReloadRomData();
328 }
329
330 //---- do boot
331 OSi_DoBoot();
332 }
333
334 #ifdef SDK_TWL
335 #include <twl/itcm_end.h>
336 #else
337 #include <nitro/itcm_end.h>
338 #endif
339
340 //---------------- ARM7
341 #else // ifdef SDK_ARM9
342 #ifdef SDK_TWL
343 #include <twl/wram_begin.h>
344 #else
345 #include <nitro/wram_begin.h>
346 #endif
347 SDK_WEAK_SYMBOL
OSi_DoResetSystem(void)348 void OSi_DoResetSystem(void)
349 __attribute__((never_inline))
350 {
351 //---- set IME = 0
352 reg_OS_IME = 0;
353
354 #ifdef SDK_TWL
355 if (OS_IsRunOnTwl() == TRUE)
356 {
357 OSi_ReloadTwlRomData();
358 }
359 #endif
360
361 //---- do boot
362 OSi_DoBoot();
363 }
364
365 #ifdef SDK_TWL
366 #include <twl/wram_end.h>
367 #else
368 #include <nitro/wram_end.h>
369 #endif
370 #endif // ifdef SDK_ARM9
371
372 /*---------------------------------------------------------------------------*
373 Name: OSi_DoBoot
374
375 Description: do boot
376
377 Arguments: None.
378
379 Returns: None.
380 *---------------------------------------------------------------------------*/
381 //---------------- ARM9
382 #ifdef SDK_ARM9
383 #ifdef SDK_TWL
384 #include <twl/itcm_begin.h>
385 #else
386 #include <nitro/itcm_begin.h>
387 #endif
OSi_DoBoot(void)388 asm void OSi_DoBoot( void )
389 {
390 //---- set IME = 0
391 mov r12, #HW_REG_BASE
392 str r12, [r12, #REG_IME_OFFSET]
393
394 //---- clear interrupt vector just to make sure
395 ldr r1, =OSi_HW_DTCM
396 add r1, r1, #0x3fc0
397 add r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR
398 mov r0, #0
399 str r0, [r1, #0]
400
401 //---- Synchronicity with ARM7
402 ldr r1, =REG_SUBPINTF_ADDR
403 @1:
404 ldrh r0, [r1]
405 and r0, r0, #0x000f
406 cmp r0, #0x0001
407 bne @1 // wait till subp status == 1
408 mov r0, #0x0100
409 strh r0, [r1] // mainp status == 1
410
411 //---- clear some memory
412 mov r0, #0
413 ldr r3, =HW_EXCP_VECTOR_MAIN // save exception vector
414 ldr r4, [r3]
415
416 ldr r1, =HW_BIOS_EXCP_STACK_MAIN // clear system area. (exception, arena, DMA clear buf...)
417 mov r2, #0x80
418 bl OSi_CpuClear32
419
420 str r4, [r3] // restore exception vector
421
422 ldr r1, =HW_PXI_SIGNAL_PARAM_ARM9 // clear system area. (wm, thread, lock, intr...)
423 mov r2, #0x18
424 bl OSi_CpuClear32
425
426 ldr r1, =HW_WM_RSSI_POOL
427 strh r0, [r1]
428
429 ldr r1, =HW_COMPONENT_PARAM // clear system area. (wm, thread, lock, intr...)
430 mov r2, #0x64
431 bl OSi_CpuClear32
432
433 //---- Synchronicity with ARM7
434 ldr r1, =REG_SUBPINTF_ADDR
435 @2:
436 ldrh r0, [r1]
437 and r0, r0, #0x000f
438 cmp r0, #0x0001 // wait till subp status == 0
439 beq @2
440 mov r0, #0
441 strh r0, [r1] // mainp status == 0
442
443 //---- get boot address
444 ldr r3, =HW_ROM_HEADER_BUF // r3 = ROM header
445 ldr r12, [r3, #0x24] // lr = r12 = ARM9 entry address
446 mov lr, r12
447
448 //---- clear registers r0-r11
449 ldr r11, =HW_PXI_SIGNAL_PARAM_ARM9 // clear r0-r11
450 ldmia r11, {r0-r10}
451 mov r11, #0
452
453 //---- boot game
454 bx r12 // jump to r12
455 }
456 #ifdef SDK_TWL
457 #include <twl/itcm_end.h>
458 #else
459 #include <nitro/itcm_end.h>
460 #endif
461
462 //---------------- ARM7
463 #else //ifdef SDK_ARM9
464 #ifdef SDK_TWL
465 #include <twl/wram_begin.h>
466 #else
467 #include <nitro/wram_begin.h>
468 #endif
OSi_DoBoot(void)469 asm void OSi_DoBoot( void )
470 {
471 //---- set IME = 0
472 mov r12, #HW_REG_BASE
473 str r12, [r12, #REG_IME_OFFSET]
474
475 //---- clear interrupt vector just to make sure
476 ldr r1, =HW_INTR_VECTOR_BUF
477 mov r0, #0
478 str r0, [r1, #0]
479
480 //---- Synchronicity with ARM9
481 ldr r1, =REG_MAINPINTF_ADDR
482 mov r0, #0x0100
483 strh r0, [r1] // subp status = 1
484 @1:
485 ldrh r0, [r1]
486 and r0, r0, #0x000f
487 cmp r0, #0x0001 // wait till mainp status == 1
488 bne @1
489
490 //---- Synchronicity with ARM9
491 ldr r1, =REG_MAINPINTF_ADDR
492 mov r0, #0 // subp status = 0
493 strh r0, [r1]
494 @2:
495 ldrh r0, [r1]
496 cmp r0, #0x0001 // wait till mainp status == 0
497 beq @2
498
499 //---- get boot address
500 ldr r3, =HW_ROM_HEADER_BUF // r3 = ROM header
501 ldr r12, [r3, #0x34] // lr = r12 = ARM7 entry address
502 mov lr, r12
503
504 //---- clear registers r0-r3
505 mov r0, #0
506 mov r1, #0
507 mov r2, #0
508 mov r3, #0
509
510 //---- boot game
511 bx r12
512 }
513 #ifdef SDK_TWL
514 #include <twl/wram_end.h>
515 #else
516 #include <nitro/wram_end.h>
517 #endif
518 #endif //ifdef SDK_ARM9
519
520
521 #ifdef SDK_ARM9
522 #ifdef SDK_TWL
523 #include <twl/itcm_begin.h>
524 #else
525 #include <nitro/itcm_begin.h>
526 #endif
527 /*---------------------------------------------------------------------------*
528 Name: OSi_CpuClear32
529
530 Description: Fills memory with specified data.
531 32-bit version.
532
533 Arguments: data: Fill data
534 destp : destination address
535 size: Size (bytes)
536
537 Returns: None.
538 *---------------------------------------------------------------------------*/
OSi_CpuClear32(register u32 data,register void * destp,register u32 size)539 static asm void OSi_CpuClear32( register u32 data, register void *destp, register u32 size )
540 {
541 add r12, r1, r2 // r12: destEndp = destp + size
542 @1:
543 cmp r1, r12 // while (destp < destEndp)
544 stmltia r1!, {r0} // *((vu32 *)(destp++)) = data
545 blt @1
546 bx lr
547 }
548
549 /*---------------------------------------------------------------------------*
550 Name: OSi_ReloadRomData
551
552 Description: reload ROM data from card
553
554 Arguments: None.
555
556 Returns: None.
557 *---------------------------------------------------------------------------*/
OSi_ReloadRomData(void)558 static void OSi_ReloadRomData(void)
559 {
560 u32 p = (u32)HW_ROM_HEADER_BUF;
561 const u32 rom_base = *(u32 *)HW_ROM_BASE_OFFSET_BUF;
562
563 /* if necessary, reload ROM header. */
564 if (rom_base >= 0x8000)
565 OSi_ReadCardRom32(rom_base, (void *)p, 0x160);
566
567 {
568 u32 src_arm9 = *(u32 *)(p + 0x20);
569 u32 dst_arm9 = *(u32 *)(p + 0x28);
570 u32 len_arm9 = *(u32 *)(p + 0x2c);
571 u32 src_arm7 = *(u32 *)(p + 0x30);
572 u32 dst_arm7 = *(u32 *)(p + 0x38);
573 u32 len_arm7 = *(u32 *)(p + 0x3c);
574
575 {
576 OSIntrMode bak_cpsr = OS_DisableInterrupts();
577 DC_StoreAll();
578 DC_InvalidateAll();
579 (void)OS_RestoreInterrupts(bak_cpsr);
580 }
581 IC_InvalidateAll();
582 DC_WaitWriteBufferEmpty();
583
584 //OS_Printf("A9 %x %x %x %x\n", *(u32*)(p+0x20), *(u32*)(p+0x24), *(u32*)(p+0x28), *(u32*)(p+0x2c) );
585 //OS_Printf("A7 %x %x %x %x\n", *(u32*)(p+0x30), *(u32*)(p+0x34), *(u32*)(p+0x38), *(u32*)(p+0x3c) );
586
587 /* add base-offset. */
588 src_arm9 += rom_base;
589 src_arm7 += rom_base;
590
591 //---- ARM9 code
592 if (src_arm9 < 0x8000) // top 32KByte of the rom cannot be read.
593 {
594 u32 diff = 0x8000 - src_arm9;
595 src_arm9 = 0x8000;
596 dst_arm9 += diff;
597 len_arm9 -= diff;
598 }
599 OSi_ReadCardRom32(src_arm9, (void *)dst_arm9, (int)len_arm9);
600
601 //---- ARM7 code
602 OSi_ReadCardRom32(src_arm7, (void *)dst_arm7, (int)len_arm7);
603 }
604 }
605
606 /*---------------------------------------------------------------------------*
607 Name: OSi_ReadCardRom32
608
609 Description: read card data by CPU
610 (subroutine of OSi_ReloadRomData)
611
612 Arguments: src: Source address, need to be 4-byte aligned
613 dest: Destination address, need to be 4-byte aligned
614 len: Size of forwarding
615
616 Returns: None.
617 *---------------------------------------------------------------------------*/
OSi_ReadCardRom32(u32 src,void * dst,int len)618 static void OSi_ReadCardRom32(u32 src, void *dst, int len)
619 {
620 //---- I/O registers for CARD
621 vu8 *const reg_CARD_MASTERCNT = (vu8 *)(HW_REG_BASE + 0x1a1);
622 vu8 *const reg_CARD_CMD = (vu8 *)(HW_REG_BASE + 0x1a8);
623 vu32 *const reg_CARD_CNT = (vu32 *)(HW_REG_BASE + 0x1a4);
624 vu32 *const reg_CARD_DATA = (vu32 *)(HW_REG_BASE + 0x100010);
625 vu32 *const hdr_GAME_BUF = (vu32 *)(HW_ROM_HEADER_BUF + 0x60);
626
627
628 enum
629 {
630 CARD_MASTER_SELECT_ROM = 0x00,
631 CARD_MASTER_ENABLE = 0x80,
632 CARD_CMD_READ_PAGE = 0xb7,
633 CARD_CTRL_CMD_MASK = 0x07000000,
634 CARD_CTRL_CMD_PAGE = 0x01000000,
635 CARD_CTRL_READ = 0x00000000,
636 CARD_CTRL_RESET_HI = 0x20000000,
637 CARD_CTRL_START = 0x80000000,
638 CARD_CTRL_READY = 0x00800000,
639 CARD_ENUM_END
640 };
641
642 const u32 ctrl_start = (u32)((*hdr_GAME_BUF & ~CARD_CTRL_CMD_MASK)
643 | (CARD_CTRL_CMD_PAGE | CARD_CTRL_READ
644 | CARD_CTRL_START | CARD_CTRL_RESET_HI));
645
646 //---- position of page. minus value mean before range.
647 int pos = -(int)(src & (512 - 1));
648
649 //---- wait finishing just to make sure, and turn master enable on
650 while ((*reg_CARD_CNT & CARD_CTRL_START) != 0)
651 {
652 }
653 *reg_CARD_MASTERCNT = (u32)(CARD_MASTER_SELECT_ROM | CARD_MASTER_ENABLE);
654
655 for (src = (u32)(src + pos); pos < len; src += 512)
656 {
657 //---- setting for command of one page reading
658 reg_CARD_CMD[0] = (u8)(CARD_CMD_READ_PAGE);
659 reg_CARD_CMD[1] = (u8)(src >> 24);
660 reg_CARD_CMD[2] = (u8)(src >> 16);
661 reg_CARD_CMD[3] = (u8)(src >> 8);
662 reg_CARD_CMD[4] = (u8)(src >> 0);
663 reg_CARD_CMD[5] = (u8)(0);
664 reg_CARD_CMD[6] = (u8)(0);
665 reg_CARD_CMD[7] = (u8)(0);
666
667 //---- start forwarding by CPU
668 *reg_CARD_CNT = ctrl_start;
669 for (;;)
670 {
671 u32 ctrl = *reg_CARD_CNT;
672
673 //---- check if ok to read word data
674 if ((ctrl & CARD_CTRL_READY) != 0)
675 {
676 //---- read data
677 const u32 data = *reg_CARD_DATA;
678
679 //---- store data
680 if ((pos >= 0) && (pos < len))
681 {
682 *(u32 *)((u32)dst + pos) = data;
683 }
684
685 pos += sizeof(u32);
686 }
687
688 //---- notice: need to read whole one page data
689 if (!(ctrl & CARD_CTRL_START))
690 {
691 break;
692 }
693 }
694 }
695 }
696
697 #ifdef SDK_TWL
698 #include <twl/itcm_end.h>
699 #else
700 #include <nitro/itcm_end.h>
701 #endif
702 #endif //ifdef SDK_ARM9
703
704 #ifdef SDK_TWL
705 /*---------------------------------------------------------------------------*
706 Name: OSi_ReloadTwlRomData
707
708 Description:
709
710 Arguments: None.
711
712 Returns: None.
713 *---------------------------------------------------------------------------*/
714 #ifdef SDK_ARM9
715 //---------------- ARM9
716 #include <twl/itcm_begin.h>
717 static asm void
OSi_ReloadTwlRomData(void)718 OSi_ReloadTwlRomData(void)
719 {
720 stmfd sp!, {lr}
721 @shakeHand01:
722 /* Synch with ARM7*/
723 ldr r0, =HW_BOOT_SYNC_PHASE
724 mov r1, #1
725 strh r1, [r0]
726 ldr r0, =HW_BOOT_SHAKEHAND_9
727 ldr r1, =HW_BOOT_SHAKEHAND_7
728 ldrh r2, [r1]
729 ldrh r3, [r0]
730 @shakeHand01_loop:
731 add r3, r3, #1
732 strh r3, [r0]
733 ldrh r12, [r1]
734 cmp r2, r12
735 beq @shakeHand01_loop
736 add r3, r3, #1
737 strh r3, [r0]
738
739 /* The ROM base offset cannot be changed when running in TWL mode */
740 mov r0, #0
741 stmfd sp!, {r0}
742
743 @loadStatic:
744 /* Load the binary for the ARM9 */
745 ldr r12, =HW_ROM_HEADER_BUF
746 ldr r0, [r12, #0x20]
747 ldr r1, [r12, #0x28]
748 ldr r2, [r12, #0x2c]
749 ldr r3, [sp]
750 add r0, r0, r3
751 subs r3, r0, #0x8000
752 movlt r0, #0x8000
753 sublt r1, r1, r3
754 addlt r2, r2, r3
755 cmp r2, #0
756 blgt OSi_ReadCardRom32
757 /* Load the binary for the ARM97 */
758 ldr r12, =HW_ROM_HEADER_BUF
759 ldr r0, [r12, #0x30]
760 ldr r1, [r12, #0x38]
761 ldr r2, [r12, #0x3c]
762 ldr r3, [sp]
763 add r0, r0, r3
764 cmp r2, #0
765 blgt OSi_ReadCardRom32
766
767 @loadLtdStatic:
768 /* Load the extension binary for the ARM9 */
769 ldr r12, =HW_TWL_ROM_HEADER_BUF
770 ldr r0, [r12, #0x1c0]
771 ldr r1, [r12, #0x1c8]
772 ldr r2, [r12, #0x1cc]
773 add r0, r0, #0x4000
774 add r1, r1, #0x4000
775 sub r2, r2, #0x4000
776 subs r3, r0, #0x8000
777 movlt r0, #0x8000
778 sublt r1, r1, r3
779 addlt r2, r2, r3
780 cmp r2, #0
781 blgt OSi_ReadCardRom32
782 /* Load the extension binary for the ARM7 */
783 ldr r12, =HW_TWL_ROM_HEADER_BUF
784 ldr r0, [r12, #0x1d0]
785 ldr r1, [r12, #0x1d8]
786 ldr r2, [r12, #0x1dc]
787 add r0, r0, #0x4000
788 add r1, r1, #0x4000
789 sub r2, r2, #0x4000
790 subs r3, r0, #0x8000
791 movlt r0, #0x8000
792 sublt r1, r1, r3
793 addlt r2, r2, r3
794 cmp r2, #0
795 blgt OSi_ReadCardRom32
796 /* It is necessary to recover the beginning portion of the extension binary that was retracted */
797 mov r3, #2
798 @arrangeCache:
799 ldmfd sp!, {r0}
800 /* DC_StoreAll() */
801 mov r1, #0
802 @arrangeCache_loop01:
803 mov r0, #0
804 @arrangeCache_loop02:
805 orr r2, r1, r0
806 mcr p15, 0, r2, c7, c10, 2
807 add r0, r0, #HW_CACHE_LINE_SIZE
808 cmp r0, #(HW_DCACHE_SIZE / 4)
809 blt @arrangeCache_loop02
810 adds r1, r1, #(1 << HW_C7_CACHE_SET_NO_SHIFT)
811 bne @arrangeCache_loop01
812 /* DC_InvalidateAll() */
813 mov r0, #0
814 mcr p15, 0, r0, c7, c6, 0
815 /* IC_InvalidateAll() */
816 // mov r0, #0
817 mcr p15, 0, r0, c7, c5, 0
818 /* DC_WaitWriteBufferEmpty() */
819 // mov r0, #0
820 mcr p15, 0, r0, c7, c10, 4
821
822 /* Synch with ARM7 */
823 ldr r0, =HW_BOOT_SYNC_PHASE
824 strh r3, [r0]
825 ldr r0, =HW_BOOT_SHAKEHAND_9
826 ldr r1, =HW_BOOT_SHAKEHAND_7
827 ldrh r2, [r1]
828 ldrh r3, [r0]
829 @shakeHand02_loop:
830 add r3, r3, #1
831 strh r3, [r0]
832 ldrh r12, [r1]
833 cmp r2, r12
834 beq @shakeHand02_loop
835 add r3, r3, #1
836 strh r3, [r0]
837
838 ldmfd sp!, {pc}
839 // bx lr
840 }
841 #include <twl/itcm_end.h>
842
843 #else // ifdef SDK_ARM9
844 //---------------- ARM7
845 #include <twl/ltdwram_begin.h>
846 static asm void
OSi_ReloadTwlRomData(void)847 OSi_ReloadTwlRomData(void)
848 {
849 @shakeHand01:
850 /* Synch with ARM9 */
851 ldr r0, =HW_BOOT_SHAKEHAND_9
852 ldr r1, =HW_BOOT_SHAKEHAND_7
853 ldrh r2, [r0]
854 ldrh r3, [r1]
855 @shakeHand01_loop:
856 add r3, r3, #1
857 strh r3, [r1]
858 ldrh r12, [r0]
859 cmp r2, r12
860 beq @shakeHand01_loop
861 add r3, r3, #1
862 strh r3, [r1]
863
864 ldr r0, =HW_BOOT_SYNC_PHASE
865 @shakeHand01_waitLoop:
866 ldrh r1, [r0]
867 cmp r1, #3
868 beq @shakeHand02
869 cmp r1, #2
870 bne @shakeHand01_waitLoop
871
872 @restoreShelteredBinary:
873 ldr r12, =HW_TWL_ROM_HEADER_BUF
874 /* Recover retracted data from the ARM7 extended binary */
875 ldr r0, [r12, #0x1dc]
876 cmp r0, #0
877 beq @restoreNext
878 ldr r2, [r12, #0x1d8] // r2 = Resident module RAM address for ARM7
879 ldr r0, =OSi_LtdMainParams
880 ldr r3, [r0] // r3 = end of src address
881 sub r1, r3, #0x4000 // r1 = start of src address
882 @restoreLoop01:
883 ldr r0, [r1], #4
884 str r0, [r2], #4
885 cmp r1, r3
886 blt @restoreLoop01
887
888 @restoreNext:
889 /* Recover retracted data of the extension binary for ARM9 */
890 ldr r0, [r12, #0x1cc]
891 cmp r0, #0
892 beq @shakeHand02
893 ldr r2, [r12, #0x1c8] // r2 = Resident module RAM address for ARM9
894 ldr r0, =OSi_LtdMainParams
895 ldr r0, [r0]
896 sub r3, r0, #0x4000 // r3 = end of src address
897 sub r1, r3, #0x4000 // r1 = start of src address
898 @restoreLoop02:
899 ldr r0, [r1], #4
900 str r0, [r2], #4
901 cmp r1, r3
902 blt @restoreLoop02
903
904 @shakeHand02:
905 /* Synch with ARM9 */
906 ldr r0, =HW_BOOT_SHAKEHAND_9
907 ldr r1, =HW_BOOT_SHAKEHAND_7
908 ldrh r2, [r0]
909 ldrh r3, [r1]
910 @shakeHand02_loop:
911 add r3, r3, #1
912 strh r3, [r1]
913 ldrh r12, [r0]
914 cmp r2, r12
915 beq @shakeHand02_loop
916 add r3, r3, #1
917 strh r3, [r1]
918
919 bx lr
920 }
921 #include <twl/ltdwram_end.h>
922
923 #endif // ifdef SDK_ARM9
924 #endif // ifdef SDK_TWL
925