1f24307deSSoby Mathew/* 2f24307deSSoby Mathew * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3f24307deSSoby Mathew * 4f24307deSSoby Mathew * Redistribution and use in source and binary forms, with or without 5f24307deSSoby Mathew * modification, are permitted provided that the following conditions are met: 6f24307deSSoby Mathew * 7f24307deSSoby Mathew * Redistributions of source code must retain the above copyright notice, this 8f24307deSSoby Mathew * list of conditions and the following disclaimer. 9f24307deSSoby Mathew * 10f24307deSSoby Mathew * Redistributions in binary form must reproduce the above copyright notice, 11f24307deSSoby Mathew * this list of conditions and the following disclaimer in the documentation 12f24307deSSoby Mathew * and/or other materials provided with the distribution. 13f24307deSSoby Mathew * 14f24307deSSoby Mathew * Neither the name of ARM nor the names of its contributors may be used 15f24307deSSoby Mathew * to endorse or promote products derived from this software without specific 16f24307deSSoby Mathew * prior written permission. 17f24307deSSoby Mathew * 18f24307deSSoby Mathew * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19f24307deSSoby Mathew * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20f24307deSSoby Mathew * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21f24307deSSoby Mathew * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22f24307deSSoby Mathew * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23f24307deSSoby Mathew * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24f24307deSSoby Mathew * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25f24307deSSoby Mathew * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26f24307deSSoby Mathew * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27f24307deSSoby Mathew * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28f24307deSSoby Mathew * POSSIBILITY OF SUCH DAMAGE. 29f24307deSSoby Mathew */ 30f24307deSSoby Mathew 31f24307deSSoby Mathew#include <arch.h> 32f24307deSSoby Mathew#include <asm_macros.S> 33f24307deSSoby Mathew 34f24307deSSoby Mathew .globl flush_dcache_range 35f24307deSSoby Mathew .globl clean_dcache_range 36f24307deSSoby Mathew .globl inv_dcache_range 37f24307deSSoby Mathew .globl dcsw_op_louis 38f24307deSSoby Mathew .globl dcsw_op_all 39f24307deSSoby Mathew .globl dcsw_op_level1 40f24307deSSoby Mathew .globl dcsw_op_level2 41f24307deSSoby Mathew .globl dcsw_op_level3 42f24307deSSoby Mathew 43f24307deSSoby Mathew/* 44f24307deSSoby Mathew * This macro can be used for implementing various data cache operations `op` 45f24307deSSoby Mathew */ 46f24307deSSoby Mathew.macro do_dcache_maintenance_by_mva op, coproc, opc1, CRn, CRm, opc2 47f24307deSSoby Mathew dcache_line_size r2, r3 48f24307deSSoby Mathew add r1, r0, r1 49f24307deSSoby Mathew sub r3, r2, #1 50f24307deSSoby Mathew bic r0, r0, r3 51f24307deSSoby Mathewloop_\op: 52f24307deSSoby Mathew stcopr r0, \coproc, \opc1, \CRn, \CRm, \opc2 53f24307deSSoby Mathew add r0, r0, r2 54f24307deSSoby Mathew cmp r0, r1 55f24307deSSoby Mathew blo loop_\op 56f24307deSSoby Mathew dsb sy 57f24307deSSoby Mathew bx lr 58f24307deSSoby Mathew.endm 59f24307deSSoby Mathew 60f24307deSSoby Mathew /* ------------------------------------------ 61f24307deSSoby Mathew * Clean+Invalidate from base address till 62f24307deSSoby Mathew * size. 'r0' = addr, 'r1' = size 63f24307deSSoby Mathew * ------------------------------------------ 64f24307deSSoby Mathew */ 65f24307deSSoby Mathewfunc flush_dcache_range 66f24307deSSoby Mathew do_dcache_maintenance_by_mva cimvac, DCCIMVAC 67f24307deSSoby Mathewendfunc flush_dcache_range 68f24307deSSoby Mathew 69f24307deSSoby Mathew /* ------------------------------------------ 70f24307deSSoby Mathew * Clean from base address till size. 71f24307deSSoby Mathew * 'r0' = addr, 'r1' = size 72f24307deSSoby Mathew * ------------------------------------------ 73f24307deSSoby Mathew */ 74f24307deSSoby Mathewfunc clean_dcache_range 75f24307deSSoby Mathew do_dcache_maintenance_by_mva cmvac, DCCMVAC 76f24307deSSoby Mathewendfunc clean_dcache_range 77f24307deSSoby Mathew 78f24307deSSoby Mathew /* ------------------------------------------ 79f24307deSSoby Mathew * Invalidate from base address till 80f24307deSSoby Mathew * size. 'r0' = addr, 'r1' = size 81f24307deSSoby Mathew * ------------------------------------------ 82f24307deSSoby Mathew */ 83f24307deSSoby Mathewfunc inv_dcache_range 84f24307deSSoby Mathew do_dcache_maintenance_by_mva imvac, DCIMVAC 85f24307deSSoby Mathewendfunc inv_dcache_range 86f24307deSSoby Mathew 87f24307deSSoby Mathew /* ---------------------------------------------------------------- 88f24307deSSoby Mathew * Data cache operations by set/way to the level specified 89f24307deSSoby Mathew * 90f24307deSSoby Mathew * The main function, do_dcsw_op requires: 91f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 92f24307deSSoby Mathew * as defined in arch.h 93f24307deSSoby Mathew * r1: The cache level to begin operation from 94f24307deSSoby Mathew * r2: clidr_el1 95f24307deSSoby Mathew * r3: The last cache level to operate on 96f24307deSSoby Mathew * and will carry out the operation on each data cache from level 0 97f24307deSSoby Mathew * to the level in r3 in sequence 98f24307deSSoby Mathew * 99f24307deSSoby Mathew * The dcsw_op macro sets up the r2 and r3 parameters based on 100f24307deSSoby Mathew * clidr_el1 cache information before invoking the main function 101f24307deSSoby Mathew * ---------------------------------------------------------------- 102f24307deSSoby Mathew */ 103f24307deSSoby Mathew 104f24307deSSoby Mathew .macro dcsw_op shift, fw, ls 105f24307deSSoby Mathew ldcopr r2, CLIDR 106f24307deSSoby Mathew ubfx r3, r2, \shift, \fw 107f24307deSSoby Mathew lsl r3, r3, \ls 108f24307deSSoby Mathew mov r1, #0 109f24307deSSoby Mathew b do_dcsw_op 110f24307deSSoby Mathew .endm 111f24307deSSoby Mathew 112f24307deSSoby Mathewfunc do_dcsw_op 113f24307deSSoby Mathew push {r4-r12,lr} 114f24307deSSoby Mathew adr r11, dcsw_loop_table // compute cache op based on the operation type 115f24307deSSoby Mathew add r6, r11, r0, lsl #3 // cache op is 2x32-bit instructions 116f24307deSSoby Mathewloop1: 117f24307deSSoby Mathew add r10, r1, r1, LSR #1 // Work out 3x current cache level 118f24307deSSoby Mathew mov r12, r2, LSR r10 // extract cache type bits from clidr 119f24307deSSoby Mathew and r12, r12, #7 // mask the bits for current cache only 120f24307deSSoby Mathew cmp r12, #2 // see what cache we have at this level 121*355a5d03SDouglas Raillard blo level_done // no cache or only instruction cache at this level 122f24307deSSoby Mathew 123f24307deSSoby Mathew stcopr r1, CSSELR // select current cache level in csselr 124f24307deSSoby Mathew isb // isb to sych the new cssr&csidr 125f24307deSSoby Mathew ldcopr r12, CCSIDR // read the new ccsidr 126f24307deSSoby Mathew and r10, r12, #7 // extract the length of the cache lines 127f24307deSSoby Mathew add r10, r10, #4 // add 4 (r10 = line length offset) 128f24307deSSoby Mathew ubfx r4, r12, #3, #10 // r4 = maximum way number (right aligned) 129f24307deSSoby Mathew clz r5, r4 // r5 = the bit position of the way size increment 130f24307deSSoby Mathew mov r9, r4 // r9 working copy of the aligned max way number 131f24307deSSoby Mathew 132f24307deSSoby Mathewloop2: 133f24307deSSoby Mathew ubfx r7, r12, #13, #15 // r7 = max set number (right aligned) 134f24307deSSoby Mathew 135f24307deSSoby Mathewloop3: 136f24307deSSoby Mathew orr r0, r1, r9, LSL r5 // factor in the way number and cache level into r0 137f24307deSSoby Mathew orr r0, r0, r7, LSL r10 // factor in the set number 138f24307deSSoby Mathew 139f24307deSSoby Mathew blx r6 140f24307deSSoby Mathew subs r7, r7, #1 // decrement the set number 141*355a5d03SDouglas Raillard bhs loop3 142f24307deSSoby Mathew subs r9, r9, #1 // decrement the way number 143*355a5d03SDouglas Raillard bhs loop2 144f24307deSSoby Mathewlevel_done: 145f24307deSSoby Mathew add r1, r1, #2 // increment the cache number 146f24307deSSoby Mathew cmp r3, r1 147f24307deSSoby Mathew dsb sy // ensure completion of previous cache maintenance instruction 148*355a5d03SDouglas Raillard bhi loop1 149f24307deSSoby Mathew 150f24307deSSoby Mathew mov r6, #0 151f24307deSSoby Mathew stcopr r6, CSSELR //select cache level 0 in csselr 152f24307deSSoby Mathew dsb sy 153f24307deSSoby Mathew isb 154f24307deSSoby Mathew pop {r4-r12,pc} 155f24307deSSoby Mathew 156f24307deSSoby Mathewdcsw_loop_table: 157f24307deSSoby Mathew stcopr r0, DCISW 158f24307deSSoby Mathew bx lr 159f24307deSSoby Mathew stcopr r0, DCCISW 160f24307deSSoby Mathew bx lr 161f24307deSSoby Mathew stcopr r0, DCCSW 162f24307deSSoby Mathew bx lr 163f24307deSSoby Mathew 164f24307deSSoby Mathewendfunc do_dcsw_op 165f24307deSSoby Mathew 166f24307deSSoby Mathew /* --------------------------------------------------------------- 167f24307deSSoby Mathew * Data cache operations by set/way till PoU. 168f24307deSSoby Mathew * 169f24307deSSoby Mathew * The function requires : 170f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 171f24307deSSoby Mathew * as defined in arch.h 172f24307deSSoby Mathew * --------------------------------------------------------------- 173f24307deSSoby Mathew */ 174f24307deSSoby Mathewfunc dcsw_op_louis 175f24307deSSoby Mathew dcsw_op #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 176f24307deSSoby Mathewendfunc dcsw_op_louis 177f24307deSSoby Mathew 178f24307deSSoby Mathew /* --------------------------------------------------------------- 179f24307deSSoby Mathew * Data cache operations by set/way till PoC. 180f24307deSSoby Mathew * 181f24307deSSoby Mathew * The function requires : 182f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 183f24307deSSoby Mathew * as defined in arch.h 184f24307deSSoby Mathew * --------------------------------------------------------------- 185f24307deSSoby Mathew */ 186f24307deSSoby Mathewfunc dcsw_op_all 187f24307deSSoby Mathew dcsw_op #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 188f24307deSSoby Mathewendfunc dcsw_op_all 189f24307deSSoby Mathew 190f24307deSSoby Mathew 191f24307deSSoby Mathew /* --------------------------------------------------------------- 192f24307deSSoby Mathew * Helper macro for data cache operations by set/way for the 193f24307deSSoby Mathew * level specified 194f24307deSSoby Mathew * --------------------------------------------------------------- 195f24307deSSoby Mathew */ 196f24307deSSoby Mathew .macro dcsw_op_level level 197f24307deSSoby Mathew ldcopr r2, CLIDR 198f24307deSSoby Mathew mov r3, \level 199f24307deSSoby Mathew sub r1, r3, #2 200f24307deSSoby Mathew b do_dcsw_op 201f24307deSSoby Mathew .endm 202f24307deSSoby Mathew 203f24307deSSoby Mathew /* --------------------------------------------------------------- 204f24307deSSoby Mathew * Data cache operations by set/way for level 1 cache 205f24307deSSoby Mathew * 206f24307deSSoby Mathew * The main function, do_dcsw_op requires: 207f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 208f24307deSSoby Mathew * as defined in arch.h 209f24307deSSoby Mathew * --------------------------------------------------------------- 210f24307deSSoby Mathew */ 211f24307deSSoby Mathewfunc dcsw_op_level1 212f24307deSSoby Mathew dcsw_op_level #(1 << LEVEL_SHIFT) 213f24307deSSoby Mathewendfunc dcsw_op_level1 214f24307deSSoby Mathew 215f24307deSSoby Mathew /* --------------------------------------------------------------- 216f24307deSSoby Mathew * Data cache operations by set/way for level 2 cache 217f24307deSSoby Mathew * 218f24307deSSoby Mathew * The main function, do_dcsw_op requires: 219f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 220f24307deSSoby Mathew * as defined in arch.h 221f24307deSSoby Mathew * --------------------------------------------------------------- 222f24307deSSoby Mathew */ 223f24307deSSoby Mathewfunc dcsw_op_level2 224f24307deSSoby Mathew dcsw_op_level #(2 << LEVEL_SHIFT) 225f24307deSSoby Mathewendfunc dcsw_op_level2 226f24307deSSoby Mathew 227f24307deSSoby Mathew /* --------------------------------------------------------------- 228f24307deSSoby Mathew * Data cache operations by set/way for level 3 cache 229f24307deSSoby Mathew * 230f24307deSSoby Mathew * The main function, do_dcsw_op requires: 231f24307deSSoby Mathew * r0: The operation type (DC_OP_ISW, DC_OP_CISW, DC_OP_CSW), 232f24307deSSoby Mathew * as defined in arch.h 233f24307deSSoby Mathew * --------------------------------------------------------------- 234f24307deSSoby Mathew */ 235f24307deSSoby Mathewfunc dcsw_op_level3 236f24307deSSoby Mathew dcsw_op_level #(3 << LEVEL_SHIFT) 237f24307deSSoby Mathewendfunc dcsw_op_level3 238