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