parisc: Also flush data TLB in flush_icache_page_asm
[firefly-linux-kernel-4.4.55.git] / arch / parisc / kernel / pacache.S
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          %r0(%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          %r0(%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         load32          cache_info, %r1
203
204         /* Flush Instruction Cache */
205
206         LDREG           ICACHE_BASE(%r1), %arg0
207         LDREG           ICACHE_STRIDE(%r1), %arg1
208         LDREG           ICACHE_COUNT(%r1), %arg2
209         LDREG           ICACHE_LOOP(%r1), %arg3
210         rsm             PSW_SM_I, %r22          /* No mmgt ops during loop*/
211         mtsp            %r0, %sr1
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         /* Some implementations may flush with a single fice instruction */
224         cmpib,COND(>>=),n       15, %arg2, fioneloop2
225
226 fioneloop1:
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         fice,m          %arg1(%sr1, %arg0)
232         fice,m          %arg1(%sr1, %arg0)
233         fice,m          %arg1(%sr1, %arg0)
234         fice,m          %arg1(%sr1, %arg0)
235         fice,m          %arg1(%sr1, %arg0)
236         fice,m          %arg1(%sr1, %arg0)
237         fice,m          %arg1(%sr1, %arg0)
238         fice,m          %arg1(%sr1, %arg0)
239         fice,m          %arg1(%sr1, %arg0)
240         fice,m          %arg1(%sr1, %arg0)
241         fice,m          %arg1(%sr1, %arg0)
242         addib,COND(>)   -16, %arg2, fioneloop1
243         fice,m          %arg1(%sr1, %arg0)
244
245         /* Check if done */
246         cmpb,COND(=),n  %arg2, %r0, fisync      /* Predict branch taken */
247
248 fioneloop2:
249         addib,COND(>)   -1, %arg2, fioneloop2   /* Outer loop count decr */
250         fice,m          %arg1(%sr1, %arg0)      /* Fice for one loop */
251
252 fisync:
253         sync
254         mtsm            %r22                    /* restore I-bit */
255         bv              %r0(%r2)
256         nop
257         .exit
258
259         .procend
260 ENDPROC(flush_instruction_cache_local)
261
262
263         .import cache_info, data
264 ENTRY(flush_data_cache_local)
265         .proc
266         .callinfo NO_CALLS
267         .entry
268
269         load32          cache_info, %r1
270
271         /* Flush Data Cache */
272
273         LDREG           DCACHE_BASE(%r1), %arg0
274         LDREG           DCACHE_STRIDE(%r1), %arg1
275         LDREG           DCACHE_COUNT(%r1), %arg2
276         LDREG           DCACHE_LOOP(%r1), %arg3
277         rsm             PSW_SM_I, %r22          /* No mmgt ops during loop*/
278         mtsp            %r0, %sr1
279         addib,COND(=)           -1, %arg3, fdoneloop    /* Preadjust and test */
280         movb,<,n        %arg3, %r31, fdsync     /* If loop < 0, do sync */
281
282 fdmanyloop:                                     /* Loop if LOOP >= 2 */
283         addib,COND(>)           -1, %r31, fdmanyloop    /* Adjusted inner loop decr */
284         fdce            %r0(%sr1, %arg0)
285         fdce,m          %arg1(%sr1, %arg0)      /* Last fdce and addr adjust */
286         movb,tr         %arg3, %r31, fdmanyloop /* Re-init inner loop count */
287         addib,COND(<=),n        -1, %arg2, fdsync       /* Outer loop decr */
288
289 fdoneloop:                                      /* Loop if LOOP = 1 */
290         /* Some implementations may flush with a single fdce instruction */
291         cmpib,COND(>>=),n       15, %arg2, fdoneloop2
292
293 fdoneloop1:
294         fdce,m          %arg1(%sr1, %arg0)
295         fdce,m          %arg1(%sr1, %arg0)
296         fdce,m          %arg1(%sr1, %arg0)
297         fdce,m          %arg1(%sr1, %arg0)
298         fdce,m          %arg1(%sr1, %arg0)
299         fdce,m          %arg1(%sr1, %arg0)
300         fdce,m          %arg1(%sr1, %arg0)
301         fdce,m          %arg1(%sr1, %arg0)
302         fdce,m          %arg1(%sr1, %arg0)
303         fdce,m          %arg1(%sr1, %arg0)
304         fdce,m          %arg1(%sr1, %arg0)
305         fdce,m          %arg1(%sr1, %arg0)
306         fdce,m          %arg1(%sr1, %arg0)
307         fdce,m          %arg1(%sr1, %arg0)
308         fdce,m          %arg1(%sr1, %arg0)
309         addib,COND(>)   -16, %arg2, fdoneloop1
310         fdce,m          %arg1(%sr1, %arg0)
311
312         /* Check if done */
313         cmpb,COND(=),n  %arg2, %r0, fdsync      /* Predict branch taken */
314
315 fdoneloop2:
316         addib,COND(>)   -1, %arg2, fdoneloop2   /* Outer loop count decr */
317         fdce,m          %arg1(%sr1, %arg0)      /* Fdce for one loop */
318
319 fdsync:
320         syncdma
321         sync
322         mtsm            %r22                    /* restore I-bit */
323         bv              %r0(%r2)
324         nop
325         .exit
326
327         .procend
328 ENDPROC(flush_data_cache_local)
329
330         .align  16
331
332 /* Macros to serialize TLB purge operations on SMP.  */
333
334         .macro  tlb_lock        la,flags,tmp
335 #ifdef CONFIG_SMP
336         ldil            L%pa_tlb_lock,%r1
337         ldo             R%pa_tlb_lock(%r1),\la
338         rsm             PSW_SM_I,\flags
339 1:      LDCW            0(\la),\tmp
340         cmpib,<>,n      0,\tmp,3f
341 2:      ldw             0(\la),\tmp
342         cmpb,<>         %r0,\tmp,1b
343         nop
344         b,n             2b
345 3:
346 #endif
347         .endm
348
349         .macro  tlb_unlock      la,flags,tmp
350 #ifdef CONFIG_SMP
351         ldi             1,\tmp
352         stw             \tmp,0(\la)
353         mtsm            \flags
354 #endif
355         .endm
356
357 /* Clear page using kernel mapping.  */
358
359 ENTRY(clear_page_asm)
360         .proc
361         .callinfo NO_CALLS
362         .entry
363
364 #ifdef CONFIG_64BIT
365
366         /* Unroll the loop.  */
367         ldi             (PAGE_SIZE / 128), %r1
368
369 1:
370         std             %r0, 0(%r26)
371         std             %r0, 8(%r26)
372         std             %r0, 16(%r26)
373         std             %r0, 24(%r26)
374         std             %r0, 32(%r26)
375         std             %r0, 40(%r26)
376         std             %r0, 48(%r26)
377         std             %r0, 56(%r26)
378         std             %r0, 64(%r26)
379         std             %r0, 72(%r26)
380         std             %r0, 80(%r26)
381         std             %r0, 88(%r26)
382         std             %r0, 96(%r26)
383         std             %r0, 104(%r26)
384         std             %r0, 112(%r26)
385         std             %r0, 120(%r26)
386
387         /* Note reverse branch hint for addib is taken.  */
388         addib,COND(>),n -1, %r1, 1b
389         ldo             128(%r26), %r26
390
391 #else
392
393         /*
394          * Note that until (if) we start saving the full 64-bit register
395          * values on interrupt, we can't use std on a 32 bit kernel.
396          */
397         ldi             (PAGE_SIZE / 64), %r1
398
399 1:
400         stw             %r0, 0(%r26)
401         stw             %r0, 4(%r26)
402         stw             %r0, 8(%r26)
403         stw             %r0, 12(%r26)
404         stw             %r0, 16(%r26)
405         stw             %r0, 20(%r26)
406         stw             %r0, 24(%r26)
407         stw             %r0, 28(%r26)
408         stw             %r0, 32(%r26)
409         stw             %r0, 36(%r26)
410         stw             %r0, 40(%r26)
411         stw             %r0, 44(%r26)
412         stw             %r0, 48(%r26)
413         stw             %r0, 52(%r26)
414         stw             %r0, 56(%r26)
415         stw             %r0, 60(%r26)
416
417         addib,COND(>),n -1, %r1, 1b
418         ldo             64(%r26), %r26
419 #endif
420         bv              %r0(%r2)
421         nop
422         .exit
423
424         .procend
425 ENDPROC(clear_page_asm)
426
427 /* Copy page using kernel mapping.  */
428
429 ENTRY(copy_page_asm)
430         .proc
431         .callinfo NO_CALLS
432         .entry
433
434 #ifdef CONFIG_64BIT
435         /* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
436          * Unroll the loop by hand and arrange insn appropriately.
437          * Prefetch doesn't improve performance on rp3440.
438          * GCC probably can do this just as well...
439          */
440
441         ldi             (PAGE_SIZE / 128), %r1
442
443 1:      ldd             0(%r25), %r19
444         ldd             8(%r25), %r20
445
446         ldd             16(%r25), %r21
447         ldd             24(%r25), %r22
448         std             %r19, 0(%r26)
449         std             %r20, 8(%r26)
450
451         ldd             32(%r25), %r19
452         ldd             40(%r25), %r20
453         std             %r21, 16(%r26)
454         std             %r22, 24(%r26)
455
456         ldd             48(%r25), %r21
457         ldd             56(%r25), %r22
458         std             %r19, 32(%r26)
459         std             %r20, 40(%r26)
460
461         ldd             64(%r25), %r19
462         ldd             72(%r25), %r20
463         std             %r21, 48(%r26)
464         std             %r22, 56(%r26)
465
466         ldd             80(%r25), %r21
467         ldd             88(%r25), %r22
468         std             %r19, 64(%r26)
469         std             %r20, 72(%r26)
470
471         ldd              96(%r25), %r19
472         ldd             104(%r25), %r20
473         std             %r21, 80(%r26)
474         std             %r22, 88(%r26)
475
476         ldd             112(%r25), %r21
477         ldd             120(%r25), %r22
478         ldo             128(%r25), %r25
479         std             %r19, 96(%r26)
480         std             %r20, 104(%r26)
481
482         std             %r21, 112(%r26)
483         std             %r22, 120(%r26)
484
485         /* Note reverse branch hint for addib is taken.  */
486         addib,COND(>),n -1, %r1, 1b
487         ldo             128(%r26), %r26
488
489 #else
490
491         /*
492          * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
493          * bundles (very restricted rules for bundling).
494          * Note that until (if) we start saving
495          * the full 64 bit register values on interrupt, we can't
496          * use ldd/std on a 32 bit kernel.
497          */
498         ldw             0(%r25), %r19
499         ldi             (PAGE_SIZE / 64), %r1
500
501 1:
502         ldw             4(%r25), %r20
503         ldw             8(%r25), %r21
504         ldw             12(%r25), %r22
505         stw             %r19, 0(%r26)
506         stw             %r20, 4(%r26)
507         stw             %r21, 8(%r26)
508         stw             %r22, 12(%r26)
509         ldw             16(%r25), %r19
510         ldw             20(%r25), %r20
511         ldw             24(%r25), %r21
512         ldw             28(%r25), %r22
513         stw             %r19, 16(%r26)
514         stw             %r20, 20(%r26)
515         stw             %r21, 24(%r26)
516         stw             %r22, 28(%r26)
517         ldw             32(%r25), %r19
518         ldw             36(%r25), %r20
519         ldw             40(%r25), %r21
520         ldw             44(%r25), %r22
521         stw             %r19, 32(%r26)
522         stw             %r20, 36(%r26)
523         stw             %r21, 40(%r26)
524         stw             %r22, 44(%r26)
525         ldw             48(%r25), %r19
526         ldw             52(%r25), %r20
527         ldw             56(%r25), %r21
528         ldw             60(%r25), %r22
529         stw             %r19, 48(%r26)
530         stw             %r20, 52(%r26)
531         ldo             64(%r25), %r25
532         stw             %r21, 56(%r26)
533         stw             %r22, 60(%r26)
534         ldo             64(%r26), %r26
535         addib,COND(>),n -1, %r1, 1b
536         ldw             0(%r25), %r19
537 #endif
538         bv              %r0(%r2)
539         nop
540         .exit
541
542         .procend
543 ENDPROC(copy_page_asm)
544
545 /*
546  * NOTE: Code in clear_user_page has a hard coded dependency on the
547  *       maximum alias boundary being 4 Mb. We've been assured by the
548  *       parisc chip designers that there will not ever be a parisc
549  *       chip with a larger alias boundary (Never say never :-) ).
550  *
551  *       Subtle: the dtlb miss handlers support the temp alias region by
552  *       "knowing" that if a dtlb miss happens within the temp alias
553  *       region it must have occurred while in clear_user_page. Since
554  *       this routine makes use of processor local translations, we
555  *       don't want to insert them into the kernel page table. Instead,
556  *       we load up some general registers (they need to be registers
557  *       which aren't shadowed) with the physical page numbers (preshifted
558  *       for tlb insertion) needed to insert the translations. When we
559  *       miss on the translation, the dtlb miss handler inserts the
560  *       translation into the tlb using these values:
561  *
562  *          %r26 physical page (shifted for tlb insert) of "to" translation
563  *          %r23 physical page (shifted for tlb insert) of "from" translation
564  */
565
566         /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
567         #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
568         .macro          convert_phys_for_tlb_insert20  phys
569         extrd,u         \phys, 56-PAGE_ADD_SHIFT, 32-PAGE_ADD_SHIFT, \phys
570 #if _PAGE_SIZE_ENCODING_DEFAULT
571         depdi           _PAGE_SIZE_ENCODING_DEFAULT, 63, (63-58), \phys
572 #endif
573         .endm
574
575         /*
576          * We can't do this since copy_user_page is used to bring in
577          * file data that might have instructions. Since the data would
578          * then need to be flushed out so the i-fetch can see it, it
579          * makes more sense to just copy through the kernel translation
580          * and flush it.
581          *
582          * I'm still keeping this around because it may be possible to
583          * use it if more information is passed into copy_user_page().
584          * Have to do some measurements to see if it is worthwhile to
585          * lobby for such a change.
586          *
587          */
588
589 ENTRY(copy_user_page_asm)
590         .proc
591         .callinfo NO_CALLS
592         .entry
593
594         /* Convert virtual `to' and `from' addresses to physical addresses.
595            Move `from' physical address to non shadowed register.  */
596         ldil            L%(__PAGE_OFFSET), %r1
597         sub             %r26, %r1, %r26
598         sub             %r25, %r1, %r23
599
600         ldil            L%(TMPALIAS_MAP_START), %r28
601 #ifdef CONFIG_64BIT
602 #if (TMPALIAS_MAP_START >= 0x80000000)
603         depdi           0, 31,32, %r28          /* clear any sign extension */
604 #endif
605         convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
606         convert_phys_for_tlb_insert20 %r23      /* convert phys addr to tlb insert format */
607         depd            %r24,63,22, %r28        /* Form aliased virtual address 'to' */
608         depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
609         copy            %r28, %r29
610         depdi           1, 41,1, %r29           /* Form aliased virtual address 'from' */
611 #else
612         extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
613         extrw,u         %r23, 24,25, %r23       /* convert phys addr to tlb insert format */
614         depw            %r24, 31,22, %r28       /* Form aliased virtual address 'to' */
615         depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
616         copy            %r28, %r29
617         depwi           1, 9,1, %r29            /* Form aliased virtual address 'from' */
618 #endif
619
620         /* Purge any old translations */
621
622 #ifdef CONFIG_PA20
623         pdtlb,l         %r0(%r28)
624         pdtlb,l         %r0(%r29)
625 #else
626         tlb_lock        %r20,%r21,%r22
627         pdtlb           %r0(%r28)
628         pdtlb           %r0(%r29)
629         tlb_unlock      %r20,%r21,%r22
630 #endif
631
632 #ifdef CONFIG_64BIT
633         /* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
634          * Unroll the loop by hand and arrange insn appropriately.
635          * GCC probably can do this just as well.
636          */
637
638         ldd             0(%r29), %r19
639         ldi             (PAGE_SIZE / 128), %r1
640
641 1:      ldd             8(%r29), %r20
642
643         ldd             16(%r29), %r21
644         ldd             24(%r29), %r22
645         std             %r19, 0(%r28)
646         std             %r20, 8(%r28)
647
648         ldd             32(%r29), %r19
649         ldd             40(%r29), %r20
650         std             %r21, 16(%r28)
651         std             %r22, 24(%r28)
652
653         ldd             48(%r29), %r21
654         ldd             56(%r29), %r22
655         std             %r19, 32(%r28)
656         std             %r20, 40(%r28)
657
658         ldd             64(%r29), %r19
659         ldd             72(%r29), %r20
660         std             %r21, 48(%r28)
661         std             %r22, 56(%r28)
662
663         ldd             80(%r29), %r21
664         ldd             88(%r29), %r22
665         std             %r19, 64(%r28)
666         std             %r20, 72(%r28)
667
668         ldd              96(%r29), %r19
669         ldd             104(%r29), %r20
670         std             %r21, 80(%r28)
671         std             %r22, 88(%r28)
672
673         ldd             112(%r29), %r21
674         ldd             120(%r29), %r22
675         std             %r19, 96(%r28)
676         std             %r20, 104(%r28)
677
678         ldo             128(%r29), %r29
679         std             %r21, 112(%r28)
680         std             %r22, 120(%r28)
681         ldo             128(%r28), %r28
682
683         /* conditional branches nullify on forward taken branch, and on
684          * non-taken backward branch. Note that .+4 is a backwards branch.
685          * The ldd should only get executed if the branch is taken.
686          */
687         addib,COND(>),n -1, %r1, 1b             /* bundle 10 */
688         ldd             0(%r29), %r19           /* start next loads */
689
690 #else
691         ldi             (PAGE_SIZE / 64), %r1
692
693         /*
694          * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw
695          * bundles (very restricted rules for bundling). It probably
696          * does OK on PCXU and better, but we could do better with
697          * ldd/std instructions. Note that until (if) we start saving
698          * the full 64 bit register values on interrupt, we can't
699          * use ldd/std on a 32 bit kernel.
700          */
701
702 1:      ldw             0(%r29), %r19
703         ldw             4(%r29), %r20
704         ldw             8(%r29), %r21
705         ldw             12(%r29), %r22
706         stw             %r19, 0(%r28)
707         stw             %r20, 4(%r28)
708         stw             %r21, 8(%r28)
709         stw             %r22, 12(%r28)
710         ldw             16(%r29), %r19
711         ldw             20(%r29), %r20
712         ldw             24(%r29), %r21
713         ldw             28(%r29), %r22
714         stw             %r19, 16(%r28)
715         stw             %r20, 20(%r28)
716         stw             %r21, 24(%r28)
717         stw             %r22, 28(%r28)
718         ldw             32(%r29), %r19
719         ldw             36(%r29), %r20
720         ldw             40(%r29), %r21
721         ldw             44(%r29), %r22
722         stw             %r19, 32(%r28)
723         stw             %r20, 36(%r28)
724         stw             %r21, 40(%r28)
725         stw             %r22, 44(%r28)
726         ldw             48(%r29), %r19
727         ldw             52(%r29), %r20
728         ldw             56(%r29), %r21
729         ldw             60(%r29), %r22
730         stw             %r19, 48(%r28)
731         stw             %r20, 52(%r28)
732         stw             %r21, 56(%r28)
733         stw             %r22, 60(%r28)
734         ldo             64(%r28), %r28
735
736         addib,COND(>)           -1, %r1,1b
737         ldo             64(%r29), %r29
738 #endif
739
740         bv              %r0(%r2)
741         nop
742         .exit
743
744         .procend
745 ENDPROC(copy_user_page_asm)
746
747 ENTRY(clear_user_page_asm)
748         .proc
749         .callinfo NO_CALLS
750         .entry
751
752         tophys_r1       %r26
753
754         ldil            L%(TMPALIAS_MAP_START), %r28
755 #ifdef CONFIG_64BIT
756 #if (TMPALIAS_MAP_START >= 0x80000000)
757         depdi           0, 31,32, %r28          /* clear any sign extension */
758 #endif
759         convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
760         depd            %r25, 63,22, %r28       /* Form aliased virtual address 'to' */
761         depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
762 #else
763         extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
764         depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
765         depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
766 #endif
767
768         /* Purge any old translation */
769
770 #ifdef CONFIG_PA20
771         pdtlb,l         %r0(%r28)
772 #else
773         tlb_lock        %r20,%r21,%r22
774         pdtlb           %r0(%r28)
775         tlb_unlock      %r20,%r21,%r22
776 #endif
777
778 #ifdef CONFIG_64BIT
779         ldi             (PAGE_SIZE / 128), %r1
780
781         /* PREFETCH (Write) has not (yet) been proven to help here */
782         /* #define      PREFETCHW_OP    ldd             256(%0), %r0 */
783
784 1:      std             %r0, 0(%r28)
785         std             %r0, 8(%r28)
786         std             %r0, 16(%r28)
787         std             %r0, 24(%r28)
788         std             %r0, 32(%r28)
789         std             %r0, 40(%r28)
790         std             %r0, 48(%r28)
791         std             %r0, 56(%r28)
792         std             %r0, 64(%r28)
793         std             %r0, 72(%r28)
794         std             %r0, 80(%r28)
795         std             %r0, 88(%r28)
796         std             %r0, 96(%r28)
797         std             %r0, 104(%r28)
798         std             %r0, 112(%r28)
799         std             %r0, 120(%r28)
800         addib,COND(>)           -1, %r1, 1b
801         ldo             128(%r28), %r28
802
803 #else   /* ! CONFIG_64BIT */
804         ldi             (PAGE_SIZE / 64), %r1
805
806 1:      stw             %r0, 0(%r28)
807         stw             %r0, 4(%r28)
808         stw             %r0, 8(%r28)
809         stw             %r0, 12(%r28)
810         stw             %r0, 16(%r28)
811         stw             %r0, 20(%r28)
812         stw             %r0, 24(%r28)
813         stw             %r0, 28(%r28)
814         stw             %r0, 32(%r28)
815         stw             %r0, 36(%r28)
816         stw             %r0, 40(%r28)
817         stw             %r0, 44(%r28)
818         stw             %r0, 48(%r28)
819         stw             %r0, 52(%r28)
820         stw             %r0, 56(%r28)
821         stw             %r0, 60(%r28)
822         addib,COND(>)           -1, %r1, 1b
823         ldo             64(%r28), %r28
824 #endif  /* CONFIG_64BIT */
825
826         bv              %r0(%r2)
827         nop
828         .exit
829
830         .procend
831 ENDPROC(clear_user_page_asm)
832
833 ENTRY(flush_dcache_page_asm)
834         .proc
835         .callinfo NO_CALLS
836         .entry
837
838         ldil            L%(TMPALIAS_MAP_START), %r28
839 #ifdef CONFIG_64BIT
840 #if (TMPALIAS_MAP_START >= 0x80000000)
841         depdi           0, 31,32, %r28          /* clear any sign extension */
842 #endif
843         convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
844         depd            %r25, 63,22, %r28       /* Form aliased virtual address 'to' */
845         depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
846 #else
847         extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
848         depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
849         depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
850 #endif
851
852         /* Purge any old translation */
853
854 #ifdef CONFIG_PA20
855         pdtlb,l         %r0(%r28)
856 #else
857         tlb_lock        %r20,%r21,%r22
858         pdtlb           %r0(%r28)
859         tlb_unlock      %r20,%r21,%r22
860 #endif
861
862         ldil            L%dcache_stride, %r1
863         ldw             R%dcache_stride(%r1), r31
864
865 #ifdef CONFIG_64BIT
866         depdi,z         1, 63-PAGE_SHIFT,1, %r25
867 #else
868         depwi,z         1, 31-PAGE_SHIFT,1, %r25
869 #endif
870         add             %r28, %r25, %r25
871         sub             %r25, r31, %r25
872
873
874 1:      fdc,m           r31(%r28)
875         fdc,m           r31(%r28)
876         fdc,m           r31(%r28)
877         fdc,m           r31(%r28)
878         fdc,m           r31(%r28)
879         fdc,m           r31(%r28)
880         fdc,m           r31(%r28)
881         fdc,m           r31(%r28)
882         fdc,m           r31(%r28)
883         fdc,m           r31(%r28)
884         fdc,m           r31(%r28)
885         fdc,m           r31(%r28)
886         fdc,m           r31(%r28)
887         fdc,m           r31(%r28)
888         fdc,m           r31(%r28)
889         cmpb,COND(<<)           %r28, %r25,1b
890         fdc,m           r31(%r28)
891
892         sync
893
894 #ifdef CONFIG_PA20
895         pdtlb,l         %r0(%r25)
896 #else
897         tlb_lock        %r20,%r21,%r22
898         pdtlb           %r0(%r25)
899         tlb_unlock      %r20,%r21,%r22
900 #endif
901
902         bv              %r0(%r2)
903         nop
904         .exit
905
906         .procend
907 ENDPROC(flush_dcache_page_asm)
908
909 ENTRY(flush_icache_page_asm)
910         .proc
911         .callinfo NO_CALLS
912         .entry
913
914         ldil            L%(TMPALIAS_MAP_START), %r28
915 #ifdef CONFIG_64BIT
916 #if (TMPALIAS_MAP_START >= 0x80000000)
917         depdi           0, 31,32, %r28          /* clear any sign extension */
918 #endif
919         convert_phys_for_tlb_insert20 %r26      /* convert phys addr to tlb insert format */
920         depd            %r25, 63,22, %r28       /* Form aliased virtual address 'to' */
921         depdi           0, 63,PAGE_SHIFT, %r28  /* Clear any offset bits */
922 #else
923         extrw,u         %r26, 24,25, %r26       /* convert phys addr to tlb insert format */
924         depw            %r25, 31,22, %r28       /* Form aliased virtual address 'to' */
925         depwi           0, 31,PAGE_SHIFT, %r28  /* Clear any offset bits */
926 #endif
927
928         /* Purge any old translation.  Note that the FIC instruction
929          * may use either the instruction or data TLB.  Given that we
930          * have a flat address space, it's not clear which TLB will be
931          * used.  So, we purge both entries.  */
932
933 #ifdef CONFIG_PA20
934         pdtlb,l         %r0(%r28)
935         pitlb,l         %r0(%sr4,%r28)
936 #else
937         tlb_lock        %r20,%r21,%r22
938         pdtlb           %r0(%r28)
939         pitlb           %r0(%sr4,%r28)
940         tlb_unlock      %r20,%r21,%r22
941 #endif
942
943         ldil            L%icache_stride, %r1
944         ldw             R%icache_stride(%r1), %r31
945
946 #ifdef CONFIG_64BIT
947         depdi,z         1, 63-PAGE_SHIFT,1, %r25
948 #else
949         depwi,z         1, 31-PAGE_SHIFT,1, %r25
950 #endif
951         add             %r28, %r25, %r25
952         sub             %r25, %r31, %r25
953
954
955         /* fic only has the type 26 form on PA1.1, requiring an
956          * explicit space specification, so use %sr4 */
957 1:      fic,m           %r31(%sr4,%r28)
958         fic,m           %r31(%sr4,%r28)
959         fic,m           %r31(%sr4,%r28)
960         fic,m           %r31(%sr4,%r28)
961         fic,m           %r31(%sr4,%r28)
962         fic,m           %r31(%sr4,%r28)
963         fic,m           %r31(%sr4,%r28)
964         fic,m           %r31(%sr4,%r28)
965         fic,m           %r31(%sr4,%r28)
966         fic,m           %r31(%sr4,%r28)
967         fic,m           %r31(%sr4,%r28)
968         fic,m           %r31(%sr4,%r28)
969         fic,m           %r31(%sr4,%r28)
970         fic,m           %r31(%sr4,%r28)
971         fic,m           %r31(%sr4,%r28)
972         cmpb,COND(<<)   %r28, %r25,1b
973         fic,m           %r31(%sr4,%r28)
974
975         sync
976
977 #ifdef CONFIG_PA20
978         pdtlb,l         %r0(%r28)
979         pitlb,l         %r0(%sr4,%r25)
980 #else
981         tlb_lock        %r20,%r21,%r22
982         pdtlb           %r0(%r28)
983         pitlb           %r0(%sr4,%r25)
984         tlb_unlock      %r20,%r21,%r22
985 #endif
986
987         bv              %r0(%r2)
988         nop
989         .exit
990
991         .procend
992 ENDPROC(flush_icache_page_asm)
993
994 ENTRY(flush_kernel_dcache_page_asm)
995         .proc
996         .callinfo NO_CALLS
997         .entry
998
999         ldil            L%dcache_stride, %r1
1000         ldw             R%dcache_stride(%r1), %r23
1001
1002 #ifdef CONFIG_64BIT
1003         depdi,z         1, 63-PAGE_SHIFT,1, %r25
1004 #else
1005         depwi,z         1, 31-PAGE_SHIFT,1, %r25
1006 #endif
1007         add             %r26, %r25, %r25
1008         sub             %r25, %r23, %r25
1009
1010
1011 1:      fdc,m           %r23(%r26)
1012         fdc,m           %r23(%r26)
1013         fdc,m           %r23(%r26)
1014         fdc,m           %r23(%r26)
1015         fdc,m           %r23(%r26)
1016         fdc,m           %r23(%r26)
1017         fdc,m           %r23(%r26)
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         cmpb,COND(<<)           %r26, %r25,1b
1027         fdc,m           %r23(%r26)
1028
1029         sync
1030         bv              %r0(%r2)
1031         nop
1032         .exit
1033
1034         .procend
1035 ENDPROC(flush_kernel_dcache_page_asm)
1036
1037 ENTRY(purge_kernel_dcache_page_asm)
1038         .proc
1039         .callinfo NO_CALLS
1040         .entry
1041
1042         ldil            L%dcache_stride, %r1
1043         ldw             R%dcache_stride(%r1), %r23
1044
1045 #ifdef CONFIG_64BIT
1046         depdi,z         1, 63-PAGE_SHIFT,1, %r25
1047 #else
1048         depwi,z         1, 31-PAGE_SHIFT,1, %r25
1049 #endif
1050         add             %r26, %r25, %r25
1051         sub             %r25, %r23, %r25
1052
1053 1:      pdc,m           %r23(%r26)
1054         pdc,m           %r23(%r26)
1055         pdc,m           %r23(%r26)
1056         pdc,m           %r23(%r26)
1057         pdc,m           %r23(%r26)
1058         pdc,m           %r23(%r26)
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         cmpb,COND(<<)           %r26, %r25, 1b
1069         pdc,m           %r23(%r26)
1070
1071         sync
1072         bv              %r0(%r2)
1073         nop
1074         .exit
1075
1076         .procend
1077 ENDPROC(purge_kernel_dcache_page_asm)
1078
1079 ENTRY(flush_user_dcache_range_asm)
1080         .proc
1081         .callinfo NO_CALLS
1082         .entry
1083
1084         ldil            L%dcache_stride, %r1
1085         ldw             R%dcache_stride(%r1), %r23
1086         ldo             -1(%r23), %r21
1087         ANDCM           %r26, %r21, %r26
1088
1089 1:      cmpb,COND(<<),n %r26, %r25, 1b
1090         fdc,m           %r23(%sr3, %r26)
1091
1092         sync
1093         bv              %r0(%r2)
1094         nop
1095         .exit
1096
1097         .procend
1098 ENDPROC(flush_user_dcache_range_asm)
1099
1100 ENTRY(flush_kernel_dcache_range_asm)
1101         .proc
1102         .callinfo NO_CALLS
1103         .entry
1104
1105         ldil            L%dcache_stride, %r1
1106         ldw             R%dcache_stride(%r1), %r23
1107         ldo             -1(%r23), %r21
1108         ANDCM           %r26, %r21, %r26
1109
1110 1:      cmpb,COND(<<),n %r26, %r25,1b
1111         fdc,m           %r23(%r26)
1112
1113         sync
1114         syncdma
1115         bv              %r0(%r2)
1116         nop
1117         .exit
1118
1119         .procend
1120 ENDPROC(flush_kernel_dcache_range_asm)
1121
1122 ENTRY(flush_user_icache_range_asm)
1123         .proc
1124         .callinfo NO_CALLS
1125         .entry
1126
1127         ldil            L%icache_stride, %r1
1128         ldw             R%icache_stride(%r1), %r23
1129         ldo             -1(%r23), %r21
1130         ANDCM           %r26, %r21, %r26
1131
1132 1:      cmpb,COND(<<),n %r26, %r25,1b
1133         fic,m           %r23(%sr3, %r26)
1134
1135         sync
1136         bv              %r0(%r2)
1137         nop
1138         .exit
1139
1140         .procend
1141 ENDPROC(flush_user_icache_range_asm)
1142
1143 ENTRY(flush_kernel_icache_page)
1144         .proc
1145         .callinfo NO_CALLS
1146         .entry
1147
1148         ldil            L%icache_stride, %r1
1149         ldw             R%icache_stride(%r1), %r23
1150
1151 #ifdef CONFIG_64BIT
1152         depdi,z         1, 63-PAGE_SHIFT,1, %r25
1153 #else
1154         depwi,z         1, 31-PAGE_SHIFT,1, %r25
1155 #endif
1156         add             %r26, %r25, %r25
1157         sub             %r25, %r23, %r25
1158
1159
1160 1:      fic,m           %r23(%sr4, %r26)
1161         fic,m           %r23(%sr4, %r26)
1162         fic,m           %r23(%sr4, %r26)
1163         fic,m           %r23(%sr4, %r26)
1164         fic,m           %r23(%sr4, %r26)
1165         fic,m           %r23(%sr4, %r26)
1166         fic,m           %r23(%sr4, %r26)
1167         fic,m           %r23(%sr4, %r26)
1168         fic,m           %r23(%sr4, %r26)
1169         fic,m           %r23(%sr4, %r26)
1170         fic,m           %r23(%sr4, %r26)
1171         fic,m           %r23(%sr4, %r26)
1172         fic,m           %r23(%sr4, %r26)
1173         fic,m           %r23(%sr4, %r26)
1174         fic,m           %r23(%sr4, %r26)
1175         cmpb,COND(<<)           %r26, %r25, 1b
1176         fic,m           %r23(%sr4, %r26)
1177
1178         sync
1179         bv              %r0(%r2)
1180         nop
1181         .exit
1182
1183         .procend
1184 ENDPROC(flush_kernel_icache_page)
1185
1186 ENTRY(flush_kernel_icache_range_asm)
1187         .proc
1188         .callinfo NO_CALLS
1189         .entry
1190
1191         ldil            L%icache_stride, %r1
1192         ldw             R%icache_stride(%r1), %r23
1193         ldo             -1(%r23), %r21
1194         ANDCM           %r26, %r21, %r26
1195
1196 1:      cmpb,COND(<<),n %r26, %r25, 1b
1197         fic,m           %r23(%sr4, %r26)
1198
1199         sync
1200         bv              %r0(%r2)
1201         nop
1202         .exit
1203         .procend
1204 ENDPROC(flush_kernel_icache_range_asm)
1205
1206         /* align should cover use of rfi in disable_sr_hashing_asm and
1207          * srdis_done.
1208          */
1209         .align  256
1210 ENTRY(disable_sr_hashing_asm)
1211         .proc
1212         .callinfo NO_CALLS
1213         .entry
1214
1215         /*
1216          * Switch to real mode
1217          */
1218         /* pcxt_ssm_bug */
1219         rsm             PSW_SM_I, %r0
1220         load32          PA(1f), %r1
1221         nop
1222         nop
1223         nop
1224         nop
1225         nop
1226
1227         rsm             PSW_SM_Q, %r0           /* prep to load iia queue */
1228         mtctl           %r0, %cr17              /* Clear IIASQ tail */
1229         mtctl           %r0, %cr17              /* Clear IIASQ head */
1230         mtctl           %r1, %cr18              /* IIAOQ head */
1231         ldo             4(%r1), %r1
1232         mtctl           %r1, %cr18              /* IIAOQ tail */
1233         load32          REAL_MODE_PSW, %r1
1234         mtctl           %r1, %ipsw
1235         rfi
1236         nop
1237
1238 1:      cmpib,=,n       SRHASH_PCXST, %r26,srdis_pcxs
1239         cmpib,=,n       SRHASH_PCXL, %r26,srdis_pcxl
1240         cmpib,=,n       SRHASH_PA20, %r26,srdis_pa20
1241         b,n             srdis_done
1242
1243 srdis_pcxs:
1244
1245         /* Disable Space Register Hashing for PCXS,PCXT,PCXT' */
1246
1247         .word           0x141c1a00              /* mfdiag %dr0, %r28 */
1248         .word           0x141c1a00              /* must issue twice */
1249         depwi           0,18,1, %r28            /* Clear DHE (dcache hash enable) */
1250         depwi           0,20,1, %r28            /* Clear IHE (icache hash enable) */
1251         .word           0x141c1600              /* mtdiag %r28, %dr0 */
1252         .word           0x141c1600              /* must issue twice */
1253         b,n             srdis_done
1254
1255 srdis_pcxl:
1256
1257         /* Disable Space Register Hashing for PCXL */
1258
1259         .word           0x141c0600              /* mfdiag %dr0, %r28 */
1260         depwi           0,28,2, %r28            /* Clear DHASH_EN & IHASH_EN */
1261         .word           0x141c0240              /* mtdiag %r28, %dr0 */
1262         b,n             srdis_done
1263
1264 srdis_pa20:
1265
1266         /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+,PCXW2 */
1267
1268         .word           0x144008bc              /* mfdiag %dr2, %r28 */
1269         depdi           0, 54,1, %r28           /* clear DIAG_SPHASH_ENAB (bit 54) */
1270         .word           0x145c1840              /* mtdiag %r28, %dr2 */
1271
1272
1273 srdis_done:
1274         /* Switch back to virtual mode */
1275         rsm             PSW_SM_I, %r0           /* prep to load iia queue */
1276         load32          2f, %r1
1277         nop
1278         nop
1279         nop
1280         nop
1281         nop
1282
1283         rsm             PSW_SM_Q, %r0           /* prep to load iia queue */
1284         mtctl           %r0, %cr17              /* Clear IIASQ tail */
1285         mtctl           %r0, %cr17              /* Clear IIASQ head */
1286         mtctl           %r1, %cr18              /* IIAOQ head */
1287         ldo             4(%r1), %r1
1288         mtctl           %r1, %cr18              /* IIAOQ tail */
1289         load32          KERNEL_PSW, %r1
1290         mtctl           %r1, %ipsw
1291         rfi
1292         nop
1293
1294 2:      bv              %r0(%r2)
1295         nop
1296         .exit
1297
1298         .procend
1299 ENDPROC(disable_sr_hashing_asm)
1300
1301         .end