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@214 b871894f-2f95-9b40-918c-086798483c85
449 lines
15 KiB
C
449 lines
15 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: CtrBrom - library - init
|
||
File: crt0_mmu.c
|
||
|
||
Copyright 2009 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>
|
||
|
||
void stupInitMMUTable( u32* t1Base, u32* t2Base );
|
||
|
||
/*---------------------------------------------------------------------------*
|
||
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: stupInitMMU
|
||
|
||
Description: Initialize MMU
|
||
|
||
Arguments: None
|
||
|
||
Returns: None
|
||
*---------------------------------------------------------------------------*/
|
||
asm void stupInitMMU( u32* t1Base, u32* t2Base )
|
||
{
|
||
stmfd sp!, {r4, lr} // stack requires 8byte alignment
|
||
|
||
// Invalidate ITLB DTLB
|
||
mov r3, #0
|
||
mcr p15, 0, r3, c8, c5, 0
|
||
mcr p15, 0, r3, c8, c6, 0
|
||
|
||
mov r2, #HW_C2_V5_T1_BOUNBARY_16KB
|
||
|
||
// MMU L1 Table Base
|
||
|
||
ldr r3, =HW_C2_0_T1_BASE_MASK_MIN
|
||
mov r3, r3, ASR r2
|
||
and r3 ,r3, r0
|
||
orr r3, r3, #(HW_C2_WALK_L2C_CA_NC << HW_C2_WALK_L2C_CA_SFT) \
|
||
| HW_C2_WALK_ON_SHARED_MEM
|
||
mcr p15, 0, r3, c2, c0, 0
|
||
|
||
ldr r3, =HW_C2_1_T1_BASE_MASK
|
||
and r3 ,r3, r0
|
||
orr r3, r3, #(HW_C2_WALK_L2C_CA_NC << HW_C2_WALK_L2C_CA_SFT) \
|
||
| HW_C2_WALK_ON_SHARED_MEM
|
||
mcr p15, 0, r3, c2, c0, 1
|
||
|
||
// MMU L1 Table Boundary
|
||
|
||
mcr p15, 0, r2, c2, c0, 2
|
||
|
||
// Domain Access Permission
|
||
#if 1 // miya
|
||
ldr r3, =0x00000001
|
||
#else
|
||
ldr r3, = 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, r3, c3, c0, 0
|
||
|
||
// VFP Access Permission
|
||
|
||
ldr r3, =HW_C1_VFP_AP_PACK( \
|
||
HW_C1_AP_PRIV, HW_C1_AP_PRIV )
|
||
mcr p15, 0, r3, 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( u32* t1Base, u32* t2Base )
|
||
{
|
||
u32* table;
|
||
u32 paddr = (u32 )NULL;
|
||
|
||
// Initialize as Access Prohibition
|
||
table = t1Base;
|
||
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,
|
||
HW_MMU6_T1_SHARED,
|
||
HW_MMU6_T1_XN,
|
||
0);
|
||
}
|
||
|
||
table = t2Base;
|
||
for ( paddr = (u32 )NULL; table < (void *)HW_BROM_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,
|
||
HW_MMU6_T2_SHARED,
|
||
HW_MMU6_T2_SP_XN);
|
||
}
|
||
|
||
|
||
// Main Memory Region (128MB cached)
|
||
paddr = HW_MAIN_MEM;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
while ( paddr < HW_MAIN_MEM_END )
|
||
{
|
||
|
||
*table++ = HW_MMU6_T1_SUSEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_L1C_WB_WA,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
#ifdef BROM_TARGET_BROM
|
||
HW_MMU6_T1_XN
|
||
#else // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
FALSE
|
||
#endif // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
);
|
||
paddr += HW_MMU6_T1_SEC_SIZE;
|
||
}
|
||
#ifndef SDK_MG20EMU
|
||
// MG20<32>ɂ͊g<CD8A><67><EFBFBD><EFBFBD><EFBFBD>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͖<EFBFBD><CD96><EFBFBD>
|
||
while ( paddr < HW_MAIN_MEM_EX_END )
|
||
{
|
||
|
||
*table++ = HW_MMU6_T1_SUSEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_ALL,
|
||
HW_MMU6_T1_RGT_L1C_WB_WA,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
#ifdef BROM_TARGET_BROM
|
||
HW_MMU6_T1_XN
|
||
#else // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
FALSE
|
||
#endif // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
);
|
||
paddr += HW_MMU6_T1_SEC_SIZE;
|
||
}
|
||
#else // SDK_MG20EMU
|
||
// for AXI-WRAM & DSP-WRAM Emulation
|
||
paddr = HW_MAIN_MEM_END - HW_MMU6_T1_SUSEC_SIZE;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
while ( paddr < HW_MAIN_MEM_END )
|
||
{
|
||
|
||
*table++ = HW_MMU6_T1_SEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_L1C_WB_WA,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
HW_MMU6_T1_XN,
|
||
0);
|
||
paddr += HW_MMU6_T1_SEC_SIZE;
|
||
}
|
||
#endif // SDK_MG20EMU
|
||
|
||
// IO Registers Region (16MB)
|
||
paddr = HW_IOREG;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
while ( paddr < HW_IOREG + HW_MMU6_T1_SUSEC_SIZE )
|
||
{
|
||
*table++ = HW_MMU6_T1_SUSEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_SHARED_DEV,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
HW_MMU6_T1_XN
|
||
);
|
||
paddr += HW_MMU6_T1_SEC_SIZE;
|
||
}
|
||
|
||
// MPCore Registers Region (1MB)
|
||
paddr = HW_MPCORE_REG;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
*table++ = HW_MMU6_T1_SEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_NSHARED_DEV,
|
||
HW_MMU6_T1_GLOBAL,
|
||
FALSE,
|
||
HW_MMU6_T1_XN,
|
||
0);
|
||
|
||
// VRAM Region (4MB cached)
|
||
paddr = HW_VRAM;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
while ( paddr < HW_VRAM_END )
|
||
{
|
||
*table++ = HW_MMU6_T1_SEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_L1C_WB_WA,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
HW_MMU6_T1_XN,
|
||
0);
|
||
paddr += HW_MMU6_T1_SEC_SIZE;
|
||
}
|
||
|
||
#ifdef SDK_NE1EMU
|
||
// NE1-TB DDR2 Registers Region (1MB)
|
||
paddr = HW_NE1DDR2_REG;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
*table++ = HW_MMU6_T1_SEC_PACK(
|
||
paddr,
|
||
HW_MMU6_T1_APX_S_RW_U_NA,
|
||
HW_MMU6_T1_RGT_SHARED_DEV,
|
||
HW_MMU6_T1_GLOBAL,
|
||
HW_MMU6_T1_SHARED,
|
||
HW_MMU6_T1_XN,
|
||
0);
|
||
#endif // SDK_NE1EMU
|
||
|
||
// AXI-WRAM & DSP-WRAM Region (1MB cached & uncached)
|
||
paddr = HW_DSP_WRAM;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
*table = HW_MMU6_T1_COURSE_PACK( (u32)t2Base, 0 );
|
||
// T2 for Page
|
||
table = &t2Base[paddr%HW_MMU6_T1_SEC_SIZE/HW_MMU6_T2_LP_ALIAS_SIZE];
|
||
while ( paddr < MATH_ROUNDDOWN(HW_BROM_MMU_TBL, HW_MMU6_T2_LP_SIZE) )
|
||
{
|
||
*table++ = HW_MMU6_T2_LP_PACK(
|
||
paddr,
|
||
HW_MMU6_T2_APX_S_RW_U_NA,
|
||
HW_MMU6_T2_LP_RGT_L1C_WB_WA,
|
||
HW_MMU6_T2_GLOBAL,
|
||
HW_MMU6_T2_SHARED,
|
||
HW_MMU6_T2_LP_XN);
|
||
paddr += HW_MMU6_T2_LP_ALIAS_SIZE;
|
||
}
|
||
while ( paddr < HW_BROM_MMU_TBL )
|
||
{
|
||
*table++ = HW_MMU6_T2_SP_PACK(
|
||
paddr,
|
||
HW_MMU6_T2_APX_S_RW_U_NA,
|
||
HW_MMU6_T2_SP_RGT_L1C_WB_WA,
|
||
HW_MMU6_T2_GLOBAL,
|
||
HW_MMU6_T2_SHARED,
|
||
HW_MMU6_T2_SP_XN);
|
||
paddr += HW_MMU6_T2_SP_SIZE;
|
||
}
|
||
// HW_BROM_MMU_TBL
|
||
while ( paddr < HW_BROM_MMU_TBL_END )
|
||
{
|
||
*table++ = HW_MMU6_T2_SP_PACK(
|
||
paddr,
|
||
HW_MMU6_T2_APX_S_RW_U_NA,
|
||
HW_MMU6_T2_SP_RGT_SHARED_DEV,
|
||
HW_MMU6_T2_GLOBAL,
|
||
HW_MMU6_T2_SHARED,
|
||
HW_MMU6_T2_SP_XN);
|
||
paddr += HW_MMU6_T2_SP_SIZE;
|
||
}
|
||
// HW_AXI_WRAM_SHARED
|
||
while ( paddr < HW_AXI_WRAM_SHARED_END )
|
||
{
|
||
*table++ = HW_MMU6_T2_SP_PACK(
|
||
paddr,
|
||
HW_MMU6_T2_APX_S_RW_U_NA,
|
||
HW_MMU6_T2_SP_RGT_SHARED_DEV,
|
||
HW_MMU6_T2_GLOBAL,
|
||
HW_MMU6_T2_SHARED,
|
||
FALSE); // for exception veneer
|
||
paddr += HW_MMU6_T2_SP_SIZE;
|
||
}
|
||
// Coarse page is 1KB boundary
|
||
t2Base += MATH_ROUNDUP((HW_DSP_WRAM_SIZE+HW_AXI_WRAM_SIZE)/HW_MMU6_T2_SP_SIZE, HW_MMU6_T1_CORS_SIZE)/sizeof(t2Base[0]);
|
||
|
||
// BROM Region (64KBx2 cached)
|
||
paddr = HW_BROM_IMG;
|
||
table = &t1Base[paddr/HW_MMU6_T1_SEC_SIZE];
|
||
*table = HW_MMU6_T1_COURSE_PACK( (u32)t2Base, 0 );
|
||
// T2 for Page
|
||
table = &t2Base[paddr%HW_MMU6_T1_SEC_SIZE/HW_MMU6_T2_LP_ALIAS_SIZE];
|
||
while ( paddr != HW_BROM_END )
|
||
{
|
||
*table++ = HW_MMU6_T2_LP_PACK(
|
||
paddr,
|
||
#ifdef BROM_TARGET_BROM
|
||
HW_MMU6_T2_APX_S_RW_U_NA,
|
||
#else // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
HW_MMU6_T2_APX_S_RO_U_NA,
|
||
#endif // BROM_TARGET_FIRM || BROM_TARGET_APP
|
||
HW_MMU6_T2_LP_RGT_L1C_WB_WA,
|
||
HW_MMU6_T2_GLOBAL,
|
||
HW_MMU6_T2_SHARED,
|
||
FALSE);
|
||
paddr += HW_MMU6_T2_LP_ALIAS_SIZE;
|
||
}
|
||
// Coarse page is 1KB boundary
|
||
t2Base += MATH_ROUNDUP(HW_BROM_SIZE*2/HW_MMU6_T2_LP_ALIAS_SIZE, HW_MMU6_T1_CORS_SIZE)/sizeof(t2Base[0]);
|
||
}
|
||
|