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@49 b871894f-2f95-9b40-918c-086798483c85
571 lines
17 KiB
C
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>
|
|
|