]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/cpufunc_asm_xscale_c3.S
Revert r336773: it removed too much.
[FreeBSD/FreeBSD.git] / sys / arm / arm / cpufunc_asm_xscale_c3.S
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/asm.h>
77 __FBSDID("$FreeBSD$");
78
79 #include <machine/armreg.h>
80
81 /*
82  * Size of the XScale core D-cache.
83  */
84 #define DCACHE_SIZE             0x00008000
85
86 /*
87  * CPWAIT -- Canonical method to wait for CP15 update.
88  * From: Intel 80200 manual, section 2.3.3.
89  *
90  * NOTE: Clobbers the specified temp reg.
91  */
92 #define CPWAIT_BRANCH                                                    \
93         sub     pc, pc, #4
94
95 #define CPWAIT(tmp)                                                      \
96         mrc     p15, 0, tmp, c2, c0, 0  /* arbitrary read of CP15 */    ;\
97         mov     tmp, tmp                /* wait for it to complete */   ;\
98         CPWAIT_BRANCH                   /* branch to next insn */
99
100 #define CPWAIT_AND_RETURN_SHIFTER       lsr #32
101
102 #define CPWAIT_AND_RETURN(tmp)                                           \
103         mrc     p15, 0, tmp, c2, c0, 0  /* arbitrary read of CP15 */    ;\
104         /* Wait for it to complete and branch to the return address */   \
105         sub     pc, lr, tmp, CPWAIT_AND_RETURN_SHIFTER
106
107 #define ARM_USE_L2_CACHE
108
109 #define L2_CACHE_SIZE           0x80000
110 #define L2_CACHE_WAYS           8
111 #define L2_CACHE_LINE_SIZE      32
112 #define L2_CACHE_SETS           (L2_CACHE_SIZE / \
113     (L2_CACHE_WAYS * L2_CACHE_LINE_SIZE))
114
115 #define L1_DCACHE_SIZE          32 * 1024
116 #define L1_DCACHE_WAYS          4
117 #define L1_DCACHE_LINE_SIZE     32
118 #define L1_DCACHE_SETS          (L1_DCACHE_SIZE / \
119     (L1_DCACHE_WAYS * L1_DCACHE_LINE_SIZE))
120 #ifdef CACHE_CLEAN_BLOCK_INTR
121 #define XSCALE_CACHE_CLEAN_BLOCK                                        \
122         stmfd   sp!, {r4}                                       ;       \
123         mrs     r4, cpsr                                        ;       \
124         orr     r0, r4, #(PSR_I | PSR_F)                        ;       \
125         msr     cpsr_fsxc, r0
126
127 #define XSCALE_CACHE_CLEAN_UNBLOCK                                      \
128         msr     cpsr_fsxc, r4                                   ;       \
129         ldmfd   sp!, {r4}
130 #else
131 #define XSCALE_CACHE_CLEAN_BLOCK
132 #define XSCALE_CACHE_CLEAN_UNBLOCK
133 #endif /* CACHE_CLEAN_BLOCK_INTR */
134
135
136 ENTRY_NP(xscalec3_cache_syncI)
137 EENTRY_NP(xscalec3_cache_purgeID)
138         mcr     p15, 0, r0, c7, c5, 0   /* flush I cache (D cleaned below) */
139 EENTRY_NP(xscalec3_cache_cleanID)
140 EENTRY_NP(xscalec3_cache_purgeD)
141 EENTRY(xscalec3_cache_cleanD)
142
143         XSCALE_CACHE_CLEAN_BLOCK
144         mov     r0, #0
145 1:
146         mov     r1, r0, asl #30
147         mov     r2, #0
148 2:
149         orr     r3, r1, r2, asl #5
150         mcr     p15, 0, r3, c7, c14, 2  /* clean and invalidate */
151         add     r2, r2, #1
152         cmp     r2, #L1_DCACHE_SETS
153         bne     2b
154         add     r0, r0, #1
155         cmp     r0, #4
156         bne     1b
157         CPWAIT(r0)
158         XSCALE_CACHE_CLEAN_UNBLOCK
159         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
160
161         RET
162 EEND(xscalec3_cache_purgeID)
163 EEND(xscalec3_cache_cleanID)
164 EEND(xscalec3_cache_purgeD)
165 EEND(xscalec3_cache_cleanD)
166 END(xscalec3_cache_syncI)
167
168 ENTRY(xscalec3_cache_purgeID_rng)
169
170         cmp     r1, #0x4000
171         bcs     _C_LABEL(xscalec3_cache_cleanID)
172         and     r2, r0, #0x1f
173         add     r1, r1, r2
174         bic     r0, r0, #0x1f
175
176 1:      mcr     p15, 0, r0, c7, c14, 1  /* clean/invalidate L1 D cache entry */
177         nop
178         mcr     p15, 0, r0, c7, c5, 1   /* flush I cache single entry */
179         add     r0, r0, #32
180         subs    r1, r1, #32
181         bhi     1b
182
183         CPWAIT(r0)
184
185         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
186
187         CPWAIT_AND_RETURN(r0)
188 END(xscalec3_cache_purgeID_rng)
189
190 ENTRY(xscalec3_cache_syncI_rng)
191         cmp     r1, #0x4000
192         bcs     _C_LABEL(xscalec3_cache_syncI)
193
194         and     r2, r0, #0x1f
195         add     r1, r1, r2
196         bic     r0, r0, #0x1f
197
198 1:      mcr     p15, 0, r0, c7, c10, 1  /* clean D cache entry */
199         mcr     p15, 0, r0, c7, c5, 1   /* flush I cache single entry */
200         add     r0, r0, #32
201         subs    r1, r1, #32
202         bhi     1b
203
204         CPWAIT(r0)
205
206         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
207
208         CPWAIT_AND_RETURN(r0)
209 END(xscalec3_cache_syncI_rng)
210
211 ENTRY(xscalec3_cache_purgeD_rng)
212
213         cmp     r1, #0x4000
214         bcs     _C_LABEL(xscalec3_cache_cleanID)
215         and     r2, r0, #0x1f
216         add     r1, r1, r2
217         bic     r0, r0, #0x1f
218
219 1:      mcr     p15, 0, r0, c7, c14, 1  /* Clean and invalidate D cache entry */
220         add     r0, r0, #32
221         subs    r1, r1, #32
222         bhi     1b
223
224         CPWAIT(r0)
225
226         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
227
228         CPWAIT_AND_RETURN(r0)
229 END(xscalec3_cache_purgeD_rng)
230
231 ENTRY(xscalec3_cache_cleanID_rng)
232 EENTRY(xscalec3_cache_cleanD_rng)
233
234         cmp     r1, #0x4000
235         bcs     _C_LABEL(xscalec3_cache_cleanID)
236         and     r2, r0, #0x1f
237         add     r1, r1, r2
238         bic     r0, r0, #0x1f
239
240 1:      mcr     p15, 0, r0, c7, c10, 1  /* clean L1 D cache entry */
241         nop
242         add     r0, r0, #32
243         subs    r1, r1, #32
244         bhi     1b
245
246         CPWAIT(r0)
247
248         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
249
250         CPWAIT_AND_RETURN(r0)
251 EEND(xscalec3_cache_cleanD_rng)
252 END(xscalec3_cache_cleanID_rng)
253
254 ENTRY(xscalec3_l2cache_purge)
255         /* Clean-up the L2 cache */
256         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
257         mov     r0, #0
258 1:
259         mov     r1, r0, asl #29
260         mov     r2, #0
261 2:
262         orr     r3, r1, r2, asl #5
263         mcr     p15, 1, r3, c7, c15, 2
264         add     r2, r2, #1
265         cmp     r2, #L2_CACHE_SETS
266         bne     2b
267         add     r0, r0, #1
268         cmp     r0, #8
269         bne     1b
270         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
271
272         CPWAIT(r0)
273         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
274         RET
275 END(xscalec3_l2cache_purge)
276
277 ENTRY(xscalec3_l2cache_clean_rng)
278         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
279
280         and     r2, r0, #0x1f
281         add     r1, r1, r2
282         bic     r0, r0, #0x1f
283
284 1:      mcr     p15, 1, r0, c7, c11, 1  /* Clean L2 D cache entry */
285         add     r0, r0, #32
286         subs    r1, r1, #32
287         bhi     1b
288
289
290         CPWAIT(r0)
291
292         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
293         mcr     p15, 0, r0, c7, c10, 5
294
295         CPWAIT_AND_RETURN(r0)
296 END(xscalec3_l2cache_clean_rng)
297
298 ENTRY(xscalec3_l2cache_purge_rng)
299
300         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
301
302         and     r2, r0, #0x1f
303         add     r1, r1, r2
304         bic     r0, r0, #0x1f
305
306 1:      mcr     p15, 1, r0, c7, c11, 1  /* Clean L2 D cache entry */
307         mcr     p15, 1, r0, c7, c7, 1   /* Invalidate L2 D cache entry */
308         add     r0, r0, #32
309         subs    r1, r1, #32
310         bhi     1b
311
312         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
313         mcr     p15, 0, r0, c7, c10, 5
314
315         CPWAIT_AND_RETURN(r0)
316 END(xscalec3_l2cache_purge_rng)
317
318 ENTRY(xscalec3_l2cache_flush_rng)
319         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
320
321         and     r2, r0, #0x1f
322         add     r1, r1, r2
323         bic     r0, r0, #0x1f
324
325 1:      mcr     p15, 1, r0, c7, c7, 1   /* Invalidate L2 cache line */
326         add     r0, r0, #32
327         subs    r1, r1, #32
328         bhi     1b
329         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
330         mcr     p15, 0, r0, c7, c10, 5
331         CPWAIT_AND_RETURN(r0)
332 END(xscalec3_l2cache_flush_rng)
333
334 /*
335  * Functions to set the MMU Translation Table Base register
336  *
337  * We need to clean and flush the cache as it uses virtual
338  * addresses that are about to change.
339  */
340 ENTRY(xscalec3_setttb)
341 #ifdef CACHE_CLEAN_BLOCK_INTR
342         mrs     r3, cpsr
343         orr     r1, r3, #(PSR_I | PSR_F)
344         msr     cpsr_fsxc, r1
345 #endif
346         stmfd   sp!, {r0-r3, lr}
347         bl      _C_LABEL(xscalec3_cache_cleanID)
348         mcr     p15, 0, r0, c7, c5, 0   /* invalidate I$ and BTB */
349         mcr     p15, 0, r0, c7, c10, 4  /* drain write and fill buffer */
350
351         CPWAIT(r0)
352
353         ldmfd   sp!, {r0-r3, lr}
354
355 #ifdef ARM_USE_L2_CACHE
356         orr     r0, r0, #0x18   /* cache the page table in L2 */
357 #endif
358         /* Write the TTB */
359         mcr     p15, 0, r0, c2, c0, 0
360
361         /* If we have updated the TTB we must flush the TLB */
362         mcr     p15, 0, r0, c8, c7, 0   /* invalidate I+D TLB */
363
364         CPWAIT(r0)
365
366 #ifdef CACHE_CLEAN_BLOCK_INTR
367         msr     cpsr_fsxc, r3
368 #endif
369         RET
370 END(xscalec3_setttb)
371
372 /*
373  * Context switch.
374  *
375  * These is the CPU-specific parts of the context switcher cpu_switch()
376  * These functions actually perform the TTB reload.
377  *
378  * NOTE: Special calling convention
379  *      r1, r4-r13 must be preserved
380  */
381 ENTRY(xscalec3_context_switch)
382         /*
383          * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
384          * Thus the data cache will contain only kernel data and the
385          * instruction cache will contain only kernel code, and all
386          * kernel mappings are shared by all processes.
387          */
388 #ifdef ARM_USE_L2_CACHE
389         orr     r0, r0, #0x18   /* Cache the page table in L2 */
390 #endif
391         /* Write the TTB */
392         mcr     p15, 0, r0, c2, c0, 0
393
394         /* If we have updated the TTB we must flush the TLB */
395         mcr     p15, 0, r0, c8, c7, 0   /* flush the I+D tlb */
396
397         CPWAIT_AND_RETURN(r0)
398 END(xscalec3_context_switch)
399