root/arch/parisc/kernel/pacache.S

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

/* [<][>][^][v][top][bottom][index][help] */