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