/*---------------------------------------------------------------------------* Project: CtrBrom - OS File: os_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 #include //====================================================================== // MMU //====================================================================== /*---------------------------------------------------------------------------* Name: osEnableMMU Description: enable mmu Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osEnableMMU( void ) { mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #HW_C1_MMU_ENABLE mcr p15, 0, r0, c1, c0, 0 bx lr } /*---------------------------------------------------------------------------* Name: osDisableMMU Description: disable mmu Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osDisableMMU( void ) { mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #HW_C1_MMU_ENABLE mcr p15, 0, r0, c1, c0, 0 bx lr } //=========================================================================== // VA TO PA //=========================================================================== /*---------------------------------------------------------------------------* Name: osGetPhysicalAddr Description: Get physical address Arguments: Virtual address Returns: Physical address *---------------------------------------------------------------------------*/ asm void* osGetPhysicalAddr( void* vaddr ) { PRESERVE8 ldr r3, =HW_C7_VA_SRC_MASK and r2, r0, r3 bic r1, r0, r3 mcr p15, 0, r2, c7, c8, 1 mrc p15, 0, r0, c7, c4, 0 tst r0, #HW_C7_PA_ABORT LSYM(1) bne BSYM(1) // Error ldr r3, =HW_C7_PA_DEST_MASK and r0, r0, r3 orr r0, r0, r1 bx lr } /*---------------------------------------------------------------------------* Name: osGetMemRegionType Description: Get memory region type Arguments: Virtual address Returns: Region type *---------------------------------------------------------------------------*/ asm u8 osGetMemRegionType( void* vaddr ) { ldr r3, =HW_C7_VA_SRC_MASK and r2, r0, r3 mcr p15, 0, r2, c7, c8, 1 mrc p15, 0, r0, c7, c4, 0 tst r0, #HW_C7_PA_ABORT LSYM(1) bne BSYM(1) // Error and r0, r0, #HW_C7_PA_RGT_MASK mov r0, r0, lsr #HW_C7_PA_RGT_TYPE_SFT bx lr } /*---------------------------------------------------------------------------* Name: osGetMemRegionCacheAttr Description: Get memory region cache attribute Arguments: Virtual address Returns: Region cache attribute *---------------------------------------------------------------------------*/ asm u8 osGetMemRegionCacheAttr( void* vaddr ) { ldr r3, =HW_C7_VA_SRC_MASK and r2, r0, r3 mcr p15, 0, r2, c7, c8, 1 mrc p15, 0, r0, c7, c4, 0 tst r0, #HW_C7_PA_ABORT LSYM(1) bne BSYM(1) // Error and r0, r0, #HW_C7_PA_L1C_CA_MASK mov r0, r0, lsr #HW_C7_PA_L1C_CA_SFT bx lr } /*---------------------------------------------------------------------------* Name: osIsMemRegionShareable Description: Whether memory region is shareable or not Arguments: Virtual address Returns: Whether region is shareable or not *---------------------------------------------------------------------------*/ asm BOOL osIsMemRegionShareable( void* vaddr ) { ldr r3, =HW_C7_VA_SRC_MASK and r2, r0, r3 mcr p15, 0, r2, c7, c8, 1 mrc p15, 0, r0, c7, c4, 0 tst r0, #HW_C7_PA_ABORT LSYM(1) bne BSYM(1) // Error and r0, r0, #HW_C7_PA_SHAREABLE mov r0, r0, lsr #HW_C7_PA_SHAREABLE_SFT bx lr } /*---------------------------------------------------------------------------* Name: osIsMemRegionAbort Description: Whether memory region is abort or not Arguments: Virtual address Returns: Whether region is shareable or not *---------------------------------------------------------------------------*/ asm BOOL osIsMemRegionAbort( void* vaddr ) { ldr r3, =HW_C7_VA_SRC_MASK and r2, r0, r3 mcr p15, 0, r2, c7, c8, 1 mrc p15, 0, r0, c7, c4, 0 and r0, r0, #HW_C7_PA_ABORT bx lr } //=========================================================================== // INVALIDATE ALL TLB //=========================================================================== /*---------------------------------------------------------------------------* Name: osInvalidateTLBAll Description: Invalidate all main/instruction/data TLBs Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateTLBAll( void ) { mov r0, #0 mcr p15, 0, r0, c8, c7, 0 bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateITLBAll Description: Invalidate all instruction TLB Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateITLBAll( void ) { mov r0, #0 mcr p15, 0, r0, c8, c5, 0 bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateDTLBAll Description: Invalidate all data TLB Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateDTLBAll( void ) { mov r0, #0 mcr p15, 0, r0, c8, c6, 0 bx lr } //=========================================================================== // INVALIDATE RANGE OF TLB //=========================================================================== /*---------------------------------------------------------------------------* Name: osInvalidateTLBRange Description: Invalidate main/instruction/data TLBs in specified range Arguments: startAddr start address nBytes size (in byte) Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateTLBRange( void* startAddr, u32 nBytes ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 LSYM(1) mcr p15, 0, r0, c8, c7, 3 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateITLBRange Description: Invalidate instruction TLB in specified range Arguments: startAddr start address nBytes size (in byte) Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateITLBRange( void* startAddr, u32 nBytes ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 LSYM(1) mcr p15, 0, r0, c8, c5, 3 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateDTLBRange Description: Invalidate TLBs in specified range Arguments: startAddr start address nBytes size (in byte) Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateDTLBRange( void* startAddr, u32 nBytes ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 LSYM(1) mcr p15, 0, r0, c8, c6, 3 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } //=========================================================================== // INVALIDATE ALL TLB With ASID //=========================================================================== /*---------------------------------------------------------------------------* Name: osInvalidateTLBAllWithASID Description: Invalidate all main/instruction/data TLBs with ASID Arguments: Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateTLBAllWithASID( u32 asID ) { and r0, r0, #HW_C8_TLB_ASID_MASK mcr p15, 0, r0, c8, c7, 2 bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateITLBAllWithASID Description: Invalidate all instruction TLB with ASID Arguments: Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateITLBAllWithASID( u32 asID ) { and r0, r0, #HW_C8_TLB_ASID_MASK mcr p15, 0, r0, c8, c5, 2 bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateDTLBAllWithASID Description: Invalidate all data TLB with ASID Arguments: Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateDTLBAllWithASID( u32 asID ) { and r0, r0, #HW_C8_TLB_ASID_MASK mcr p15, 0, r0, c8, c6, 2 bx lr } //=========================================================================== // INVALIDATE RANGE OF TLB WITH ASID //=========================================================================== /*---------------------------------------------------------------------------* Name: osInvalidateTLBRangeWithASID Description: Invalidate TLBs in specified rang with ASIDe Arguments: startAddr start address nBytes size (in byte) asID Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateTLBRangeWithASID( void* startAddr, u32 nBytes, u32 asID ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 and r2, r2, #HW_C8_TLB_ASID_MASK orr r0, r0, r2 LSYM(1) mcr p15, 0, r0, c8, c5, 1 mcr p15, 0, r0, c8, c6, 1 mcr p15, 0, r0, c8, c7, 1 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateITLBRangeWithASID Description: Invalidate instruction TLB in specified range with ASID Arguments: startAddr start address nBytes size (in byte) asID Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateITLBRangeWithASID( void* startAddr, u32 nBytes, u32 asID ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 and r2, r2, #HW_C8_TLB_ASID_MASK orr r0, r0, r2 LSYM(1) mcr p15, 0, r0, c8, c5, 1 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } /*---------------------------------------------------------------------------* Name: osInvalidateDTLBRangeWithASID Description: Invalidate TLBs in specified range with ASID Arguments: startAddr start address nBytes size (in byte) asID Application Space ID Returns: None *---------------------------------------------------------------------------*/ asm void osInvalidateDTLBRangeWithASID( void* startAddr, u32 nBytes, u32 asID ) { add r1, r1, r0 ldr r3, =HW_MMU6_T2_SP_BASE_MASK and r0, r0, r3 and r2, r2, #HW_C8_TLB_ASID_MASK orr r0, r0, r2 LSYM(1) mcr p15, 0, r0, c8, c6, 1 add r0, r0, #HW_MMU6_T2_SP_SIZE cmp r0, r1 blt BSYM(1) bx lr } //=========================================================================== // LOCKDOWN TLB //=========================================================================== /*---------------------------------------------------------------------------* Name: osStartTLBLockDown Description: Start TLB Lockdown Arguments: TLB ID (0-7) Returns: None *---------------------------------------------------------------------------*/ asm void osStartTLBLockDown( u32 tlbID ) { mov r0, r0, lsl #HW_C10_TLBL_VICTIM_SFT and r0, r0, #HW_C10_TLBL_VICTIM_MASK and r0, r0, #HW_C10_TLBL_PRESERVE mcr p15, 0, r0, c10, c0, 0 bx lr } /*---------------------------------------------------------------------------* Name: osEndTLBLockDown Description: End TLB Lockdown Arguments: None Returns: None *---------------------------------------------------------------------------*/ asm void osEndTLBLockDown( void ) { mov r0, #0 mcr p15, 0, r0, c10, c0, 0 bx lr }