blob: 2108837d6f4fbae9aea799bc8de170bf2f77f522 [file] [log] [blame]
Thomas Gleixnerd2912cb2019-06-04 10:11:33 +02001/* SPDX-License-Identifier: GPL-2.0-only */
GuanXuetao10c9c102011-01-15 18:18:29 +08002/*
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 *
GuanXuetao10c9c102011-01-15 18:18:29 +08009 * 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