Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/kernel/pacache.S
26288 views
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
2
/*
3
* PARISC TLB and cache flushing support
4
* Copyright (C) 2000-2001 Hewlett-Packard (John Marvin)
5
* Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org)
6
* Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org)
7
*/
8
9
/*
10
* NOTE: fdc,fic, and pdc instructions that use base register modification
11
* should only use index and base registers that are not shadowed,
12
* so that the fast path emulation in the non access miss handler
13
* can be used.
14
*/
15
16
#ifdef CONFIG_64BIT
17
.level 2.0w
18
#else
19
.level 2.0
20
#endif
21
22
#include <asm/psw.h>
23
#include <asm/assembly.h>
24
#include <asm/cache.h>
25
#include <asm/ldcw.h>
26
#include <asm/alternative.h>
27
#include <linux/linkage.h>
28
#include <linux/init.h>
29
#include <linux/pgtable.h>
30
31
.section .text.hot
32
.align 16
33
34
ENTRY_CFI(flush_tlb_all_local)
35
/*
36
* The pitlbe and pdtlbe instructions should only be used to
37
* flush the entire tlb. Also, there needs to be no intervening
38
* tlb operations, e.g. tlb misses, so the operation needs
39
* to happen in real mode with all interruptions disabled.
40
*/
41
42
/* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */
43
rsm PSW_SM_I, %r19 /* save I-bit state */
44
load32 PA(1f), %r1
45
nop
46
nop
47
nop
48
nop
49
nop
50
51
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
52
mtctl %r0, %cr17 /* Clear IIASQ tail */
53
mtctl %r0, %cr17 /* Clear IIASQ head */
54
mtctl %r1, %cr18 /* IIAOQ head */
55
ldo 4(%r1), %r1
56
mtctl %r1, %cr18 /* IIAOQ tail */
57
load32 REAL_MODE_PSW, %r1
58
mtctl %r1, %ipsw
59
rfi
60
nop
61
62
1: load32 PA(cache_info), %r1
63
64
/* Flush Instruction Tlb */
65
66
88: LDREG ITLB_SID_BASE(%r1), %r20
67
LDREG ITLB_SID_STRIDE(%r1), %r21
68
LDREG ITLB_SID_COUNT(%r1), %r22
69
LDREG ITLB_OFF_BASE(%r1), %arg0
70
LDREG ITLB_OFF_STRIDE(%r1), %arg1
71
LDREG ITLB_OFF_COUNT(%r1), %arg2
72
LDREG ITLB_LOOP(%r1), %arg3
73
74
addib,COND(=) -1, %arg3, fitoneloop /* Preadjust and test */
75
movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */
76
copy %arg0, %r28 /* Init base addr */
77
78
fitmanyloop: /* Loop if LOOP >= 2 */
79
mtsp %r20, %sr1
80
add %r21, %r20, %r20 /* increment space */
81
copy %arg2, %r29 /* Init middle loop count */
82
83
fitmanymiddle: /* Loop if LOOP >= 2 */
84
addib,COND(>) -1, %r31, fitmanymiddle /* Adjusted inner loop decr */
85
pitlbe %r0(%sr1, %r28)
86
pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */
87
addib,COND(>) -1, %r29, fitmanymiddle /* Middle loop decr */
88
copy %arg3, %r31 /* Re-init inner loop count */
89
90
movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */
91
addib,COND(<=),n -1, %r22, fitdone /* Outer loop count decr */
92
93
fitoneloop: /* Loop if LOOP = 1 */
94
mtsp %r20, %sr1
95
copy %arg0, %r28 /* init base addr */
96
copy %arg2, %r29 /* init middle loop count */
97
98
fitonemiddle: /* Loop if LOOP = 1 */
99
addib,COND(>) -1, %r29, fitonemiddle /* Middle loop count decr */
100
pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */
101
102
addib,COND(>) -1, %r22, fitoneloop /* Outer loop count decr */
103
add %r21, %r20, %r20 /* increment space */
104
105
fitdone:
106
ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
107
108
/* Flush Data Tlb */
109
110
LDREG DTLB_SID_BASE(%r1), %r20
111
LDREG DTLB_SID_STRIDE(%r1), %r21
112
LDREG DTLB_SID_COUNT(%r1), %r22
113
LDREG DTLB_OFF_BASE(%r1), %arg0
114
LDREG DTLB_OFF_STRIDE(%r1), %arg1
115
LDREG DTLB_OFF_COUNT(%r1), %arg2
116
LDREG DTLB_LOOP(%r1), %arg3
117
118
addib,COND(=) -1, %arg3, fdtoneloop /* Preadjust and test */
119
movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */
120
copy %arg0, %r28 /* Init base addr */
121
122
fdtmanyloop: /* Loop if LOOP >= 2 */
123
mtsp %r20, %sr1
124
add %r21, %r20, %r20 /* increment space */
125
copy %arg2, %r29 /* Init middle loop count */
126
127
fdtmanymiddle: /* Loop if LOOP >= 2 */
128
addib,COND(>) -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */
129
pdtlbe %r0(%sr1, %r28)
130
pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */
131
addib,COND(>) -1, %r29, fdtmanymiddle /* Middle loop decr */
132
copy %arg3, %r31 /* Re-init inner loop count */
133
134
movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */
135
addib,COND(<=),n -1, %r22,fdtdone /* Outer loop count decr */
136
137
fdtoneloop: /* Loop if LOOP = 1 */
138
mtsp %r20, %sr1
139
copy %arg0, %r28 /* init base addr */
140
copy %arg2, %r29 /* init middle loop count */
141
142
fdtonemiddle: /* Loop if LOOP = 1 */
143
addib,COND(>) -1, %r29, fdtonemiddle /* Middle loop count decr */
144
pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */
145
146
addib,COND(>) -1, %r22, fdtoneloop /* Outer loop count decr */
147
add %r21, %r20, %r20 /* increment space */
148
149
150
fdtdone:
151
/*
152
* Switch back to virtual mode
153
*/
154
/* pcxt_ssm_bug */
155
rsm PSW_SM_I, %r0
156
load32 2f, %r1
157
nop
158
nop
159
nop
160
nop
161
nop
162
163
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
164
mtctl %r0, %cr17 /* Clear IIASQ tail */
165
mtctl %r0, %cr17 /* Clear IIASQ head */
166
mtctl %r1, %cr18 /* IIAOQ head */
167
ldo 4(%r1), %r1
168
mtctl %r1, %cr18 /* IIAOQ tail */
169
load32 KERNEL_PSW, %r1
170
or %r1, %r19, %r1 /* I-bit to state on entry */
171
mtctl %r1, %ipsw /* restore I-bit (entire PSW) */
172
rfi
173
nop
174
175
2: bv %r0(%r2)
176
nop
177
178
/*
179
* When running in qemu, drop whole flush_tlb_all_local function and
180
* replace by one pdtlbe instruction, for which QEMU will drop all
181
* local TLB entries.
182
*/
183
3: pdtlbe %r0(%sr1,%r0)
184
bv,n %r0(%r2)
185
ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b)
186
ENDPROC_CFI(flush_tlb_all_local)
187
188
.import cache_info,data
189
190
ENTRY_CFI(flush_instruction_cache_local)
191
88: load32 cache_info, %r1
192
193
/* Flush Instruction Cache */
194
195
LDREG ICACHE_BASE(%r1), %arg0
196
LDREG ICACHE_STRIDE(%r1), %arg1
197
LDREG ICACHE_COUNT(%r1), %arg2
198
LDREG ICACHE_LOOP(%r1), %arg3
199
rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/
200
mtsp %r0, %sr1
201
addib,COND(=) -1, %arg3, fioneloop /* Preadjust and test */
202
movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */
203
204
fimanyloop: /* Loop if LOOP >= 2 */
205
addib,COND(>) -1, %r31, fimanyloop /* Adjusted inner loop decr */
206
fice %r0(%sr1, %arg0)
207
fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */
208
movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */
209
addib,COND(<=),n -1, %arg2, fisync /* Outer loop decr */
210
211
fioneloop: /* Loop if LOOP = 1 */
212
/* Some implementations may flush with a single fice instruction */
213
cmpib,COND(>>=),n 15, %arg2, fioneloop2
214
215
fioneloop1:
216
fice,m %arg1(%sr1, %arg0)
217
fice,m %arg1(%sr1, %arg0)
218
fice,m %arg1(%sr1, %arg0)
219
fice,m %arg1(%sr1, %arg0)
220
fice,m %arg1(%sr1, %arg0)
221
fice,m %arg1(%sr1, %arg0)
222
fice,m %arg1(%sr1, %arg0)
223
fice,m %arg1(%sr1, %arg0)
224
fice,m %arg1(%sr1, %arg0)
225
fice,m %arg1(%sr1, %arg0)
226
fice,m %arg1(%sr1, %arg0)
227
fice,m %arg1(%sr1, %arg0)
228
fice,m %arg1(%sr1, %arg0)
229
fice,m %arg1(%sr1, %arg0)
230
fice,m %arg1(%sr1, %arg0)
231
addib,COND(>) -16, %arg2, fioneloop1
232
fice,m %arg1(%sr1, %arg0)
233
234
/* Check if done */
235
cmpb,COND(=),n %arg2, %r0, fisync /* Predict branch taken */
236
237
fioneloop2:
238
addib,COND(>) -1, %arg2, fioneloop2 /* Outer loop count decr */
239
fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
240
241
fisync:
242
sync
243
mtsm %r22 /* restore I-bit */
244
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
245
bv %r0(%r2)
246
nop
247
ENDPROC_CFI(flush_instruction_cache_local)
248
249
250
.import cache_info, data
251
ENTRY_CFI(flush_data_cache_local)
252
88: load32 cache_info, %r1
253
254
/* Flush Data Cache */
255
256
LDREG DCACHE_BASE(%r1), %arg0
257
LDREG DCACHE_STRIDE(%r1), %arg1
258
LDREG DCACHE_COUNT(%r1), %arg2
259
LDREG DCACHE_LOOP(%r1), %arg3
260
rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/
261
mtsp %r0, %sr1
262
addib,COND(=) -1, %arg3, fdoneloop /* Preadjust and test */
263
movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */
264
265
fdmanyloop: /* Loop if LOOP >= 2 */
266
addib,COND(>) -1, %r31, fdmanyloop /* Adjusted inner loop decr */
267
fdce %r0(%sr1, %arg0)
268
fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */
269
movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */
270
addib,COND(<=),n -1, %arg2, fdsync /* Outer loop decr */
271
272
fdoneloop: /* Loop if LOOP = 1 */
273
/* Some implementations may flush with a single fdce instruction */
274
cmpib,COND(>>=),n 15, %arg2, fdoneloop2
275
276
fdoneloop1:
277
fdce,m %arg1(%sr1, %arg0)
278
fdce,m %arg1(%sr1, %arg0)
279
fdce,m %arg1(%sr1, %arg0)
280
fdce,m %arg1(%sr1, %arg0)
281
fdce,m %arg1(%sr1, %arg0)
282
fdce,m %arg1(%sr1, %arg0)
283
fdce,m %arg1(%sr1, %arg0)
284
fdce,m %arg1(%sr1, %arg0)
285
fdce,m %arg1(%sr1, %arg0)
286
fdce,m %arg1(%sr1, %arg0)
287
fdce,m %arg1(%sr1, %arg0)
288
fdce,m %arg1(%sr1, %arg0)
289
fdce,m %arg1(%sr1, %arg0)
290
fdce,m %arg1(%sr1, %arg0)
291
fdce,m %arg1(%sr1, %arg0)
292
addib,COND(>) -16, %arg2, fdoneloop1
293
fdce,m %arg1(%sr1, %arg0)
294
295
/* Check if done */
296
cmpb,COND(=),n %arg2, %r0, fdsync /* Predict branch taken */
297
298
fdoneloop2:
299
addib,COND(>) -1, %arg2, fdoneloop2 /* Outer loop count decr */
300
fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */
301
302
fdsync:
303
sync
304
mtsm %r22 /* restore I-bit */
305
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
306
bv %r0(%r2)
307
nop
308
ENDPROC_CFI(flush_data_cache_local)
309
310
/* Clear page using kernel mapping. */
311
312
ENTRY_CFI(clear_page_asm)
313
#ifdef CONFIG_64BIT
314
315
/* Unroll the loop. */
316
ldi (PAGE_SIZE / 128), %r1
317
318
1:
319
std %r0, 0(%r26)
320
std %r0, 8(%r26)
321
std %r0, 16(%r26)
322
std %r0, 24(%r26)
323
std %r0, 32(%r26)
324
std %r0, 40(%r26)
325
std %r0, 48(%r26)
326
std %r0, 56(%r26)
327
std %r0, 64(%r26)
328
std %r0, 72(%r26)
329
std %r0, 80(%r26)
330
std %r0, 88(%r26)
331
std %r0, 96(%r26)
332
std %r0, 104(%r26)
333
std %r0, 112(%r26)
334
std %r0, 120(%r26)
335
336
/* Note reverse branch hint for addib is taken. */
337
addib,COND(>),n -1, %r1, 1b
338
ldo 128(%r26), %r26
339
340
#else
341
342
/*
343
* Note that until (if) we start saving the full 64-bit register
344
* values on interrupt, we can't use std on a 32 bit kernel.
345
*/
346
ldi (PAGE_SIZE / 64), %r1
347
348
1:
349
stw %r0, 0(%r26)
350
stw %r0, 4(%r26)
351
stw %r0, 8(%r26)
352
stw %r0, 12(%r26)
353
stw %r0, 16(%r26)
354
stw %r0, 20(%r26)
355
stw %r0, 24(%r26)
356
stw %r0, 28(%r26)
357
stw %r0, 32(%r26)
358
stw %r0, 36(%r26)
359
stw %r0, 40(%r26)
360
stw %r0, 44(%r26)
361
stw %r0, 48(%r26)
362
stw %r0, 52(%r26)
363
stw %r0, 56(%r26)
364
stw %r0, 60(%r26)
365
366
addib,COND(>),n -1, %r1, 1b
367
ldo 64(%r26), %r26
368
#endif
369
bv %r0(%r2)
370
nop
371
ENDPROC_CFI(clear_page_asm)
372
373
/* Copy page using kernel mapping. */
374
375
ENTRY_CFI(copy_page_asm)
376
#ifdef CONFIG_64BIT
377
/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
378
* Unroll the loop by hand and arrange insn appropriately.
379
* Prefetch doesn't improve performance on rp3440.
380
* GCC probably can do this just as well...
381
*/
382
383
ldi (PAGE_SIZE / 128), %r1
384
385
1: ldd 0(%r25), %r19
386
ldd 8(%r25), %r20
387
388
ldd 16(%r25), %r21
389
ldd 24(%r25), %r22
390
std %r19, 0(%r26)
391
std %r20, 8(%r26)
392
393
ldd 32(%r25), %r19
394
ldd 40(%r25), %r20
395
std %r21, 16(%r26)
396
std %r22, 24(%r26)
397
398
ldd 48(%r25), %r21
399
ldd 56(%r25), %r22
400
std %r19, 32(%r26)
401
std %r20, 40(%r26)
402
403
ldd 64(%r25), %r19
404
ldd 72(%r25), %r20
405
std %r21, 48(%r26)
406
std %r22, 56(%r26)
407
408
ldd 80(%r25), %r21
409
ldd 88(%r25), %r22
410
std %r19, 64(%r26)
411
std %r20, 72(%r26)
412
413
ldd 96(%r25), %r19
414
ldd 104(%r25), %r20
415
std %r21, 80(%r26)
416
std %r22, 88(%r26)
417
418
ldd 112(%r25), %r21
419
ldd 120(%r25), %r22
420
ldo 128(%r25), %r25
421
std %r19, 96(%r26)
422
std %r20, 104(%r26)
423
424
std %r21, 112(%r26)
425
std %r22, 120(%r26)
426
427
/* Note reverse branch hint for addib is taken. */
428
addib,COND(>),n -1, %r1, 1b
429
ldo 128(%r26), %r26
430
431
#else
432
433
/*
434
* This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
435
* bundles (very restricted rules for bundling).
436
* Note that until (if) we start saving
437
* the full 64 bit register values on interrupt, we can't
438
* use ldd/std on a 32 bit kernel.
439
*/
440
ldw 0(%r25), %r19
441
ldi (PAGE_SIZE / 64), %r1
442
443
1:
444
ldw 4(%r25), %r20
445
ldw 8(%r25), %r21
446
ldw 12(%r25), %r22
447
stw %r19, 0(%r26)
448
stw %r20, 4(%r26)
449
stw %r21, 8(%r26)
450
stw %r22, 12(%r26)
451
ldw 16(%r25), %r19
452
ldw 20(%r25), %r20
453
ldw 24(%r25), %r21
454
ldw 28(%r25), %r22
455
stw %r19, 16(%r26)
456
stw %r20, 20(%r26)
457
stw %r21, 24(%r26)
458
stw %r22, 28(%r26)
459
ldw 32(%r25), %r19
460
ldw 36(%r25), %r20
461
ldw 40(%r25), %r21
462
ldw 44(%r25), %r22
463
stw %r19, 32(%r26)
464
stw %r20, 36(%r26)
465
stw %r21, 40(%r26)
466
stw %r22, 44(%r26)
467
ldw 48(%r25), %r19
468
ldw 52(%r25), %r20
469
ldw 56(%r25), %r21
470
ldw 60(%r25), %r22
471
stw %r19, 48(%r26)
472
stw %r20, 52(%r26)
473
ldo 64(%r25), %r25
474
stw %r21, 56(%r26)
475
stw %r22, 60(%r26)
476
ldo 64(%r26), %r26
477
addib,COND(>),n -1, %r1, 1b
478
ldw 0(%r25), %r19
479
#endif
480
bv %r0(%r2)
481
nop
482
ENDPROC_CFI(copy_page_asm)
483
484
/*
485
* NOTE: Code in clear_user_page has a hard coded dependency on the
486
* maximum alias boundary being 4 Mb. We've been assured by the
487
* parisc chip designers that there will not ever be a parisc
488
* chip with a larger alias boundary (Never say never :-) ).
489
*
490
* Yah, what about the PA8800 and PA8900 processors?
491
*
492
* Subtle: the dtlb miss handlers support the temp alias region by
493
* "knowing" that if a dtlb miss happens within the temp alias
494
* region it must have occurred while in clear_user_page. Since
495
* this routine makes use of processor local translations, we
496
* don't want to insert them into the kernel page table. Instead,
497
* we load up some general registers (they need to be registers
498
* which aren't shadowed) with the physical page numbers (preshifted
499
* for tlb insertion) needed to insert the translations. When we
500
* miss on the translation, the dtlb miss handler inserts the
501
* translation into the tlb using these values:
502
*
503
* %r26 physical address of "to" translation
504
* %r23 physical address of "from" translation
505
*/
506
507
/*
508
* copy_user_page_asm() performs a page copy using mappings
509
* equivalent to the user page mappings. It can be used to
510
* implement copy_user_page() but unfortunately both the `from'
511
* and `to' pages need to be flushed through mappings equivalent
512
* to the user mappings after the copy because the kernel accesses
513
* the `from' page through the kmap kernel mapping and the `to'
514
* page needs to be flushed since code can be copied. As a
515
* result, this implementation is less efficient than the simpler
516
* copy using the kernel mapping. It only needs the `from' page
517
* to flushed via the user mapping. The kunmap routines handle
518
* the flushes needed for the kernel mapping.
519
*
520
* I'm still keeping this around because it may be possible to
521
* use it if more information is passed into copy_user_page().
522
* Have to do some measurements to see if it is worthwhile to
523
* lobby for such a change.
524
*
525
*/
526
527
ENTRY_CFI(copy_user_page_asm)
528
/* Convert virtual `to' and `from' addresses to physical addresses.
529
Move `from' physical address to non shadowed register. */
530
ldil L%(__PAGE_OFFSET), %r1
531
sub %r26, %r1, %r26
532
sub %r25, %r1, %r23
533
534
ldil L%(TMPALIAS_MAP_START), %r28
535
dep_safe %r24, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */
536
depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
537
copy %r28, %r29
538
depi_safe 1, 31-TMPALIAS_SIZE_BITS,1, %r29 /* Form aliased virtual address 'from' */
539
540
/* Purge any old translations */
541
542
#ifdef CONFIG_PA20
543
pdtlb,l %r0(%r28)
544
pdtlb,l %r0(%r29)
545
#else
546
0: pdtlb %r0(%r28)
547
1: pdtlb %r0(%r29)
548
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
549
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
550
#endif
551
552
#ifdef CONFIG_64BIT
553
/* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
554
* Unroll the loop by hand and arrange insn appropriately.
555
* GCC probably can do this just as well.
556
*/
557
558
ldd 0(%r29), %r19
559
ldi (PAGE_SIZE / 128), %r1
560
561
1: ldd 8(%r29), %r20
562
563
ldd 16(%r29), %r21
564
ldd 24(%r29), %r22
565
std %r19, 0(%r28)
566
std %r20, 8(%r28)
567
568
ldd 32(%r29), %r19
569
ldd 40(%r29), %r20
570
std %r21, 16(%r28)
571
std %r22, 24(%r28)
572
573
ldd 48(%r29), %r21
574
ldd 56(%r29), %r22
575
std %r19, 32(%r28)
576
std %r20, 40(%r28)
577
578
ldd 64(%r29), %r19
579
ldd 72(%r29), %r20
580
std %r21, 48(%r28)
581
std %r22, 56(%r28)
582
583
ldd 80(%r29), %r21
584
ldd 88(%r29), %r22
585
std %r19, 64(%r28)
586
std %r20, 72(%r28)
587
588
ldd 96(%r29), %r19
589
ldd 104(%r29), %r20
590
std %r21, 80(%r28)
591
std %r22, 88(%r28)
592
593
ldd 112(%r29), %r21
594
ldd 120(%r29), %r22
595
std %r19, 96(%r28)
596
std %r20, 104(%r28)
597
598
ldo 128(%r29), %r29
599
std %r21, 112(%r28)
600
std %r22, 120(%r28)
601
ldo 128(%r28), %r28
602
603
/* conditional branches nullify on forward taken branch, and on
604
* non-taken backward branch. Note that .+4 is a backwards branch.
605
* The ldd should only get executed if the branch is taken.
606
*/
607
addib,COND(>),n -1, %r1, 1b /* bundle 10 */
608
ldd 0(%r29), %r19 /* start next loads */
609
610
#else
611
ldi (PAGE_SIZE / 64), %r1
612
613
/*
614
* This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
615
* bundles (very restricted rules for bundling). It probably
616
* does OK on PCXU and better, but we could do better with
617
* ldd/std instructions. Note that until (if) we start saving
618
* the full 64 bit register values on interrupt, we can't
619
* use ldd/std on a 32 bit kernel.
620
*/
621
622
1: ldw 0(%r29), %r19
623
ldw 4(%r29), %r20
624
ldw 8(%r29), %r21
625
ldw 12(%r29), %r22
626
stw %r19, 0(%r28)
627
stw %r20, 4(%r28)
628
stw %r21, 8(%r28)
629
stw %r22, 12(%r28)
630
ldw 16(%r29), %r19
631
ldw 20(%r29), %r20
632
ldw 24(%r29), %r21
633
ldw 28(%r29), %r22
634
stw %r19, 16(%r28)
635
stw %r20, 20(%r28)
636
stw %r21, 24(%r28)
637
stw %r22, 28(%r28)
638
ldw 32(%r29), %r19
639
ldw 36(%r29), %r20
640
ldw 40(%r29), %r21
641
ldw 44(%r29), %r22
642
stw %r19, 32(%r28)
643
stw %r20, 36(%r28)
644
stw %r21, 40(%r28)
645
stw %r22, 44(%r28)
646
ldw 48(%r29), %r19
647
ldw 52(%r29), %r20
648
ldw 56(%r29), %r21
649
ldw 60(%r29), %r22
650
stw %r19, 48(%r28)
651
stw %r20, 52(%r28)
652
stw %r21, 56(%r28)
653
stw %r22, 60(%r28)
654
ldo 64(%r28), %r28
655
656
addib,COND(>) -1, %r1,1b
657
ldo 64(%r29), %r29
658
#endif
659
660
bv %r0(%r2)
661
nop
662
ENDPROC_CFI(copy_user_page_asm)
663
664
ENTRY_CFI(clear_user_page_asm)
665
tophys_r1 %r26
666
667
ldil L%(TMPALIAS_MAP_START), %r28
668
dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */
669
depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
670
671
/* Purge any old translation */
672
673
#ifdef CONFIG_PA20
674
pdtlb,l %r0(%r28)
675
#else
676
0: pdtlb %r0(%r28)
677
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
678
#endif
679
680
#ifdef CONFIG_64BIT
681
ldi (PAGE_SIZE / 128), %r1
682
683
/* PREFETCH (Write) has not (yet) been proven to help here */
684
/* #define PREFETCHW_OP ldd 256(%0), %r0 */
685
686
1: std %r0, 0(%r28)
687
std %r0, 8(%r28)
688
std %r0, 16(%r28)
689
std %r0, 24(%r28)
690
std %r0, 32(%r28)
691
std %r0, 40(%r28)
692
std %r0, 48(%r28)
693
std %r0, 56(%r28)
694
std %r0, 64(%r28)
695
std %r0, 72(%r28)
696
std %r0, 80(%r28)
697
std %r0, 88(%r28)
698
std %r0, 96(%r28)
699
std %r0, 104(%r28)
700
std %r0, 112(%r28)
701
std %r0, 120(%r28)
702
addib,COND(>) -1, %r1, 1b
703
ldo 128(%r28), %r28
704
705
#else /* ! CONFIG_64BIT */
706
ldi (PAGE_SIZE / 64), %r1
707
708
1: stw %r0, 0(%r28)
709
stw %r0, 4(%r28)
710
stw %r0, 8(%r28)
711
stw %r0, 12(%r28)
712
stw %r0, 16(%r28)
713
stw %r0, 20(%r28)
714
stw %r0, 24(%r28)
715
stw %r0, 28(%r28)
716
stw %r0, 32(%r28)
717
stw %r0, 36(%r28)
718
stw %r0, 40(%r28)
719
stw %r0, 44(%r28)
720
stw %r0, 48(%r28)
721
stw %r0, 52(%r28)
722
stw %r0, 56(%r28)
723
stw %r0, 60(%r28)
724
addib,COND(>) -1, %r1, 1b
725
ldo 64(%r28), %r28
726
#endif /* CONFIG_64BIT */
727
728
bv %r0(%r2)
729
nop
730
ENDPROC_CFI(clear_user_page_asm)
731
732
ENTRY_CFI(flush_dcache_page_asm)
733
ldil L%(TMPALIAS_MAP_START), %r28
734
dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */
735
depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
736
737
/* Purge any old translation */
738
739
#ifdef CONFIG_PA20
740
pdtlb,l %r0(%r28)
741
#else
742
0: pdtlb %r0(%r28)
743
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
744
#endif
745
746
88: ldil L%dcache_stride, %r1
747
ldw R%dcache_stride(%r1), r31
748
749
#ifdef CONFIG_64BIT
750
depdi,z 1, 63-PAGE_SHIFT,1, %r25
751
#else
752
depwi,z 1, 31-PAGE_SHIFT,1, %r25
753
#endif
754
add %r28, %r25, %r25
755
sub %r25, r31, %r25
756
757
1: fdc,m r31(%r28)
758
fdc,m r31(%r28)
759
fdc,m r31(%r28)
760
fdc,m r31(%r28)
761
fdc,m r31(%r28)
762
fdc,m r31(%r28)
763
fdc,m r31(%r28)
764
fdc,m r31(%r28)
765
fdc,m r31(%r28)
766
fdc,m r31(%r28)
767
fdc,m r31(%r28)
768
fdc,m r31(%r28)
769
fdc,m r31(%r28)
770
fdc,m r31(%r28)
771
fdc,m r31(%r28)
772
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
773
fdc,m r31(%r28)
774
775
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
776
sync
777
bv %r0(%r2)
778
nop
779
ENDPROC_CFI(flush_dcache_page_asm)
780
781
ENTRY_CFI(purge_dcache_page_asm)
782
ldil L%(TMPALIAS_MAP_START), %r28
783
dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */
784
depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
785
786
/* Purge any old translation */
787
788
#ifdef CONFIG_PA20
789
pdtlb,l %r0(%r28)
790
#else
791
0: pdtlb %r0(%r28)
792
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
793
#endif
794
795
88: ldil L%dcache_stride, %r1
796
ldw R%dcache_stride(%r1), r31
797
798
#ifdef CONFIG_64BIT
799
depdi,z 1, 63-PAGE_SHIFT,1, %r25
800
#else
801
depwi,z 1, 31-PAGE_SHIFT,1, %r25
802
#endif
803
add %r28, %r25, %r25
804
sub %r25, r31, %r25
805
806
1: pdc,m r31(%r28)
807
pdc,m r31(%r28)
808
pdc,m r31(%r28)
809
pdc,m r31(%r28)
810
pdc,m r31(%r28)
811
pdc,m r31(%r28)
812
pdc,m r31(%r28)
813
pdc,m r31(%r28)
814
pdc,m r31(%r28)
815
pdc,m r31(%r28)
816
pdc,m r31(%r28)
817
pdc,m r31(%r28)
818
pdc,m r31(%r28)
819
pdc,m r31(%r28)
820
pdc,m r31(%r28)
821
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
822
pdc,m r31(%r28)
823
824
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
825
sync
826
bv %r0(%r2)
827
nop
828
ENDPROC_CFI(purge_dcache_page_asm)
829
830
ENTRY_CFI(flush_icache_page_asm)
831
ldil L%(TMPALIAS_MAP_START), %r28
832
dep_safe %r25, 31,TMPALIAS_SIZE_BITS, %r28 /* Form aliased virtual address 'to' */
833
depi_safe 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
834
835
/* Purge any old translation. Note that the FIC instruction
836
* may use either the instruction or data TLB. Given that we
837
* have a flat address space, it's not clear which TLB will be
838
* used. So, we purge both entries. */
839
840
#ifdef CONFIG_PA20
841
pdtlb,l %r0(%r28)
842
1: pitlb,l %r0(%sr4,%r28)
843
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
844
#else
845
0: pdtlb %r0(%r28)
846
1: pitlb %r0(%sr4,%r28)
847
ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
848
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
849
ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
850
#endif
851
852
88: ldil L%icache_stride, %r1
853
ldw R%icache_stride(%r1), %r31
854
855
#ifdef CONFIG_64BIT
856
depdi,z 1, 63-PAGE_SHIFT,1, %r25
857
#else
858
depwi,z 1, 31-PAGE_SHIFT,1, %r25
859
#endif
860
add %r28, %r25, %r25
861
sub %r25, %r31, %r25
862
863
/* fic only has the type 26 form on PA1.1, requiring an
864
* explicit space specification, so use %sr4 */
865
1: fic,m %r31(%sr4,%r28)
866
fic,m %r31(%sr4,%r28)
867
fic,m %r31(%sr4,%r28)
868
fic,m %r31(%sr4,%r28)
869
fic,m %r31(%sr4,%r28)
870
fic,m %r31(%sr4,%r28)
871
fic,m %r31(%sr4,%r28)
872
fic,m %r31(%sr4,%r28)
873
fic,m %r31(%sr4,%r28)
874
fic,m %r31(%sr4,%r28)
875
fic,m %r31(%sr4,%r28)
876
fic,m %r31(%sr4,%r28)
877
fic,m %r31(%sr4,%r28)
878
fic,m %r31(%sr4,%r28)
879
fic,m %r31(%sr4,%r28)
880
cmpb,COND(>>) %r25, %r28, 1b /* predict taken */
881
fic,m %r31(%sr4,%r28)
882
883
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
884
sync
885
bv %r0(%r2)
886
nop
887
ENDPROC_CFI(flush_icache_page_asm)
888
889
ENTRY_CFI(flush_kernel_dcache_page_asm)
890
88: ldil L%dcache_stride, %r1
891
ldw R%dcache_stride(%r1), %r23
892
depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
893
894
#ifdef CONFIG_64BIT
895
depdi,z 1, 63-PAGE_SHIFT,1, %r25
896
#else
897
depwi,z 1, 31-PAGE_SHIFT,1, %r25
898
#endif
899
add %r26, %r25, %r25
900
sub %r25, %r23, %r25
901
902
1: fdc,m %r23(%r26)
903
fdc,m %r23(%r26)
904
fdc,m %r23(%r26)
905
fdc,m %r23(%r26)
906
fdc,m %r23(%r26)
907
fdc,m %r23(%r26)
908
fdc,m %r23(%r26)
909
fdc,m %r23(%r26)
910
fdc,m %r23(%r26)
911
fdc,m %r23(%r26)
912
fdc,m %r23(%r26)
913
fdc,m %r23(%r26)
914
fdc,m %r23(%r26)
915
fdc,m %r23(%r26)
916
fdc,m %r23(%r26)
917
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
918
fdc,m %r23(%r26)
919
920
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
921
sync
922
bv %r0(%r2)
923
nop
924
ENDPROC_CFI(flush_kernel_dcache_page_asm)
925
926
ENTRY_CFI(purge_kernel_dcache_page_asm)
927
88: ldil L%dcache_stride, %r1
928
ldw R%dcache_stride(%r1), %r23
929
depi_safe 0, 31,PAGE_SHIFT, %r26 /* Clear any offset bits */
930
931
#ifdef CONFIG_64BIT
932
depdi,z 1, 63-PAGE_SHIFT,1, %r25
933
#else
934
depwi,z 1, 31-PAGE_SHIFT,1, %r25
935
#endif
936
add %r26, %r25, %r25
937
sub %r25, %r23, %r25
938
939
1: pdc,m %r23(%r26)
940
pdc,m %r23(%r26)
941
pdc,m %r23(%r26)
942
pdc,m %r23(%r26)
943
pdc,m %r23(%r26)
944
pdc,m %r23(%r26)
945
pdc,m %r23(%r26)
946
pdc,m %r23(%r26)
947
pdc,m %r23(%r26)
948
pdc,m %r23(%r26)
949
pdc,m %r23(%r26)
950
pdc,m %r23(%r26)
951
pdc,m %r23(%r26)
952
pdc,m %r23(%r26)
953
pdc,m %r23(%r26)
954
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
955
pdc,m %r23(%r26)
956
957
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
958
sync
959
bv %r0(%r2)
960
nop
961
ENDPROC_CFI(purge_kernel_dcache_page_asm)
962
963
ENTRY_CFI(flush_user_dcache_range_asm)
964
88: ldil L%dcache_stride, %r1
965
ldw R%dcache_stride(%r1), %r23
966
ldo -1(%r23), %r21
967
ANDCM %r26, %r21, %r26
968
969
#ifdef CONFIG_64BIT
970
depd,z %r23, 59, 60, %r21
971
#else
972
depw,z %r23, 27, 28, %r21
973
#endif
974
add %r26, %r21, %r22
975
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
976
1: add %r22, %r21, %r22
977
fdc,m %r23(%sr3, %r26)
978
fdc,m %r23(%sr3, %r26)
979
fdc,m %r23(%sr3, %r26)
980
fdc,m %r23(%sr3, %r26)
981
fdc,m %r23(%sr3, %r26)
982
fdc,m %r23(%sr3, %r26)
983
fdc,m %r23(%sr3, %r26)
984
fdc,m %r23(%sr3, %r26)
985
fdc,m %r23(%sr3, %r26)
986
fdc,m %r23(%sr3, %r26)
987
fdc,m %r23(%sr3, %r26)
988
fdc,m %r23(%sr3, %r26)
989
fdc,m %r23(%sr3, %r26)
990
fdc,m %r23(%sr3, %r26)
991
fdc,m %r23(%sr3, %r26)
992
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
993
fdc,m %r23(%sr3, %r26)
994
995
2: cmpb,COND(>>),n %r25, %r26, 2b
996
fdc,m %r23(%sr3, %r26)
997
998
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
999
sync
1000
bv %r0(%r2)
1001
nop
1002
ENDPROC_CFI(flush_user_dcache_range_asm)
1003
1004
ENTRY_CFI(flush_kernel_dcache_range_asm)
1005
88: ldil L%dcache_stride, %r1
1006
ldw R%dcache_stride(%r1), %r23
1007
ldo -1(%r23), %r21
1008
ANDCM %r26, %r21, %r26
1009
1010
#ifdef CONFIG_64BIT
1011
depd,z %r23, 59, 60, %r21
1012
#else
1013
depw,z %r23, 27, 28, %r21
1014
#endif
1015
add %r26, %r21, %r22
1016
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
1017
1: add %r22, %r21, %r22
1018
fdc,m %r23(%r26)
1019
fdc,m %r23(%r26)
1020
fdc,m %r23(%r26)
1021
fdc,m %r23(%r26)
1022
fdc,m %r23(%r26)
1023
fdc,m %r23(%r26)
1024
fdc,m %r23(%r26)
1025
fdc,m %r23(%r26)
1026
fdc,m %r23(%r26)
1027
fdc,m %r23(%r26)
1028
fdc,m %r23(%r26)
1029
fdc,m %r23(%r26)
1030
fdc,m %r23(%r26)
1031
fdc,m %r23(%r26)
1032
fdc,m %r23(%r26)
1033
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1034
fdc,m %r23(%r26)
1035
1036
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1037
fdc,m %r23(%r26)
1038
1039
sync
1040
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
1041
bv %r0(%r2)
1042
nop
1043
ENDPROC_CFI(flush_kernel_dcache_range_asm)
1044
1045
ENTRY_CFI(purge_kernel_dcache_range_asm)
1046
88: ldil L%dcache_stride, %r1
1047
ldw R%dcache_stride(%r1), %r23
1048
ldo -1(%r23), %r21
1049
ANDCM %r26, %r21, %r26
1050
1051
#ifdef CONFIG_64BIT
1052
depd,z %r23, 59, 60, %r21
1053
#else
1054
depw,z %r23, 27, 28, %r21
1055
#endif
1056
add %r26, %r21, %r22
1057
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
1058
1: add %r22, %r21, %r22
1059
pdc,m %r23(%r26)
1060
pdc,m %r23(%r26)
1061
pdc,m %r23(%r26)
1062
pdc,m %r23(%r26)
1063
pdc,m %r23(%r26)
1064
pdc,m %r23(%r26)
1065
pdc,m %r23(%r26)
1066
pdc,m %r23(%r26)
1067
pdc,m %r23(%r26)
1068
pdc,m %r23(%r26)
1069
pdc,m %r23(%r26)
1070
pdc,m %r23(%r26)
1071
pdc,m %r23(%r26)
1072
pdc,m %r23(%r26)
1073
pdc,m %r23(%r26)
1074
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1075
pdc,m %r23(%r26)
1076
1077
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1078
pdc,m %r23(%r26)
1079
1080
sync
1081
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
1082
bv %r0(%r2)
1083
nop
1084
ENDPROC_CFI(purge_kernel_dcache_range_asm)
1085
1086
ENTRY_CFI(flush_user_icache_range_asm)
1087
88: ldil L%icache_stride, %r1
1088
ldw R%icache_stride(%r1), %r23
1089
ldo -1(%r23), %r21
1090
ANDCM %r26, %r21, %r26
1091
1092
#ifdef CONFIG_64BIT
1093
depd,z %r23, 59, 60, %r21
1094
#else
1095
depw,z %r23, 27, 28, %r21
1096
#endif
1097
add %r26, %r21, %r22
1098
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
1099
1: add %r22, %r21, %r22
1100
fic,m %r23(%sr3, %r26)
1101
fic,m %r23(%sr3, %r26)
1102
fic,m %r23(%sr3, %r26)
1103
fic,m %r23(%sr3, %r26)
1104
fic,m %r23(%sr3, %r26)
1105
fic,m %r23(%sr3, %r26)
1106
fic,m %r23(%sr3, %r26)
1107
fic,m %r23(%sr3, %r26)
1108
fic,m %r23(%sr3, %r26)
1109
fic,m %r23(%sr3, %r26)
1110
fic,m %r23(%sr3, %r26)
1111
fic,m %r23(%sr3, %r26)
1112
fic,m %r23(%sr3, %r26)
1113
fic,m %r23(%sr3, %r26)
1114
fic,m %r23(%sr3, %r26)
1115
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1116
fic,m %r23(%sr3, %r26)
1117
1118
2: cmpb,COND(>>),n %r25, %r26, 2b
1119
fic,m %r23(%sr3, %r26)
1120
1121
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1122
sync
1123
bv %r0(%r2)
1124
nop
1125
ENDPROC_CFI(flush_user_icache_range_asm)
1126
1127
ENTRY_CFI(flush_kernel_icache_page)
1128
88: ldil L%icache_stride, %r1
1129
ldw R%icache_stride(%r1), %r23
1130
1131
#ifdef CONFIG_64BIT
1132
depdi,z 1, 63-PAGE_SHIFT,1, %r25
1133
#else
1134
depwi,z 1, 31-PAGE_SHIFT,1, %r25
1135
#endif
1136
add %r26, %r25, %r25
1137
sub %r25, %r23, %r25
1138
1139
1140
1: fic,m %r23(%sr4, %r26)
1141
fic,m %r23(%sr4, %r26)
1142
fic,m %r23(%sr4, %r26)
1143
fic,m %r23(%sr4, %r26)
1144
fic,m %r23(%sr4, %r26)
1145
fic,m %r23(%sr4, %r26)
1146
fic,m %r23(%sr4, %r26)
1147
fic,m %r23(%sr4, %r26)
1148
fic,m %r23(%sr4, %r26)
1149
fic,m %r23(%sr4, %r26)
1150
fic,m %r23(%sr4, %r26)
1151
fic,m %r23(%sr4, %r26)
1152
fic,m %r23(%sr4, %r26)
1153
fic,m %r23(%sr4, %r26)
1154
fic,m %r23(%sr4, %r26)
1155
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
1156
fic,m %r23(%sr4, %r26)
1157
1158
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1159
sync
1160
bv %r0(%r2)
1161
nop
1162
ENDPROC_CFI(flush_kernel_icache_page)
1163
1164
ENTRY_CFI(flush_kernel_icache_range_asm)
1165
88: ldil L%icache_stride, %r1
1166
ldw R%icache_stride(%r1), %r23
1167
ldo -1(%r23), %r21
1168
ANDCM %r26, %r21, %r26
1169
1170
#ifdef CONFIG_64BIT
1171
depd,z %r23, 59, 60, %r21
1172
#else
1173
depw,z %r23, 27, 28, %r21
1174
#endif
1175
add %r26, %r21, %r22
1176
cmpb,COND(>>),n %r22, %r25, 2f /* predict not taken */
1177
1: add %r22, %r21, %r22
1178
fic,m %r23(%sr4, %r26)
1179
fic,m %r23(%sr4, %r26)
1180
fic,m %r23(%sr4, %r26)
1181
fic,m %r23(%sr4, %r26)
1182
fic,m %r23(%sr4, %r26)
1183
fic,m %r23(%sr4, %r26)
1184
fic,m %r23(%sr4, %r26)
1185
fic,m %r23(%sr4, %r26)
1186
fic,m %r23(%sr4, %r26)
1187
fic,m %r23(%sr4, %r26)
1188
fic,m %r23(%sr4, %r26)
1189
fic,m %r23(%sr4, %r26)
1190
fic,m %r23(%sr4, %r26)
1191
fic,m %r23(%sr4, %r26)
1192
fic,m %r23(%sr4, %r26)
1193
cmpb,COND(<<=) %r22, %r25, 1b /* predict taken */
1194
fic,m %r23(%sr4, %r26)
1195
1196
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
1197
fic,m %r23(%sr4, %r26)
1198
1199
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
1200
sync
1201
bv %r0(%r2)
1202
nop
1203
ENDPROC_CFI(flush_kernel_icache_range_asm)
1204
1205
.text
1206
1207
/* align should cover use of rfi in disable_sr_hashing_asm and
1208
* srdis_done.
1209
*/
1210
.align 256
1211
ENTRY_CFI(disable_sr_hashing_asm)
1212
/*
1213
* Switch to real mode
1214
*/
1215
/* pcxt_ssm_bug */
1216
rsm PSW_SM_I, %r0
1217
load32 PA(1f), %r1
1218
nop
1219
nop
1220
nop
1221
nop
1222
nop
1223
1224
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
1225
mtctl %r0, %cr17 /* Clear IIASQ tail */
1226
mtctl %r0, %cr17 /* Clear IIASQ head */
1227
mtctl %r1, %cr18 /* IIAOQ head */
1228
ldo 4(%r1), %r1
1229
mtctl %r1, %cr18 /* IIAOQ tail */
1230
load32 REAL_MODE_PSW, %r1
1231
mtctl %r1, %ipsw
1232
rfi
1233
nop
1234
1235
1: cmpib,=,n SRHASH_PCXST, %r26,srdis_pcxs
1236
cmpib,=,n SRHASH_PCXL, %r26,srdis_pcxl
1237
cmpib,=,n SRHASH_PA20, %r26,srdis_pa20
1238
b,n srdis_done
1239
1240
srdis_pcxs:
1241
1242
/* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
1243
1244
.word 0x141c1a00 /* mfdiag %dr0, %r28 */
1245
.word 0x141c1a00 /* must issue twice */
1246
depwi 0,18,1, %r28 /* Clear DHE (dcache hash enable) */
1247
depwi 0,20,1, %r28 /* Clear IHE (icache hash enable) */
1248
.word 0x141c1600 /* mtdiag %r28, %dr0 */
1249
.word 0x141c1600 /* must issue twice */
1250
b,n srdis_done
1251
1252
srdis_pcxl:
1253
1254
/* Disable Space Register Hashing for PCXL */
1255
1256
.word 0x141c0600 /* mfdiag %dr0, %r28 */
1257
depwi 0,28,2, %r28 /* Clear DHASH_EN & IHASH_EN */
1258
.word 0x141c0240 /* mtdiag %r28, %dr0 */
1259
b,n srdis_done
1260
1261
srdis_pa20:
1262
1263
/* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
1264
1265
.word 0x144008bc /* mfdiag %dr2, %r28 */
1266
depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */
1267
.word 0x145c1840 /* mtdiag %r28, %dr2 */
1268
1269
1270
srdis_done:
1271
/* Switch back to virtual mode */
1272
rsm PSW_SM_I, %r0 /* prep to load iia queue */
1273
load32 2f, %r1
1274
nop
1275
nop
1276
nop
1277
nop
1278
nop
1279
1280
rsm PSW_SM_Q, %r0 /* prep to load iia queue */
1281
mtctl %r0, %cr17 /* Clear IIASQ tail */
1282
mtctl %r0, %cr17 /* Clear IIASQ head */
1283
mtctl %r1, %cr18 /* IIAOQ head */
1284
ldo 4(%r1), %r1
1285
mtctl %r1, %cr18 /* IIAOQ tail */
1286
load32 KERNEL_PSW, %r1
1287
mtctl %r1, %ipsw
1288
rfi
1289
nop
1290
1291
2: bv %r0(%r2)
1292
nop
1293
ENDPROC_CFI(disable_sr_hashing_asm)
1294
1295
.end
1296
1297