1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK
3   File:     crt0.c
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-12-05#$
14   $Rev: 9534 $
15   $Author: sasaki_yu $
16  *---------------------------------------------------------------------------*/
17 #include        <nitro.h>
18 #include        <nitro/code32.h>
19 
20 extern void NitroMain(void);
21 extern void OS_IrqHandler(void);
22 static void do_autoload(void);
23 static void init_cp15(void);
24 void    _start(void);
25 static void INITi_CpuClear32(register u32 data, register void *destp, register u32 size);
26 extern void *const _start_ModuleParams[];
27 void    _start_AutoloadDoneCallback(void *argv[]);
28 
29 extern void __call_static_initializers(void);
30 extern void _fp_init(void);
31 
32 // From LCF
33 extern void SDK_IRQ_STACKSIZE(void);
34 extern void SDK_AUTOLOAD_START(void);  // Autoload data will start from here
35 extern void SDK_AUTOLOAD_LIST(void);   // Start pointer to autoload information
36 extern void SDK_AUTOLOAD_LIST_END(void);        // End pointer to autoload information
37 extern void SDK_STATIC_BSS_START(void); // Static bss start address
38 extern void SDK_STATIC_BSS_END(void);  // Static bss end address
39 
40 #include        <nitro/version.h>
41 #define         SDK_VERSION_ID   ((u32)SDK_VERSION_MAJOR<<24|\
42                                   (u32)SDK_VERSION_MINOR<<16|\
43                                   (u32)SDK_VERSION_RELSTEP)
44 
45 #define     SDK_NITROCODE_LE    0x2106c0de
46 #define     SDK_NITROCODE_BE    0xdec00621
47 
48 #define     SDK_BUILDCODE_LE      0x3381c0de
49 #define     SDK_BUILDCODE_BE      0xdec08133
50 
51 /* For embedding build type */
52 #if defined(SDK_DEBUG)
53 #define SDK_BUILDCODE 2
54 #elif defined(SDK_RELEASE)
55 #define SDK_BUILDCODE 1
56 #elif defined(SDK_FINALROM)
57 #define SDK_BUILDCODE 0
58 #else
59 #define SDK_BUILDCODE 255     //  Error
60 #endif
61 
62 #if defined(SDK_ARM9)
63 #define SDK_TARGET 9
64 #elif defined(SDK_ARM7)
65 #define SDK_TARGET 7
66 #else
67 #define SDK_TARGET 255      //  Error
68 #endif
69 
70 
71 /*---------------------------------------------------------------------------*
72   Name:         _start
73 
74   Description:  Start up
75 
76   Arguments:    None.
77 
78   Returns:      None.
79  *---------------------------------------------------------------------------*/
80 #define INITi_HW_DTCM   SDK_AUTOLOAD_DTCM_START
81 
_start(void)82 SDK_WEAK_SYMBOL asm void _start( void )
83 {
84         //---- Set IME = 0
85         //     (Use that LSB of HW_REG_BASE equal to 0)
86         mov             r12, #HW_REG_BASE
87         str             r12, [r12, #REG_IME_OFFSET]
88 
89         //---- Adjust VCOUNT
90 @wait_vcount_0:
91         ldrh            r0, [r12, #REG_VCOUNT_OFFSET]
92         cmp             r0, #0
93         bne             @wait_vcount_0
94 
95         //---- Initialize cp15
96         bl              init_cp15
97 
98         //---- Initialize stack pointer
99         // SVC mode
100         mov             r0, #HW_PSR_SVC_MODE
101         msr             cpsr_c, r0
102         ldr             r0, =INITi_HW_DTCM
103         add             r0, r0, #0x3fc0
104         mov             sp, r0
105 
106         // IRQ mode
107         mov             r0, #HW_PSR_IRQ_MODE
108         msr             cpsr_c, r0
109         ldr             r0, =INITi_HW_DTCM
110         add             r0, r0, #0x3fc0
111         sub             r0, r0, #HW_SVC_STACK_SIZE
112         sub             sp, r0, #4 // 4 bytes for stack check code
113         tst             sp, #4
114         subeq           sp, sp, #4 // For 8-byte alignment
115 
116         // System mode
117         ldr             r1, =SDK_IRQ_STACKSIZE
118         sub             r1, r0, r1
119         mov             r0, #HW_PSR_SYS_MODE
120         msr             cpsr_csfx, r0
121         sub             sp, r1, #4 // 4 bytes for stack check code
122         tst             sp, #4
123         subne           sp, sp, #4 // For 8-byte alignment
124 
125         //---- Clear memory
126         // DTCM (16KB)
127         mov             r0, #0
128         ldr             r1, =INITi_HW_DTCM
129         mov             r2, #HW_DTCM_SIZE
130         bl              INITi_CpuClear32
131 
132         // BG/OBJ palette (1KB)
133         mov             r0, #0
134         ldr             r1, =HW_PLTT
135         mov             r2, #HW_PLTT_SIZE
136         bl              INITi_CpuClear32
137 
138         // OAM (1KB)
139         mov             r0, #0x0200
140         ldr             r1, =HW_OAM
141         mov             r2, #HW_OAM_SIZE
142         bl              INITi_CpuClear32
143 
144         //---- Load autoload block and initialize bss
145         ldr             r1, =_start_ModuleParams
146         ldr             r0, [r1, #20]   // r0 = bottom of compressed data
147         bl              MIi_UncompressBackward
148         bl              do_autoload
149 
150         //---- Fill static static bss with 0
151         ldr             r0, =_start_ModuleParams
152         ldr                r1, [r0, #12]   // BSS segment start
153         ldr                r2, [r0, #16]   // BSS segment end
154         mov                r3, r1          // For next step (flush bss)
155         mov                r0, #0
156 @1:     cmp                r1, r2
157         strcc              r0, [r1], #4
158         bcc                @1
159 
160         //---- Flush static bss region
161         //     (r0 == #0, r3 == _start_ModuleParams::BSS_segment_start)
162         bic                r1, r3, #HW_CACHE_LINE_SIZE - 1
163 @cacheflush:
164         mcr                p15, 0, r0, c7, c10, 4         // Wait writebuffer empty
165         mcr                p15, 0, r1, c7,  c5, 1         // ICache
166         mcr                p15, 0, r1, c7, c14, 1         // DCache
167         add                r1, r1, #HW_CACHE_LINE_SIZE
168         cmp                r1, r2
169         blt                @cacheflush
170 
171         // Print buffer (used for ARM7's printing)
172         ldr             r1, =HW_COMPONENT_PARAM
173         str             r0, [r1, #0]
174 
175         //---- Set interrupt vector
176         ldr             r1, =INITi_HW_DTCM
177         add             r1, r1, #0x3fc0
178         add             r1, r1, #HW_DTCM_SYSRV_OFS_INTR_VECTOR
179         ldr             r0, =OS_IrqHandler
180         str             r0, [r1, #0]
181 
182 #ifndef SDK_NOINIT
183         //---- For C++
184         bl             _fp_init
185         bl             NitroStartUp
186         bl             __call_static_initializers
187 #endif
188         //---- Start (to 16-bit code)
189         ldr             r1, =NitroMain
190         ldr             lr, =HW_RESET_VECTOR
191         bx              r1
192 }
193 
194 
195 /*---------------------------------------------------------------------------*
196   Name:         INITi_CpuClear32
197 
198   Description:  Fill memory with specified data.
199                 32-bit version.
200 
201   Arguments:    data: Fill data
202                 destp: Destination address
203                 size: Size (bytes)
204 
205   Returns:      None.
206  *---------------------------------------------------------------------------*/
INITi_CpuClear32(register u32 data,register void * destp,register u32 size)207 static asm void  INITi_CpuClear32( register u32 data, register void *destp, register u32 size )
208 {
209         add     r12, r1, r2             // r12: destEndp = destp + size
210 @20:
211         cmp     r1, r12                 // while (destp < destEndp)
212         stmltia r1!, {r0}               // *((vu32 *)(destp++)) = data
213         blt     @20
214         bx      lr
215 }
216 
217 
218 /*---------------------------------------------------------------------------*
219   Name:         _start_ModuleParams
220 
221   Description:  Autoload/compress/arguments data block.
222 
223   Arguments:    None.
224 
225   Returns:      None.
226  *---------------------------------------------------------------------------*/
227 void   *const _start_ModuleParams[] = {
228     (void *)SDK_AUTOLOAD_LIST,
229     (void *)SDK_AUTOLOAD_LIST_END,
230     (void *)SDK_AUTOLOAD_START,
231     (void *)SDK_STATIC_BSS_START,
232     (void *)SDK_STATIC_BSS_END,
233     (void *)0,                         // CompressedStaticEnd
234     (void *)SDK_VERSION_ID,            // SDK version info
235     (void *)SDK_NITROCODE_BE,          // Checker 1
236     (void *)SDK_NITROCODE_LE,          // Checker 2
237 };
238 
239 /* Allocate 32 bytes for storage of build information */
240 #pragma force_active on
241 void* const _start_BuildParams[]    =
242 {
243     (void*)0,       // Reserved
244     (void*)0,       // Reserved
245     (void*)0,       // Reserved
246     (void*)0,       // Reserved
247     (void*)(SDK_BUILDCODE | (SDK_TARGET << 8)), // Build target and build type
248     (void*)1,       // Version(1byte) Reserved(3byte)
249     (void*)SDK_BUILDCODE_BE,
250     (void*)SDK_BUILDCODE_LE,
251 };
252 
253 /*
254     When built for NITRO, not to link on the force_active
255 */
256 #ifdef SDK_NITRO
257 static void* DUMMY = (void*)&_start_BuildParams[0];
258 #endif
259 /*---------------------------------------------------------------------------*
260   Name:         MIi_UncompressBackward
261 
262   Description:  Uncompress special archive for module compression.
263 
264   Arguments:    bottom      = Bottom adrs of packed archive + 1
265                 bottom[-8..-6] = offset for top of compressed data
266                                  inp_top = bottom - bottom[-8..-6]
267                 bottom[ -5] = offset for bottom of compressed data
268                                  inp     = bottom - bottom[-5]
269                 bottom[-4..-1] = offset for bottom of original data
270                                  outp    = bottom + bottom[-4..-1]
271 
272                 typedef struct
273                 {
274                    u32         bufferTop:24;
275                    u32         compressBottom:8;
276                    u32         originalBottom;
277                 }   CompFooter;
278 
279   Returns:      None.
280  *---------------------------------------------------------------------------*/
MIi_UncompressBackward(register void * bottom)281 asm void  MIi_UncompressBackward( register void* bottom )
282 {
283 #define data            r0
284 #define inp_top         r1
285 #define outp            r2
286 #define inp             r3
287 #define outp_save       r4
288 #define flag            r5
289 #define count8          r6
290 #define index           r7
291 #define len             r12
292                 cmp     bottom, #0
293                 beq     @exit
294                 stmfd   sp!,    {r4-r7}
295                 ldmdb   bottom, {r1-r2}
296                 add     outp,    bottom,  outp
297                 sub     inp,     bottom,  inp_top, LSR #24
298                 bic     inp_top, inp_top, #0xff000000
299                 sub     inp_top, bottom,  inp_top
300                 mov     outp_save, outp
301 @loop:
302                 cmp     inp, inp_top            // Exit if inp==inp_top
303                 ble     @end_loop
304                 ldrb    flag, [inp, #-1]!       // r4 = compress_flag = *--inp
305                 mov     count8, #8
306 @loop8:
307                 subs    count8, count8, #1
308                 blt     @loop
309                 tst     flag, #0x80
310                 bne     @blockcopy
311 @bytecopy:
312                 ldrb    data, [inp, #-1]!
313 #ifdef  SDK_TEG
314                 sub     outp, outp, #1
315                 swpb    data, data, [outp]
316 #else
317                 strb    data, [outp, #-1]!      // Copy 1 byte
318 #endif
319                 b       @joinhere
320 @blockcopy:
321                 ldrb    len,   [inp, #-1]!
322                 ldrb    index, [inp, #-1]!
323                 orr     index, index, len, LSL #8
324                 bic     index, index, #0xf000
325                 add     index, index, #0x0002
326                 add     len,   len,   #0x0020
327 @patterncopy:
328                 ldrb    data,  [outp, index]
329 #ifdef  SDK_TEG
330                 sub     outp, outp, #1
331                 swpb    data, data, [outp]
332 #else
333                 strb    data,  [outp, #-1]!
334 #endif
335                 subs    len,   len,   #0x0010
336                 bge     @patterncopy
337 
338 @joinhere:
339                 cmp     inp, inp_top
340                 mov     flag, flag, LSL #1
341                 bgt     @loop8
342 @end_loop:
343 
344                 // DC_FlushRange & IC_InvalidateRange
345                 mov     r0, #0
346                 bic     inp,  inp_top, #HW_CACHE_LINE_SIZE - 1
347 @cacheflush:
348                 mcr     p15, 0, r0, c7, c10, 4          // Wait writebuffer empty
349                 mcr     p15, 0, inp, c7,  c5, 1         // ICache
350                 mcr     p15, 0, inp, c7, c14, 1         // DCache
351                 add     inp, inp, #HW_CACHE_LINE_SIZE
352                 cmp     inp, outp_save
353                 blt     @cacheflush
354 
355                 ldmfd   sp!, {r4-r7}
356 @exit           bx      lr
357 }
358 
359 
360 /*---------------------------------------------------------------------------*
361   Name:         do_autoload
362 
363   Description:  Put autoload data block according to autoload information,
364                 and clear static bss by filling with 0.
365 
366   Arguments:    None.
367 
368   Returns:      None.
369  *---------------------------------------------------------------------------*/
do_autoload(void)370 static asm void do_autoload( void )
371 {
372 #define ptable          r0
373 #define infop           r1
374 #define infop_end       r2
375 #define src             r3
376 #define dest            r4
377 #define dest_begin      r5
378 #define dest_end        r6
379 #define tmp             r7
380 
381         ldr     ptable, =_start_ModuleParams
382         ldr     infop,      [ptable, #0]   // r1 = start pointer to autoload_info
383         ldr     infop_end,  [ptable, #4]   // r2 = end pointer to autoload_info
384         ldr     src,        [ptable, #8]   // r3 = autoload block
385 
386 @2:
387         cmp     infop, infop_end                // Does it get to the end?
388         beq     @skipout
389 
390         ldr     dest_begin,[infop], #4          // dest_begin
391         ldr     tmp,       [infop], #4          // size
392         add     dest_end, dest_begin, tmp       // dest_end
393         mov     dest,     dest_begin            // dest working pointer
394 @1:
395         cmp     dest, dest_end
396         ldrmi   tmp, [src],  #4                 // [dest++] <- [src++]
397         strmi   tmp, [dest], #4
398         bmi     @1
399 
400         //---- fill bss with 0
401         ldr     tmp, [infop], #4                // size
402         add     dest_end, dest, tmp             // bss end
403         mov     tmp, #0
404 @3:
405         cmp     dest, dest_end
406         strcc   tmp, [dest], #4
407         bcc     @3
408 
409         //---- cache work (DC_FlushRange & IC_InvalidateRange)
410         bic     dest, dest_begin, #HW_CACHE_LINE_SIZE - 1
411 @cacheflush:
412         mcr     p15, 0, tmp, c7, c10, 4          /* Wait writebuffer empty */
413         mcr     p15, 0, dest, c7,  c5, 1         // ICache
414         mcr     p15, 0, dest, c7, c14, 1         // DCache
415         add     dest, dest, #HW_CACHE_LINE_SIZE
416         cmp     dest, dest_end
417         blt     @cacheflush
418 
419         b       @2
420 
421 @skipout:
422         // r0 = _start_ModuleParams
423         b       _start_AutoloadDoneCallback   // Jump into the callback
424 }
425 
426 /*---------------------------------------------------------------------------*
427   Name:         _start_AutoloadDoneCallback
428 
429   Description:  Hook for end of autoload (This is a dummy target for DEBUGGER).
430 
431   Arguments:    argv: Pointer for autoload parameters.
432                      argv[0] = SDK_AUTOLOAD_LIST
433                      argv[1] = SDK_AUTOLOAD_LIST_END
434                      argv[2] = SDK_AUTOLOAD_START
435                      argv[3] = SDK_STATIC_BSS_START
436                      argv[4] = SDK_STATIC_BSS_END
437 
438   Returns:      None.
439  *---------------------------------------------------------------------------*/
_start_AutoloadDoneCallback(void * argv[])440 SDK_WEAK_SYMBOL asm void _start_AutoloadDoneCallback( void* argv[] )
441 {
442         bx      lr
443 }
444 
445 //-----------------------------------------------------------------------
446 //                   Initialize system control coprocessor
447 //-----------------------------------------------------------------------
init_cp15(void)448 static asm void init_cp15(void)
449 {
450         // Protection unit / Cache / TCM disable
451 
452         mrc     p15, 0, r0, c1, c0, 0
453         ldr     r1, =HW_C1_ICACHE_ENABLE  | HW_C1_DCACHE_ENABLE  \
454                    | HW_C1_ITCM_ENABLE    | HW_C1_DTCM_ENABLE    \
455                    | HW_C1_ITCM_LOAD_MODE | HW_C1_DTCM_LOAD_MODE \
456                    | HW_C1_LD_INTERWORK_DISABLE                  \
457                    | HW_C1_PROTECT_UNIT_ENABLE
458         bic     r0, r0, r1
459         mcr     p15, 0, r0, c1, c0, 0
460 
461         // Invalidate cache
462         mov     r0, #0
463         mcr     p15, 0, r0, c7, c5, 0       // Instruction cache
464         mcr     p15, 0, r0, c7, c6, 0       // Data cache
465 
466         // Wait for the write buffer to empty.
467         mcr     p15, 0, r0, c7, c10, 4
468 
469 /*
470 ; Region G:    BACK_GROUND: Base = 0x0,        Size = 4GB,   I:NC NB    / D:NC NB,     I:NA / D:NA
471 ; Region 0:    IO_VRAM       :     Base = 0x04000000, Size = 64MB,  I:NC NB    / D:NC NB,     I:RW / D:RW
472 ; Region 1Rel: MAIN_MEM+W:  Base = 0x02000000, Size = 32MB*, I:Cach Buf / D:Cach Buf,  I:RW / D:RW
473 ; Region 1Dbg: MAIN_MEM+W:  Base = 0x02000000, Size = 32MB,  I:Cach Buf / D:Cach Buf,  I:RW / D:RW
474 ;                                              (* Size will be arranged in OS_InitArena(). )
475 ; Region 2Rel: SOUND_DATA:  Base = 0x02380000, Size = 512KB, I:NC NB    / D:NC NB,     I:NA / D:NA
476 ; Region 2D4M: SOUND_DATA:  Base = 0x02300000, Size = 1MB,   I:NC NB    / D:NC NB,     I:NA / D:NA
477 ; Region 2D8M: SOUND_DATA:  Base = 0x02600000, Size = 2MB,   I:NC NB    / D:NC NB,     I:NA / D:NA
478 ; Region 2:    SHARE_WORK:  Base = 0x027ff000, Size = 4KB,   I:NC NB    / D:NC NB,     I:NA / D:RW
479 ; Region 3:    MAIN_MEM_HI: Base = 0x08000000, Size = 128MB, I:NC NB    / D:NC NB,     I:NA / D:RW
480 ; Region 4:    DTCM          :        Base = SOUND_DATA, Size = 16KB,  I:NC NB    / D:NC NB,     I:NA / D:RW
481 ; Region 5:    ITCM          :        Base = 0x01000000, Size = 16MB,  I:NC NB    / D:NC NB,     I:RW / D:RW
482 
483 ; Region 6:    BIOS          :        Base = 0xffff0000, Size = 32KB,  I:Cach NB  / D:Cach NB,   I:RO / D:RO
484 ; Region 7:    SHARE_WORK:  Base = 0x02fff000, Size = 4KB,   I:NC NB    / D:NC NB,     I:NA / D:RW
485 ;(Region 7:    DBG_RESERVE: Base = 0x02700000, Size = 1MB,   I:NC NB    / D:NC NB,     I:RW / D:RW)
486 */
487 #define SET_PROTECTION_A( id, adr, siz )        ldr r0, =(adr|HW_C6_PR_##siz|HW_C6_PR_ENABLE)
488 #define SET_PROTECTION_B( id, adr, siz )        mcr     p15, 0, r0, c6, id, 0
489 #define REGION_BIT(a,b,c,d,e,f,g,h)     (((a)<<0)|((b)<<1)|((c)<<2)|((d)<<3)|((e)<<4)|((f)<<5)|((g)<<6)|((h)<<7))
490 #define REGION_ACC(a,b,c,d,e,f,g,h)     (((a)<<0)|((b)<<4)|((c)<<8)|((d)<<12)|((e)<<16)|((f)<<20)|((g)<<24)|((h)<<28))
491 #define NA      0
492 #define RW      1
493 #define RO      5
494 
495 
496         //
497         // Initialize memory region
498         //
499         //---- I/O registers and VRAM, etc.
500         SET_PROTECTION_A( c0, HW_IOREG, 64MB )
501         SET_PROTECTION_B( c0, HW_IOREG, 64MB )
502 
503         //---- Main memory
504         SET_PROTECTION_A( c1, HW_MAIN_MEM_MAIN, 32MB )
505         SET_PROTECTION_B( c1, HW_MAIN_MEM_MAIN, 32MB )
506 
507         //---- SHARED (image)
508         SET_PROTECTION_A( c2, HW_MAIN_MEM_IM_SHARED, 4KB )
509         SET_PROTECTION_B( c2, HW_MAIN_MEM_IM_SHARED, 4KB )
510 
511         //---- Game Pak or other use
512         //      CPU internal work RAM etc.
513         SET_PROTECTION_A( c3, HW_CTRDG_ROM, 128MB )
514         SET_PROTECTION_B( c3, HW_CTRDG_ROM, 128MB )
515 
516         //---- Data TCM
517         //      + There is sometimes CPU internal work RAM
518 //#if   (HW_DTCM & 0x3FFF) != 0
519 //#pragma message(ERROR: HW_DTCM need to be aligned 16KB!)
520 //#endif
521 
522 //        SET_PROTECTION_A( c4, HW_DTCM, 16KB )
523         ldr     r0, =SDK_AUTOLOAD_DTCM_START
524         orr     r0, r0, #HW_C6_PR_16KB
525         orr     r0, r0, #HW_C6_PR_ENABLE
526         SET_PROTECTION_B( c4, HW_DTCM, 16KB )
527 
528         //---- Instruction TCM
529         //      Image up to the main memory region that has a higher priority than the data TCM.
530         SET_PROTECTION_A( c5, HW_ITCM_IMAGE, 16MB )
531         SET_PROTECTION_B( c5, HW_ITCM_IMAGE, 16MB )
532 
533         //---- BIOS
534         SET_PROTECTION_A( c6, HW_BIOS, 32KB )
535         SET_PROTECTION_B( c6, HW_BIOS, 32KB )
536 
537         //---- SHARED communication work area between CPUs
538         SET_PROTECTION_A( c7, HW_MAIN_MEM_SHARED, 4KB )
539         SET_PROTECTION_B( c7, HW_MAIN_MEM_SHARED, 4KB )
540 
541 #if     HW_MAIN_MEM_SHARED_SIZE != 0x1000
542 #pragma message(ERROR: Size unmatch HW_MAIN_MEM_SHARED_SIZE)
543 #endif
544 
545         //
546         // Instruction TCM settings
547         //
548         mov     r0, #HW_C9_TCMR_32MB
549         mcr     p15, 0, r0, c9, c1, 1
550 
551         //
552         // Data TCM settings
553         //
554         ldr     r0, =INITi_HW_DTCM
555         orr     r0, r0, #HW_C9_TCMR_16KB
556         mcr     p15, 0, r0, c9, c1, 0
557 
558         //
559         // Instruction cache enable (Region settings)
560         //      1: MAIN_MEM + WRAM
561         //      3: MAIN_MEM_HI (or CTRDG)
562         //      6: BIOS
563         //
564         mov     r0, #REGION_BIT(0,1,0,1,0,0,1,0)
565         mcr     p15, 0, r0, c2, c0, 1
566 
567         //
568         // Data cache enable (Region settings)
569         //      1: MAIN_MEM + WRAM
570         //      3: MAIN_MEM_HI (or CTRDG)
571         //      6: BIOS
572         //
573         mov     r0, #REGION_BIT(0,1,0,1,0,0,1,0)
574         mcr     p15, 0, r0, c2, c0, 0
575 
576         //
577         // Write buffer enable (Region settings)
578         //      1: MAIN_MEM + WRAM
579         //      3: MAIN_MEM (or CTRDG)
580         //
581         mov     r0, #REGION_BIT(0,1,0,1,0,0,0,0)
582         mcr     p15, 0, r0, c3, c0, 0
583 
584         //
585         // Instruction access permissions (Region settings)
586         //  IO_VRAM       : RW
587         //  MAIN_MEM_MAIN : RW
588         //  MAIN_MEM_SUB  : NA
589         //  MAIN_MEM_HI: RW
590         //  DTCM          : NA
591         //  ITCM          : RW
592         //  BIOS          : RO
593         //  SHARED        : NA
594         //
595 //        ldr     r0, =REGION_ACC(RW,RW,NA,RW,NA,RW,RO,NA)
596         ldr     r0, =REGION_ACC(RW,RW,NA,RW,NA,RW,RO,NA)
597         mcr     p15, 0, r0, c5, c0, 3
598 
599         //
600         // Data access permissions (Region settings)
601         //  IO_VRAM       : RW
602         //  MAIN_MEM_MAIN : RW
603         //  MAIN_MEM_SUB  : NA
604         //  MAIN_MEM_HI: RW
605         //  DTCM          : RW
606         //  ITCM          : RW
607         //  BIOS          : RO
608         //  SHARED        : RW
609         //
610 //        ldr     r0, =REGION_ACC(RW,RW,NA,RW,RW,RW,RO,RW)
611         ldr     r0, =REGION_ACC(RW,RW,RW,RW,RW,RW,RO,RW)
612         mcr     p15, 0, r0, c5, c0, 2
613 
614         //
615         // System control coprocessor master settings
616         //
617         mrc     p15, 0, r0, c1, c0, 0
618         ldr     r1,=HW_C1_ICACHE_ENABLE | HW_C1_DCACHE_ENABLE | HW_C1_CACHE_ROUND_ROBIN \
619                   | HW_C1_ITCM_ENABLE   | HW_C1_DTCM_ENABLE                             \
620                   | HW_C1_SB1_BITSET    | HW_C1_EXCEPT_VEC_UPPER                        \
621                   | HW_C1_PROTECT_UNIT_ENABLE
622         orr     r0, r0, r1
623         mcr     p15, 0, r0, c1, c0, 0
624 
625         bx      lr
626 }
627 
628 
629 /*---------------------------------------------------------------------------*
630   Name:         NitroStartUp
631 
632   Description:  Hook for user start-up.
633 
634   Arguments:    None.
635 
636   Returns:      None.
637  *---------------------------------------------------------------------------*/
NitroStartUp(void)638 SDK_WEAK_SYMBOL void NitroStartUp(void)
639 {
640 }
641 
642 /*---------------------------------------------------------------------------*
643   Name:         OSi_ReferSymbol
644 
645   Description:  Used by SDK_REFER_SYMBOL macro to avoid deadstripping.
646 
647   Arguments:    symbol:            Unused
648 
649   Returns:      None.
650  *---------------------------------------------------------------------------*/
OSi_ReferSymbol(void * symbol)651 void OSi_ReferSymbol(void *symbol)
652 {
653 #pragma unused(symbol)
654 }
655