ctr_firmware/trunk/bootrom/build/libraries/init/ARM11/crt0_secure.c
nakasima 81a57bd9ed small fix.
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@49 b871894f-2f95-9b40-918c-086798483c85
2008-12-01 09:02:18 +00:00

571 lines
17 KiB
C

/*---------------------------------------------------------------------------*
Project: CtrBrom - library - init
File: crt0_secure.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:: 2008-12-1#$
$Rev: 46 $
$Author: nakasima $
*---------------------------------------------------------------------------*/
#include <brom/code32.h>
#include <brom/os.h>
//#include <brom/mi.h>
#define STUPi_HW_DTCM |Image$$DTCM$$Base|
void stupInitMMUTable( void );
/*---------------------------------------------------------------------------*
Name: STUPi_StartHandler
Description: start handler
Arguments: None
Returns: None.
*---------------------------------------------------------------------------*/
asm void STUPi_StartHandler( void )
{
PRESERVE8
INASM_EXTERN( STUPi_HW_DTCM )
INASM_EXTERN( BromMain )
INASM_EXTERN( main )
//---- disable cp15
bl stupDisableCP15
//---- initialize MMU
bl stupInitMMU
//---- enable cp15
bl stupEnableCP15
//---- initialize stack pointer
// SVC mode
mov r0, #HW_PSR_SVC_MODE
msr cpsr_c, r0
ldr sp, =HW_BROM_SVC_STACK_END
// IRQ mode
mov r0, #HW_PSR_IRQ_MODE
msr cpsr_c, r0
ldr r0, =HW_BROM_IRQ_STACK_END
mov sp, r0
// System mode
mov r0, #HW_PSR_SYS_MODE
msr cpsr_csfx, r0
ldr r0, =HW_BROM_SYS_STACK_END
mov sp, r0
//---- clear wram
// 1KB
mov r0, #0
ldr r1, =HW_AXI_WRAM_END
mov r2, #0x0400
sub r1, r1, r2
bl STUPi_CpuClear32
//---- lnitialize sections
bl stupInitSections
//---- start (to 16bit code)
ldr r1, =BromMain
adr lr, terminate
bx r1
terminate
b terminate
}
/*---------------------------------------------------------------------------*
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_NMFI_FIQ \
| 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
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
#if 0
// Invalidate Caches
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 // Inst Cache
mcr p15, 0, r0, c7, c6, 0 // Data cache
#endif
// 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
#if 1 // 0 -> 1 miya
ldr r1, =HW_C1_EXCEPT_VEC_UPPER \
| HW_C1_FORCE_AP_BIT \
| 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
#else
ldr r1, =HW_C1_0_SB1 \
| HW_C1_EXCEPT_LITTLE_ENDIAN \
| HW_C1_EXCEPT_VEC_UPPER \
| 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
#endif
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: stupInitMMU
Description: Initialize MMU
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
ASM void stupInitMMU( void )
{
stmfd sp!, {r4, lr} // stack requires 8byte alignment
// Invalidate ITLB DTLB
mov r0, #0
mcr p15, 0, r0, c8, c5, 0
mcr p15, 0, r0, c8, c6, 0
ldr r0, =HW_BROM_MMU_T1
mov r2, #HW_C2_V5_T1_BOUNBRY_16KB
// MMU L1 Table Base
ldr r1, =HW_C2_0_T1_BASE_MASK_MIN
mov r1, r1, ASR r2
and r1 ,r1, r0
orr r1, r1, #HW_C2_WALK_L2C_CA_NC << HW_C2_WALK_L2C_CA_SFT
mcr p15, 0, r1, c2, c0, 0
ldr r1, =HW_C2_1_T1_BASE_MASK
and r1 ,r1, r0
orr r1, r1, #HW_C2_WALK_L2C_CA_NC << HW_C2_WALK_L2C_CA_SFT
mcr p15, 0, r1, c2, c0, 1
// MMU L1 Table Boundary
mcr p15, 0, r2, c2, c0, 2
// Domain Access Permission
#if 1 // miya
ldr r1, =0x00000001
#else
ldr r1, = HW_C3_DOMAIN_PACK( \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_CLIENT, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER, \
HW_C3_DM_AP_MANAGER \
)
#endif
mcr p15, 0, r1, c3, c0, 0
// VFP Access Permission
ldr r1, =HW_C1_VFP_AP_PACK( \
HW_C1_AP_PRIV, HW_C1_AP_PRIV )
mcr p15, 0, r1, c1, c0, 2
// Initialize MMU Table
bl __cpp(stupInitMMUTable)
ldmfd sp!, {r4, pc} // stack requires 8byte alignment
}
/*---------------------------------------------------------------------------*
Name: stupInitMMUTable
Description: Initialize MMU Table
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void stupInitMMUTable( void )
{
u32* t1Base = (u32* )HW_BROM_MMU_T1;
u32* t2Base = (u32* )HW_BROM_MMU_T2;
u32* table;
u32 paddr = (u32 )NULL;
// Initialize as Access Prohibition
table = &t1Base[0];
for ( paddr = (u32 )NULL; table < (void *)HW_BROM_MMU_T1_END; )
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_APX_NA,
HW_MMU6_T1_RGT_STRONG_ORDER,
HW_MMU6_T1_GLOBAL,
FALSE,
HW_MMU6_T1_XN,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
#if 0
table = &t2Base[0];
for ( paddr = (u32 )NULL; table < (void *)HW_MAIN_MEM_MMU_T2_END; )
{
*table++ = HW_MMU6_T2_SP_PACK(
paddr,
HW_MMU6_T2_APX_NA,
HW_MMU6_T2_LP_RGT_STRONG_ORDER,
HW_MMU6_T2_GLOBAL,
FALSE,
HW_MMU6_T2_SP_XN);
}
// EDRAM Region (4MB uncache)
table = &t1Base[HW_EDRAM/HW_MMU6_T1_SEC_SIZE];
for ( paddr = HW_EDRAM; paddr < HW_EDRAM_END; )
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_NC,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
// EDRAM Region (4MB cache)
table = &t1Base[HW_EDRAM_CACHED/HW_MMU6_T1_SEC_SIZE];
for ( paddr = HW_EDRAM; paddr < HW_EDRAM_END; )
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_WB_WA,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
// Main Memory Region (64MB uncache)
table = &t1Base[HW_MAIN_MEM/HW_MMU6_T1_SEC_SIZE];
#ifdef MIYA_MMU
for ( paddr = HW_MAIN_MEM; paddr < HW_MAIN_MEM_SEC_END; )
#else
for ( paddr = HW_MAIN_MEM; paddr < (HW_MAIN_MEM +( 64 * 1024 *1024 )); )
#endif
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_NC,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
// Main Memory Region (64MB cache)
table = &t1Base[HW_MAIN_MEM_CACHED/HW_MMU6_T1_SEC_SIZE];
#ifdef MIYA_MMU
for ( paddr = HW_MAIN_MEM; paddr < HW_MAIN_MEM_SEC_END; )
#else
for ( paddr = HW_MAIN_MEM; paddr < (HW_MAIN_MEM +( 64 * 1024 *1024 )); )
#endif
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_WB_WA,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
#ifdef MIYA_MMU
*table = HW_MMU6_T1_COURSE_PACK( paddr, 0 );
// T2 for Page
table = &t2Base[0];
for ( paddr = HW_MAIN_MEM_LP; paddr < HW_MAIN_MEM_LP_END; )
{
*table++ = HW_MMU6_T2_LP_PACK(
paddr,
HW_MMU6_T2_APX_ALL,
//miya HW_MMU6_T2_LP_RGT_L1L2C_WB_WA,
HW_MMU6_T2_LP_RGT_L1L2C_NC,
HW_MMU6_T2_GLOBAL,
FALSE,
FALSE);
paddr += HW_MMU6_T2_LP_ALIAS_SIZE;
}
for ( paddr = HW_MAIN_MEM_SP_NA; paddr < HW_MAIN_MEM_SP_NA_END; )
{
*table++ = HW_MMU6_T2_SP_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
// miya HW_MMU6_T2_SP_RGT_STRONG_ORDER,
HW_MMU6_T2_SP_RGT_L1L2C_NC,
HW_MMU6_T2_GLOBAL,
FALSE,
FALSE);
paddr += HW_MMU6_T2_SP_SIZE;
}
for ( paddr = HW_MAIN_MEM_SP; paddr < HW_MAIN_MEM_SP_END; )
{
*table++ = HW_MMU6_T2_SP_PACK(
paddr,
HW_MMU6_T2_APX_ALL,
// HW_MMU6_T2_SP_RGT_STRONG_ORDER,
HW_MMU6_T2_SP_RGT_L1L2C_NC,
HW_MMU6_T2_GLOBAL,
FALSE,
FALSE);
paddr += HW_MMU6_T2_SP_SIZE;
}
t2Base += HW_MMU6_T1_CORS_SIZE/sizeof(t2Base[0]);
#endif
// IO Registers Region (4MB)
// IOPIF (4MB) 0x40000000
table = &t1Base[HW_IOPIF/HW_MMU6_T1_SEC_SIZE];
for ( paddr = HW_IOPIF; paddr < (HW_IOPIF + 0x00100000 * 16) ; ) // HW_IOPIF_END
{
*table++ = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_NSHARED_DEV,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
paddr += HW_MMU6_T1_SEC_SIZE;
}
// APBIF (64KB) 0x44100000
table = &t1Base[HW_APBIF/HW_MMU6_T1_SEC_SIZE];
paddr = HW_APBIF;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_NSHARED_DEV,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
// GPUIF (64MB) 0x48000000
table = &t1Base[HW_GPUIF/HW_MMU6_T1_SEC_SIZE];
paddr = HW_GPUIF;
*table = HW_MMU6_T1_SUSEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_NSHARED_DEV,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE);
// CONFIF (64KB) 0xfe000000 mmio cfg.
table = &t1Base[HW_CONFIF/HW_MMU6_T1_SEC_SIZE];
paddr = HW_CONFIF;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_NSHARED_DEV,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
// MPCore Registers Region (8KB) 0xff000000
table = &t1Base[HW_MPCORE_REG/HW_MMU6_T1_SEC_SIZE];
paddr = HW_MPCORE_REG;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_NSHARED_DEV,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
// TCRAM Region (4KB)
table = &t1Base[HW_TCRAM/HW_MMU6_T1_SEC_SIZE];
paddr = HW_TCRAM;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_NC,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
// BIOS Region (32KB) 0xffff0000
table = &t1Base[HW_BIOS/HW_MMU6_T1_SEC_SIZE];
paddr = HW_BIOS;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_L1L2C_WB_WA,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
// MSelect Region (4KB) = 0xfdff0000
table = &t1Base[HW_MSEL_VIRTUAL/HW_MMU6_T1_SEC_SIZE];
paddr = HW_BIOS;
*table = HW_MMU6_T1_SEC_PACK(
paddr,
HW_MMU6_T1_APX_ALL,
HW_MMU6_T1_RGT_STRONG_ORDER,
HW_MMU6_T1_GLOBAL,
FALSE,
FALSE,
0);
#endif
}
#include <./crt0_misc.c>