ctr_firmware/trunk/bootrom/build/libraries/init/ARM11/crt0_mmu.c
nakasima 88a1531191 MMUテーブルアドレスを引数で渡す仕様に。
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@214 b871894f-2f95-9b40-918c-086798483c85
2009-01-27 03:01:52 +00:00

449 lines
15 KiB
C
Raw Blame History

/*---------------------------------------------------------------------------*
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]);
}