cpufunc_asm_xscale_c3.S revision 278613
1/*	$NetBSD: cpufunc_asm_xscale.S,v 1.16 2002/08/17 16:36:32 thorpej Exp $	*/
2
3/*-
4 * Copyright (c) 2007 Olivier Houchard
5 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
6 * All rights reserved.
7 *
8 * Written by Allen Briggs and Jason R. Thorpe for Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed for the NetBSD Project by
21 *	Wasabi Systems, Inc.
22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23 *    or promote products derived from this software without specific prior
24 *    written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 */
39
40/*-
41 * Copyright (c) 2001 Matt Thomas.
42 * Copyright (c) 1997,1998 Mark Brinicombe.
43 * Copyright (c) 1997 Causality Limited
44 * All rights reserved.
45 *
46 * Redistribution and use in source and binary forms, with or without
47 * modification, are permitted provided that the following conditions
48 * are met:
49 * 1. Redistributions of source code must retain the above copyright
50 *    notice, this list of conditions and the following disclaimer.
51 * 2. Redistributions in binary form must reproduce the above copyright
52 *    notice, this list of conditions and the following disclaimer in the
53 *    documentation and/or other materials provided with the distribution.
54 * 3. All advertising materials mentioning features or use of this software
55 *    must display the following acknowledgement:
56 *	This product includes software developed by Causality Limited.
57 * 4. The name of Causality Limited may not be used to endorse or promote
58 *    products derived from this software without specific prior written
59 *    permission.
60 *
61 * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
62 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
63 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
64 * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
65 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
67 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71 * SUCH DAMAGE.
72 *
73 * XScale core 3 assembly functions for CPU / MMU / TLB specific operations
74 */
75
76#include <machine/armreg.h>
77#include <machine/asm.h>
78__FBSDID("$FreeBSD: stable/10/sys/arm/arm/cpufunc_asm_xscale_c3.S 278613 2015-02-12 03:50:33Z ian $");
79
80/*
81 * Size of the XScale core D-cache.
82 */
83#define	DCACHE_SIZE		0x00008000
84
85.Lblock_userspace_access:
86	.word	_C_LABEL(block_userspace_access)
87
88/*
89 * CPWAIT -- Canonical method to wait for CP15 update.
90 * From: Intel 80200 manual, section 2.3.3.
91 *
92 * NOTE: Clobbers the specified temp reg.
93 */
94#define	CPWAIT_BRANCH							 \
95	sub	pc, pc, #4
96
97#define	CPWAIT(tmp)							 \
98	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
99	mov	tmp, tmp		/* wait for it to complete */	;\
100	CPWAIT_BRANCH			/* branch to next insn */
101
102#define	CPWAIT_AND_RETURN_SHIFTER	lsr #32
103
104#define	CPWAIT_AND_RETURN(tmp)						 \
105	mrc	p15, 0, tmp, c2, c0, 0	/* arbitrary read of CP15 */	;\
106	/* Wait for it to complete and branch to the return address */	 \
107	sub	pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
108
109#define ARM_USE_L2_CACHE
110
111#define L2_CACHE_SIZE		0x80000
112#define L2_CACHE_WAYS		8
113#define L2_CACHE_LINE_SIZE	32
114#define L2_CACHE_SETS		(L2_CACHE_SIZE / \
115    (L2_CACHE_WAYS * L2_CACHE_LINE_SIZE))
116
117#define L1_DCACHE_SIZE		32 * 1024
118#define L1_DCACHE_WAYS		4
119#define L1_DCACHE_LINE_SIZE	32
120#define L1_DCACHE_SETS		(L1_DCACHE_SIZE / \
121    (L1_DCACHE_WAYS * L1_DCACHE_LINE_SIZE))
122#ifdef CACHE_CLEAN_BLOCK_INTR
123#define	XSCALE_CACHE_CLEAN_BLOCK					\
124	stmfd	sp!, {r4}					;	\
125	mrs	r4, cpsr					;	\
126	orr	r0, r4, #(PSR_I | PSR_F)			;	\
127	msr	cpsr_fsxc, r0
128
129#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
130	msr	cpsr_fsxc, r4					;	\
131	ldmfd	sp!, {r4}
132#else
133#define	XSCALE_CACHE_CLEAN_BLOCK					\
134	stmfd	sp!, {r4}					;	\
135	ldr	r4, .Lblock_userspace_access			;	\
136	ldr	ip, [r4]					;	\
137	orr	r0, ip, #1					;	\
138	str	r0, [r4]
139
140#define	XSCALE_CACHE_CLEAN_UNBLOCK					\
141	str	ip, [r3]					;	\
142	ldmfd	sp!, {r4}
143#endif /* CACHE_CLEAN_BLOCK_INTR */
144
145
146ENTRY_NP(xscalec3_cache_syncI)
147EENTRY_NP(xscalec3_cache_purgeID)
148	mcr	p15, 0, r0, c7, c5, 0	/* flush I cache (D cleaned below) */
149EENTRY_NP(xscalec3_cache_cleanID)
150EENTRY_NP(xscalec3_cache_purgeD)
151EENTRY(xscalec3_cache_cleanD)
152
153	XSCALE_CACHE_CLEAN_BLOCK
154	mov	r0, #0
1551:
156	mov	r1, r0, asl #30
157	mov	r2, #0
1582:
159	orr	r3, r1, r2, asl #5
160	mcr	p15, 0, r3, c7, c14, 2	/* clean and invalidate */
161	add	r2, r2, #1
162	cmp	r2, #L1_DCACHE_SETS
163	bne	2b
164	add	r0, r0, #1
165	cmp	r0, #4
166	bne	1b
167	CPWAIT(r0)
168	XSCALE_CACHE_CLEAN_UNBLOCK
169	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
170
171	RET
172EEND(xscalec3_cache_purgeID)
173EEND(xscalec3_cache_cleanID)
174EEND(xscalec3_cache_purgeD)
175EEND(xscalec3_cache_cleanD)
176END(xscalec3_cache_syncI)
177
178ENTRY(xscalec3_cache_purgeID_rng)
179
180	cmp	r1, #0x4000
181	bcs	_C_LABEL(xscalec3_cache_cleanID)
182	and	r2, r0, #0x1f
183	add	r1, r1, r2
184	bic	r0, r0, #0x1f
185
1861:	mcr	p15, 0, r0, c7, c14, 1	/* clean/invalidate L1 D cache entry */
187	nop
188	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
189	add	r0, r0, #32
190	subs	r1, r1, #32
191	bhi	1b
192
193	CPWAIT(r0)
194
195	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
196
197	CPWAIT_AND_RETURN(r0)
198END(xscalec3_cache_purgeID_rng)
199
200ENTRY(xscalec3_cache_syncI_rng)
201	cmp	r1, #0x4000
202	bcs	_C_LABEL(xscalec3_cache_syncI)
203
204	and	r2, r0, #0x1f
205	add	r1, r1, r2
206	bic	r0, r0, #0x1f
207
2081:	mcr	p15, 0, r0, c7, c10, 1	/* clean D cache entry */
209	mcr	p15, 0, r0, c7, c5, 1	/* flush I cache single entry */
210	add	r0, r0, #32
211	subs	r1, r1, #32
212	bhi	1b
213
214	CPWAIT(r0)
215
216	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
217
218	CPWAIT_AND_RETURN(r0)
219END(xscalec3_cache_syncI_rng)
220
221ENTRY(xscalec3_cache_purgeD_rng)
222
223	cmp	r1, #0x4000
224	bcs	_C_LABEL(xscalec3_cache_cleanID)
225	and	r2, r0, #0x1f
226	add	r1, r1, r2
227	bic	r0, r0, #0x1f
228
2291:	mcr	p15, 0, r0, c7, c14, 1	/* Clean and invalidate D cache entry */
230	add	r0, r0, #32
231	subs	r1, r1, #32
232	bhi	1b
233
234	CPWAIT(r0)
235
236	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
237
238	CPWAIT_AND_RETURN(r0)
239END(xscalec3_cache_purgeD_rng)
240
241ENTRY(xscalec3_cache_cleanID_rng)
242EENTRY(xscalec3_cache_cleanD_rng)
243
244	cmp	r1, #0x4000
245	bcs	_C_LABEL(xscalec3_cache_cleanID)
246	and	r2, r0, #0x1f
247	add	r1, r1, r2
248	bic	r0, r0, #0x1f
249
2501:	mcr	p15, 0, r0, c7, c10, 1	/* clean L1 D cache entry */
251	nop
252	add	r0, r0, #32
253	subs	r1, r1, #32
254	bhi	1b
255
256	CPWAIT(r0)
257
258	mcr	p15, 0, r0, c7, c10, 4	/* drain write buffer */
259
260	CPWAIT_AND_RETURN(r0)
261EEND(xscalec3_cache_cleanD_rng)
262END(xscalec3_cache_cleanID_rng)
263
264ENTRY(xscalec3_l2cache_purge)
265	/* Clean-up the L2 cache */
266	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
267	mov	r0, #0
2681:
269	mov	r1, r0, asl #29
270	mov	r2, #0
2712:
272	orr	r3, r1, r2, asl #5
273	mcr	p15, 1, r3, c7, c15, 2
274	add	r2, r2, #1
275	cmp	r2, #L2_CACHE_SETS
276	bne	2b
277	add	r0, r0, #1
278	cmp	r0, #8
279	bne	1b
280	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
281
282	CPWAIT(r0)
283	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
284	RET
285END(xscalec3_l2cache_purge)
286
287ENTRY(xscalec3_l2cache_clean_rng)
288	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
289
290	and	r2, r0, #0x1f
291	add	r1, r1, r2
292	bic	r0, r0, #0x1f
293
2941:	mcr	p15, 1, r0, c7, c11, 1	/* Clean L2 D cache entry */
295	add	r0, r0, #32
296	subs	r1, r1, #32
297	bhi	1b
298
299
300	CPWAIT(r0)
301
302	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
303	mcr	p15, 0, r0, c7, c10, 5
304
305	CPWAIT_AND_RETURN(r0)
306END(xscalec3_l2cache_clean_rng)
307
308ENTRY(xscalec3_l2cache_purge_rng)
309
310	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
311
312	and	r2, r0, #0x1f
313	add	r1, r1, r2
314	bic	r0, r0, #0x1f
315
3161:	mcr	p15, 1, r0, c7, c11, 1	/* Clean L2 D cache entry */
317	mcr	p15, 1, r0, c7, c7, 1   /* Invalidate L2 D cache entry */
318	add	r0, r0, #32
319	subs	r1, r1, #32
320	bhi	1b
321
322	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
323	mcr	p15, 0, r0, c7, c10, 5
324
325	CPWAIT_AND_RETURN(r0)
326END(xscalec3_l2cache_purge_rng)
327
328ENTRY(xscalec3_l2cache_flush_rng)
329	mcr	p15, 0, r0, c7, c10, 5	/* Data memory barrier */
330
331	and	r2, r0, #0x1f
332	add	r1, r1, r2
333	bic	r0, r0, #0x1f
334
3351:	mcr	p15, 1, r0, c7, c7, 1   /* Invalidate L2 cache line */
336	add	r0, r0, #32
337	subs	r1, r1, #32
338	bhi	1b
339	mcr	p15, 0, r0, c7, c10, 4		@ data write barrier
340	mcr	p15, 0, r0, c7, c10, 5
341	CPWAIT_AND_RETURN(r0)
342END(xscalec3_l2cache_flush_rng)
343
344/*
345 * Functions to set the MMU Translation Table Base register
346 *
347 * We need to clean and flush the cache as it uses virtual
348 * addresses that are about to change.
349 */
350ENTRY(xscalec3_setttb)
351#ifdef CACHE_CLEAN_BLOCK_INTR
352	mrs	r3, cpsr
353	orr	r1, r3, #(PSR_I | PSR_F)
354	msr	cpsr_fsxc, r1
355#else
356	ldr	r3, .Lblock_userspace_access
357	ldr	r2, [r3]
358	orr	r1, r2, #1
359	str	r1, [r3]
360#endif
361	stmfd	sp!, {r0-r3, lr}
362	bl	_C_LABEL(xscalec3_cache_cleanID)
363	mcr	p15, 0, r0, c7, c5, 0	/* invalidate I$ and BTB */
364	mcr	p15, 0, r0, c7, c10, 4	/* drain write and fill buffer */
365
366	CPWAIT(r0)
367
368	ldmfd	sp!, {r0-r3, lr}
369
370#ifdef ARM_USE_L2_CACHE
371	orr	r0, r0, #0x18	/* cache the page table in L2 */
372#endif
373	/* Write the TTB */
374	mcr	p15, 0, r0, c2, c0, 0
375
376	/* If we have updated the TTB we must flush the TLB */
377	mcr	p15, 0, r0, c8, c7, 0	/* invalidate I+D TLB */
378
379	CPWAIT(r0)
380
381#ifdef CACHE_CLEAN_BLOCK_INTR
382	msr	cpsr_fsxc, r3
383#else
384	str	r2, [r3]
385#endif
386	RET
387END(xscalec3_setttb)
388
389/*
390 * Context switch.
391 *
392 * These is the CPU-specific parts of the context switcher cpu_switch()
393 * These functions actually perform the TTB reload.
394 *
395 * NOTE: Special calling convention
396 *	r1, r4-r13 must be preserved
397 */
398ENTRY(xscalec3_context_switch)
399	/*
400	 * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
401	 * Thus the data cache will contain only kernel data and the
402	 * instruction cache will contain only kernel code, and all
403	 * kernel mappings are shared by all processes.
404	 */
405#ifdef ARM_USE_L2_CACHE
406	orr	r0, r0, #0x18	/* Cache the page table in L2 */
407#endif
408	/* Write the TTB */
409	mcr	p15, 0, r0, c2, c0, 0
410
411	/* If we have updated the TTB we must flush the TLB */
412	mcr	p15, 0, r0, c8, c7, 0	/* flush the I+D tlb */
413
414	CPWAIT_AND_RETURN(r0)
415END(xscalec3_context_switch)
416
417