Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/xtensa/mm/misc.S
26424 views
1
/*
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
*
10
* Copyright (C) 2001 - 2007 Tensilica Inc.
11
*
12
* Chris Zankel <[email protected]>
13
*/
14
15
16
#include <linux/linkage.h>
17
#include <linux/pgtable.h>
18
#include <asm/page.h>
19
#include <asm/asmmacro.h>
20
#include <asm/cacheasm.h>
21
#include <asm/tlbflush.h>
22
23
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
*/
30
31
ENTRY(clear_page)
32
33
abi_entry_default
34
35
movi a3, 0
36
__loopi a2, a7, PAGE_SIZE, 32
37
s32i a3, a2, 0
38
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
45
__endla a2, a7, 32
46
47
abi_ret_default
48
49
ENDPROC(clear_page)
50
EXPORT_SYMBOL(clear_page)
51
52
/*
53
* copy_page and copy_user_page are the same for non-cache-aliased configs.
54
*
55
* copy_page (void *to, void *from)
56
* a2 a3
57
*/
58
59
ENTRY(copy_page)
60
61
abi_entry_default
62
63
__loopi a2, a4, PAGE_SIZE, 32
64
65
l32i a8, a3, 0
66
l32i a9, a3, 4
67
s32i a8, a2, 0
68
s32i a9, a2, 4
69
70
l32i a8, a3, 8
71
l32i a9, a3, 12
72
s32i a8, a2, 8
73
s32i a9, a2, 12
74
75
l32i a8, a3, 16
76
l32i a9, a3, 20
77
s32i a8, a2, 16
78
s32i a9, a2, 20
79
80
l32i a8, a3, 24
81
l32i a9, a3, 28
82
s32i a8, a2, 24
83
s32i a9, a2, 28
84
85
addi a2, a2, 32
86
addi a3, a3, 32
87
88
__endl a2, a4
89
90
abi_ret_default
91
92
ENDPROC(copy_page)
93
EXPORT_SYMBOL(copy_page)
94
95
#ifdef CONFIG_MMU
96
/*
97
* If we have to deal with cache aliasing, we use temporary memory mappings
98
* to ensure that the source and destination pages have the same color as
99
* the virtual address. We use way 0 and 1 for temporary mappings in such cases.
100
*
101
* The temporary DTLB entries shouldn't be flushed by interrupts, but are
102
* flushed by preemptive task switches. Special code in the
103
* fast_second_level_miss handler re-established the temporary mapping.
104
* It requires that the PPNs for the destination and source addresses are
105
* in a6, and a7, respectively.
106
*/
107
108
/* TLB miss exceptions are treated special in the following region */
109
110
ENTRY(__tlbtemp_mapping_start)
111
112
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
113
114
/*
115
* clear_page_alias(void *addr, unsigned long paddr)
116
* a2 a3
117
*/
118
119
ENTRY(clear_page_alias)
120
121
abi_entry_default
122
123
movi a5, PAGE_OFFSET
124
addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
125
mov a4, a2
126
wdtlb a6, a2
127
dsync
128
129
movi a3, 0
130
__loopi a2, a7, PAGE_SIZE, 32
131
s32i a3, a2, 0
132
s32i a3, a2, 4
133
s32i a3, a2, 8
134
s32i a3, a2, 12
135
s32i a3, a2, 16
136
s32i a3, a2, 20
137
s32i a3, a2, 24
138
s32i a3, a2, 28
139
__endla a2, a7, 32
140
141
/* We need to invalidate the temporary dtlb entry. */
142
143
idtlb a4
144
dsync
145
146
abi_ret_default
147
148
ENDPROC(clear_page_alias)
149
150
/*
151
* copy_page_alias(void *to, void *from,
152
* a2 a3
153
* unsigned long to_paddr, unsigned long from_paddr)
154
* a4 a5
155
*/
156
157
ENTRY(copy_page_alias)
158
159
abi_entry_default
160
161
/* Setup a temporary DTLB for destination. */
162
163
addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE)
164
wdtlb a6, a2
165
dsync
166
167
/* Setup a temporary DTLB for source. */
168
169
addi a7, a5, PAGE_KERNEL
170
addi a8, a3, 1 # way1
171
172
wdtlb a7, a8
173
dsync
174
175
1: __loopi a2, a4, PAGE_SIZE, 32
176
177
l32i a8, a3, 0
178
l32i a9, a3, 4
179
s32i a8, a2, 0
180
s32i a9, a2, 4
181
182
l32i a8, a3, 8
183
l32i a9, a3, 12
184
s32i a8, a2, 8
185
s32i a9, a2, 12
186
187
l32i a8, a3, 16
188
l32i a9, a3, 20
189
s32i a8, a2, 16
190
s32i a9, a2, 20
191
192
l32i a8, a3, 24
193
l32i a9, a3, 28
194
s32i a8, a2, 24
195
s32i a9, a2, 28
196
197
addi a2, a2, 32
198
addi a3, a3, 32
199
200
__endl a2, a4
201
202
/* We need to invalidate any temporary mapping! */
203
204
addi a2, a2, -PAGE_SIZE
205
idtlb a2
206
dsync
207
208
addi a3, a3, -PAGE_SIZE+1
209
idtlb a3
210
dsync
211
212
abi_ret_default
213
214
ENDPROC(copy_page_alias)
215
216
#endif
217
218
#if (DCACHE_WAY_SIZE > PAGE_SIZE)
219
220
/*
221
* void __flush_invalidate_dcache_page_alias (addr, phys)
222
* a2 a3
223
*/
224
225
ENTRY(__flush_invalidate_dcache_page_alias)
226
227
abi_entry_default
228
229
movi a7, 0 # required for exception handler
230
addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE)
231
mov a4, a2
232
wdtlb a6, a2
233
dsync
234
235
___flush_invalidate_dcache_page a2 a3
236
237
idtlb a4
238
dsync
239
240
abi_ret_default
241
242
ENDPROC(__flush_invalidate_dcache_page_alias)
243
244
/*
245
* void __invalidate_dcache_page_alias (addr, phys)
246
* a2 a3
247
*/
248
249
ENTRY(__invalidate_dcache_page_alias)
250
251
abi_entry_default
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
___invalidate_dcache_page a2 a3
260
261
idtlb a4
262
dsync
263
264
abi_ret_default
265
266
ENDPROC(__invalidate_dcache_page_alias)
267
#endif
268
269
ENTRY(__tlbtemp_mapping_itlb)
270
271
#if (ICACHE_WAY_SIZE > PAGE_SIZE)
272
273
ENTRY(__invalidate_icache_page_alias)
274
275
abi_entry_default
276
277
addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE)
278
mov a4, a2
279
witlb a6, a2
280
isync
281
282
___invalidate_icache_page a2 a3
283
284
iitlb a4
285
isync
286
abi_ret_default
287
288
ENDPROC(__invalidate_icache_page_alias)
289
290
#endif
291
292
/* End of special treatment in tlb miss exception */
293
294
ENTRY(__tlbtemp_mapping_end)
295
296
#endif /* CONFIG_MMU
297
298
/*
299
* void __invalidate_icache_page(ulong start)
300
*/
301
302
ENTRY(__invalidate_icache_page)
303
304
abi_entry_default
305
306
___invalidate_icache_page a2 a3
307
isync
308
309
abi_ret_default
310
311
ENDPROC(__invalidate_icache_page)
312
313
/*
314
* void __invalidate_dcache_page(ulong start)
315
*/
316
317
ENTRY(__invalidate_dcache_page)
318
319
abi_entry_default
320
321
___invalidate_dcache_page a2 a3
322
dsync
323
324
abi_ret_default
325
326
ENDPROC(__invalidate_dcache_page)
327
328
/*
329
* void __flush_invalidate_dcache_page(ulong start)
330
*/
331
332
ENTRY(__flush_invalidate_dcache_page)
333
334
abi_entry_default
335
336
___flush_invalidate_dcache_page a2 a3
337
338
dsync
339
abi_ret_default
340
341
ENDPROC(__flush_invalidate_dcache_page)
342
343
/*
344
* void __flush_dcache_page(ulong start)
345
*/
346
347
ENTRY(__flush_dcache_page)
348
349
abi_entry_default
350
351
___flush_dcache_page a2 a3
352
353
dsync
354
abi_ret_default
355
356
ENDPROC(__flush_dcache_page)
357
358
/*
359
* void __invalidate_icache_range(ulong start, ulong size)
360
*/
361
362
ENTRY(__invalidate_icache_range)
363
364
abi_entry_default
365
366
___invalidate_icache_range a2 a3 a4
367
isync
368
369
abi_ret_default
370
371
ENDPROC(__invalidate_icache_range)
372
EXPORT_SYMBOL(__invalidate_icache_range)
373
374
/*
375
* void __flush_invalidate_dcache_range(ulong start, ulong size)
376
*/
377
378
ENTRY(__flush_invalidate_dcache_range)
379
380
abi_entry_default
381
382
___flush_invalidate_dcache_range a2 a3 a4
383
dsync
384
385
abi_ret_default
386
387
ENDPROC(__flush_invalidate_dcache_range)
388
389
/*
390
* void _flush_dcache_range(ulong start, ulong size)
391
*/
392
393
ENTRY(__flush_dcache_range)
394
395
abi_entry_default
396
397
___flush_dcache_range a2 a3 a4
398
dsync
399
400
abi_ret_default
401
402
ENDPROC(__flush_dcache_range)
403
EXPORT_SYMBOL(__flush_dcache_range)
404
405
/*
406
* void _invalidate_dcache_range(ulong start, ulong size)
407
*/
408
409
ENTRY(__invalidate_dcache_range)
410
411
abi_entry_default
412
413
___invalidate_dcache_range a2 a3 a4
414
415
abi_ret_default
416
417
ENDPROC(__invalidate_dcache_range)
418
EXPORT_SYMBOL(__invalidate_dcache_range)
419
420
/*
421
* void _invalidate_icache_all(void)
422
*/
423
424
ENTRY(__invalidate_icache_all)
425
426
abi_entry_default
427
428
___invalidate_icache_all a2 a3
429
isync
430
431
abi_ret_default
432
433
ENDPROC(__invalidate_icache_all)
434
435
/*
436
* void _flush_invalidate_dcache_all(void)
437
*/
438
439
ENTRY(__flush_invalidate_dcache_all)
440
441
abi_entry_default
442
443
___flush_invalidate_dcache_all a2 a3
444
dsync
445
446
abi_ret_default
447
448
ENDPROC(__flush_invalidate_dcache_all)
449
450
/*
451
* void _invalidate_dcache_all(void)
452
*/
453
454
ENTRY(__invalidate_dcache_all)
455
456
abi_entry_default
457
458
___invalidate_dcache_all a2 a3
459
dsync
460
461
abi_ret_default
462
463
ENDPROC(__invalidate_dcache_all)
464
465