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