blob: 11a01c3e9cea91ece949e93c0c7776bdb4826170 [file] [log] [blame]
Chris Zankel3f65ce42005-06-23 22:01:24 -07001/*
2 * arch/xtensa/mm/misc.S
3 *
4 * Miscellaneous assembly functions.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
Chris Zankel66569202007-08-22 10:14:51 -070010 * Copyright (C) 2001 - 2007 Tensilica Inc.
Chris Zankel3f65ce42005-06-23 22:01:24 -070011 *
12 * Chris Zankel <chris@zankel.net>
13 */
14
Chris Zankel3f65ce42005-06-23 22:01:24 -070015
16#include <linux/linkage.h>
17#include <asm/page.h>
18#include <asm/pgtable.h>
Chris Zankel173d66812006-12-10 02:18:48 -080019#include <asm/asmmacro.h>
20#include <asm/cacheasm.h>
Chris Zankel66569202007-08-22 10:14:51 -070021#include <asm/tlbflush.h>
Chris Zankel3f65ce42005-06-23 22:01:24 -070022
Chris Zankel66569202007-08-22 10:14:51 -070023
24/*
25 * clear_page and clear_user_page are the same for non-cache-aliased configs.
26 *
27 * clear_page (unsigned long page)
28 * a2
29 */
Chris Zankel3f65ce42005-06-23 22:01:24 -070030
31ENTRY(clear_page)
Chris Zankeld1538c42012-11-16 16:16:20 -080032
Chris Zankel3f65ce42005-06-23 22:01:24 -070033 entry a1, 16
Chris Zankel3f65ce42005-06-23 22:01:24 -070034
Chris Zankel66569202007-08-22 10:14:51 -070035 movi a3, 0
36 __loopi a2, a7, PAGE_SIZE, 32
37 s32i a3, a2, 0
Chris Zankel3f65ce42005-06-23 22:01:24 -070038 s32i a3, a2, 4
39 s32i a3, a2, 8
40 s32i a3, a2, 12
41 s32i a3, a2, 16
42 s32i a3, a2, 20
43 s32i a3, a2, 24
44 s32i a3, a2, 28
Chris Zankel66569202007-08-22 10:14:51 -070045 __endla a2, a7, 32
Chris Zankel3f65ce42005-06-23 22:01:24 -070046
47 retw
48
Chris Zankeld1538c42012-11-16 16:16:20 -080049ENDPROC(clear_page)
50
Chris Zankel3f65ce42005-06-23 22:01:24 -070051/*
Chris Zankel66569202007-08-22 10:14:51 -070052 * copy_page and copy_user_page are the same for non-cache-aliased configs.
53 *
Chris Zankel3f65ce42005-06-23 22:01:24 -070054 * copy_page (void *to, void *from)
Chris Zankel66569202007-08-22 10:14:51 -070055 * a2 a3
Chris Zankel3f65ce42005-06-23 22:01:24 -070056 */
57
58ENTRY(copy_page)
Chris Zankeld1538c42012-11-16 16:16:20 -080059
Chris Zankel3f65ce42005-06-23 22:01:24 -070060 entry a1, 16
Chris Zankel3f65ce42005-06-23 22:01:24 -070061
Chris Zankel66569202007-08-22 10:14:51 -070062 __loopi a2, a4, PAGE_SIZE, 32
63
64 l32i a8, a3, 0
65 l32i a9, a3, 4
66 s32i a8, a2, 0
67 s32i a9, a2, 4
68
69 l32i a8, a3, 8
70 l32i a9, a3, 12
71 s32i a8, a2, 8
72 s32i a9, a2, 12
73
74 l32i a8, a3, 16
75 l32i a9, a3, 20
76 s32i a8, a2, 16
77 s32i a9, a2, 20
78
79 l32i a8, a3, 24
80 l32i a9, a3, 28
81 s32i a8, a2, 24
82 s32i a9, a2, 28
83
84 addi a2, a2, 32
85 addi a3, a3, 32
86
87 __endl a2, a4
Chris Zankel3f65ce42005-06-23 22:01:24 -070088
89 retw
90
Chris Zankeld1538c42012-11-16 16:16:20 -080091ENDPROC(copy_page)
92
Johannes Weinere5083a62009-03-04 16:21:31 +010093#ifdef CONFIG_MMU
Chris Zankel3f65ce42005-06-23 22:01:24 -070094/*
Chris Zankel66569202007-08-22 10:14:51 -070095 * If we have to deal with cache aliasing, we use temporary memory mappings
96 * to ensure that the source and destination pages have the same color as
97 * the virtual address. We use way 0 and 1 for temporary mappings in such cases.
98 *
99 * The temporary DTLB entries shouldn't be flushed by interrupts, but are
100 * flushed by preemptive task switches. Special code in the
101 * fast_second_level_miss handler re-established the temporary mapping.
102 * It requires that the PPNs for the destination and source addresses are
103 * in a6, and a7, respectively.
104 */
105
106/* TLB miss exceptions are treated special in the following region */
107
108ENTRY(__tlbtemp_mapping_start)
109
110#if (DCACHE_WAY_SIZE > PAGE_SIZE)
111
112/*
Max Filippova91902d2014-07-21 18:54:11 +0400113 * clear_page_alias(void *addr, unsigned long paddr)
114 * a2 a3
Chris Zankel66569202007-08-22 10:14:51 -0700115 */
116
Max Filippova91902d2014-07-21 18:54:11 +0400117ENTRY(clear_page_alias)
Chris Zankeld1538c42012-11-16 16:16:20 -0800118
Chris Zankel66569202007-08-22 10:14:51 -0700119 entry a1, 32
120
Max Filippova91902d2014-07-21 18:54:11 +0400121 /* Skip setting up a temporary DTLB if not aliased low page. */
Chris Zankel66569202007-08-22 10:14:51 -0700122
Max Filippova91902d2014-07-21 18:54:11 +0400123 movi a5, PAGE_OFFSET
124 movi a6, 0
125 beqz a3, 1f
Chris Zankel66569202007-08-22 10:14:51 -0700126
Max Filippova91902d2014-07-21 18:54:11 +0400127 /* Setup a temporary DTLB for the addr. */
Chris Zankel66569202007-08-22 10:14:51 -0700128
Max Filippova91902d2014-07-21 18:54:11 +0400129 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
130 mov a4, a2
Chris Zankel66569202007-08-22 10:14:51 -0700131 wdtlb a6, a2
132 dsync
133
1341: movi a3, 0
135 __loopi a2, a7, PAGE_SIZE, 32
136 s32i a3, a2, 0
137 s32i a3, a2, 4
138 s32i a3, a2, 8
139 s32i a3, a2, 12
140 s32i a3, a2, 16
141 s32i a3, a2, 20
142 s32i a3, a2, 24
143 s32i a3, a2, 28
144 __endla a2, a7, 32
145
146 bnez a6, 1f
147 retw
148
149 /* We need to invalidate the temporary idtlb entry, if any. */
150
Max Filippova91902d2014-07-21 18:54:11 +04001511: idtlb a4
Chris Zankel66569202007-08-22 10:14:51 -0700152 dsync
153
154 retw
155
Max Filippova91902d2014-07-21 18:54:11 +0400156ENDPROC(clear_page_alias)
Chris Zankeld1538c42012-11-16 16:16:20 -0800157
Chris Zankel66569202007-08-22 10:14:51 -0700158/*
Max Filippova91902d2014-07-21 18:54:11 +0400159 * copy_page_alias(void *to, void *from,
160 * a2 a3
161 * unsigned long to_paddr, unsigned long from_paddr)
162 * a4 a5
Chris Zankel66569202007-08-22 10:14:51 -0700163 */
164
Max Filippova91902d2014-07-21 18:54:11 +0400165ENTRY(copy_page_alias)
Chris Zankel66569202007-08-22 10:14:51 -0700166
Chris Zankelc4c45942012-11-28 16:53:51 -0800167 entry a1, 32
Chris Zankel66569202007-08-22 10:14:51 -0700168
Max Filippova91902d2014-07-21 18:54:11 +0400169 /* Skip setting up a temporary DTLB for destination if not aliased. */
Chris Zankel66569202007-08-22 10:14:51 -0700170
Max Filippova91902d2014-07-21 18:54:11 +0400171 movi a6, 0
172 movi a7, 0
173 beqz a4, 1f
Chris Zankel66569202007-08-22 10:14:51 -0700174
Max Filippova91902d2014-07-21 18:54:11 +0400175 /* Setup a temporary DTLB for destination. */
Chris Zankel66569202007-08-22 10:14:51 -0700176
Max Filippova91902d2014-07-21 18:54:11 +0400177 addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
Chris Zankel66569202007-08-22 10:14:51 -0700178 wdtlb a6, a2
179 dsync
180
Max Filippova91902d2014-07-21 18:54:11 +0400181 /* Skip setting up a temporary DTLB for source if not aliased. */
Chris Zankel66569202007-08-22 10:14:51 -0700182
Max Filippova91902d2014-07-21 18:54:11 +04001831: beqz a5, 1f
Chris Zankel66569202007-08-22 10:14:51 -0700184
Max Filippova91902d2014-07-21 18:54:11 +0400185 /* Setup a temporary DTLB for source. */
Chris Zankel66569202007-08-22 10:14:51 -0700186
Max Filippova91902d2014-07-21 18:54:11 +0400187 addi a7, a5, PAGE_KERNEL
Chris Zankel66569202007-08-22 10:14:51 -0700188 addi a8, a3, 1 # way1
189
190 wdtlb a7, a8
191 dsync
192
1931: __loopi a2, a4, PAGE_SIZE, 32
194
195 l32i a8, a3, 0
196 l32i a9, a3, 4
197 s32i a8, a2, 0
198 s32i a9, a2, 4
199
200 l32i a8, a3, 8
201 l32i a9, a3, 12
202 s32i a8, a2, 8
203 s32i a9, a2, 12
204
205 l32i a8, a3, 16
206 l32i a9, a3, 20
207 s32i a8, a2, 16
208 s32i a9, a2, 20
209
210 l32i a8, a3, 24
211 l32i a9, a3, 28
212 s32i a8, a2, 24
213 s32i a9, a2, 28
214
215 addi a2, a2, 32
216 addi a3, a3, 32
217
218 __endl a2, a4
219
220 /* We need to invalidate any temporary mapping! */
221
222 bnez a6, 1f
223 bnez a7, 2f
224 retw
225
2261: addi a2, a2, -PAGE_SIZE
227 idtlb a2
228 dsync
229 bnez a7, 2f
230 retw
231
2322: addi a3, a3, -PAGE_SIZE+1
233 idtlb a3
234 dsync
235
236 retw
237
Max Filippova91902d2014-07-21 18:54:11 +0400238ENDPROC(copy_page_alias)
Chris Zankeld1538c42012-11-16 16:16:20 -0800239
Chris Zankel66569202007-08-22 10:14:51 -0700240#endif
241
242#if (DCACHE_WAY_SIZE > PAGE_SIZE)
243
244/*
245 * void __flush_invalidate_dcache_page_alias (addr, phys)
246 * a2 a3
247 */
248
249ENTRY(__flush_invalidate_dcache_page_alias)
Chris Zankeld1538c42012-11-16 16:16:20 -0800250
Chris Zankel66569202007-08-22 10:14:51 -0700251 entry sp, 16
252
253 movi a7, 0 # required for exception handler
254 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
255 mov a4, a2
256 wdtlb a6, a2
257 dsync
258
259 ___flush_invalidate_dcache_page a2 a3
260
261 idtlb a4
262 dsync
263
264 retw
265
Chris Zankeld1538c42012-11-16 16:16:20 -0800266ENDPROC(__flush_invalidate_dcache_page_alias)
Max Filippova91902d2014-07-21 18:54:11 +0400267
268/*
269 * void __invalidate_dcache_page_alias (addr, phys)
270 * a2 a3
271 */
272
273ENTRY(__invalidate_dcache_page_alias)
274
275 entry sp, 16
276
277 movi a7, 0 # required for exception handler
278 addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
279 mov a4, a2
280 wdtlb a6, a2
281 dsync
282
283 ___invalidate_dcache_page a2 a3
284
285 idtlb a4
286 dsync
287
288 retw
289
290ENDPROC(__invalidate_dcache_page_alias)
Chris Zankel66569202007-08-22 10:14:51 -0700291#endif
292
293ENTRY(__tlbtemp_mapping_itlb)
294
295#if (ICACHE_WAY_SIZE > PAGE_SIZE)
296
297ENTRY(__invalidate_icache_page_alias)
Chris Zankeld1538c42012-11-16 16:16:20 -0800298
Chris Zankel66569202007-08-22 10:14:51 -0700299 entry sp, 16
300
Chris Zankel0b2c3af2008-02-12 10:11:45 -0800301 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
Chris Zankel66569202007-08-22 10:14:51 -0700302 mov a4, a2
303 witlb a6, a2
304 isync
305
306 ___invalidate_icache_page a2 a3
307
308 iitlb a4
309 isync
310 retw
311
Chris Zankeld1538c42012-11-16 16:16:20 -0800312ENDPROC(__invalidate_icache_page_alias)
313
Chris Zankel66569202007-08-22 10:14:51 -0700314#endif
315
316/* End of special treatment in tlb miss exception */
317
318ENTRY(__tlbtemp_mapping_end)
Chris Zankeld1538c42012-11-16 16:16:20 -0800319
Johannes Weinere5083a62009-03-04 16:21:31 +0100320#endif /* CONFIG_MMU
Chris Zankel66569202007-08-22 10:14:51 -0700321
322/*
Chris Zankel3f65ce42005-06-23 22:01:24 -0700323 * void __invalidate_icache_page(ulong start)
324 */
325
326ENTRY(__invalidate_icache_page)
Chris Zankeld1538c42012-11-16 16:16:20 -0800327
Chris Zankel3f65ce42005-06-23 22:01:24 -0700328 entry sp, 16
Chris Zankel173d66812006-12-10 02:18:48 -0800329
330 ___invalidate_icache_page a2 a3
331 isync
332
Chris Zankel3f65ce42005-06-23 22:01:24 -0700333 retw
334
Chris Zankeld1538c42012-11-16 16:16:20 -0800335ENDPROC(__invalidate_icache_page)
336
Chris Zankel3f65ce42005-06-23 22:01:24 -0700337/*
338 * void __invalidate_dcache_page(ulong start)
339 */
340
341ENTRY(__invalidate_dcache_page)
Chris Zankeld1538c42012-11-16 16:16:20 -0800342
Chris Zankel3f65ce42005-06-23 22:01:24 -0700343 entry sp, 16
Chris Zankel3f65ce42005-06-23 22:01:24 -0700344
Chris Zankel173d66812006-12-10 02:18:48 -0800345 ___invalidate_dcache_page a2 a3
346 dsync
Chris Zankel3f65ce42005-06-23 22:01:24 -0700347
Chris Zankel3f65ce42005-06-23 22:01:24 -0700348 retw
349
Chris Zankeld1538c42012-11-16 16:16:20 -0800350ENDPROC(__invalidate_dcache_page)
351
Chris Zankel3f65ce42005-06-23 22:01:24 -0700352/*
353 * void __flush_invalidate_dcache_page(ulong start)
354 */
355
356ENTRY(__flush_invalidate_dcache_page)
Chris Zankeld1538c42012-11-16 16:16:20 -0800357
Chris Zankel3f65ce42005-06-23 22:01:24 -0700358 entry sp, 16
Chris Zankel173d66812006-12-10 02:18:48 -0800359
360 ___flush_invalidate_dcache_page a2 a3
361
362 dsync
363 retw
364
Chris Zankeld1538c42012-11-16 16:16:20 -0800365ENDPROC(__flush_invalidate_dcache_page)
366
Chris Zankel173d66812006-12-10 02:18:48 -0800367/*
368 * void __flush_dcache_page(ulong start)
369 */
370
371ENTRY(__flush_dcache_page)
Chris Zankeld1538c42012-11-16 16:16:20 -0800372
Chris Zankel173d66812006-12-10 02:18:48 -0800373 entry sp, 16
374
375 ___flush_dcache_page a2 a3
376
377 dsync
378 retw
379
Chris Zankeld1538c42012-11-16 16:16:20 -0800380ENDPROC(__flush_dcache_page)
381
Chris Zankel173d66812006-12-10 02:18:48 -0800382/*
383 * void __invalidate_icache_range(ulong start, ulong size)
384 */
385
386ENTRY(__invalidate_icache_range)
Chris Zankeld1538c42012-11-16 16:16:20 -0800387
Chris Zankel173d66812006-12-10 02:18:48 -0800388 entry sp, 16
389
390 ___invalidate_icache_range a2 a3 a4
391 isync
392
Chris Zankel3f65ce42005-06-23 22:01:24 -0700393 retw
394
Chris Zankeld1538c42012-11-16 16:16:20 -0800395ENDPROC(__invalidate_icache_range)
396
Chris Zankel3f65ce42005-06-23 22:01:24 -0700397/*
398 * void __flush_invalidate_dcache_range(ulong start, ulong size)
399 */
400
401ENTRY(__flush_invalidate_dcache_range)
Chris Zankeld1538c42012-11-16 16:16:20 -0800402
Chris Zankel3f65ce42005-06-23 22:01:24 -0700403 entry sp, 16
Chris Zankel173d66812006-12-10 02:18:48 -0800404
405 ___flush_invalidate_dcache_range a2 a3 a4
406 dsync
407
Chris Zankel3f65ce42005-06-23 22:01:24 -0700408 retw
409
Chris Zankeld1538c42012-11-16 16:16:20 -0800410ENDPROC(__flush_invalidate_dcache_range)
411
Chris Zankel3f65ce42005-06-23 22:01:24 -0700412/*
Chris Zankel173d66812006-12-10 02:18:48 -0800413 * void _flush_dcache_range(ulong start, ulong size)
414 */
415
416ENTRY(__flush_dcache_range)
Chris Zankeld1538c42012-11-16 16:16:20 -0800417
Chris Zankel173d66812006-12-10 02:18:48 -0800418 entry sp, 16
419
420 ___flush_dcache_range a2 a3 a4
421 dsync
422
423 retw
424
Chris Zankeld1538c42012-11-16 16:16:20 -0800425ENDPROC(__flush_dcache_range)
426
Chris Zankel173d66812006-12-10 02:18:48 -0800427/*
428 * void _invalidate_dcache_range(ulong start, ulong size)
429 */
430
431ENTRY(__invalidate_dcache_range)
Chris Zankeld1538c42012-11-16 16:16:20 -0800432
Chris Zankel173d66812006-12-10 02:18:48 -0800433 entry sp, 16
434
435 ___invalidate_dcache_range a2 a3 a4
436
Chris Zankel173d66812006-12-10 02:18:48 -0800437 retw
438
Chris Zankeld1538c42012-11-16 16:16:20 -0800439ENDPROC(__invalidate_dcache_range)
440
Chris Zankel173d66812006-12-10 02:18:48 -0800441/*
442 * void _invalidate_icache_all(void)
443 */
444
445ENTRY(__invalidate_icache_all)
Chris Zankeld1538c42012-11-16 16:16:20 -0800446
Chris Zankel173d66812006-12-10 02:18:48 -0800447 entry sp, 16
448
449 ___invalidate_icache_all a2 a3
450 isync
451
452 retw
453
Chris Zankeld1538c42012-11-16 16:16:20 -0800454ENDPROC(__invalidate_icache_all)
455
Chris Zankel173d66812006-12-10 02:18:48 -0800456/*
457 * void _flush_invalidate_dcache_all(void)
458 */
459
460ENTRY(__flush_invalidate_dcache_all)
Chris Zankeld1538c42012-11-16 16:16:20 -0800461
Chris Zankel173d66812006-12-10 02:18:48 -0800462 entry sp, 16
463
464 ___flush_invalidate_dcache_all a2 a3
465 dsync
466
467 retw
468
Chris Zankeld1538c42012-11-16 16:16:20 -0800469ENDPROC(__flush_invalidate_dcache_all)
470
Chris Zankel173d66812006-12-10 02:18:48 -0800471/*
472 * void _invalidate_dcache_all(void)
Chris Zankel3f65ce42005-06-23 22:01:24 -0700473 */
474
475ENTRY(__invalidate_dcache_all)
Chris Zankeld1538c42012-11-16 16:16:20 -0800476
Chris Zankel3f65ce42005-06-23 22:01:24 -0700477 entry sp, 16
Chris Zankel3f65ce42005-06-23 22:01:24 -0700478
Chris Zankel173d66812006-12-10 02:18:48 -0800479 ___invalidate_dcache_all a2 a3
Chris Zankel3f65ce42005-06-23 22:01:24 -0700480 dsync
Chris Zankel3f65ce42005-06-23 22:01:24 -0700481
482 retw
483
Chris Zankeld1538c42012-11-16 16:16:20 -0800484ENDPROC(__invalidate_dcache_all)