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