mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@205 b871894f-2f95-9b40-918c-086798483c85
481 lines
13 KiB
C
481 lines
13 KiB
C
/*---------------------------------------------------------------------------*
|
|
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 <brom/code32.h>
|
|
#include <brom/os.h>
|
|
|
|
#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
|
|
}
|
|
|