A27系列优化I2C/RTC处理,新增版本A270Y
This commit is contained in:
728
A27-AMTLDR/Src/cp15_asm_iar.s
Normal file
728
A27-AMTLDR/Src/cp15_asm_iar.s
Normal file
@ -0,0 +1,728 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2012, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES// LOSS OF USE, DATA,
|
||||
* OR PROFITS// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/** \file */
|
||||
|
||||
|
||||
/**
|
||||
* \addtogroup cp15_cache Cache Operations
|
||||
*
|
||||
* \section Usage
|
||||
*
|
||||
* They are performed as MCR instructions and only operate on a level 1 cache associated with
|
||||
* ATM v7 processor.
|
||||
* The supported operations are:
|
||||
* <ul>
|
||||
* <li> Any of these operations can be applied to
|
||||
* -# any data cache
|
||||
* -# any unified cache.
|
||||
* <li> Invalidate by MVA
|
||||
* Performs an invalidate of a data or unified cache line based on the address it contains.
|
||||
* <li> Invalidate by set/way
|
||||
* Performs an invalidate of a data or unified cache line based on its location in the cache hierarchy.
|
||||
* <li> Clean by MVA
|
||||
* Performs a clean of a data or unified cache line based on the address it contains.
|
||||
* <li> Clean by set/way
|
||||
* Performs a clean of a data or unified cache line based on its location in the cache hierarchy.
|
||||
* <li> Clean and Invalidate by MVA
|
||||
* Performs a clean and invalidate of a data or unified cache line based on the address it contains.
|
||||
* <li> Clean and Invalidate by set/way
|
||||
* Performs a clean and invalidate of a data or unified cache line based on its location in the cache hierarchy.
|
||||
* </ul>
|
||||
*
|
||||
* Related files:\n
|
||||
* \ref cp15.h\n
|
||||
* \ref cp15_arm_iar.s \n
|
||||
*/
|
||||
|
||||
|
||||
MODULE ?cp15
|
||||
|
||||
//// Forward declaration of sections.
|
||||
SECTION IRQ_STACK:DATA:NOROOT(2)
|
||||
SECTION CSTACK:DATA:NOROOT(3)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define __ASSEMBLY__
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions to access CP15 coprocessor register
|
||||
*----------------------------------------------------------------------------*/
|
||||
PUBLIC CP15_ReadID
|
||||
PUBLIC CP15_ExclusiveCache
|
||||
PUBLIC CP15_NonExclusiveCache
|
||||
PUBLIC CP15_ISB
|
||||
PUBLIC CP15_DSB
|
||||
PUBLIC CP15_DMB
|
||||
PUBLIC CP15_SelectICache
|
||||
PUBLIC CP15_SelectDCache
|
||||
PUBLIC CP15_ReadControl
|
||||
PUBLIC CP15_WriteControl
|
||||
PUBLIC CP15_WriteDomainAccessControl
|
||||
PUBLIC CP15_WriteTTB
|
||||
PUBLIC CP15_InvalidateIcacheInnerSharable
|
||||
PUBLIC CP15_InvalidateBTBinnerSharable
|
||||
PUBLIC CP15_InvalidateIcache
|
||||
PUBLIC CP15_InvalidateIcacheByMva
|
||||
PUBLIC CP15_InvalidateBTB
|
||||
PUBLIC CP15_InvalidateBTBbyMva
|
||||
|
||||
PUBLIC CP15_InvalidateDcacheBySetWay
|
||||
PUBLIC CP15_CleanDCacheBySetWay
|
||||
PUBLIC CP15_CleanInvalidateDCacheBySetWay
|
||||
|
||||
PUBLIC CP15_InvalidateDcacheByMva
|
||||
PUBLIC CP15_CleanDCacheByMva
|
||||
PUBLIC CP15_CleanDCacheUMva
|
||||
PUBLIC CP15_CleanInvalidateDcacheByMva
|
||||
PUBLIC CP15_InvalidateTranslationTable
|
||||
|
||||
PUBLIC CP15_coherent_dcache_for_dma
|
||||
PUBLIC CP15_invalidate_dcache_for_dma
|
||||
PUBLIC CP15_clean_dcache_for_dma
|
||||
PUBLIC CP15_flush_dcache_for_dma
|
||||
PUBLIC CP15_flush_kern_dcache_for_dma
|
||||
|
||||
/**
|
||||
* \brief Register c0 accesses the ID Register, Cache Type Register, and TCM Status Registers.
|
||||
* Reading from this register returns the device ID, the cache type, or the TCM status
|
||||
* depending on the value of Opcode_2 used.
|
||||
*/
|
||||
SECTION .CP15_ReadID:DATA:NOROOT(2)
|
||||
PUBLIC CP15_ReadID
|
||||
CP15_ReadID:
|
||||
mov r0, #0
|
||||
mrc p15, 0, r0, c0, c0, 0
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Register c7 accesses the ACTLR Register, to indicate cpu that L2 is in exclusive mode
|
||||
*/
|
||||
SECTION .CP15_ISB:DATA:NOROOT(2)
|
||||
PUBLIC CP15_ISB
|
||||
CP15_ISB:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 4
|
||||
nop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Register c7 accesses the ACTLR Register, to indicate cpu that L2 is in exclusive mode
|
||||
*/
|
||||
SECTION .CP15_DSB:DATA:NOROOT(2)
|
||||
PUBLIC CP15_DSB
|
||||
CP15_DSB:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 4
|
||||
nop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Register c7 accesses the ACTLR Register, to indicate cpu that L2 is in exclusive mode
|
||||
*/
|
||||
SECTION .CP15_DMB:DATA:NOROOT(2)
|
||||
PUBLIC CP15_DMB
|
||||
CP15_DMB:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c10, 5
|
||||
nop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Register c1 accesses the ACTLR Register, to indicate cpu that L2 is in exclusive mode
|
||||
*/
|
||||
SECTION .CP15_ExclusiveCache:DATA:NOROOT(2)
|
||||
PUBLIC CP15_ExclusiveCache
|
||||
CP15_ExclusiveCache:
|
||||
mov r0, #0
|
||||
mrc p15, 0, r0, c1, c0, 1 ; Read ACTLR
|
||||
orr r0, r0, #0x00000080
|
||||
mcr p15, 0, r0, c1, c0, 1 ; Write ACTLR
|
||||
nop
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Register c1 accesses the ACTLR Register, to indicate cpu that L2 is in exclusive mode
|
||||
*/
|
||||
SECTION .CP15_NonExclusiveCache:DATA:NOROOT(2)
|
||||
PUBLIC CP15_NonExclusiveCache
|
||||
CP15_NonExclusiveCache:
|
||||
mov r0, #0
|
||||
mrc p15, 0, r0, c1, c0, 1 ; Read ACTLR
|
||||
bic r0, r0, #0x00000080
|
||||
mcr p15, 0, r0, c1, c0, 1 ; Write ACTLR
|
||||
nop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Register c1 accesses the CSSELR Register, to select ICache
|
||||
*/
|
||||
SECTION .CP15_SelectICache:DATA:NOROOT(2)
|
||||
PUBLIC CP15_SelectICache
|
||||
CP15_SelectICache:
|
||||
mrc p15, 2, r0, c0, c0, 0 ; Read CSSELR
|
||||
orr r0, r0, #0x1 ; Change 0th bit to ICache
|
||||
mcr p15, 2, r0, c0, c0, 0 ; Write CSSELR
|
||||
nop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Register c1 accesses the CSSELR Register, to select DCache
|
||||
*/
|
||||
SECTION .CP15_SelectDCache:DATA:NOROOT(2)
|
||||
PUBLIC CP15_SelectDCache
|
||||
CP15_SelectDCache:
|
||||
mrc p15, 2, r0, c0, c0, 0 ; Read CSSELR
|
||||
and r0, r0, #0xFFFFFFFE ; Change 0th bit to ICache
|
||||
mcr p15, 2, r0, c0, c0, 0 ; Write CSSELR
|
||||
nop
|
||||
bx lr
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Register c1 is the Control Register for the ARM926EJ-S processor.
|
||||
* This register specifies the configuration used to enable and disable the
|
||||
* caches and MMU. It is recommended that you access this register using a
|
||||
* read-modify-write sequence
|
||||
*/
|
||||
SECTION .CP15_ReadControl:CODE:NOROOT(2)
|
||||
PUBLIC CP15_ReadControl
|
||||
CP15_ReadControl:
|
||||
mov r0, #0
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
bx lr
|
||||
|
||||
SECTION .CP15_WriteControl:CODE:NOROOT(2)
|
||||
PUBLIC CP15_WriteControl
|
||||
CP15_WriteControl:
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
SECTION .CP15_WriteDomainAccessControl:CODE:NOROOT(2)
|
||||
PUBLIC CP15_WriteDomainAccessControl
|
||||
CP15_WriteDomainAccessControl:
|
||||
mcr p15, 0, r0, c3, c0, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief ARMv7A architecture supports two translation tables
|
||||
* Configure translation table base (TTB) control register cp15,c2
|
||||
* to a value of all zeros, indicates we are using TTB register 0.
|
||||
* write the address of our page table base to TTB register 0.
|
||||
*/
|
||||
SECTION .CP15_WriteTTB:CODE:NOROOT(2)
|
||||
PUBLIC CP15_WriteTTB
|
||||
CP15_WriteTTB:
|
||||
mcr p15, 0, r0, c2, c0, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate I cache predictor array inner Sharable
|
||||
*/
|
||||
SECTION .CP15_InvalidateIcacheInnerSharable:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateIcacheInnerSharable
|
||||
CP15_InvalidateIcacheInnerSharable:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c1, 0
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate entire branch predictor array inner Sharable
|
||||
*/
|
||||
SECTION .CP15_InvalidateBTBinnerSharable:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateBTBinnerSharable
|
||||
CP15_InvalidateBTBinnerSharable:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c1, 6
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate all instruction caches to PoU, also flushes branch target cache
|
||||
*/
|
||||
SECTION .CP15_InvalidateIcache:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateIcache
|
||||
CP15_InvalidateIcache:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 0
|
||||
isb
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate instruction caches by VA to PoU
|
||||
*/
|
||||
SECTION .CP15_InvalidateIcacheByMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateIcacheByMva
|
||||
CP15_InvalidateIcacheByMva:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 1
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate entire branch predictor array
|
||||
*/
|
||||
SECTION .CP15_InvalidateBTB:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateBTB
|
||||
CP15_InvalidateBTB:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c5, 6
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Invalidate branch predictor array entry by MVA
|
||||
*/
|
||||
SECTION .CP15_InvalidateBTBbyMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateBTBbyMva
|
||||
CP15_InvalidateBTBbyMva:
|
||||
mcr p15, 0, r0, c7, c5, 7
|
||||
bx lr
|
||||
|
||||
/***********************************************************
|
||||
*
|
||||
* ===Data Cache related maintenance functions===
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
|
||||
// ===Data Cache maintenance by SetWay ===
|
||||
|
||||
/**
|
||||
* \brief Invalidate entire data cache by set/way
|
||||
*/
|
||||
SECTION .CP15_InvalidateDcacheBySetWay:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateDcacheBySetWay
|
||||
CP15_InvalidateDcacheBySetWay:
|
||||
MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR
|
||||
ANDS r3, r0, #0x07000000 ; Extract coherency level
|
||||
MOV r3, r3, LSR #23 ; Total cache levels << 1
|
||||
BEQ inv_finish ; If 0, no need to clean
|
||||
|
||||
MOV r10, #0 ; R10 holds current cache level << 1
|
||||
inv_cache_level_loop
|
||||
ADD r2, r10, r10, LSR #1 ; R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 ; Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 ; Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
BLT inv_skip ; No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, r10, c0, c0, 0 ; Write the Cache Size selection register
|
||||
ISB ; ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, r1, c0, c0, 0 ; Reads current Cache Size ID register
|
||||
AND r2, r1, #7 ; Extract the line length field
|
||||
ADD r2, r2, #4 ; Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR r4, =0x3FF
|
||||
ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned)
|
||||
CLZ r5, r4 ; R5 is the bit position of the way size increment
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned)
|
||||
|
||||
inv_set_loop
|
||||
MOV r9, r4 ; R9 working copy of the max way size (right aligned)
|
||||
|
||||
inv_way_loop
|
||||
ORR r11, r10, r9, LSL r5 ; Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 ; Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c6, 2 ; Invalidate by Set/Way
|
||||
SUBS r9, r9, #1 ; Decrement the Way number
|
||||
BGE inv_way_loop
|
||||
SUBS r7, r7, #1 ; Decrement the Set number
|
||||
BGE inv_set_loop
|
||||
inv_skip
|
||||
ADD r10, r10, #2 ; increment the cache number
|
||||
CMP r3, r10
|
||||
BGT inv_cache_level_loop
|
||||
inv_finish
|
||||
NOP
|
||||
BX lr
|
||||
|
||||
/**
|
||||
* \brief Clean entire data cache by set/way
|
||||
*/
|
||||
SECTION .CP15_CleanDCacheBySetWay:CODE:NOROOT(2)
|
||||
PUBLIC CP15_CleanDCacheBySetWay
|
||||
CP15_CleanDCacheBySetWay:
|
||||
MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR
|
||||
ANDS r3, r0, #0x07000000 ; Extract coherency level
|
||||
MOV r3, r3, LSR #23 ; Total cache levels << 1
|
||||
BEQ clean_finish ; If 0, no need to clean
|
||||
|
||||
MOV r10, #0 ; R10 holds current cache level << 1
|
||||
clean_cache_level_loop
|
||||
ADD r2, r10, r10, LSR #1 ; R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 ; Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 ; Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
BLT clean_skip ; No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, r10, c0, c0, 0 ; Write the Cache Size selection register
|
||||
ISB ; ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, r1, c0, c0, 0 ; Reads current Cache Size ID register
|
||||
AND r2, r1, #7 ; Extract the line length field
|
||||
ADD r2, r2, #4 ; Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR r4, =0x3FF
|
||||
ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned)
|
||||
CLZ r5, r4 ; R5 is the bit position of the way size increment
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned)
|
||||
|
||||
clean_set_loop
|
||||
MOV r9, r4 ; R9 working copy of the max way size (right aligned)
|
||||
|
||||
clean_way_loop
|
||||
ORR r11, r10, r9, LSL r5 ; Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 ; Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c10, 2 ; Clean by Set/Way
|
||||
SUBS r9, r9, #1 ; Decrement the Way number
|
||||
BGE clean_way_loop
|
||||
SUBS r7, r7, #1 ; Decrement the Set number
|
||||
BGE clean_set_loop
|
||||
clean_skip
|
||||
ADD r10, r10, #2 ; increment the cache number
|
||||
CMP r3, r10
|
||||
BGT clean_cache_level_loop
|
||||
clean_finish
|
||||
NOP
|
||||
BX lr
|
||||
|
||||
/**
|
||||
* \brief Clean and Invalidate entire data cache by set/way
|
||||
*/
|
||||
SECTION .CP15_CleanInvalidateDCacheBySetWay:CODE:NOROOT(2)
|
||||
PUBLIC CP15_CleanInvalidateDCacheBySetWay
|
||||
CP15_CleanInvalidateDCacheBySetWay:
|
||||
MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR
|
||||
ANDS r3, r0, #0x07000000 ; Extract coherency level
|
||||
MOV r3, r3, LSR #23 ; Total cache levels << 1
|
||||
BEQ clinv_finish ; If 0, no need to clean
|
||||
|
||||
MOV r10, #0 ; R10 holds current cache level << 1
|
||||
clinv_cache_level_loop
|
||||
ADD r2, r10, r10, LSR #1 ; R2 holds cache "Set" position
|
||||
MOV r1, r0, LSR r2 ; Bottom 3 bits are the Cache-type for this level
|
||||
AND r1, r1, #7 ; Isolate those lower 3 bits
|
||||
CMP r1, #2
|
||||
BLT clean_skip ; No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, r10, c0, c0, 0 ; Write the Cache Size selection register
|
||||
ISB ; ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, r1, c0, c0, 0 ; Reads current Cache Size ID register
|
||||
AND r2, r1, #7 ; Extract the line length field
|
||||
ADD r2, r2, #4 ; Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR r4, =0x3FF
|
||||
ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned)
|
||||
CLZ r5, r4 ; R5 is the bit position of the way size increment
|
||||
LDR r7, =0x7FFF
|
||||
ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned)
|
||||
|
||||
clinv_set_loop
|
||||
MOV r9, r4 ; R9 working copy of the max way size (right aligned)
|
||||
|
||||
clinv_way_loop
|
||||
ORR r11, r10, r9, LSL r5 ; Factor in the Way number and cache number into R11
|
||||
ORR r11, r11, r7, LSL r2 ; Factor in the Set number
|
||||
MCR p15, 0, r11, c7, c14, 2 ; Clean and Invalidate by Set/Way
|
||||
SUBS r9, r9, #1 ; Decrement the Way number
|
||||
BGE clean_way_loop
|
||||
SUBS r7, r7, #1 ; Decrement the Set number
|
||||
BGE clean_set_loop
|
||||
clinv_skip
|
||||
ADD r10, r10, #2 ; increment the cache number
|
||||
CMP r3, r10
|
||||
BGT clean_cache_level_loop
|
||||
clinv_finish
|
||||
NOP
|
||||
BX lr
|
||||
|
||||
|
||||
|
||||
// ===Data Cache maintenance by VA ===
|
||||
|
||||
|
||||
/**
|
||||
* \brief Invalidate data cache by VA to Poc
|
||||
*/
|
||||
SECTION .CP15_InvalidateDcacheByMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateDcacheByMva
|
||||
CP15_InvalidateDcacheByMva:
|
||||
mov r2, #0x20 ;Eight words per line, Cortex-A5 L1 Line Size 32 Bytes
|
||||
mov r3, r0
|
||||
inv_loop
|
||||
mcr p15, 0, r0, c7, c6, 1
|
||||
add r3, r3, r2
|
||||
cmp r3, r1
|
||||
bls inv_loop
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Clean data cache by MVA
|
||||
*/
|
||||
SECTION .CP15_CleanDCacheByMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_CleanDCacheByMva
|
||||
CP15_CleanDCacheByMva:
|
||||
mov r2, #0x20 ;Eight words per line, Cortex-A5 L1 Line Size 32 Bytes
|
||||
mov r3, r0
|
||||
clean_loop
|
||||
mcr p15, 0, r0, c7, c10, 1
|
||||
add r3, r3, r2
|
||||
cmp r3, r1
|
||||
bls clean_loop
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Clean unified cache by MVA
|
||||
*/
|
||||
SECTION .CP15_CleanDCacheUMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_CleanDCacheUMva
|
||||
CP15_CleanDCacheUMva:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c11, 1
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief Clean and invalidate data cache by VA to PoC
|
||||
*/
|
||||
SECTION .CP15_CleanInvalidateDcacheByMva:CODE:NOROOT(2)
|
||||
PUBLIC CP15_CleanInvalidateDcacheByMva
|
||||
CP15_CleanInvalidateDcacheByMva:
|
||||
mov r2, #0x20 ;Eight words per line, Cortex-A5 L1 Line Size 32 Bytes
|
||||
mov r3, r0
|
||||
clinv_loop
|
||||
mcr p15, 0, r0, c7, c14, 1
|
||||
add r3, r3, r2
|
||||
cmp r3, r1
|
||||
bls clinv_loop
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Invalidate translation table
|
||||
*/
|
||||
SECTION .CP15_InvalidateTranslationTable:CODE:NOROOT(2)
|
||||
PUBLIC CP15_InvalidateTranslationTable
|
||||
CP15_InvalidateTranslationTable:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c8, c3, 0
|
||||
dsb
|
||||
isb
|
||||
mcr p15, 0, r0, c8, c7, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
/**
|
||||
* \brief flush translation table
|
||||
*/
|
||||
SECTION .CP15_FlushTranslationTable:CODE:NOROOT(2)
|
||||
PUBLIC CP15_FlushTranslationTable
|
||||
CP15_FlushTranslationTable:
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c8, c3, 0
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Ensure that the I and D caches are coherent within specified
|
||||
* region. This is typically used when code has been written to
|
||||
* a memory region, and will be executed.
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
SECTION .CP15_coherent_dcache_for_dma:CODE:NOROOT(2)
|
||||
PUBLIC CP15_coherent_dcache_for_dma
|
||||
CP15_coherent_dcache_for_dma:
|
||||
// dcache_line_size r2, r3
|
||||
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
lsr r3, r3, #16
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
|
||||
sub r3, r2, #1
|
||||
bic r12, r0, r3
|
||||
loop1:
|
||||
mcr p15, 0, r12, c7, c11, 1 // clean D line to the point of unification
|
||||
add r12, r12, r2
|
||||
cmp r12, r1
|
||||
blo loop1
|
||||
dsb
|
||||
|
||||
// .macro icache_line_size, reg, tmp
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
|
||||
sub r3, r2, #1
|
||||
bic r12, r0, r3
|
||||
loop2:
|
||||
mcr p15, 0, r12, c7, c5, 1 // invalidate I line
|
||||
add r12, r12, r2
|
||||
cmp r12, r1
|
||||
blo loop2
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c1, 6 //invalidate BTB Inner Shareable
|
||||
mcr p15, 0, r0, c7, c5, 6 // invalidate BTB
|
||||
dsb
|
||||
isb
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Invalidate the data cache within the specified region; we will
|
||||
* be performing a DMA operation in this region and we want to
|
||||
* purge old data in the cache.
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
SECTION .CP15_invalidate_dcache_for_dma:CODE:NOROOT(2)
|
||||
PUBLIC CP15_invalidate_dcache_for_dma
|
||||
CP15_invalidate_dcache_for_dma:
|
||||
|
||||
// dcache_line_size r2, r3
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
lsr r3, r3, #16
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
|
||||
sub r3, r2, #1
|
||||
tst r0, r3
|
||||
bic r0, r0, r3
|
||||
|
||||
mcrne p15, 0, r0, c7, c14, 1 // clean & invalidate D / U line
|
||||
|
||||
tst r1, r3
|
||||
bic r1, r1, r3
|
||||
mcrne p15, 0, r1, c7, c14, 1 // clean & invalidate D / U line
|
||||
loop3:
|
||||
mcr p15, 0, r0, c7, c6, 1 // invalidate D / U line
|
||||
add r0, r0, r2
|
||||
cmp r0, r1
|
||||
blo loop3
|
||||
dsb
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Clean the data cache within the specified region
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
SECTION .CP15_clean_dcache_for_dma:CODE:NOROOT(2)
|
||||
PUBLIC CP15_clean_dcache_for_dma
|
||||
CP15_clean_dcache_for_dma:
|
||||
// dcache_line_size r2, r3
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
lsr r3, r3, #16
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
|
||||
sub r3, r2, #1
|
||||
bic r0, r0, r3
|
||||
loop4:
|
||||
mcr p15, 0, r0, c7, c10, 1 // clean D / U line
|
||||
add r0, r0, r2
|
||||
cmp r0, r1
|
||||
blo loop4
|
||||
dsb
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief Flush the data cache within the specified region
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
SECTION .CP15_flush_dcache_for_dma:CODE:NOROOT(2)
|
||||
PUBLIC CP15_flush_dcache_for_dma
|
||||
CP15_flush_dcache_for_dma:
|
||||
// dcache_line_size r2, r3
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
lsr r3, r3, #16
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
sub r3, r2, #1
|
||||
bic r0, r0, r3
|
||||
loop5:
|
||||
mcr p15, 0, r0, c7, c14, 1 // clean & invalidate D / U line
|
||||
add r0, r0, r2
|
||||
cmp r0, r1
|
||||
blo loop5
|
||||
dsb
|
||||
bx lr
|
||||
|
||||
|
||||
/**
|
||||
* \brief CP15_flush_kern_dcache_for_dma
|
||||
* Ensure that the data held in the page kaddr is written back to the page in question.
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
SECTION .CP15_flush_kern_dcache_for_dma:CODE:NOROOT(2)
|
||||
PUBLIC CP15_flush_kern_dcache_for_dma
|
||||
CP15_flush_kern_dcache_for_dma:
|
||||
// dcache_line_size r2, r3
|
||||
mrc p15, 0, r3, c0, c0, 1 // read ctr
|
||||
lsr r3, r3, #16
|
||||
and r3, r3, #0xf // cache line size encoding
|
||||
mov r2, #4 // bytes per word
|
||||
mov r2, r2, lsl r3 // actual cache line size
|
||||
|
||||
add r1, r0, r1
|
||||
sub r3, r2, #1
|
||||
bic r0, r0, r3
|
||||
|
||||
mcr p15, 0, r0, c7, c14, 1 // clean & invalidate D line / unified line
|
||||
add r0, r0, r2
|
||||
cmp r0, r1
|
||||
blo 1b
|
||||
dsb
|
||||
bx lr
|
||||
END
|
||||
|
Reference in New Issue
Block a user