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