1c09d2905SHans de Goede/* 2c09d2905SHans de Goede * SPDX-License-Identifier: GPL-2.0+ 3c09d2905SHans de Goede */ 4c09d2905SHans de Goede 5c09d2905SHans de Goede#include <config.h> 6c09d2905SHans de Goede#include <linux/linkage.h> 7c09d2905SHans de Goede#include <linux/sizes.h> 8c09d2905SHans de Goede#include <asm/system.h> 9c09d2905SHans de Goede 103a649407STom Rini#if CONFIG_IS_ENABLED(SYS_THUMB_BUILD) 11c09d2905SHans de Goede#define ARM(x...) 12c09d2905SHans de Goede#define THUMB(x...) x 13c09d2905SHans de Goede#else 14c09d2905SHans de Goede#define ARM(x...) x 15c09d2905SHans de Goede#define THUMB(x...) 16c09d2905SHans de Goede#endif 17c09d2905SHans de Goede 18c09d2905SHans de Goede/* 19c09d2905SHans de Goede * v7_flush_dcache_all() 20c09d2905SHans de Goede * 21c09d2905SHans de Goede * Flush the whole D-cache. 22c09d2905SHans de Goede * 23c09d2905SHans de Goede * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) 24c09d2905SHans de Goede * 25c09d2905SHans de Goede * Note: copied from arch/arm/mm/cache-v7.S of Linux 4.4 26c09d2905SHans de Goede */ 27c09d2905SHans de GoedeENTRY(__v7_flush_dcache_all) 28c09d2905SHans de Goede dmb @ ensure ordering with previous memory accesses 29c09d2905SHans de Goede mrc p15, 1, r0, c0, c0, 1 @ read clidr 30c09d2905SHans de Goede mov r3, r0, lsr #23 @ move LoC into position 31c09d2905SHans de Goede ands r3, r3, #7 << 1 @ extract LoC*2 from clidr 32c09d2905SHans de Goede beq finished @ if loc is 0, then no need to clean 33c09d2905SHans de Goedestart_flush_levels: 34c09d2905SHans de Goede mov r10, #0 @ start clean at cache level 0 35c09d2905SHans de Goedeflush_levels: 36c09d2905SHans de Goede add r2, r10, r10, lsr #1 @ work out 3x current cache level 37c09d2905SHans de Goede mov r1, r0, lsr r2 @ extract cache type bits from clidr 38c09d2905SHans de Goede and r1, r1, #7 @ mask of the bits for current cache only 39c09d2905SHans de Goede cmp r1, #2 @ see what cache we have at this level 40c09d2905SHans de Goede blt skip @ skip if no cache, or just i-cache 41c09d2905SHans de Goede mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 42c09d2905SHans de Goede isb @ isb to sych the new cssr&csidr 43c09d2905SHans de Goede mrc p15, 1, r1, c0, c0, 0 @ read the new csidr 44c09d2905SHans de Goede and r2, r1, #7 @ extract the length of the cache lines 45c09d2905SHans de Goede add r2, r2, #4 @ add 4 (line length offset) 46c09d2905SHans de Goede movw r4, #0x3ff 47c09d2905SHans de Goede ands r4, r4, r1, lsr #3 @ find maximum number on the way size 48c09d2905SHans de Goede clz r5, r4 @ find bit position of way size increment 49c09d2905SHans de Goede movw r7, #0x7fff 50c09d2905SHans de Goede ands r7, r7, r1, lsr #13 @ extract max number of the index size 51c09d2905SHans de Goedeloop1: 52c09d2905SHans de Goede mov r9, r7 @ create working copy of max index 53c09d2905SHans de Goedeloop2: 54c09d2905SHans de Goede ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11 55c09d2905SHans de Goede THUMB( lsl r6, r4, r5 ) 56c09d2905SHans de Goede THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 57c09d2905SHans de Goede ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 58c09d2905SHans de Goede THUMB( lsl r6, r9, r2 ) 59c09d2905SHans de Goede THUMB( orr r11, r11, r6 ) @ factor index number into r11 60c09d2905SHans de Goede mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way 61c09d2905SHans de Goede subs r9, r9, #1 @ decrement the index 62c09d2905SHans de Goede bge loop2 63c09d2905SHans de Goede subs r4, r4, #1 @ decrement the way 64c09d2905SHans de Goede bge loop1 65c09d2905SHans de Goedeskip: 66c09d2905SHans de Goede add r10, r10, #2 @ increment cache number 67c09d2905SHans de Goede cmp r3, r10 68*9bdfc344SJoseph Chen#ifdef CONFIG_ARM_ERRATA_814220 69*9bdfc344SJoseph Chen dsb 70*9bdfc344SJoseph Chen#endif 71c09d2905SHans de Goede bgt flush_levels 72c09d2905SHans de Goedefinished: 73c09d2905SHans de Goede mov r10, #0 @ swith back to cache level 0 74c09d2905SHans de Goede mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 75c09d2905SHans de Goede dsb st 76c09d2905SHans de Goede isb 77c09d2905SHans de Goede bx lr 78c09d2905SHans de GoedeENDPROC(__v7_flush_dcache_all) 79c09d2905SHans de Goede 80c09d2905SHans de GoedeENTRY(v7_flush_dcache_all) 81c09d2905SHans de Goede ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) 82c09d2905SHans de Goede THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) 83c09d2905SHans de Goede bl __v7_flush_dcache_all 84c09d2905SHans de Goede ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) 85c09d2905SHans de Goede THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) 86c09d2905SHans de Goede bx lr 87c09d2905SHans de GoedeENDPROC(v7_flush_dcache_all) 88df120142SHans de Goede 89df120142SHans de Goede/* 90df120142SHans de Goede * v7_invalidate_dcache_all() 91df120142SHans de Goede * 92df120142SHans de Goede * Invalidate the whole D-cache. 93df120142SHans de Goede * 94df120142SHans de Goede * Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode) 95df120142SHans de Goede * 96df120142SHans de Goede * Note: copied from __v7_flush_dcache_all above with 97df120142SHans de Goede * mcr p15, 0, r11, c7, c14, 2 98df120142SHans de Goede * Replaced with: 99df120142SHans de Goede * mcr p15, 0, r11, c7, c6, 2 100df120142SHans de Goede */ 101df120142SHans de GoedeENTRY(__v7_invalidate_dcache_all) 102df120142SHans de Goede dmb @ ensure ordering with previous memory accesses 103df120142SHans de Goede mrc p15, 1, r0, c0, c0, 1 @ read clidr 104df120142SHans de Goede mov r3, r0, lsr #23 @ move LoC into position 105df120142SHans de Goede ands r3, r3, #7 << 1 @ extract LoC*2 from clidr 106df120142SHans de Goede beq inval_finished @ if loc is 0, then no need to clean 107df120142SHans de Goede mov r10, #0 @ start clean at cache level 0 108df120142SHans de Goedeinval_levels: 109df120142SHans de Goede add r2, r10, r10, lsr #1 @ work out 3x current cache level 110df120142SHans de Goede mov r1, r0, lsr r2 @ extract cache type bits from clidr 111df120142SHans de Goede and r1, r1, #7 @ mask of the bits for current cache only 112df120142SHans de Goede cmp r1, #2 @ see what cache we have at this level 113df120142SHans de Goede blt inval_skip @ skip if no cache, or just i-cache 114df120142SHans de Goede mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 115df120142SHans de Goede isb @ isb to sych the new cssr&csidr 116df120142SHans de Goede mrc p15, 1, r1, c0, c0, 0 @ read the new csidr 117df120142SHans de Goede and r2, r1, #7 @ extract the length of the cache lines 118df120142SHans de Goede add r2, r2, #4 @ add 4 (line length offset) 119df120142SHans de Goede movw r4, #0x3ff 120df120142SHans de Goede ands r4, r4, r1, lsr #3 @ find maximum number on the way size 121df120142SHans de Goede clz r5, r4 @ find bit position of way size increment 122df120142SHans de Goede movw r7, #0x7fff 123df120142SHans de Goede ands r7, r7, r1, lsr #13 @ extract max number of the index size 124df120142SHans de Goedeinval_loop1: 125df120142SHans de Goede mov r9, r7 @ create working copy of max index 126df120142SHans de Goedeinval_loop2: 127df120142SHans de Goede ARM( orr r11, r10, r4, lsl r5 ) @ factor way and cache number into r11 128df120142SHans de Goede THUMB( lsl r6, r4, r5 ) 129df120142SHans de Goede THUMB( orr r11, r10, r6 ) @ factor way and cache number into r11 130df120142SHans de Goede ARM( orr r11, r11, r9, lsl r2 ) @ factor index number into r11 131df120142SHans de Goede THUMB( lsl r6, r9, r2 ) 132df120142SHans de Goede THUMB( orr r11, r11, r6 ) @ factor index number into r11 133df120142SHans de Goede mcr p15, 0, r11, c7, c6, 2 @ invalidate by set/way 134df120142SHans de Goede subs r9, r9, #1 @ decrement the index 135df120142SHans de Goede bge inval_loop2 136df120142SHans de Goede subs r4, r4, #1 @ decrement the way 137df120142SHans de Goede bge inval_loop1 138df120142SHans de Goedeinval_skip: 139df120142SHans de Goede add r10, r10, #2 @ increment cache number 140df120142SHans de Goede cmp r3, r10 141df120142SHans de Goede bgt inval_levels 142df120142SHans de Goedeinval_finished: 143df120142SHans de Goede mov r10, #0 @ swith back to cache level 0 144df120142SHans de Goede mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr 145df120142SHans de Goede dsb st 146df120142SHans de Goede isb 147df120142SHans de Goede bx lr 148df120142SHans de GoedeENDPROC(__v7_invalidate_dcache_all) 149df120142SHans de Goede 150df120142SHans de GoedeENTRY(v7_invalidate_dcache_all) 151df120142SHans de Goede ARM( stmfd sp!, {r4-r5, r7, r9-r11, lr} ) 152df120142SHans de Goede THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) 153df120142SHans de Goede bl __v7_invalidate_dcache_all 154df120142SHans de Goede ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) 155df120142SHans de Goede THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) 156df120142SHans de Goede bx lr 157df120142SHans de GoedeENDPROC(v7_invalidate_dcache_all) 158