]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/arm/cpufunc_asm_xscale_c3.S
There is no Python in the FreeBSD base system
[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/armreg.h>
77 #include <machine/asm.h>
78 __FBSDID("$FreeBSD$");
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
146 ENTRY_NP(xscalec3_cache_syncI)
147 xscalec3_cache_purgeID:
148 EENTRY_NP(xscalec3_cache_purgeID)
149         mcr     p15, 0, r0, c7, c5, 0   /* flush I cache (D cleaned below) */
150 EENTRY_NP(xscalec3_cache_cleanID)
151 EENTRY_NP(xscalec3_cache_purgeD)
152 EENTRY(xscalec3_cache_cleanD)
153
154         XSCALE_CACHE_CLEAN_BLOCK
155         mov     r0, #0
156 1:
157         mov     r1, r0, asl #30
158         mov     r2, #0
159 2:
160         orr     r3, r1, r2, asl #5
161         mcr     p15, 0, r3, c7, c14, 2  /* clean and invalidate */
162         add     r2, r2, #1
163         cmp     r2, #L1_DCACHE_SETS
164         bne     2b
165         add     r0, r0, #1
166         cmp     r0, #4
167         bne     1b
168         CPWAIT(r0)
169         XSCALE_CACHE_CLEAN_UNBLOCK
170         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
171
172         RET
173 EEND(xscalec3_cache_purgeID)
174 EEND(xscalec3_cache_cleanID)
175 EEND(xscalec3_cache_purgeD)
176 EEND(xscalec3_cache_cleanD)
177 END(xscalec3_cache_syncI)
178
179 ENTRY(xscalec3_cache_purgeID_rng)
180
181         cmp     r1, #0x4000
182         bcs     _C_LABEL(xscalec3_cache_cleanID)
183         and     r2, r0, #0x1f
184         add     r1, r1, r2
185         bic     r0, r0, #0x1f
186
187 1:      mcr     p15, 0, r0, c7, c14, 1  /* clean/invalidate L1 D cache entry */
188         nop
189         mcr     p15, 0, r0, c7, c5, 1   /* flush I cache single entry */
190         add     r0, r0, #32
191         subs    r1, r1, #32
192         bhi     1b
193
194         CPWAIT(r0)
195
196         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
197
198         CPWAIT_AND_RETURN(r0)
199 END(xscalec3_cache_purgeID_rng)
200
201 ENTRY(xscalec3_cache_syncI_rng)
202         cmp     r1, #0x4000
203         bcs     _C_LABEL(xscalec3_cache_syncI)
204
205         and     r2, r0, #0x1f
206         add     r1, r1, r2
207         bic     r0, r0, #0x1f
208
209 1:      mcr     p15, 0, r0, c7, c10, 1  /* clean D cache entry */
210         mcr     p15, 0, r0, c7, c5, 1   /* flush I cache single entry */
211         add     r0, r0, #32
212         subs    r1, r1, #32
213         bhi     1b
214
215         CPWAIT(r0)
216
217         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
218
219         CPWAIT_AND_RETURN(r0)
220 END(xscalec3_cache_syncI_rng)
221         
222 ENTRY(xscalec3_cache_purgeD_rng)
223
224         cmp     r1, #0x4000
225         bcs     _C_LABEL(xscalec3_cache_cleanID)
226         and     r2, r0, #0x1f
227         add     r1, r1, r2
228         bic     r0, r0, #0x1f
229
230 1:      mcr     p15, 0, r0, c7, c14, 1  /* Clean and invalidate D cache entry */
231         add     r0, r0, #32
232         subs    r1, r1, #32
233         bhi     1b
234
235         CPWAIT(r0)
236
237         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
238
239         CPWAIT_AND_RETURN(r0)
240 END(xscalec3_cache_purgeD_rng)
241
242 ENTRY(xscalec3_cache_cleanID_rng)
243 EENTRY(xscalec3_cache_cleanD_rng)
244
245         cmp     r1, #0x4000
246         bcs     _C_LABEL(xscalec3_cache_cleanID)
247         and     r2, r0, #0x1f
248         add     r1, r1, r2
249         bic     r0, r0, #0x1f
250
251 1:      mcr     p15, 0, r0, c7, c10, 1  /* clean L1 D cache entry */
252         nop
253         add     r0, r0, #32
254         subs    r1, r1, #32
255         bhi     1b
256
257         CPWAIT(r0)
258
259         mcr     p15, 0, r0, c7, c10, 4  /* drain write buffer */
260
261         CPWAIT_AND_RETURN(r0)
262 EEND(xscalec3_cache_cleanD_rng)
263 END(xscalec3_cache_cleanID_rng)
264
265 ENTRY(xscalec3_l2cache_purge)
266         /* Clean-up the L2 cache */
267         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
268         mov     r0, #0
269 1:
270         mov     r1, r0, asl #29
271         mov     r2, #0
272 2:
273         orr     r3, r1, r2, asl #5
274         mcr     p15, 1, r3, c7, c15, 2
275         add     r2, r2, #1
276         cmp     r2, #L2_CACHE_SETS
277         bne     2b
278         add     r0, r0, #1
279         cmp     r0, #8
280         bne     1b
281         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
282
283         CPWAIT(r0)
284         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
285         RET
286 END(xscalec3_l2cache_purge)
287
288 ENTRY(xscalec3_l2cache_clean_rng)
289         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
290
291         and     r2, r0, #0x1f
292         add     r1, r1, r2
293         bic     r0, r0, #0x1f
294
295 1:      mcr     p15, 1, r0, c7, c11, 1  /* Clean L2 D cache entry */
296         add     r0, r0, #32
297         subs    r1, r1, #32
298         bhi     1b
299
300
301         CPWAIT(r0)
302
303         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
304         mcr     p15, 0, r0, c7, c10, 5
305
306         CPWAIT_AND_RETURN(r0)
307 END(xscalec3_l2cache_clean_rng)
308
309 ENTRY(xscalec3_l2cache_purge_rng)
310
311         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
312
313         and     r2, r0, #0x1f
314         add     r1, r1, r2
315         bic     r0, r0, #0x1f
316
317 1:      mcr     p15, 1, r0, c7, c11, 1  /* Clean L2 D cache entry */
318         mcr     p15, 1, r0, c7, c7, 1   /* Invalidate L2 D cache entry */
319         add     r0, r0, #32
320         subs    r1, r1, #32
321         bhi     1b
322
323         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
324         mcr     p15, 0, r0, c7, c10, 5
325
326         CPWAIT_AND_RETURN(r0)
327 END(xscalec3_l2cache_purge_rng)
328
329 ENTRY(xscalec3_l2cache_flush_rng)
330         mcr     p15, 0, r0, c7, c10, 5  /* Data memory barrier */
331
332         and     r2, r0, #0x1f
333         add     r1, r1, r2
334         bic     r0, r0, #0x1f
335
336 1:      mcr     p15, 1, r0, c7, c7, 1   /* Invalidate L2 cache line */
337         add     r0, r0, #32
338         subs    r1, r1, #32
339         bhi     1b
340         mcr     p15, 0, r0, c7, c10, 4          @ data write barrier
341         mcr     p15, 0, r0, c7, c10, 5
342         CPWAIT_AND_RETURN(r0)
343 END(xscalec3_l2cache_flush_rng)
344
345 /*
346  * Functions to set the MMU Translation Table Base register
347  *
348  * We need to clean and flush the cache as it uses virtual
349  * addresses that are about to change.
350  */
351 ENTRY(xscalec3_setttb)
352 #ifdef CACHE_CLEAN_BLOCK_INTR
353         mrs     r3, cpsr
354         orr     r1, r3, #(PSR_I | PSR_F)
355         msr     cpsr_fsxc, r1
356 #else
357         ldr     r3, .Lblock_userspace_access
358         ldr     r2, [r3]
359         orr     r1, r2, #1
360         str     r1, [r3]
361 #endif
362         stmfd   sp!, {r0-r3, lr}
363         bl      _C_LABEL(xscalec3_cache_cleanID)
364         mcr     p15, 0, r0, c7, c5, 0   /* invalidate I$ and BTB */
365         mcr     p15, 0, r0, c7, c10, 4  /* drain write and fill buffer */
366
367         CPWAIT(r0)
368
369         ldmfd   sp!, {r0-r3, lr}
370
371 #ifdef ARM_USE_L2_CACHE
372         orr     r0, r0, #0x18   /* cache the page table in L2 */
373 #endif
374         /* Write the TTB */
375         mcr     p15, 0, r0, c2, c0, 0
376
377         /* If we have updated the TTB we must flush the TLB */
378         mcr     p15, 0, r0, c8, c7, 0   /* invalidate I+D TLB */
379
380         CPWAIT(r0)
381
382 #ifdef CACHE_CLEAN_BLOCK_INTR
383         msr     cpsr_fsxc, r3
384 #else
385         str     r2, [r3]
386 #endif
387         RET
388 END(xscalec3_setttb)
389
390 /*
391  * Context switch.
392  *
393  * These is the CPU-specific parts of the context switcher cpu_switch()
394  * These functions actually perform the TTB reload.
395  *
396  * NOTE: Special calling convention
397  *      r1, r4-r13 must be preserved
398  */
399 ENTRY(xscalec3_context_switch)
400         /*
401          * CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
402          * Thus the data cache will contain only kernel data and the
403          * instruction cache will contain only kernel code, and all
404          * kernel mappings are shared by all processes.
405          */
406 #ifdef ARM_USE_L2_CACHE
407         orr     r0, r0, #0x18   /* Cache the page table in L2 */
408 #endif
409         /* Write the TTB */
410         mcr     p15, 0, r0, c2, c0, 0
411
412         /* If we have updated the TTB we must flush the TLB */
413         mcr     p15, 0, r0, c8, c7, 0   /* flush the I+D tlb */
414
415         CPWAIT_AND_RETURN(r0)
416 END(xscalec3_context_switch)
417