/*---------------------------------------------------------------------------* Project: CtrBrom - library - init File: crt0_misc.c Copyright 2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: $ $Rev$ $Author$ *---------------------------------------------------------------------------*/ #include #include #ifdef SDK_NE1EMU /*---------------------------------------------------------------------------* Name: i_stupInitDDR2 Description: Initialize DDR2 for NE1-TBoard Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void i_stupInitDDR2( void ) { INASM_EXTERN( i_osWaitCpuCycles ) mov r3, lr ldr r0, =HW_NE1EXBUS_REG ldr r1, =0x0000004A str r1, [r0, #REG_EXBUS_PCS0_OFFSET] ldr r1, =0x08000049 str r1, [r0, #REG_EXBUS_PCS1_OFFSET] ldr r1, =0x0600004E str r1, [r0, #REG_EXBUS_PCS2_OFFSET] ldr r1, =0x0400004B str r1, [r0, #REG_EXBUS_PCS3_OFFSET] ldr r1, =0x1000004A str r1, [r0, #REG_EXBUS_PCS4_OFFSET] ldr r1, =0x1400000A str r1, [r0, #REG_EXBUS_PCS5_OFFSET] ldr r1, =0x10388E7F str r1, [r0, #REG_EXBUS_PCS0TIM_OFFSET] ldr r1, =0x10388E7E str r1, [r0, #REG_EXBUS_PCS1TIM_OFFSET] ldr r1, =0x10388E7E str r1, [r0, #REG_EXBUS_PCS2TIM_OFFSET] ldr r1, =0x10388E7F str r1, [r0, #REG_EXBUS_PCS3TIM_OFFSET] ldr r1, =0x10388E7E str r1, [r0, #REG_EXBUS_PCS4TIM_OFFSET] ldr r1, =0x10388E7E str r1, [r0, #REG_EXBUS_PCS5TIM_OFFSET] // Check device version // ES1.0 : go to ContinueBoot ldr r0, =HW_NE1SYS_REG ldr r1, [r0, #REG_SYS_VERSION_OFFSET] ldr r2, =0x00000001 cmp r1, r2 bne ContinueBoot // Check reset cause // Software reset : ContinueBoot ldr r1, [r0, #REG_SYS_RESET_STATUS_OFFSET] and r1, r1, #REG_NE1SYS_SYS_RESET_STATUS_RST_STAT_MASK mov r2, #REG_NE1SYS_SYS_RESET_STATUS_RST_STAT_MASK cmp r1, r2 beq ContinueBoot // Check BTM // DSW1_7 OFF : ContinueBoot ldr r1, [r0, #REG_SYS_BOOT_ID_OFFSET] and r1, r1, #REG_NE1SYS_SYS_BOOT_ID_MODE_MASK mov r2, #REG_NE1SYS_SYS_BOOT_ID_MODE_MASK cmp r1, r2 bne ContinueBoot // Change WTOP normal mode setting ldr r1, [r0, #REG_SYS_WTOP_MODE_OFFSET] and r1, r1, #0xFFFFFFFE str r1, [r0, #REG_SYS_WTOP_MODE_OFFSET] // Do Software reset mov r1, #REG_NE1SYS_SYS_RESET_STATUS_RST_MASK str r1, [r0, #REG_SYS_RESET_STATUS_OFFSET] wait_reset b wait_reset ContinueBoot // Clear Software reset mov r1, #REG_NE1SYS_SYS_RESET_STATUS_RST_STAT_MASK str r1, [r0, #REG_SYS_RESET_STATUS_OFFSET] // Setup DDR2 ldr r0, =HW_NE1DDR2_REG ldr r1, =0x30022123 str r1, [r0, #REG_MIF_SDC_CFG2_OFFSET] mov r1, #0x1 str r1, [r0, #REG_MIF_DLL_CFG_OFFSET] mov r1, #0x20 str r1, [r0, #REG_MIF_INIT_OFFSET] // wait 480ns ldr r0, =__cpp(OS_USEC_TO_TICK32(10)) bl i_osWaitCpuCycles ldr r0, =HW_NE1DDR2_REG ldr r1, =0x10000004 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x00010002 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x00018002 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x00008002 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x1D480002 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x10000004 str r1, [r0, #REG_MIF_INIT_OFFSET] mov r1, #0x1 str r1, [r0, #REG_MIF_INIT_OFFSET] mov r1, #0x1 str r1, [r0, #REG_MIF_INIT_OFFSET] // wait 1080ns ldr r0, =__cpp(OS_USEC_TO_TICK32(10)) bl i_osWaitCpuCycles ldr r0, =HW_NE1DDR2_REG ldr r1, =0x19480002 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x01308002 str r1, [r0, #REG_MIF_INIT_OFFSET] mov r1, #0x100 str r1, [r0, #REG_MIF_INIT_OFFSET] ldr r1, =0x1485A912 str r1, [r0, #REG_MIF_SDC_CFG1_OFFSET] ldr r1, =0x00000121 str r1, [r0, #REG_MIF_REF_CFG_OFFSET] mov lr, r3 bx lr } #endif // SDK_NE1EMU /*---------------------------------------------------------------------------* Name: stupDisableCP15 Description: Disable Coprocessor 15 Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void stupDisableCP15( void ) { // MMU/Caches/BranchPrediction disable mrc p15, 0, r0, c1, c0, 0 ldr r1, =HW_C1_IC_ENABLE | HW_C1_DC_ENABLE \ | HW_C1_FORCE_AP_BIT \ | HW_C1_TEX_CB_REMAP \ | HW_C1_EXCEPT_BIG_ENDIAN \ | HW_C1_BR_PREDICT_ENABLE \ | HW_C1_LD_INTERWORK_DISABLE \ | HW_C1_UNALIGN_ACCESS_ENABLE \ | HW_C1_ALIGN_FAULT_ENABLE \ | HW_C1_ROM_PROTECT_ENABLE \ | HW_C1_MMU_PROTECT_ENABLE \ | HW_C1_MMU_ENABLE #ifndef SDK_MG20EMU orr r1, r1, #HW_C1_EXCEPT_VEC_UPPER #endif // SDK_MG20EMU bic r0, r0, r1 mcr p15, 0, r0, c1, c0, 0 mrc p15, 0, r0, c1, c0, 1 ldr r1, =HW_C1_SMP_MODE \ | HW_C1_EXCLUSIVE_L1C_L2C \ | HW_C1_BR_FOLDING_ENABLE \ | HW_C1_SBR_PREDICT_ENABLE \ | HW_C1_DBR_PREDICT_ENABLE \ | HW_C1_RETURN_STACK_ENABLE bic r0, r0, r1 mcr p15, 0, r0, c1, c0, 1 // Invalidate Caches mov r0, #0 mcr p15, 0, r0, c7, c5, 0 // Inst Cache mcr p15, 0, r0, c7, c6, 0 // Data cache // Wait for write buffer empty mcr p15, 0, r0, c7, c10, 4 bx lr } /*---------------------------------------------------------------------------* Name: stupEnableCP15 Description: Enable Coprocessor 15 Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void stupEnableCP15( void ) { // // Auxiliary Control // mrc p15, 0, r0, c1, c0, 1 ldr r1, =HW_C1_AMP_MODE \ | HW_C1_BR_FOLDING_ENABLE \ | HW_C1_SBR_PREDICT_ENABLE \ | HW_C1_DBR_PREDICT_ENABLE \ | HW_C1_RETURN_STACK_ENABLE orr r0, r0, r1 mcr p15, 0, r0, c1, c0, 1 // // Master Control // mrc p15, 0, r0, c1, c0, 0 ldr r1, = 0 \ | HW_C1_EXCEPT_LITTLE_ENDIAN \ | HW_C1_UNALIGN_ACCESS_ENABLE \ | HW_C1_BR_PREDICT_ENABLE \ | HW_C1_MMU_V6 \ | HW_C1_IC_ENABLE \ | HW_C1_DC_ENABLE \ | HW_C1_MMU_ENABLE #ifdef SDK_MG20EMU orr r1, r1, #HW_C1_EXCEPT_VEC_UPPER #endif // SDK_MG20EMU orr r0, r0, r1 // mcr p15, 0, r0, c1, c0, 0 // Invalidate Caches mov r0, #0 mcr p15, 0, r0, c7, c5, 0 // Inst Cache mcr p15, 0, r0, c7, c6, 0 // Data cache // Wait for write buffer empty mcr p15, 0, r0, c7, c10, 4 bx lr } /*---------------------------------------------------------------------------* Name: __user_initial_stackheap Description: called from __scatterload Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void __user_initial_stackheap( void ) { #ifdef BROM_ENABLE_INITIAL_STACKHEAP INASM_EXTERN( |Image$$ZI$$ZI$$Limit| ) ldr r0, =|Image$$ZI$$ZI$$Limit| // heap base ldr r1, =HW_BROM_IRQ_STACK_END sub r1, r1, #HW_BROM_IRQ_STACK_SIZE mov r2, r0 mov r3, r0 #endif // BROM_ENABLE_INITIAL_STACKHEAP bx lr } /*---------------------------------------------------------------------------* Name: stupInitSections Description: Initialize Sections Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void stupInitSections( void ) { b stupInitStaticSections } /*---------------------------------------------------------------------------* Name: stupInitStaticSections Description: Initialize Static Sections Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void stupInitStaticSections( void ) { #ifdef BROM_TARGET_BROM INASM_EXTERN( |Image$$SEC_RO$$Limit| ) ldr r0, =|Image$$SEC_RO$$Limit| #else // BROM_TARGET_NORFIRM || BROM_TARGET_APP INASM_EXTERN( |Image$$RO$$Limit| ) ldr r0, =|Image$$RO$$Limit| #endif // BROM_TARGET_NORFIRM || BROM_TARGET_APP INASM_EXTERN( |Image$$RW$$Base| ) INASM_EXTERN( |Image$$ZI$$ZI$$Base| ) INASM_EXTERN( |Image$$ZI$$ZI$$Limit| ) ldr r1, =|Image$$RW$$Base| ldr r3, =|Image$$ZI$$ZI$$Base| cmp r0, r1 beq FSYM(20) LSYM(10) cmp r1, r3 ldrcc r2, [r0], #4 strcc r2, [r1], #4 bcc BSYM(10) LSYM(20) ldr r1, =|Image$$ZI$$ZI$$Limit| mov r2, #0 LSYM(30) cmp r3, r1 strcc r2, [r3], #4 bcc BSYM(30) bx lr } /*---------------------------------------------------------------------------* Name: i_stupCpuCopy32 Description: copy memory by CPU 32bit version Arguments: srcp : source address destp : destination address size : size (byte) Returns: None *---------------------------------------------------------------------------*/ asm void i_stupCpuCopy32( const void *srcp, void *destp, u32 size ) { add r12, r1, r2 LSYM(10) cmp r1, r12 ldmltia r0!, {r2} stmltia r1!, {r2} blt BSYM(10) bx lr } /*---------------------------------------------------------------------------* Name: i_stupCpuClear32 Description: fill memory with specified data. 32bit version Arguments: data : fill data destp : destination address size : size (byte) Returns: None *---------------------------------------------------------------------------*/ asm void i_stupCpuClear32( u32 data, void *destp, u32 size ) { add r12, r1, r2 LSYM(10) cmp r1, r12 stmltia r1!, {r0} blt BSYM(10) bx lr } /*---------------------------------------------------------------------------* Name: i_stupNotifyToARM9 Description: notify 4bit id to ARM9 Arguments: id notifying id Returns: None *---------------------------------------------------------------------------*/ asm void i_stupNotifyToARM9( u32 id ) { ldr r3, =REG_SUBPINTF_ADDR mov r0, r0, lsl #REG_PXI_SUBPINTF_A11STATUS_SHIFT and r0, r0, #REG_PXI_SUBPINTF_A11STATUS_MASK str r0, [r3] bx lr } /*---------------------------------------------------------------------------* Name: i_stupWaitARM9 Description: Wait 4bit id from ARM9 Arguments: id waiting id Returns: None *---------------------------------------------------------------------------*/ asm void i_stupWaitARM9( u32 id ) { ldr r3, =REG_SUBPINTF_ADDR LSYM(10) ldr r1, [r3] and r1, r1, #REG_PXI_SUBPINTF_A9STATUS_MASK cmp r0, r1 bne BSYM(10) bx lr } /*---------------------------------------------------------------------------* Name: i_stupWaitCpuCycles Description: Loop and Wait for specified CPU cycles at least Arguments: cycles waiting CPU cycle Returns: None *---------------------------------------------------------------------------*/ asm void i_stupWaitCpuCycles( u32 cycle ) { sub r0, r0, #(6-2) // subtract call-return overhead and add the margin of 2 cycles LSYM(10) subs r0, r0, #4 // 1 cycle bcs BSYM(10) // 3 cycle bx lr }