1/* SPDX-License-Identifier: GPL-2.0-or-later */ 2/* 3 * PARISC TLB and cache flushing support 4 * Copyright (C) 2000-2001 Hewlett-Packard (John Marvin) 5 * Copyright (C) 2001 Matthew Wilcox (willy at parisc-linux.org) 6 * Copyright (C) 2002 Richard Hirst (rhirst with parisc-linux.org) 7 */ 8 9/* 10 * NOTE: fdc,fic, and pdc instructions that use base register modification 11 * should only use index and base registers that are not shadowed, 12 * so that the fast path emulation in the non access miss handler 13 * can be used. 14 */ 15 16#ifdef CONFIG_64BIT 17 .level 2.0w 18#else 19 .level 2.0 20#endif 21 22#include <asm/psw.h> 23#include <asm/assembly.h> 24#include <asm/cache.h> 25#include <asm/ldcw.h> 26#include <asm/alternative.h> 27#include <linux/linkage.h> 28#include <linux/init.h> 29#include <linux/pgtable.h> 30 31 .section .text.hot 32 .align 16 33 34ENTRY_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 621: load32 PA(cache_info), %r1 63 64 /* Flush Instruction Tlb */ 65 6688: 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 78fitmanyloop: /* Loop if LOOP >= 2 */ 79 mtsp %r20, %sr1 80 add %r21, %r20, %r20 /* increment space */ 81 copy %arg2, %r29 /* Init middle loop count */ 82 83fitmanymiddle: /* 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 93fitoneloop: /* Loop if LOOP = 1 */ 94 mtsp %r20, %sr1 95 copy %arg0, %r28 /* init base addr */ 96 copy %arg2, %r29 /* init middle loop count */ 97 98fitonemiddle: /* 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 105fitdone: 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 122fdtmanyloop: /* Loop if LOOP >= 2 */ 123 mtsp %r20, %sr1 124 add %r21, %r20, %r20 /* increment space */ 125 copy %arg2, %r29 /* Init middle loop count */ 126 127fdtmanymiddle: /* 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 137fdtoneloop: /* Loop if LOOP = 1 */ 138 mtsp %r20, %sr1 139 copy %arg0, %r28 /* init base addr */ 140 copy %arg2, %r29 /* init middle loop count */ 141 142fdtonemiddle: /* 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 150fdtdone: 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 1752: 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 */ 1833: pdtlbe %r0(%sr1,%r0) 184 bv,n %r0(%r2) 185 ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b) 186ENDPROC_CFI(flush_tlb_all_local) 187 188 .import cache_info,data 189 190ENTRY_CFI(flush_instruction_cache_local) 19188: 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 204fimanyloop: /* 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 211fioneloop: /* Loop if LOOP = 1 */ 212 /* Some implementations may flush with a single fice instruction */ 213 cmpib,COND(>>=),n 15, %arg2, fioneloop2 214 215fioneloop1: 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 237fioneloop2: 238 addib,COND(>) -1, %arg2, fioneloop2 /* Outer loop count decr */ 239 fice,m %arg1(%sr1, %arg0) /* Fice for one loop */ 240 241fisync: 242 sync 243 mtsm %r22 /* restore I-bit */ 24489: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) 245 bv %r0(%r2) 246 nop 247ENDPROC_CFI(flush_instruction_cache_local) 248 249 250 .import cache_info, data 251ENTRY_CFI(flush_data_cache_local) 25288: 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 265fdmanyloop: /* 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 272fdoneloop: /* Loop if LOOP = 1 */ 273 /* Some implementations may flush with a single fdce instruction */ 274 cmpib,COND(>>=),n 15, %arg2, fdoneloop2 275 276fdoneloop1: 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 298fdoneloop2: 299 addib,COND(>) -1, %arg2, fdoneloop2 /* Outer loop count decr */ 300 fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */ 301 302fdsync: 303 syncdma 304 sync 305 mtsm %r22 /* restore I-bit */ 30689: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 307 bv %r0(%r2) 308 nop 309ENDPROC_CFI(flush_data_cache_local) 310 311/* Clear page using kernel mapping. */ 312 313ENTRY_CFI(clear_page_asm) 314#ifdef CONFIG_64BIT 315 316 /* Unroll the loop. */ 317 ldi (PAGE_SIZE / 128), %r1 318 3191: 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 3491: 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 372ENDPROC_CFI(clear_page_asm) 373 374/* Copy page using kernel mapping. */ 375 376ENTRY_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 3861: 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 4441: 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 483ENDPROC_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 535ENTRY_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 5680: pdtlb %r0(%r28) 5691: 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 5831: 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 6441: 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 684ENDPROC_CFI(copy_user_page_asm) 685 686ENTRY_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 7080: 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 7181: 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 7401: 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 762ENDPROC_CFI(clear_user_page_asm) 763 764ENTRY_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 7840: pdtlb %r0(%r28) 785 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 786#endif 787 78888: 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 7991: 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 81789: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 818 sync 819 bv %r0(%r2) 820 nop 821ENDPROC_CFI(flush_dcache_page_asm) 822 823ENTRY_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 8430: pdtlb %r0(%r28) 844 ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB) 845#endif 846 84788: 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 8581: 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 87689: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 877 sync 878 bv %r0(%r2) 879 nop 880ENDPROC_CFI(purge_dcache_page_asm) 881 882ENTRY_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) 9041: pitlb,l %r0(%sr4,%r28) 905 ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP) 906#else 9070: pdtlb %r0(%r28) 9081: 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 91488: 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 */ 9271: 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 94589: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) 946 sync 947 bv %r0(%r2) 948 nop 949ENDPROC_CFI(flush_icache_page_asm) 950 951ENTRY_CFI(flush_kernel_dcache_page_asm) 95288: 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 9631: 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 98189: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 982 sync 983 bv %r0(%r2) 984 nop 985ENDPROC_CFI(flush_kernel_dcache_page_asm) 986 987ENTRY_CFI(purge_kernel_dcache_page_asm) 98888: 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 9991: 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 101789: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 1018 sync 1019 bv %r0(%r2) 1020 nop 1021ENDPROC_CFI(purge_kernel_dcache_page_asm) 1022 1023ENTRY_CFI(flush_user_dcache_range_asm) 102488: 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 */ 10361: 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 10552: cmpb,COND(>>),n %r25, %r26, 2b 1056 fdc,m %r23(%sr3, %r26) 1057 105889: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 1059 sync 1060 bv %r0(%r2) 1061 nop 1062ENDPROC_CFI(flush_user_dcache_range_asm) 1063 1064ENTRY_CFI(flush_kernel_dcache_range_asm) 106588: 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 */ 10771: 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 10962: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ 1097 fdc,m %r23(%r26) 1098 1099 sync 110089: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 1101 syncdma 1102 bv %r0(%r2) 1103 nop 1104ENDPROC_CFI(flush_kernel_dcache_range_asm) 1105 1106ENTRY_CFI(purge_kernel_dcache_range_asm) 110788: 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 */ 11191: 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 11382: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ 1139 pdc,m %r23(%r26) 1140 1141 sync 114289: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP) 1143 syncdma 1144 bv %r0(%r2) 1145 nop 1146ENDPROC_CFI(purge_kernel_dcache_range_asm) 1147 1148ENTRY_CFI(flush_user_icache_range_asm) 114988: 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 */ 11611: 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 11802: cmpb,COND(>>),n %r25, %r26, 2b 1181 fic,m %r23(%sr3, %r26) 1182 118389: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) 1184 sync 1185 bv %r0(%r2) 1186 nop 1187ENDPROC_CFI(flush_user_icache_range_asm) 1188 1189ENTRY_CFI(flush_kernel_icache_page) 119088: 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 12021: 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 122089: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) 1221 sync 1222 bv %r0(%r2) 1223 nop 1224ENDPROC_CFI(flush_kernel_icache_page) 1225 1226ENTRY_CFI(flush_kernel_icache_range_asm) 122788: 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 */ 12391: 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 12582: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */ 1259 fic,m %r23(%sr4, %r26) 1260 126189: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP) 1262 sync 1263 bv %r0(%r2) 1264 nop 1265ENDPROC_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 1273ENTRY_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 12971: 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 1302srdis_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 1314srdis_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 1323srdis_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 1332srdis_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 13532: bv %r0(%r2) 1354 nop 1355ENDPROC_CFI(disable_sr_hashing_asm) 1356 1357 .end 1358