1/* 2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include <arch.h> 32#include <asm_macros.S> 33 34 .globl dcisw 35 .globl dccisw 36 .globl dccsw 37 .globl dccvac 38 .globl dcivac 39 .globl dccivac 40 .globl dccvau 41 .globl dczva 42 .globl flush_dcache_range 43 .globl inv_dcache_range 44 .globl dcsw_op_louis 45 .globl dcsw_op_all 46 47func dcisw 48 dc isw, x0 49 dsb sy 50 isb 51 ret 52 53 54func dccisw 55 dc cisw, x0 56 dsb sy 57 isb 58 ret 59 60 61func dccsw 62 dc csw, x0 63 dsb sy 64 isb 65 ret 66 67 68func dccvac 69 dc cvac, x0 70 dsb sy 71 isb 72 ret 73 74 75func dcivac 76 dc ivac, x0 77 dsb sy 78 isb 79 ret 80 81 82func dccivac 83 dc civac, x0 84 dsb sy 85 isb 86 ret 87 88 89func dccvau 90 dc cvau, x0 91 dsb sy 92 isb 93 ret 94 95 96func dczva 97 dc zva, x0 98 dsb sy 99 isb 100 ret 101 102 103 /* ------------------------------------------ 104 * Clean+Invalidate from base address till 105 * size. 'x0' = addr, 'x1' = size 106 * ------------------------------------------ 107 */ 108func flush_dcache_range 109 dcache_line_size x2, x3 110 add x1, x0, x1 111 sub x3, x2, #1 112 bic x0, x0, x3 113flush_loop: 114 dc civac, x0 115 add x0, x0, x2 116 cmp x0, x1 117 b.lo flush_loop 118 dsb sy 119 ret 120 121 122 /* ------------------------------------------ 123 * Invalidate from base address till 124 * size. 'x0' = addr, 'x1' = size 125 * ------------------------------------------ 126 */ 127func inv_dcache_range 128 dcache_line_size x2, x3 129 add x1, x0, x1 130 sub x3, x2, #1 131 bic x0, x0, x3 132inv_loop: 133 dc ivac, x0 134 add x0, x0, x2 135 cmp x0, x1 136 b.lo inv_loop 137 dsb sy 138 ret 139 140 141 /* ------------------------------------------ 142 * Data cache operations by set/way to the 143 * level specified 144 * ------------------------------------------ 145 * ---------------------------------- 146 * Call this func with the clidr in 147 * x0, starting cache level in x10, 148 * last cache level in x3 & cm op in 149 * x14 150 * ---------------------------------- 151 */ 152func dcsw_op 153all_start_at_level: 154 add x2, x10, x10, lsr #1 // work out 3x current cache level 155 lsr x1, x0, x2 // extract cache type bits from clidr 156 and x1, x1, #7 // mask of the bits for current cache only 157 cmp x1, #2 // see what cache we have at this level 158 b.lt skip // skip if no cache, or just i-cache 159 msr csselr_el1, x10 // select current cache level in csselr 160 isb // isb to sych the new cssr&csidr 161 mrs x1, ccsidr_el1 // read the new ccsidr 162 and x2, x1, #7 // extract the length of the cache lines 163 add x2, x2, #4 // add 4 (line length offset) 164 mov x4, #0x3ff 165 and x4, x4, x1, lsr #3 // find maximum number on the way size 166 clz w5, w4 // find bit position of way size increment 167 mov x7, #0x7fff 168 and x7, x7, x1, lsr #13 // extract max number of the index size 169loop2: 170 mov x9, x4 // create working copy of max way size 171loop3: 172 lsl x6, x9, x5 173 orr x11, x10, x6 // factor way and cache number into x11 174 lsl x6, x7, x2 175 orr x11, x11, x6 // factor index number into x11 176 mov x12, x0 177 mov x13, x30 // lr 178 mov x0, x11 179 blr x14 180 mov x0, x12 181 mov x30, x13 // lr 182 subs x9, x9, #1 // decrement the way 183 b.ge loop3 184 subs x7, x7, #1 // decrement the index 185 b.ge loop2 186skip: 187 add x10, x10, #2 // increment cache number 188 cmp x3, x10 189 b.gt all_start_at_level 190finished: 191 mov x10, #0 // swith back to cache level 0 192 msr csselr_el1, x10 // select current cache level in csselr 193 dsb sy 194 isb 195 ret 196 197 198func do_dcsw_op 199 cbz x3, exit 200 cmp x0, #DCISW 201 b.eq dc_isw 202 cmp x0, #DCCISW 203 b.eq dc_cisw 204 cmp x0, #DCCSW 205 b.eq dc_csw 206dc_isw: 207 mov x0, x9 208 adr x14, dcisw 209 b dcsw_op 210dc_cisw: 211 mov x0, x9 212 adr x14, dccisw 213 b dcsw_op 214dc_csw: 215 mov x0, x9 216 adr x14, dccsw 217 b dcsw_op 218exit: 219 ret 220 221 222func dcsw_op_louis 223 dsb sy 224 setup_dcsw_op_args x10, x3, x9, #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 225 b do_dcsw_op 226 227 228func dcsw_op_all 229 dsb sy 230 setup_dcsw_op_args x10, x3, x9, #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT 231 b do_dcsw_op 232