Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/parisc/kernel/pacache.S
10817 views
1
/*
2
* PARISC TLB and cache flushing support
3
* Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
4
* Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
5
* Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2, or (at your option)
10
* any later version.
11
*
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
*
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
*/
21
22
/*
23
* NOTE: fdc,fic, and pdc instructions that use base register modification
24
* should only use index and base registers that are not shadowed,
25
* so that the fast path emulation in the non access miss handler
26
* can be used.
27
*/
28
29
#ifdef CONFIG_64BIT
30
.level 2.0w
31
#else
32
.level 2.0
33
#endif
34
35
#include <asm/psw.h>
36
#include <asm/assembly.h>
37
#include <asm/pgtable.h>
38
#include <asm/cache.h>
39
#include <linux/linkage.h>
40
41
.text
42
.align 128
43
44
ENTRY(flush_tlb_all_local)
45
.proc
46
.callinfo NO_CALLS
47
.entry
48
49
/*
50
* The pitlbe and pdtlbe instructions should only be used to
51
* flush the entire tlb. Also, there needs to be no intervening
52
* tlb operations, e.g. tlb misses, so the operation needs
53
* to happen in real mode with all interruptions disabled.
54
*/
55
56
/* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */
57
rsm PSW_SM_I, %r19 /* save I-bit state */
58
load32 PA(1f), %r1
59
nop
60
nop
61
nop
62
nop
63
nop
64
65
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
66
mtctl %r0, %cr17 /* Clear IIASQ tail */
67
mtctl %r0, %cr17 /* Clear IIASQ head */
68
mtctl %r1, %cr18 /* IIAOQ head */
69
ldo 4(%r1), %r1
70
mtctl %r1, %cr18 /* IIAOQ tail */
71
load32 REAL_MODE_PSW, %r1
72
mtctl %r1, %ipsw
73
rfi
74
nop
75
76
1: load32 PA(cache_info), %r1
77
78
/* Flush Instruction Tlb */
79
80
LDREG ITLB_SID_BASE(%r1), %r20
81
LDREG ITLB_SID_STRIDE(%r1), %r21
82
LDREG ITLB_SID_COUNT(%r1), %r22
83
LDREG ITLB_OFF_BASE(%r1), %arg0
84
LDREG ITLB_OFF_STRIDE(%r1), %arg1
85
LDREG ITLB_OFF_COUNT(%r1), %arg2
86
LDREG ITLB_LOOP(%r1), %arg3
87
88
addib,COND(=) -1, %arg3, fitoneloop /* Preadjust and test */
89
movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */
90
copy %arg0, %r28 /* Init base addr */
91
92
fitmanyloop: /* Loop if LOOP >= 2 */
93
mtsp %r20, %sr1
94
add %r21, %r20, %r20 /* increment space */
95
copy %arg2, %r29 /* Init middle loop count */
96
97
fitmanymiddle: /* Loop if LOOP >= 2 */
98
addib,COND(>) -1, %r31, fitmanymiddle /* Adjusted inner loop decr */
99
pitlbe 0(%sr1, %r28)
100
pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */
101
addib,COND(>) -1, %r29, fitmanymiddle /* Middle loop decr */
102
copy %arg3, %r31 /* Re-init inner loop count */
103
104
movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */
105
addib,COND(<=),n -1, %r22, fitdone /* Outer loop count decr */
106
107
fitoneloop: /* Loop if LOOP = 1 */
108
mtsp %r20, %sr1
109
copy %arg0, %r28 /* init base addr */
110
copy %arg2, %r29 /* init middle loop count */
111
112
fitonemiddle: /* Loop if LOOP = 1 */
113
addib,COND(>) -1, %r29, fitonemiddle /* Middle loop count decr */
114
pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */
115
116
addib,COND(>) -1, %r22, fitoneloop /* Outer loop count decr */
117
add %r21, %r20, %r20 /* increment space */
118
119
fitdone:
120
121
/* Flush Data Tlb */
122
123
LDREG DTLB_SID_BASE(%r1), %r20
124
LDREG DTLB_SID_STRIDE(%r1), %r21
125
LDREG DTLB_SID_COUNT(%r1), %r22
126
LDREG DTLB_OFF_BASE(%r1), %arg0
127
LDREG DTLB_OFF_STRIDE(%r1), %arg1
128
LDREG DTLB_OFF_COUNT(%r1), %arg2
129
LDREG DTLB_LOOP(%r1), %arg3
130
131
addib,COND(=) -1, %arg3, fdtoneloop /* Preadjust and test */
132
movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */
133
copy %arg0, %r28 /* Init base addr */
134
135
fdtmanyloop: /* Loop if LOOP >= 2 */
136
mtsp %r20, %sr1
137
add %r21, %r20, %r20 /* increment space */
138
copy %arg2, %r29 /* Init middle loop count */
139
140
fdtmanymiddle: /* Loop if LOOP >= 2 */
141
addib,COND(>) -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */
142
pdtlbe 0(%sr1, %r28)
143
pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */
144
addib,COND(>) -1, %r29, fdtmanymiddle /* Middle loop decr */
145
copy %arg3, %r31 /* Re-init inner loop count */
146
147
movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */
148
addib,COND(<=),n -1, %r22,fdtdone /* Outer loop count decr */
149
150
fdtoneloop: /* Loop if LOOP = 1 */
151
mtsp %r20, %sr1
152
copy %arg0, %r28 /* init base addr */
153
copy %arg2, %r29 /* init middle loop count */
154
155
fdtonemiddle: /* Loop if LOOP = 1 */
156
addib,COND(>) -1, %r29, fdtonemiddle /* Middle loop count decr */
157
pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */
158
159
addib,COND(>) -1, %r22, fdtoneloop /* Outer loop count decr */
160
add %r21, %r20, %r20 /* increment space */
161
162
163
fdtdone:
164
/*
165
* Switch back to virtual mode
166
*/
167
/* pcxt_ssm_bug */
168
rsm PSW_SM_I, %r0
169
load32 2f, %r1
170
nop
171
nop
172
nop
173
nop
174
nop
175
176
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
177
mtctl %r0, %cr17 /* Clear IIASQ tail */
178
mtctl %r0, %cr17 /* Clear IIASQ head */
179
mtctl %r1, %cr18 /* IIAOQ head */
180
ldo 4(%r1), %r1
181
mtctl %r1, %cr18 /* IIAOQ tail */
182
load32 KERNEL_PSW, %r1
183
or %r1, %r19, %r1 /* I-bit to state on entry */
184
mtctl %r1, %ipsw /* restore I-bit (entire PSW) */
185
rfi
186
nop
187
188
2: bv %r0(%r2)
189
nop
190
191
.exit
192
.procend
193
ENDPROC(flush_tlb_all_local)
194
195
.import cache_info,data
196
197
ENTRY(flush_instruction_cache_local)
198
.proc
199
.callinfo NO_CALLS
200
.entry
201
202
mtsp %r0, %sr1
203
load32 cache_info, %r1
204
205
/* Flush Instruction Cache */
206
207
LDREG ICACHE_BASE(%r1), %arg0
208
LDREG ICACHE_STRIDE(%r1), %arg1
209
LDREG ICACHE_COUNT(%r1), %arg2
210
LDREG ICACHE_LOOP(%r1), %arg3
211
rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/
212
addib,COND(=) -1, %arg3, fioneloop /* Preadjust and test */
213
movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */
214
215
fimanyloop: /* Loop if LOOP >= 2 */
216
addib,COND(>) -1, %r31, fimanyloop /* Adjusted inner loop decr */
217
fice %r0(%sr1, %arg0)
218
fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */
219
movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */
220
addib,COND(<=),n -1, %arg2, fisync /* Outer loop decr */
221
222
fioneloop: /* Loop if LOOP = 1 */
223
addib,COND(>) -1, %arg2, fioneloop /* Outer loop count decr */
224
fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
225
226
fisync:
227
sync
228
mtsm %r22 /* restore I-bit */
229
bv %r0(%r2)
230
nop
231
.exit
232
233
.procend
234
ENDPROC(flush_instruction_cache_local)
235
236
237
.import cache_info, data
238
ENTRY(flush_data_cache_local)
239
.proc
240
.callinfo NO_CALLS
241
.entry
242
243
mtsp %r0, %sr1
244
load32 cache_info, %r1
245
246
/* Flush Data Cache */
247
248
LDREG DCACHE_BASE(%r1), %arg0
249
LDREG DCACHE_STRIDE(%r1), %arg1
250
LDREG DCACHE_COUNT(%r1), %arg2
251
LDREG DCACHE_LOOP(%r1), %arg3
252
rsm PSW_SM_I, %r22
253
addib,COND(=) -1, %arg3, fdoneloop /* Preadjust and test */
254
movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */
255
256
fdmanyloop: /* Loop if LOOP >= 2 */
257
addib,COND(>) -1, %r31, fdmanyloop /* Adjusted inner loop decr */
258
fdce %r0(%sr1, %arg0)
259
fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */
260
movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */
261
addib,COND(<=),n -1, %arg2, fdsync /* Outer loop decr */
262
263
fdoneloop: /* Loop if LOOP = 1 */
264
addib,COND(>) -1, %arg2, fdoneloop /* Outer loop count decr */
265
fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */
266
267
fdsync:
268
syncdma
269
sync
270
mtsm %r22 /* restore I-bit */
271
bv %r0(%r2)
272
nop
273
.exit
274
275
.procend
276
ENDPROC(flush_data_cache_local)
277
278
.align 16
279
280
ENTRY(copy_user_page_asm)
281
.proc
282
.callinfo NO_CALLS
283
.entry
284
285
#ifdef CONFIG_64BIT
286
/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
287
* Unroll the loop by hand and arrange insn appropriately.
288
* GCC probably can do this just as well.
289
*/
290
291
ldd 0(%r25), %r19
292
ldi (PAGE_SIZE / 128), %r1
293
294
ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */
295
ldw 128(%r25), %r0 /* prefetch 2 */
296
297
1: ldd 8(%r25), %r20
298
ldw 192(%r25), %r0 /* prefetch 3 */
299
ldw 256(%r25), %r0 /* prefetch 4 */
300
301
ldd 16(%r25), %r21
302
ldd 24(%r25), %r22
303
std %r19, 0(%r26)
304
std %r20, 8(%r26)
305
306
ldd 32(%r25), %r19
307
ldd 40(%r25), %r20
308
std %r21, 16(%r26)
309
std %r22, 24(%r26)
310
311
ldd 48(%r25), %r21
312
ldd 56(%r25), %r22
313
std %r19, 32(%r26)
314
std %r20, 40(%r26)
315
316
ldd 64(%r25), %r19
317
ldd 72(%r25), %r20
318
std %r21, 48(%r26)
319
std %r22, 56(%r26)
320
321
ldd 80(%r25), %r21
322
ldd 88(%r25), %r22
323
std %r19, 64(%r26)
324
std %r20, 72(%r26)
325
326
ldd 96(%r25), %r19
327
ldd 104(%r25), %r20
328
std %r21, 80(%r26)
329
std %r22, 88(%r26)
330
331
ldd 112(%r25), %r21
332
ldd 120(%r25), %r22
333
std %r19, 96(%r26)
334
std %r20, 104(%r26)
335
336
ldo 128(%r25), %r25
337
std %r21, 112(%r26)
338
std %r22, 120(%r26)
339
ldo 128(%r26), %r26
340
341
/* conditional branches nullify on forward taken branch, and on
342
* non-taken backward branch. Note that .+4 is a backwards branch.
343
* The ldd should only get executed if the branch is taken.
344
*/
345
addib,COND(>),n -1, %r1, 1b /* bundle 10 */
346
ldd 0(%r25), %r19 /* start next loads */
347
348
#else
349
350
/*
351
* This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
352
* bundles (very restricted rules for bundling).
353
* Note that until (if) we start saving
354
* the full 64 bit register values on interrupt, we can't
355
* use ldd/std on a 32 bit kernel.
356
*/
357
ldw 0(%r25), %r19
358
ldi (PAGE_SIZE / 64), %r1
359
360
1:
361
ldw 4(%r25), %r20
362
ldw 8(%r25), %r21
363
ldw 12(%r25), %r22
364
stw %r19, 0(%r26)
365
stw %r20, 4(%r26)
366
stw %r21, 8(%r26)
367
stw %r22, 12(%r26)
368
ldw 16(%r25), %r19
369
ldw 20(%r25), %r20
370
ldw 24(%r25), %r21
371
ldw 28(%r25), %r22
372
stw %r19, 16(%r26)
373
stw %r20, 20(%r26)
374
stw %r21, 24(%r26)
375
stw %r22, 28(%r26)
376
ldw 32(%r25), %r19
377
ldw 36(%r25), %r20
378
ldw 40(%r25), %r21
379
ldw 44(%r25), %r22
380
stw %r19, 32(%r26)
381
stw %r20, 36(%r26)
382
stw %r21, 40(%r26)
383
stw %r22, 44(%r26)
384
ldw 48(%r25), %r19
385
ldw 52(%r25), %r20
386
ldw 56(%r25), %r21
387
ldw 60(%r25), %r22
388
stw %r19, 48(%r26)
389
stw %r20, 52(%r26)
390
ldo 64(%r25), %r25
391
stw %r21, 56(%r26)
392
stw %r22, 60(%r26)
393
ldo 64(%r26), %r26
394
addib,COND(>),n -1, %r1, 1b
395
ldw 0(%r25), %r19
396
#endif
397
bv %r0(%r2)
398
nop
399
.exit
400
401
.procend
402
ENDPROC(copy_user_page_asm)
403
404
/*
405
* NOTE: Code in clear_user_page has a hard coded dependency on the
406
* maximum alias boundary being 4 Mb. We've been assured by the
407
* parisc chip designers that there will not ever be a parisc
408
* chip with a larger alias boundary (Never say never :-) ).
409
*
410
* Subtle: the dtlb miss handlers support the temp alias region by
411
* "knowing" that if a dtlb miss happens within the temp alias
412
* region it must have occurred while in clear_user_page. Since
413
* this routine makes use of processor local translations, we
414
* don't want to insert them into the kernel page table. Instead,
415
* we load up some general registers (they need to be registers
416
* which aren't shadowed) with the physical page numbers (preshifted
417
* for tlb insertion) needed to insert the translations. When we
418
* miss on the translation, the dtlb miss handler inserts the
419
* translation into the tlb using these values:
420
*
421
* %r26 physical page (shifted for tlb insert) of "to" translation
422
* %r23 physical page (shifted for tlb insert) of "from" translation
423
*/
424
425
#if 0
426
427
/*
428
* We can't do this since copy_user_page is used to bring in
429
* file data that might have instructions. Since the data would
430
* then need to be flushed out so the i-fetch can see it, it
431
* makes more sense to just copy through the kernel translation
432
* and flush it.
433
*
434
* I'm still keeping this around because it may be possible to
435
* use it if more information is passed into copy_user_page().
436
* Have to do some measurements to see if it is worthwhile to
437
* lobby for such a change.
438
*/
439
440
ENTRY(copy_user_page_asm)
441
.proc
442
.callinfo NO_CALLS
443
.entry
444
445
ldil L%(__PAGE_OFFSET), %r1
446
sub %r26, %r1, %r26
447
sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */
448
449
ldil L%(TMPALIAS_MAP_START), %r28
450
/* FIXME for different page sizes != 4k */
451
#ifdef CONFIG_64BIT
452
extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */
453
extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */
454
depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */
455
depdi 0, 63,12, %r28 /* Clear any offset bits */
456
copy %r28, %r29
457
depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */
458
#else
459
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
460
extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */
461
depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */
462
depwi 0, 31,12, %r28 /* Clear any offset bits */
463
copy %r28, %r29
464
depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */
465
#endif
466
467
/* Purge any old translations */
468
469
pdtlb 0(%r28)
470
pdtlb 0(%r29)
471
472
ldi 64, %r1
473
474
/*
475
* This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
476
* bundles (very restricted rules for bundling). It probably
477
* does OK on PCXU and better, but we could do better with
478
* ldd/std instructions. Note that until (if) we start saving
479
* the full 64 bit register values on interrupt, we can't
480
* use ldd/std on a 32 bit kernel.
481
*/
482
483
484
1:
485
ldw 0(%r29), %r19
486
ldw 4(%r29), %r20
487
ldw 8(%r29), %r21
488
ldw 12(%r29), %r22
489
stw %r19, 0(%r28)
490
stw %r20, 4(%r28)
491
stw %r21, 8(%r28)
492
stw %r22, 12(%r28)
493
ldw 16(%r29), %r19
494
ldw 20(%r29), %r20
495
ldw 24(%r29), %r21
496
ldw 28(%r29), %r22
497
stw %r19, 16(%r28)
498
stw %r20, 20(%r28)
499
stw %r21, 24(%r28)
500
stw %r22, 28(%r28)
501
ldw 32(%r29), %r19
502
ldw 36(%r29), %r20
503
ldw 40(%r29), %r21
504
ldw 44(%r29), %r22
505
stw %r19, 32(%r28)
506
stw %r20, 36(%r28)
507
stw %r21, 40(%r28)
508
stw %r22, 44(%r28)
509
ldw 48(%r29), %r19
510
ldw 52(%r29), %r20
511
ldw 56(%r29), %r21
512
ldw 60(%r29), %r22
513
stw %r19, 48(%r28)
514
stw %r20, 52(%r28)
515
stw %r21, 56(%r28)
516
stw %r22, 60(%r28)
517
ldo 64(%r28), %r28
518
addib,COND(>) -1, %r1,1b
519
ldo 64(%r29), %r29
520
521
bv %r0(%r2)
522
nop
523
.exit
524
525
.procend
526
ENDPROC(copy_user_page_asm)
527
#endif
528
529
ENTRY(__clear_user_page_asm)
530
.proc
531
.callinfo NO_CALLS
532
.entry
533
534
tophys_r1 %r26
535
536
ldil L%(TMPALIAS_MAP_START), %r28
537
#ifdef CONFIG_64BIT
538
#if (TMPALIAS_MAP_START >= 0x80000000)
539
depdi 0, 31,32, %r28 /* clear any sign extension */
540
/* FIXME: page size dependend */
541
#endif
542
extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
543
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
544
depdi 0, 63,12, %r28 /* Clear any offset bits */
545
#else
546
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
547
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
548
depwi 0, 31,12, %r28 /* Clear any offset bits */
549
#endif
550
551
/* Purge any old translation */
552
553
pdtlb 0(%r28)
554
555
#ifdef CONFIG_64BIT
556
ldi (PAGE_SIZE / 128), %r1
557
558
/* PREFETCH (Write) has not (yet) been proven to help here */
559
/* #define PREFETCHW_OP ldd 256(%0), %r0 */
560
561
1: std %r0, 0(%r28)
562
std %r0, 8(%r28)
563
std %r0, 16(%r28)
564
std %r0, 24(%r28)
565
std %r0, 32(%r28)
566
std %r0, 40(%r28)
567
std %r0, 48(%r28)
568
std %r0, 56(%r28)
569
std %r0, 64(%r28)
570
std %r0, 72(%r28)
571
std %r0, 80(%r28)
572
std %r0, 88(%r28)
573
std %r0, 96(%r28)
574
std %r0, 104(%r28)
575
std %r0, 112(%r28)
576
std %r0, 120(%r28)
577
addib,COND(>) -1, %r1, 1b
578
ldo 128(%r28), %r28
579
580
#else /* ! CONFIG_64BIT */
581
ldi (PAGE_SIZE / 64), %r1
582
583
1:
584
stw %r0, 0(%r28)
585
stw %r0, 4(%r28)
586
stw %r0, 8(%r28)
587
stw %r0, 12(%r28)
588
stw %r0, 16(%r28)
589
stw %r0, 20(%r28)
590
stw %r0, 24(%r28)
591
stw %r0, 28(%r28)
592
stw %r0, 32(%r28)
593
stw %r0, 36(%r28)
594
stw %r0, 40(%r28)
595
stw %r0, 44(%r28)
596
stw %r0, 48(%r28)
597
stw %r0, 52(%r28)
598
stw %r0, 56(%r28)
599
stw %r0, 60(%r28)
600
addib,COND(>) -1, %r1, 1b
601
ldo 64(%r28), %r28
602
#endif /* CONFIG_64BIT */
603
604
bv %r0(%r2)
605
nop
606
.exit
607
608
.procend
609
ENDPROC(__clear_user_page_asm)
610
611
ENTRY(flush_dcache_page_asm)
612
.proc
613
.callinfo NO_CALLS
614
.entry
615
616
ldil L%(TMPALIAS_MAP_START), %r28
617
#ifdef CONFIG_64BIT
618
#if (TMPALIAS_MAP_START >= 0x80000000)
619
depdi 0, 31,32, %r28 /* clear any sign extension */
620
/* FIXME: page size dependend */
621
#endif
622
extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
623
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
624
depdi 0, 63,12, %r28 /* Clear any offset bits */
625
#else
626
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
627
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
628
depwi 0, 31,12, %r28 /* Clear any offset bits */
629
#endif
630
631
/* Purge any old translation */
632
633
pdtlb 0(%r28)
634
635
ldil L%dcache_stride, %r1
636
ldw R%dcache_stride(%r1), %r1
637
638
#ifdef CONFIG_64BIT
639
depdi,z 1, 63-PAGE_SHIFT,1, %r25
640
#else
641
depwi,z 1, 31-PAGE_SHIFT,1, %r25
642
#endif
643
add %r28, %r25, %r25
644
sub %r25, %r1, %r25
645
646
647
1: fdc,m %r1(%r28)
648
fdc,m %r1(%r28)
649
fdc,m %r1(%r28)
650
fdc,m %r1(%r28)
651
fdc,m %r1(%r28)
652
fdc,m %r1(%r28)
653
fdc,m %r1(%r28)
654
fdc,m %r1(%r28)
655
fdc,m %r1(%r28)
656
fdc,m %r1(%r28)
657
fdc,m %r1(%r28)
658
fdc,m %r1(%r28)
659
fdc,m %r1(%r28)
660
fdc,m %r1(%r28)
661
fdc,m %r1(%r28)
662
cmpb,COND(<<) %r28, %r25,1b
663
fdc,m %r1(%r28)
664
665
sync
666
bv %r0(%r2)
667
pdtlb (%r25)
668
.exit
669
670
.procend
671
ENDPROC(flush_dcache_page_asm)
672
673
ENTRY(flush_icache_page_asm)
674
.proc
675
.callinfo NO_CALLS
676
.entry
677
678
ldil L%(TMPALIAS_MAP_START), %r28
679
#ifdef CONFIG_64BIT
680
#if (TMPALIAS_MAP_START >= 0x80000000)
681
depdi 0, 31,32, %r28 /* clear any sign extension */
682
/* FIXME: page size dependend */
683
#endif
684
extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
685
depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
686
depdi 0, 63,12, %r28 /* Clear any offset bits */
687
#else
688
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
689
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
690
depwi 0, 31,12, %r28 /* Clear any offset bits */
691
#endif
692
693
/* Purge any old translation */
694
695
pitlb (%sr0,%r28)
696
697
ldil L%icache_stride, %r1
698
ldw R%icache_stride(%r1), %r1
699
700
#ifdef CONFIG_64BIT
701
depdi,z 1, 63-PAGE_SHIFT,1, %r25
702
#else
703
depwi,z 1, 31-PAGE_SHIFT,1, %r25
704
#endif
705
add %r28, %r25, %r25
706
sub %r25, %r1, %r25
707
708
709
1: fic,m %r1(%r28)
710
fic,m %r1(%r28)
711
fic,m %r1(%r28)
712
fic,m %r1(%r28)
713
fic,m %r1(%r28)
714
fic,m %r1(%r28)
715
fic,m %r1(%r28)
716
fic,m %r1(%r28)
717
fic,m %r1(%r28)
718
fic,m %r1(%r28)
719
fic,m %r1(%r28)
720
fic,m %r1(%r28)
721
fic,m %r1(%r28)
722
fic,m %r1(%r28)
723
fic,m %r1(%r28)
724
cmpb,COND(<<) %r28, %r25,1b
725
fic,m %r1(%r28)
726
727
sync
728
bv %r0(%r2)
729
pitlb (%sr0,%r25)
730
.exit
731
732
.procend
733
ENDPROC(flush_icache_page_asm)
734
735
ENTRY(flush_kernel_dcache_page_asm)
736
.proc
737
.callinfo NO_CALLS
738
.entry
739
740
ldil L%dcache_stride, %r1
741
ldw R%dcache_stride(%r1), %r23
742
743
#ifdef CONFIG_64BIT
744
depdi,z 1, 63-PAGE_SHIFT,1, %r25
745
#else
746
depwi,z 1, 31-PAGE_SHIFT,1, %r25
747
#endif
748
add %r26, %r25, %r25
749
sub %r25, %r23, %r25
750
751
752
1: fdc,m %r23(%r26)
753
fdc,m %r23(%r26)
754
fdc,m %r23(%r26)
755
fdc,m %r23(%r26)
756
fdc,m %r23(%r26)
757
fdc,m %r23(%r26)
758
fdc,m %r23(%r26)
759
fdc,m %r23(%r26)
760
fdc,m %r23(%r26)
761
fdc,m %r23(%r26)
762
fdc,m %r23(%r26)
763
fdc,m %r23(%r26)
764
fdc,m %r23(%r26)
765
fdc,m %r23(%r26)
766
fdc,m %r23(%r26)
767
cmpb,COND(<<) %r26, %r25,1b
768
fdc,m %r23(%r26)
769
770
sync
771
bv %r0(%r2)
772
nop
773
.exit
774
775
.procend
776
ENDPROC(flush_kernel_dcache_page_asm)
777
778
ENTRY(purge_kernel_dcache_page)
779
.proc
780
.callinfo NO_CALLS
781
.entry
782
783
ldil L%dcache_stride, %r1
784
ldw R%dcache_stride(%r1), %r23
785
786
#ifdef CONFIG_64BIT
787
depdi,z 1, 63-PAGE_SHIFT,1, %r25
788
#else
789
depwi,z 1, 31-PAGE_SHIFT,1, %r25
790
#endif
791
add %r26, %r25, %r25
792
sub %r25, %r23, %r25
793
794
1: pdc,m %r23(%r26)
795
pdc,m %r23(%r26)
796
pdc,m %r23(%r26)
797
pdc,m %r23(%r26)
798
pdc,m %r23(%r26)
799
pdc,m %r23(%r26)
800
pdc,m %r23(%r26)
801
pdc,m %r23(%r26)
802
pdc,m %r23(%r26)
803
pdc,m %r23(%r26)
804
pdc,m %r23(%r26)
805
pdc,m %r23(%r26)
806
pdc,m %r23(%r26)
807
pdc,m %r23(%r26)
808
pdc,m %r23(%r26)
809
cmpb,COND(<<) %r26, %r25, 1b
810
pdc,m %r23(%r26)
811
812
sync
813
bv %r0(%r2)
814
nop
815
.exit
816
817
.procend
818
ENDPROC(purge_kernel_dcache_page)
819
820
ENTRY(flush_user_dcache_range_asm)
821
.proc
822
.callinfo NO_CALLS
823
.entry
824
825
ldil L%dcache_stride, %r1
826
ldw R%dcache_stride(%r1), %r23
827
ldo -1(%r23), %r21
828
ANDCM %r26, %r21, %r26
829
830
1: cmpb,COND(<<),n %r26, %r25, 1b
831
fdc,m %r23(%sr3, %r26)
832
833
sync
834
bv %r0(%r2)
835
nop
836
.exit
837
838
.procend
839
ENDPROC(flush_user_dcache_range_asm)
840
841
ENTRY(flush_kernel_dcache_range_asm)
842
.proc
843
.callinfo NO_CALLS
844
.entry
845
846
ldil L%dcache_stride, %r1
847
ldw R%dcache_stride(%r1), %r23
848
ldo -1(%r23), %r21
849
ANDCM %r26, %r21, %r26
850
851
1: cmpb,COND(<<),n %r26, %r25,1b
852
fdc,m %r23(%r26)
853
854
sync
855
syncdma
856
bv %r0(%r2)
857
nop
858
.exit
859
860
.procend
861
ENDPROC(flush_kernel_dcache_range_asm)
862
863
ENTRY(flush_user_icache_range_asm)
864
.proc
865
.callinfo NO_CALLS
866
.entry
867
868
ldil L%icache_stride, %r1
869
ldw R%icache_stride(%r1), %r23
870
ldo -1(%r23), %r21
871
ANDCM %r26, %r21, %r26
872
873
1: cmpb,COND(<<),n %r26, %r25,1b
874
fic,m %r23(%sr3, %r26)
875
876
sync
877
bv %r0(%r2)
878
nop
879
.exit
880
881
.procend
882
ENDPROC(flush_user_icache_range_asm)
883
884
ENTRY(flush_kernel_icache_page)
885
.proc
886
.callinfo NO_CALLS
887
.entry
888
889
ldil L%icache_stride, %r1
890
ldw R%icache_stride(%r1), %r23
891
892
#ifdef CONFIG_64BIT
893
depdi,z 1, 63-PAGE_SHIFT,1, %r25
894
#else
895
depwi,z 1, 31-PAGE_SHIFT,1, %r25
896
#endif
897
add %r26, %r25, %r25
898
sub %r25, %r23, %r25
899
900
901
1: fic,m %r23(%sr4, %r26)
902
fic,m %r23(%sr4, %r26)
903
fic,m %r23(%sr4, %r26)
904
fic,m %r23(%sr4, %r26)
905
fic,m %r23(%sr4, %r26)
906
fic,m %r23(%sr4, %r26)
907
fic,m %r23(%sr4, %r26)
908
fic,m %r23(%sr4, %r26)
909
fic,m %r23(%sr4, %r26)
910
fic,m %r23(%sr4, %r26)
911
fic,m %r23(%sr4, %r26)
912
fic,m %r23(%sr4, %r26)
913
fic,m %r23(%sr4, %r26)
914
fic,m %r23(%sr4, %r26)
915
fic,m %r23(%sr4, %r26)
916
cmpb,COND(<<) %r26, %r25, 1b
917
fic,m %r23(%sr4, %r26)
918
919
sync
920
bv %r0(%r2)
921
nop
922
.exit
923
924
.procend
925
ENDPROC(flush_kernel_icache_page)
926
927
ENTRY(flush_kernel_icache_range_asm)
928
.proc
929
.callinfo NO_CALLS
930
.entry
931
932
ldil L%icache_stride, %r1
933
ldw R%icache_stride(%r1), %r23
934
ldo -1(%r23), %r21
935
ANDCM %r26, %r21, %r26
936
937
1: cmpb,COND(<<),n %r26, %r25, 1b
938
fic,m %r23(%sr4, %r26)
939
940
sync
941
bv %r0(%r2)
942
nop
943
.exit
944
.procend
945
ENDPROC(flush_kernel_icache_range_asm)
946
947
/* align should cover use of rfi in disable_sr_hashing_asm and
948
* srdis_done.
949
*/
950
.align 256
951
ENTRY(disable_sr_hashing_asm)
952
.proc
953
.callinfo NO_CALLS
954
.entry
955
956
/*
957
* Switch to real mode
958
*/
959
/* pcxt_ssm_bug */
960
rsm PSW_SM_I, %r0
961
load32 PA(1f), %r1
962
nop
963
nop
964
nop
965
nop
966
nop
967
968
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
969
mtctl %r0, %cr17 /* Clear IIASQ tail */
970
mtctl %r0, %cr17 /* Clear IIASQ head */
971
mtctl %r1, %cr18 /* IIAOQ head */
972
ldo 4(%r1), %r1
973
mtctl %r1, %cr18 /* IIAOQ tail */
974
load32 REAL_MODE_PSW, %r1
975
mtctl %r1, %ipsw
976
rfi
977
nop
978
979
1: cmpib,=,n SRHASH_PCXST, %r26,srdis_pcxs
980
cmpib,=,n SRHASH_PCXL, %r26,srdis_pcxl
981
cmpib,=,n SRHASH_PA20, %r26,srdis_pa20
982
b,n srdis_done
983
984
srdis_pcxs:
985
986
/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
987
988
.word 0x141c1a00 /* mfdiag %dr0, %r28 */
989
.word 0x141c1a00 /* must issue twice */
990
depwi 0,18,1, %r28 /* Clear DHE (dcache hash enable) */
991
depwi 0,20,1, %r28 /* Clear IHE (icache hash enable) */
992
.word 0x141c1600 /* mtdiag %r28, %dr0 */
993
.word 0x141c1600 /* must issue twice */
994
b,n srdis_done
995
996
srdis_pcxl:
997
998
/* Disable Space Register Hashing for PCXL */
999
1000
.word 0x141c0600 /* mfdiag %dr0, %r28 */
1001
depwi 0,28,2, %r28 /* Clear DHASH_EN & IHASH_EN */
1002
.word 0x141c0240 /* mtdiag %r28, %dr0 */
1003
b,n srdis_done
1004
1005
srdis_pa20:
1006
1007
/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
1008
1009
.word 0x144008bc /* mfdiag %dr2, %r28 */
1010
depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
1011
.word 0x145c1840 /* mtdiag %r28, %dr2 */
1012
1013
1014
srdis_done:
1015
/* Switch back to virtual mode */
1016
rsm PSW_SM_I, %r0 /* prep to load iia queue */
1017
load32 2f, %r1
1018
nop
1019
nop
1020
nop
1021
nop
1022
nop
1023
1024
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
1025
mtctl %r0, %cr17 /* Clear IIASQ tail */
1026
mtctl %r0, %cr17 /* Clear IIASQ head */
1027
mtctl %r1, %cr18 /* IIAOQ head */
1028
ldo 4(%r1), %r1
1029
mtctl %r1, %cr18 /* IIAOQ tail */
1030
load32 KERNEL_PSW, %r1
1031
mtctl %r1, %ipsw
1032
rfi
1033
nop
1034
1035
2: bv %r0(%r2)
1036
nop
1037
.exit
1038
1039
.procend
1040
ENDPROC(disable_sr_hashing_asm)
1041
1042
.end
1043
1044