1/* 2 * linux/arch/unicore32/mm/cache-ucv2.S 3 * 4 * Code specific to PKUnity SoC and UniCore ISA 5 * 6 * Copyright (C) 2001-2010 GUAN Xue-tao 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * This is the "shell" of the UniCore-v2 processor support. 13 */ 14#include <linux/linkage.h> 15#include <linux/init.h> 16#include <asm/assembler.h> 17#include <asm/page.h> 18 19#include "proc-macros.S" 20 21/* 22 * __cpuc_flush_icache_all() 23 * __cpuc_flush_kern_all() 24 * __cpuc_flush_user_all() 25 * 26 * Flush the entire cache. 27 */ 28ENTRY(__cpuc_flush_icache_all) 29 /*FALLTHROUGH*/ 30ENTRY(__cpuc_flush_kern_all) 31 /*FALLTHROUGH*/ 32ENTRY(__cpuc_flush_user_all) 33 mov r0, #0 34 movc p0.c5, r0, #14 @ Dcache flush all 35 nop8 36 37 mov r0, #0 38 movc p0.c5, r0, #20 @ Icache invalidate all 39 nop8 40 41 mov pc, lr 42 43/* 44 * __cpuc_flush_user_range(start, end, flags) 45 * 46 * Flush a range of TLB entries in the specified address space. 47 * 48 * - start - start address (may not be aligned) 49 * - end - end address (exclusive, may not be aligned) 50 * - flags - vm_area_struct flags describing address space 51 */ 52ENTRY(__cpuc_flush_user_range) 53 cxor.a r2, #0 54 beq __cpuc_dma_flush_range 55 56#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 57 andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check 58 sub r1, r1, r0 59 csub.a r1, #MAX_AREA_SIZE 60 bsg 2f 61 62 andn r1, r1, #CACHE_LINESIZE - 1 63 add r1, r1, #CACHE_LINESIZE 64 65101: dcacheline_flush r0, r11, r12 66 67 add r0, r0, #CACHE_LINESIZE 68 sub.a r1, r1, #CACHE_LINESIZE 69 bns 101b 70 b 3f 71#endif 722: mov ip, #0 73 movc p0.c5, ip, #14 @ Dcache flush all 74 nop8 75 763: mov ip, #0 77 movc p0.c5, ip, #20 @ Icache invalidate all 78 nop8 79 80 mov pc, lr 81 82/* 83 * __cpuc_coherent_kern_range(start,end) 84 * __cpuc_coherent_user_range(start,end) 85 * 86 * Ensure that the I and D caches are coherent within specified 87 * region. This is typically used when code has been written to 88 * a memory region, and will be executed. 89 * 90 * - start - virtual start address of region 91 * - end - virtual end address of region 92 */ 93ENTRY(__cpuc_coherent_kern_range) 94 /* FALLTHROUGH */ 95ENTRY(__cpuc_coherent_user_range) 96#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 97 andn r0, r0, #CACHE_LINESIZE - 1 @ Safety check 98 sub r1, r1, r0 99 csub.a r1, #MAX_AREA_SIZE 100 bsg 2f 101 102 andn r1, r1, #CACHE_LINESIZE - 1 103 add r1, r1, #CACHE_LINESIZE 104 105 @ r0 va2pa r10 106 mov r9, #PAGE_SZ 107 sub r9, r9, #1 @ PAGE_MASK 108101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA 109 b 103f 110102: cand.a r0, r9 111 beq 101b 112 113103: movc p0.c5, r10, #11 @ Dcache clean line of R10 114 nop8 115 116 add r0, r0, #CACHE_LINESIZE 117 add r10, r10, #CACHE_LINESIZE 118 sub.a r1, r1, #CACHE_LINESIZE 119 bns 102b 120 b 3f 121#endif 1222: mov ip, #0 123 movc p0.c5, ip, #10 @ Dcache clean all 124 nop8 125 1263: mov ip, #0 127 movc p0.c5, ip, #20 @ Icache invalidate all 128 nop8 129 130 mov pc, lr 131 132/* 133 * __cpuc_flush_kern_dcache_area(void *addr, size_t size) 134 * 135 * - addr - kernel address 136 * - size - region size 137 */ 138ENTRY(__cpuc_flush_kern_dcache_area) 139 mov ip, #0 140 movc p0.c5, ip, #14 @ Dcache flush all 141 nop8 142 mov pc, lr 143 144/* 145 * __cpuc_dma_clean_range(start,end) 146 * - start - virtual start address of region 147 * - end - virtual end address of region 148 */ 149ENTRY(__cpuc_dma_clean_range) 150#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 151 andn r0, r0, #CACHE_LINESIZE - 1 152 sub r1, r1, r0 153 andn r1, r1, #CACHE_LINESIZE - 1 154 add r1, r1, #CACHE_LINESIZE 155 156 csub.a r1, #MAX_AREA_SIZE 157 bsg 2f 158 159 @ r0 va2pa r10 160 mov r9, #PAGE_SZ 161 sub r9, r9, #1 @ PAGE_MASK 162101: va2pa r0, r10, r11, r12, r13, 2f @ r10 is PA 163 b 1f 164102: cand.a r0, r9 165 beq 101b 166 1671: movc p0.c5, r10, #11 @ Dcache clean line of R10 168 nop8 169 add r0, r0, #CACHE_LINESIZE 170 add r10, r10, #CACHE_LINESIZE 171 sub.a r1, r1, #CACHE_LINESIZE 172 bns 102b 173 mov pc, lr 174#endif 1752: mov ip, #0 176 movc p0.c5, ip, #10 @ Dcache clean all 177 nop8 178 179 mov pc, lr 180 181/* 182 * __cpuc_dma_inv_range(start,end) 183 * __cpuc_dma_flush_range(start,end) 184 * - start - virtual start address of region 185 * - end - virtual end address of region 186 */ 187__cpuc_dma_inv_range: 188 /* FALLTHROUGH */ 189ENTRY(__cpuc_dma_flush_range) 190#ifndef CONFIG_CPU_DCACHE_LINE_DISABLE 191 andn r0, r0, #CACHE_LINESIZE - 1 192 sub r1, r1, r0 193 andn r1, r1, #CACHE_LINESIZE - 1 194 add r1, r1, #CACHE_LINESIZE 195 196 csub.a r1, #MAX_AREA_SIZE 197 bsg 2f 198 199 @ r0 va2pa r10 200101: dcacheline_flush r0, r11, r12 201 202 add r0, r0, #CACHE_LINESIZE 203 sub.a r1, r1, #CACHE_LINESIZE 204 bns 101b 205 mov pc, lr 206#endif 2072: mov ip, #0 208 movc p0.c5, ip, #14 @ Dcache flush all 209 nop8 210 211 mov pc, lr 212 213