blob: c582582fcfb892e95576a823cb8a243a60ea7a70 [file] [log] [blame]
/*
* Copyright (C) 2016 MediaTek Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
.text
#include <linux/linkage.h>
.equ C1_IBIT , 0x00001000
.equ C1_CBIT , 0x00000004
.equ PSR_F_BIT, 0x00000040
.equ PSR_I_BIT, 0x00000080
ENTRY(__enable_icache)
MRC p15,0,r0,c1,c0,0
ORR r0,r0,#C1_IBIT
MCR p15,0,r0,c1,c0,0
BX lr
ENDPROC(__enable_icache)
ENTRY(__disable_icache)
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_IBIT
MCR p15,0,r0,c1,c0,0
BX lr
ENDPROC(__disable_icache)
ENTRY(__enable_dcache)
MRC p15,0,r0,c1,c0,0
ORR r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
BX lr
ENDPROC(__enable_dcache)
ENTRY(__disable_dcache)
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
isb
BX lr
ENDPROC(__disable_dcache)
ENTRY(__enable_cache)
MRC p15,0,r0,c1,c0,0
ORR r0,r0,#C1_IBIT
ORR r0,r0,#C1_CBIT
MCR p15,0,r0,c1,c0,0
BX lr
ENDPROC(__enable_cache)
ENTRY(__disable_cache)
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_IBIT
BIC r0,r0,#C1_CBIT
MCR p15,0,r0,c1,c0,0
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
BX lr
ENDPROC(__disable_cache)
ENTRY(__inner_flush_dcache_all)
push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r14}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq all_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
all_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt all_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
all_loop2:
mov r9, r4 @ create working copy of max way size
all_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#ifdef CONFIG_L1C_OPT
#replace DCCISW by DCISW+DCCSW
cmp r10, #2
mrsne r1, cpsr @disable IRQ and save flag to make clean and invalidate atomic
orrne r8, r1, #PSR_I_BIT | PSR_F_BIT
msrne cpsr_c, r8
mcrne p15, 0, r11, c7, c10, 2 @ clean by set/way
mcrne p15, 0, r11, c7, c6, 2 @ invalidate by set/way
msrne cpsr_c, r1
mcreq p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#else
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge all_loop3
subs r7, r7, #1 @ decrement the index
bge all_loop2
all_skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt all_loop1
all_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_flush_dcache_all)
ENTRY(__inner_flush_dcache_L1)
push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r14}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L1_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
L1_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L1_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L1_loop2:
mov r9, r4 @ create working copy of max way size
L1_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#ifdef CONFIG_L1C_OPT
#replace DCCISW by DCISW+DCCSW
mrs r1, cpsr @disable IRQ and save flag to make clean and invalidate atomic
orr r8, r1, #PSR_I_BIT | PSR_F_BIT
msr cpsr_c, r8
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
msr cpsr_c, r1
#else
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge L1_loop3
subs r7, r7, #1 @ decrement the index
bge L1_loop2
L1_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L1_loop1
L1_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_flush_dcache_L1)
ENTRY(__inner_flush_dcache_L2)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L2_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
L2_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L2_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L2_loop2:
mov r9, r4 @ create working copy of max way size
L2_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge L2_loop3
subs r7, r7, #1 @ decrement the index
bge L2_loop2
L2_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L2_loop1
L2_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_flush_dcache_L2)
ENTRY(__inner_clean_dcache_all)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq all_cl_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
all_cl_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt all_cl_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
all_cl_loop2:
mov r9, r4 @ create working copy of max way size
all_cl_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
subs r9, r9, #1 @ decrement the way
bge all_cl_loop3
subs r7, r7, #1 @ decrement the index
bge all_cl_loop2
all_cl_skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt all_cl_loop1
all_cl_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_clean_dcache_all)
ENTRY(__inner_clean_dcache_L1)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L1_cl_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
L1_cl_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L1_cl_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L1_cl_loop2:
mov r9, r4 @ create working copy of max way size
L1_cl_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
subs r9, r9, #1 @ decrement the way
bge L1_cl_loop3
subs r7, r7, #1 @ decrement the index
bge L1_cl_loop2
L1_cl_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L1_cl_loop1
L1_cl_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_clean_dcache_L1)
ENTRY(__inner_clean_dcache_L2)
#if 0
mov r0, sp
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
dsb
sub r0, r0, #64
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
dsb
#endif
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
#if 0
mov r0, sp
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
dsb
sub r0, r0, #64
mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
dsb
#endif
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L2_cl_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
L2_cl_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L2_cl_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L2_cl_loop2:
mov r9, r4 @ create working copy of max way size
L2_cl_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
subs r9, r9, #1 @ decrement the way
bge L2_cl_loop3
subs r7, r7, #1 @ decrement the index
bge L2_cl_loop2
L2_cl_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L2_cl_loop1
L2_cl_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_clean_dcache_L2)
ENTRY(__inner_inv_dcache_all)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq all_inv_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 0
all_inv_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt all_inv_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
all_inv_loop2:
mov r9, r4 @ create working copy of max way size
all_inv_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge all_inv_loop3
subs r7, r7, #1 @ decrement the index
bge all_inv_loop2
all_inv_skip:
add r10, r10, #2 @ increment cache number
cmp r3, r10
bgt all_inv_loop1
all_inv_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_inv_dcache_all)
ENTRY(__inner_inv_dcache_L1)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L1_inv_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
L1_inv_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L1_inv_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L1_inv_loop2:
mov r9, r4 @ create working copy of max way size
L1_inv_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge L1_inv_loop3
subs r7, r7, #1 @ decrement the index
bge L1_inv_loop2
L1_inv_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L1_inv_loop1
L1_inv_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_inv_dcache_L1)
ENTRY(__inner_inv_dcache_L2)
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
@push {r4,r5,r7,r9,r10,r11}
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq L2_inv_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
L2_inv_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt L2_inv_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
L2_inv_loop2:
mov r9, r4 @ create working copy of max way size
L2_inv_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge L2_inv_loop3
subs r7, r7, #1 @ decrement the index
bge L2_inv_loop2
L2_inv_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt L2_inv_loop1
L2_inv_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
@pop {r4,r5,r7,r9,r10,r11}
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__inner_inv_dcache_L2)
ENTRY(__disable_dcache__inner_flush_dcache_L1)
/*******************************************************************************
* push stack *
******************************************************************************/
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
/*******************************************************************************
* __disable_dcache *
******************************************************************************/
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
isb
/*******************************************************************************
* __inner_flush_dcache_L1 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DF1_L1_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
DF1_L1_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DF1_L1_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DF1_L1_loop2:
mov r9, r4 @ create working copy of max way size
DF1_L1_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB (lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#if 1
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
#endif
#if 0
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge DF1_L1_loop3
subs r7, r7, #1 @ decrement the index
bge DF1_L1_loop2
DF1_L1_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DF1_L1_loop1
DF1_L1_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* pop stack *
******************************************************************************/
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__disable_dcache__inner_flush_dcache_L1)
ENTRY(__disable_dcache__inner_flush_dcache_L1__inner_flush_dcache_L2)
/*******************************************************************************
* push stack *
******************************************************************************/
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
/*******************************************************************************
* __disable_dcache *
******************************************************************************/
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
isb
/*******************************************************************************
* __inner_flush_dcache_L1 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DF1F2_L1_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
DF1F2_L1_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DF1F2_L1_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DF1F2_L1_loop2:
mov r9, r4 @ create working copy of max way size
DF1F2_L1_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#if 1
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
#endif
#if 0
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge DF1F2_L1_loop3
subs r7, r7, #1 @ decrement the index
bge DF1F2_L1_loop2
DF1F2_L1_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DF1F2_L1_loop1
DF1F2_L1_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* clrex *
******************************************************************************/
clrex
/*******************************************************************************
* __inner_flush_dcache_L2 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DF1F2_L2_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
DF1F2_L2_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DF1F2_L2_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DF1F2_L2_loop2:
mov r9, r4 @ create working copy of max way size
DF1F2_L2_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge DF1F2_L2_loop3
subs r7, r7, #1 @ decrement the index
bge DF1F2_L2_loop2
DF1F2_L2_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DF1F2_L2_loop1
DF1F2_L2_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* pop stack *
******************************************************************************/
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__disable_dcache__inner_flush_dcache_L1__inner_flush_dcache_L2)
ENTRY(dis_D_inner_fL1L2)
ENTRY(__disable_dcache__inner_flush_dcache_L1__inner_clean_dcache_L2)
/*******************************************************************************
* push stack *
******************************************************************************/
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
/*******************************************************************************
* __disable_dcache *
******************************************************************************/
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
isb
/*******************************************************************************
* __inner_flush_dcache_L1 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DF1C2_L1_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
DF1C2_L1_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DF1C2_L1_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DF1C2_L1_loop2:
mov r9, r4 @ create working copy of max way size
DF1C2_L1_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#if 1
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
#endif
#if 0
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge DF1C2_L1_loop3
subs r7, r7, #1 @ decrement the index
bge DF1C2_L1_loop2
DF1C2_L1_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DF1C2_L1_loop1
DF1C2_L1_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* clrex *
******************************************************************************/
clrex
/*******************************************************************************
* __inner_clean_dcache_L2 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DF1C2_L2_cl_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
DF1C2_L2_cl_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DF1C2_L2_cl_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DF1C2_L2_cl_loop2:
mov r9, r4 @ create working copy of max way size
DF1C2_L2_cl_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
subs r9, r9, #1 @ decrement the way
bge DF1C2_L2_cl_loop3
subs r7, r7, #1 @ decrement the index
bge DF1C2_L2_cl_loop2
DF1C2_L2_cl_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DF1C2_L2_cl_loop1
DF1C2_L2_cl_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* pop stack *
******************************************************************************/
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(__disable_dcache__inner_flush_dcache_L1__inner_clean_dcache_L2)
ENDPROC(dis_D_inner_fL1L2)
ENTRY(d_i_dis_flush_all)
/*******************************************************************************
* push stack *
******************************************************************************/
push {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
/*******************************************************************************
* __disable_dcache *
******************************************************************************/
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
BIC r0,r0,#C1_IBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
/*
Erratum:794322,An instruction fetch can be allocated into the L2 cache after the cache is disabled Status
This erratum can be avoided by inserting both of the following after the SCTLR.C bit is cleared to 0,
and before the caches are cleaned or invalidated:
1) A TLBIMVA operation to any address.
2) A DSB instruction.
*/
MCR p15,0,r0,c8,c7,1
dsb
isb
/*******************************************************************************
* __inner_flush_dcache_L1 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DIF1F2_L1_finished @ if loc is 0, then no need to clean
mov r10, #0 @ start clean at cache level 1
DIF1F2_L1_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DIF1F2_L1_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DIF1F2_L1_loop2:
mov r9, r4 @ create working copy of max way size
DIF1F2_L1_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
#if 1
mcr p15, 0, r11, c7, c10, 2 @ clean by set/way
mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way
#endif
#if 0
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
#endif
subs r9, r9, #1 @ decrement the way
bge DIF1F2_L1_loop3
subs r7, r7, #1 @ decrement the index
bge DIF1F2_L1_loop2
DIF1F2_L1_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DIF1F2_L1_loop1
DIF1F2_L1_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* clrex *
******************************************************************************/
clrex
/*******************************************************************************
* __inner_flush_dcache_L2 *
******************************************************************************/
dmb @ ensure ordering with previous memory accesses
mrc p15, 1, r0, c0, c0, 1 @ read clidr
ands r3, r0, #0x7000000 @ extract loc from clidr
mov r3, r3, lsr #23 @ left align loc bit field
beq DIF1F2_L2_finished @ if loc is 0, then no need to clean
mov r10, #2 @ start clean at cache level 2
DIF1F2_L2_loop1:
add r2, r10, r10, lsr #1 @ work out 3x current cache level
mov r1, r0, lsr r2 @ extract cache type bits from clidr
and r1, r1, #7 @ mask of the bits for current cache only
cmp r1, #2 @ see what cache we have at this level
blt DIF1F2_L2_skip @ skip if no cache, or just i-cache
#ifdef CONFIG_ARM_ERRATA_814220
dsb
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
and r2, r1, #7 @ extract the length of the cache lines
add r2, r2, #4 @ add 4 (line length offset)
ldr r4, =0x3ff
ands r4, r4, r1, lsr #3 @ find maximum number on the way size
clz r5, r4 @ find bit position of way size increment
ldr r7, =0x7fff
ands r7, r7, r1, lsr #13 @ extract max number of the index size
DIF1F2_L2_loop2:
mov r9, r4 @ create working copy of max way size
DIF1F2_L2_loop3:
ARM ( orr r11, r10, r9, lsl r5 ) @ factor way and cache number into r11
THUMB( lsl r6, r9, r5 )
THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11
ARM ( orr r11, r11, r7, lsl r2 ) @ factor index number into r11
THUMB( lsl r6, r7, r2 )
THUMB( orr r11, r11, r6 ) @ factor index number into r11
mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
subs r9, r9, #1 @ decrement the way
bge DIF1F2_L2_loop3
subs r7, r7, #1 @ decrement the index
bge DIF1F2_L2_loop2
DIF1F2_L2_skip:
@add r10, r10, #2 @ increment cache number
@cmp r3, r10
@bgt DIF1F2_L2_loop1
DIF1F2_L2_finished:
mov r10, #0 @ swith back to cache level 0
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
dsb
isb
/*******************************************************************************
* pop stack *
******************************************************************************/
pop {r0,r1,r2,r3,r4,r5,r6,r7,r9,r10,r11,r14}
bx lr
ENDPROC(d_i_dis_flush_all)
ENTRY(dis_D_inner_flush_all)
/* disable data cache*/
ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} )
THUMB( stmfd sp!, {r4-r7, r9-r11, lr} )
MRC p15,0,r0,c1,c0,0
BIC r0,r0,#C1_CBIT
dsb
MCR p15,0,r0,c1,c0,0
dsb
isb
bl v7_flush_dcache_all
ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} )
THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} )
bx lr
ENDPROC(dis_D_inner_flush_all)
.end