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 __LP64__ 30#define ADDIB addib,* 31#define CMPB cmpb,* 32#define ANDCM andcm,* 33 34 .level 2.0w 35#else 36#define ADDIB addib, 37#define CMPB cmpb, 38#define ANDCM andcm 39 40 .level 2.0 41#endif 42 43#include <asm/assembly.h> 44#include <asm/psw.h> 45#include <asm/pgtable.h> 46#include <asm/cache.h> 47 48 .text 49 .align 128 50 51 .export flush_tlb_all_local,code 52 53flush_tlb_all_local: 54 .proc 55 .callinfo NO_CALLS 56 .entry 57 58 /* 59 * The pitlbe and pdtlbe instructions should only be used to 60 * flush the entire tlb. Also, there needs to be no intervening 61 * tlb operations, e.g. tlb misses, so the operation needs 62 * to happen in real mode with all interruptions disabled. 63 */ 64 65 /* 66 * Once again, we do the rfi dance ... some day we need examine 67 * all of our uses of this type of code and see what can be 68 * consolidated. 69 */ 70 71 rsm PSW_SM_I, %r19 /* relied upon translation! PA 2.0 Arch. F-5 */ 72 nop 73 nop 74 nop 75 nop 76 nop 77 nop 78 nop 79 80 rsm PSW_SM_Q, %r0 /* Turn off Q bit to load iia queue */ 81 ldil L%REAL_MODE_PSW, %r1 82 ldo R%REAL_MODE_PSW(%r1), %r1 83 mtctl %r1, %cr22 84 mtctl %r0, %cr17 /* Clear IIASQ tail */ 85 mtctl %r0, %cr17 /* Clear IIASQ head */ 86 ldil L%PA(1f), %r1 87 ldo R%PA(1f)(%r1), %r1 88 mtctl %r1, %cr18 /* IIAOQ head */ 89 ldo 4(%r1), %r1 90 mtctl %r1, %cr18 /* IIAOQ tail */ 91 rfi 92 nop 93 941: ldil L%PA(cache_info), %r1 95 ldo R%PA(cache_info)(%r1), %r1 96 97 /* Flush Instruction Tlb */ 98 99 LDREG ITLB_SID_BASE(%r1), %r20 100 LDREG ITLB_SID_STRIDE(%r1), %r21 101 LDREG ITLB_SID_COUNT(%r1), %r22 102 LDREG ITLB_OFF_BASE(%r1), %arg0 103 LDREG ITLB_OFF_STRIDE(%r1), %arg1 104 LDREG ITLB_OFF_COUNT(%r1), %arg2 105 LDREG ITLB_LOOP(%r1), %arg3 106 107 ADDIB= -1, %arg3, fitoneloop /* Preadjust and test */ 108 movb,<,n %arg3, %r31, fitdone /* If loop < 0, skip */ 109 copy %arg0, %r28 /* Init base addr */ 110 111fitmanyloop: /* Loop if LOOP >= 2 */ 112 mtsp %r20, %sr1 113 add %r21, %r20, %r20 /* increment space */ 114 copy %arg2, %r29 /* Init middle loop count */ 115 116fitmanymiddle: /* Loop if LOOP >= 2 */ 117 ADDIB> -1, %r31, fitmanymiddle /* Adjusted inner loop decr */ 118 pitlbe 0(%sr1, %r28) 119 pitlbe,m %arg1(%sr1, %r28) /* Last pitlbe and addr adjust */ 120 ADDIB> -1, %r29, fitmanymiddle /* Middle loop decr */ 121 copy %arg3, %r31 /* Re-init inner loop count */ 122 123 movb,tr %arg0, %r28, fitmanyloop /* Re-init base addr */ 124 ADDIB<=,n -1, %r22, fitdone /* Outer loop count decr */ 125 126fitoneloop: /* Loop if LOOP = 1 */ 127 mtsp %r20, %sr1 128 copy %arg0, %r28 /* init base addr */ 129 copy %arg2, %r29 /* init middle loop count */ 130 131fitonemiddle: /* Loop if LOOP = 1 */ 132 ADDIB> -1, %r29, fitonemiddle /* Middle loop count decr */ 133 pitlbe,m %arg1(%sr1, %r28) /* pitlbe for one loop */ 134 135 ADDIB> -1, %r22, fitoneloop /* Outer loop count decr */ 136 add %r21, %r20, %r20 /* increment space */ 137 138fitdone: 139 140 /* Flush Data Tlb */ 141 142 LDREG DTLB_SID_BASE(%r1), %r20 143 LDREG DTLB_SID_STRIDE(%r1), %r21 144 LDREG DTLB_SID_COUNT(%r1), %r22 145 LDREG DTLB_OFF_BASE(%r1), %arg0 146 LDREG DTLB_OFF_STRIDE(%r1), %arg1 147 LDREG DTLB_OFF_COUNT(%r1), %arg2 148 LDREG DTLB_LOOP(%r1), %arg3 149 150 ADDIB= -1, %arg3, fdtoneloop /* Preadjust and test */ 151 movb,<,n %arg3, %r31, fdtdone /* If loop < 0, skip */ 152 copy %arg0, %r28 /* Init base addr */ 153 154fdtmanyloop: /* Loop if LOOP >= 2 */ 155 mtsp %r20, %sr1 156 add %r21, %r20, %r20 /* increment space */ 157 copy %arg2, %r29 /* Init middle loop count */ 158 159fdtmanymiddle: /* Loop if LOOP >= 2 */ 160 ADDIB> -1, %r31, fdtmanymiddle /* Adjusted inner loop decr */ 161 pdtlbe 0(%sr1, %r28) 162 pdtlbe,m %arg1(%sr1, %r28) /* Last pdtlbe and addr adjust */ 163 ADDIB> -1, %r29, fdtmanymiddle /* Middle loop decr */ 164 copy %arg3, %r31 /* Re-init inner loop count */ 165 166 movb,tr %arg0, %r28, fdtmanyloop /* Re-init base addr */ 167 ADDIB<=,n -1, %r22,fdtdone /* Outer loop count decr */ 168 169fdtoneloop: /* Loop if LOOP = 1 */ 170 mtsp %r20, %sr1 171 copy %arg0, %r28 /* init base addr */ 172 copy %arg2, %r29 /* init middle loop count */ 173 174fdtonemiddle: /* Loop if LOOP = 1 */ 175 ADDIB> -1, %r29, fdtonemiddle /* Middle loop count decr */ 176 pdtlbe,m %arg1(%sr1, %r28) /* pdtlbe for one loop */ 177 178 ADDIB> -1, %r22, fdtoneloop /* Outer loop count decr */ 179 add %r21, %r20, %r20 /* increment space */ 180 181fdtdone: 182 183 /* Switch back to virtual mode */ 184 185 rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ 186 ldil L%KERNEL_PSW, %r1 187 ldo R%KERNEL_PSW(%r1), %r1 188 or %r1, %r19, %r1 /* Set I bit if set on entry */ 189 mtctl %r1, %cr22 190 mtctl %r0, %cr17 /* Clear IIASQ tail */ 191 mtctl %r0, %cr17 /* Clear IIASQ head */ 192 ldil L%(2f), %r1 193 ldo R%(2f)(%r1), %r1 194 mtctl %r1, %cr18 /* IIAOQ head */ 195 ldo 4(%r1), %r1 196 mtctl %r1, %cr18 /* IIAOQ tail */ 197 rfi 198 nop 199 2002: bv %r0(%r2) 201 nop 202 .exit 203 204 .procend 205 206 .export flush_instruction_cache_local,code 207 .import cache_info,data 208 209flush_instruction_cache_local: 210 .proc 211 .callinfo NO_CALLS 212 .entry 213 214 mtsp %r0, %sr1 215 ldil L%cache_info, %r1 216 ldo R%cache_info(%r1), %r1 217 218 /* Flush Instruction Cache */ 219 220 LDREG ICACHE_BASE(%r1), %arg0 221 LDREG ICACHE_STRIDE(%r1), %arg1 222 LDREG ICACHE_COUNT(%r1), %arg2 223 LDREG ICACHE_LOOP(%r1), %arg3 224 rsm PSW_SM_I, %r22 /* No mmgt ops during loop*/ 225 ADDIB= -1, %arg3, fioneloop /* Preadjust and test */ 226 movb,<,n %arg3, %r31, fisync /* If loop < 0, do sync */ 227 228fimanyloop: /* Loop if LOOP >= 2 */ 229 ADDIB> -1, %r31, fimanyloop /* Adjusted inner loop decr */ 230 fice 0(%sr1, %arg0) 231 fice,m %arg1(%sr1, %arg0) /* Last fice and addr adjust */ 232 movb,tr %arg3, %r31, fimanyloop /* Re-init inner loop count */ 233 ADDIB<=,n -1, %arg2, fisync /* Outer loop decr */ 234 235fioneloop: /* Loop if LOOP = 1 */ 236 ADDIB> -1, %arg2, fioneloop /* Outer loop count decr */ 237 fice,m %arg1(%sr1, %arg0) /* Fice for one loop */ 238 239fisync: 240 sync 241 mtsm %r22 242 bv %r0(%r2) 243 nop 244 .exit 245 246 .procend 247 248 .export flush_data_cache_local, code 249 .import cache_info, data 250 251flush_data_cache_local: 252 .proc 253 .callinfo NO_CALLS 254 .entry 255 256 mtsp %r0, %sr1 257 ldil L%cache_info, %r1 258 ldo R%cache_info(%r1), %r1 259 260 /* Flush Data Cache */ 261 262 LDREG DCACHE_BASE(%r1), %arg0 263 LDREG DCACHE_STRIDE(%r1), %arg1 264 LDREG DCACHE_COUNT(%r1), %arg2 265 LDREG DCACHE_LOOP(%r1), %arg3 266 rsm PSW_SM_I, %r22 267 ADDIB= -1, %arg3, fdoneloop /* Preadjust and test */ 268 movb,<,n %arg3, %r31, fdsync /* If loop < 0, do sync */ 269 270fdmanyloop: /* Loop if LOOP >= 2 */ 271 ADDIB> -1, %r31, fdmanyloop /* Adjusted inner loop decr */ 272 fdce 0(%sr1, %arg0) 273 fdce,m %arg1(%sr1, %arg0) /* Last fdce and addr adjust */ 274 movb,tr %arg3, %r31, fdmanyloop /* Re-init inner loop count */ 275 ADDIB<=,n -1, %arg2, fdsync /* Outer loop decr */ 276 277fdoneloop: /* Loop if LOOP = 1 */ 278 ADDIB> -1, %arg2, fdoneloop /* Outer loop count decr */ 279 fdce,m %arg1(%sr1, %arg0) /* Fdce for one loop */ 280 281fdsync: 282 syncdma 283 sync 284 mtsm %r22 285 bv %r0(%r2) 286 nop 287 .exit 288 289 .procend 290 291 .export copy_user_page_asm,code 292 .align 16 293 294copy_user_page_asm: 295 .proc 296 .callinfo NO_CALLS 297 .entry 298 299#ifdef __LP64__ 300 /* PA8x00 CPUs can consume 2 loads or 1 store per cycle. 301 * Unroll the loop by hand and arrange insn appropriately. 302 * GCC probably can do this just as well. 303 */ 304 305 ldd 0(%r25), %r19 306 ldi 32, %r1 /* PAGE_SIZE/128 == 32 */ 307 ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */ 308 ldw 128(%r25), %r0 /* prefetch 2 */ 309 3101: ldd 8(%r25), %r20 311 ldw 192(%r25), %r0 /* prefetch 3 */ 312 ldw 256(%r25), %r0 /* prefetch 4 */ 313 314 ldd 16(%r25), %r21 315 ldd 24(%r25), %r22 316 std %r19, 0(%r26) 317 std %r20, 8(%r26) 318 319 ldd 32(%r25), %r19 320 ldd 40(%r25), %r20 321 std %r21, 16(%r26) 322 std %r22, 24(%r26) 323 324 ldd 48(%r25), %r21 325 ldd 56(%r25), %r22 326 std %r19, 32(%r26) 327 std %r20, 40(%r26) 328 329 ldd 64(%r25), %r19 330 ldd 72(%r25), %r20 331 std %r21, 48(%r26) 332 std %r22, 56(%r26) 333 334 ldd 80(%r25), %r21 335 ldd 88(%r25), %r22 336 std %r19, 64(%r26) 337 std %r20, 72(%r26) 338 339 ldd 96(%r25), %r19 340 ldd 104(%r25), %r20 341 std %r21, 80(%r26) 342 std %r22, 88(%r26) 343 344 ldd 112(%r25), %r21 345 ldd 120(%r25), %r22 346 std %r19, 96(%r26) 347 std %r20, 104(%r26) 348 349 ldo 128(%r25), %r25 350 std %r21, 112(%r26) 351 std %r22, 120(%r26) 352 ldo 128(%r26), %r26 353 354 ADDIB> -1, %r1, 1b /* bundle 10 */ 355 ldd 0(%r25), %r19 /* start next loads */ 356 357#else 358 359 /* 360 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw 361 * bundles (very restricted rules for bundling). 362 * Note that until (if) we start saving 363 * the full 64 bit register values on interrupt, we can't 364 * use ldd/std on a 32 bit kernel. 365 */ 366 ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ 367 3681: 369 ldw 0(%r25), %r19 370 ldw 4(%r25), %r20 371 ldw 8(%r25), %r21 372 ldw 12(%r25), %r22 373 stw %r19, 0(%r26) 374 stw %r20, 4(%r26) 375 stw %r21, 8(%r26) 376 stw %r22, 12(%r26) 377 ldw 16(%r25), %r19 378 ldw 20(%r25), %r20 379 ldw 24(%r25), %r21 380 ldw 28(%r25), %r22 381 stw %r19, 16(%r26) 382 stw %r20, 20(%r26) 383 stw %r21, 24(%r26) 384 stw %r22, 28(%r26) 385 ldw 32(%r25), %r19 386 ldw 36(%r25), %r20 387 ldw 40(%r25), %r21 388 ldw 44(%r25), %r22 389 stw %r19, 32(%r26) 390 stw %r20, 36(%r26) 391 stw %r21, 40(%r26) 392 stw %r22, 44(%r26) 393 ldw 48(%r25), %r19 394 ldw 52(%r25), %r20 395 ldw 56(%r25), %r21 396 ldw 60(%r25), %r22 397 stw %r19, 48(%r26) 398 stw %r20, 52(%r26) 399 stw %r21, 56(%r26) 400 stw %r22, 60(%r26) 401 ldo 64(%r26), %r26 402 ADDIB> -1, %r1, 1b 403 ldo 64(%r25), %r25 404#endif 405 bv %r0(%r2) 406 nop 407 .exit 408 409 .procend 410 411/* 412 * NOTE: Code in clear_user_page has a hard coded dependency on the 413 * maximum alias boundary being 4 Mb. We've been assured by the 414 * parisc chip designers that there will not ever be a parisc 415 * chip with a larger alias boundary (Never say never :-) ). 416 * 417 * Subtle: the dtlb miss handlers support the temp alias region by 418 * "knowing" that if a dtlb miss happens within the temp alias 419 * region it must have occurred while in clear_user_page. Since 420 * this routine makes use of processor local translations, we 421 * don't want to insert them into the kernel page table. Instead, 422 * we load up some general registers (they need to be registers 423 * which aren't shadowed) with the physical page numbers (preshifted 424 * for tlb insertion) needed to insert the translations. When we 425 * miss on the translation, the dtlb miss handler inserts the 426 * translation into the tlb using these values: 427 * 428 * %r26 physical page (shifted for tlb insert) of "to" translation 429 * %r23 physical page (shifted for tlb insert) of "from" translation 430 */ 431 432#if 0 433 434 /* 435 * We can't do this since copy_user_page is used to bring in 436 * file data that might have instructions. Since the data would 437 * then need to be flushed out so the i-fetch can see it, it 438 * makes more sense to just copy through the kernel translation 439 * and flush it. 440 * 441 * I'm still keeping this around because it may be possible to 442 * use it if more information is passed into copy_user_page(). 443 * Have to do some measurements to see if it is worthwhile to 444 * lobby for such a change. 445 */ 446 447 .export copy_user_page_asm,code 448 449copy_user_page_asm: 450 .proc 451 .callinfo NO_CALLS 452 .entry 453 454 ldil L%(__PAGE_OFFSET), %r1 455 sub %r26, %r1, %r26 456 sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */ 457 458 ldil L%(TMPALIAS_MAP_START), %r28 459#ifdef __LP64__ 460 extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */ 461 extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */ 462 depd %r24,63,22, %r28 /* Form aliased virtual address 'to' */ 463 depdi 0, 63,12, %r28 /* Clear any offset bits */ 464 copy %r28, %r29 465 depdi 1, 41,1, %r29 /* Form aliased virtual address 'from' */ 466#else 467 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 468 extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */ 469 depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */ 470 depwi 0, 31,12, %r28 /* Clear any offset bits */ 471 copy %r28, %r29 472 depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */ 473#endif 474 475 /* Purge any old translations */ 476 477 pdtlb 0(%r28) 478 pdtlb 0(%r29) 479 480 ldi 64, %r1 481 482 /* 483 * This loop is optimized for PCXL/PCXL2 ldw/ldw and stw/stw 484 * bundles (very restricted rules for bundling). It probably 485 * does OK on PCXU and better, but we could do better with 486 * ldd/std instructions. Note that until (if) we start saving 487 * the full 64 bit register values on interrupt, we can't 488 * use ldd/std on a 32 bit kernel. 489 */ 490 491 4921: 493 ldw 0(%r29), %r19 494 ldw 4(%r29), %r20 495 ldw 8(%r29), %r21 496 ldw 12(%r29), %r22 497 stw %r19, 0(%r28) 498 stw %r20, 4(%r28) 499 stw %r21, 8(%r28) 500 stw %r22, 12(%r28) 501 ldw 16(%r29), %r19 502 ldw 20(%r29), %r20 503 ldw 24(%r29), %r21 504 ldw 28(%r29), %r22 505 stw %r19, 16(%r28) 506 stw %r20, 20(%r28) 507 stw %r21, 24(%r28) 508 stw %r22, 28(%r28) 509 ldw 32(%r29), %r19 510 ldw 36(%r29), %r20 511 ldw 40(%r29), %r21 512 ldw 44(%r29), %r22 513 stw %r19, 32(%r28) 514 stw %r20, 36(%r28) 515 stw %r21, 40(%r28) 516 stw %r22, 44(%r28) 517 ldw 48(%r29), %r19 518 ldw 52(%r29), %r20 519 ldw 56(%r29), %r21 520 ldw 60(%r29), %r22 521 stw %r19, 48(%r28) 522 stw %r20, 52(%r28) 523 stw %r21, 56(%r28) 524 stw %r22, 60(%r28) 525 ldo 64(%r28), %r28 526 ADDIB> -1, %r1,1b 527 ldo 64(%r29), %r29 528 529 bv %r0(%r2) 530 nop 531 .exit 532 533 .procend 534#endif 535 536 .export __clear_user_page_asm,code 537 538__clear_user_page_asm: 539 .proc 540 .callinfo NO_CALLS 541 .entry 542 543 tophys_r1 %r26 544 545 ldil L%(TMPALIAS_MAP_START), %r28 546#ifdef __LP64__ 547#if (TMPALIAS_MAP_START >= 0x80000000) 548 depdi 0, 31,32, %r28 /* clear any sign extension */ 549#endif 550 extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ 551 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ 552 depdi 0, 63,12, %r28 /* Clear any offset bits */ 553#else 554 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 555 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ 556 depwi 0, 31,12, %r28 /* Clear any offset bits */ 557#endif 558 559 /* Purge any old translation */ 560 561 pdtlb 0(%r28) 562 563#ifdef __LP64__ 564 ldi 32, %r1 /* PAGE_SIZE/128 == 32 */ 565 566 /* PREFETCH (Write) has not (yet) been proven to help here */ 567/* #define PREFETCHW_OP ldd 256(%0), %r0 */ 568 5691: std %r0, 0(%r28) 570 std %r0, 8(%r28) 571 std %r0, 16(%r28) 572 std %r0, 24(%r28) 573 std %r0, 32(%r28) 574 std %r0, 40(%r28) 575 std %r0, 48(%r28) 576 std %r0, 56(%r28) 577 std %r0, 64(%r28) 578 std %r0, 72(%r28) 579 std %r0, 80(%r28) 580 std %r0, 88(%r28) 581 std %r0, 96(%r28) 582 std %r0, 104(%r28) 583 std %r0, 112(%r28) 584 std %r0, 120(%r28) 585 ADDIB> -1, %r1, 1b 586 ldo 128(%r28), %r28 587 588#else /* ! __LP64 */ 589 590 ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ 591 5921: 593 stw %r0, 0(%r28) 594 stw %r0, 4(%r28) 595 stw %r0, 8(%r28) 596 stw %r0, 12(%r28) 597 stw %r0, 16(%r28) 598 stw %r0, 20(%r28) 599 stw %r0, 24(%r28) 600 stw %r0, 28(%r28) 601 stw %r0, 32(%r28) 602 stw %r0, 36(%r28) 603 stw %r0, 40(%r28) 604 stw %r0, 44(%r28) 605 stw %r0, 48(%r28) 606 stw %r0, 52(%r28) 607 stw %r0, 56(%r28) 608 stw %r0, 60(%r28) 609 ADDIB> -1, %r1, 1b 610 ldo 64(%r28), %r28 611#endif /* __LP64 */ 612 613 bv %r0(%r2) 614 nop 615 .exit 616 617 .procend 618 619 .export flush_kernel_dcache_page 620 621flush_kernel_dcache_page: 622 .proc 623 .callinfo NO_CALLS 624 .entry 625 626 ldil L%dcache_stride, %r1 627 ldw R%dcache_stride(%r1), %r23 628 629#ifdef __LP64__ 630 depdi,z 1, 63-PAGE_SHIFT,1, %r25 631#else 632 depwi,z 1, 31-PAGE_SHIFT,1, %r25 633#endif 634 add %r26, %r25, %r25 635 sub %r25, %r23, %r25 636 637 6381: fdc,m %r23(%r26) 639 fdc,m %r23(%r26) 640 fdc,m %r23(%r26) 641 fdc,m %r23(%r26) 642 fdc,m %r23(%r26) 643 fdc,m %r23(%r26) 644 fdc,m %r23(%r26) 645 fdc,m %r23(%r26) 646 fdc,m %r23(%r26) 647 fdc,m %r23(%r26) 648 fdc,m %r23(%r26) 649 fdc,m %r23(%r26) 650 fdc,m %r23(%r26) 651 fdc,m %r23(%r26) 652 fdc,m %r23(%r26) 653 CMPB<< %r26, %r25,1b 654 fdc,m %r23(%r26) 655 656 sync 657 bv %r0(%r2) 658 nop 659 .exit 660 661 .procend 662 663 .export flush_user_dcache_page 664 665flush_user_dcache_page: 666 .proc 667 .callinfo NO_CALLS 668 .entry 669 670 ldil L%dcache_stride, %r1 671 ldw R%dcache_stride(%r1), %r23 672 673#ifdef __LP64__ 674 depdi,z 1,63-PAGE_SHIFT,1, %r25 675#else 676 depwi,z 1,31-PAGE_SHIFT,1, %r25 677#endif 678 add %r26, %r25, %r25 679 sub %r25, %r23, %r25 680 681 6821: fdc,m %r23(%sr3, %r26) 683 fdc,m %r23(%sr3, %r26) 684 fdc,m %r23(%sr3, %r26) 685 fdc,m %r23(%sr3, %r26) 686 fdc,m %r23(%sr3, %r26) 687 fdc,m %r23(%sr3, %r26) 688 fdc,m %r23(%sr3, %r26) 689 fdc,m %r23(%sr3, %r26) 690 fdc,m %r23(%sr3, %r26) 691 fdc,m %r23(%sr3, %r26) 692 fdc,m %r23(%sr3, %r26) 693 fdc,m %r23(%sr3, %r26) 694 fdc,m %r23(%sr3, %r26) 695 fdc,m %r23(%sr3, %r26) 696 fdc,m %r23(%sr3, %r26) 697 CMPB<< %r26, %r25,1b 698 fdc,m %r23(%sr3, %r26) 699 700 sync 701 bv %r0(%r2) 702 nop 703 .exit 704 705 .procend 706 707 .export flush_user_icache_page 708 709flush_user_icache_page: 710 .proc 711 .callinfo NO_CALLS 712 .entry 713 714 ldil L%dcache_stride, %r1 715 ldw R%dcache_stride(%r1), %r23 716 717#ifdef __LP64__ 718 depdi,z 1, 63-PAGE_SHIFT,1, %r25 719#else 720 depwi,z 1, 31-PAGE_SHIFT,1, %r25 721#endif 722 add %r26, %r25, %r25 723 sub %r25, %r23, %r25 724 725 7261: fic,m %r23(%sr3, %r26) 727 fic,m %r23(%sr3, %r26) 728 fic,m %r23(%sr3, %r26) 729 fic,m %r23(%sr3, %r26) 730 fic,m %r23(%sr3, %r26) 731 fic,m %r23(%sr3, %r26) 732 fic,m %r23(%sr3, %r26) 733 fic,m %r23(%sr3, %r26) 734 fic,m %r23(%sr3, %r26) 735 fic,m %r23(%sr3, %r26) 736 fic,m %r23(%sr3, %r26) 737 fic,m %r23(%sr3, %r26) 738 fic,m %r23(%sr3, %r26) 739 fic,m %r23(%sr3, %r26) 740 fic,m %r23(%sr3, %r26) 741 CMPB<< %r26, %r25,1b 742 fic,m %r23(%sr3, %r26) 743 744 sync 745 bv %r0(%r2) 746 nop 747 .exit 748 749 .procend 750 751 752 .export purge_kernel_dcache_page 753 754purge_kernel_dcache_page: 755 .proc 756 .callinfo NO_CALLS 757 .entry 758 759 ldil L%dcache_stride, %r1 760 ldw R%dcache_stride(%r1), %r23 761 762#ifdef __LP64__ 763 depdi,z 1, 63-PAGE_SHIFT,1, %r25 764#else 765 depwi,z 1, 31-PAGE_SHIFT,1, %r25 766#endif 767 add %r26, %r25, %r25 768 sub %r25, %r23, %r25 769 7701: pdc,m %r23(%r26) 771 pdc,m %r23(%r26) 772 pdc,m %r23(%r26) 773 pdc,m %r23(%r26) 774 pdc,m %r23(%r26) 775 pdc,m %r23(%r26) 776 pdc,m %r23(%r26) 777 pdc,m %r23(%r26) 778 pdc,m %r23(%r26) 779 pdc,m %r23(%r26) 780 pdc,m %r23(%r26) 781 pdc,m %r23(%r26) 782 pdc,m %r23(%r26) 783 pdc,m %r23(%r26) 784 pdc,m %r23(%r26) 785 CMPB<< %r26, %r25, 1b 786 pdc,m %r23(%r26) 787 788 sync 789 bv %r0(%r2) 790 nop 791 .exit 792 793 .procend 794 795#if 0 796 /* Currently not used, but it still is a possible alternate 797 * solution. 798 */ 799 800 .export flush_alias_page 801 802flush_alias_page: 803 .proc 804 .callinfo NO_CALLS 805 .entry 806 807 tophys_r1 %r26 808 809 ldil L%(TMPALIAS_MAP_START), %r28 810#ifdef __LP64__ 811 extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ 812 depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ 813 depdi 0, 63,12, %r28 /* Clear any offset bits */ 814#else 815 extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ 816 depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ 817 depwi 0, 31,12, %r28 /* Clear any offset bits */ 818#endif 819 820 /* Purge any old translation */ 821 822 pdtlb 0(%r28) 823 824 ldil L%dcache_stride, %r1 825 ldw R%dcache_stride(%r1), %r23 826 827#ifdef __LP64__ 828 depdi,z 1, 63-PAGE_SHIFT,1, %r29 829#else 830 depwi,z 1, 31-PAGE_SHIFT,1, %r29 831#endif 832 add %r28, %r29, %r29 833 sub %r29, %r23, %r29 834 8351: fdc,m %r23(%r28) 836 fdc,m %r23(%r28) 837 fdc,m %r23(%r28) 838 fdc,m %r23(%r28) 839 fdc,m %r23(%r28) 840 fdc,m %r23(%r28) 841 fdc,m %r23(%r28) 842 fdc,m %r23(%r28) 843 fdc,m %r23(%r28) 844 fdc,m %r23(%r28) 845 fdc,m %r23(%r28) 846 fdc,m %r23(%r28) 847 fdc,m %r23(%r28) 848 fdc,m %r23(%r28) 849 fdc,m %r23(%r28) 850 CMPB<< %r28, %r29, 1b 851 fdc,m %r23(%r28) 852 853 sync 854 bv %r0(%r2) 855 nop 856 .exit 857 858 .procend 859#endif 860 861 .export flush_user_dcache_range_asm 862 863flush_user_dcache_range_asm: 864 .proc 865 .callinfo NO_CALLS 866 .entry 867 868 ldil L%dcache_stride, %r1 869 ldw R%dcache_stride(%r1), %r23 870 ldo -1(%r23), %r21 871 ANDCM %r26, %r21, %r26 872 8731: CMPB<<,n %r26, %r25, 1b 874 fdc,m %r23(%sr3, %r26) 875 876 sync 877 bv %r0(%r2) 878 nop 879 .exit 880 881 .procend 882 883 .export flush_kernel_dcache_range_asm 884 885flush_kernel_dcache_range_asm: 886 .proc 887 .callinfo NO_CALLS 888 .entry 889 890 ldil L%dcache_stride, %r1 891 ldw R%dcache_stride(%r1), %r23 892 ldo -1(%r23), %r21 893 ANDCM %r26, %r21, %r26 894 8951: CMPB<<,n %r26, %r25,1b 896 fdc,m %r23(%r26) 897 898 sync 899 syncdma 900 bv %r0(%r2) 901 nop 902 .exit 903 904 .procend 905 906 .export flush_user_icache_range_asm 907 908flush_user_icache_range_asm: 909 .proc 910 .callinfo NO_CALLS 911 .entry 912 913 ldil L%icache_stride, %r1 914 ldw R%icache_stride(%r1), %r23 915 ldo -1(%r23), %r21 916 ANDCM %r26, %r21, %r26 917 9181: CMPB<<,n %r26, %r25,1b 919 fic,m %r23(%sr3, %r26) 920 921 sync 922 bv %r0(%r2) 923 nop 924 .exit 925 926 .procend 927 928 .export flush_kernel_icache_page 929 930flush_kernel_icache_page: 931 .proc 932 .callinfo NO_CALLS 933 .entry 934 935 ldil L%icache_stride, %r1 936 ldw R%icache_stride(%r1), %r23 937 938#ifdef __LP64__ 939 depdi,z 1, 63-PAGE_SHIFT,1, %r25 940#else 941 depwi,z 1, 31-PAGE_SHIFT,1, %r25 942#endif 943 add %r26, %r25, %r25 944 sub %r25, %r23, %r25 945 946 9471: fic,m %r23(%r26) 948 fic,m %r23(%r26) 949 fic,m %r23(%r26) 950 fic,m %r23(%r26) 951 fic,m %r23(%r26) 952 fic,m %r23(%r26) 953 fic,m %r23(%r26) 954 fic,m %r23(%r26) 955 fic,m %r23(%r26) 956 fic,m %r23(%r26) 957 fic,m %r23(%r26) 958 fic,m %r23(%r26) 959 fic,m %r23(%r26) 960 fic,m %r23(%r26) 961 fic,m %r23(%r26) 962 CMPB<< %r26, %r25, 1b 963 fic,m %r23(%r26) 964 965 sync 966 bv %r0(%r2) 967 nop 968 .exit 969 970 .procend 971 972 .export flush_kernel_icache_range_asm 973 974flush_kernel_icache_range_asm: 975 .proc 976 .callinfo NO_CALLS 977 .entry 978 979 ldil L%icache_stride, %r1 980 ldw R%icache_stride(%r1), %r23 981 ldo -1(%r23), %r21 982 ANDCM %r26, %r21, %r26 983 9841: CMPB<<,n %r26, %r25, 1b 985 fic,m %r23(%r26) 986 987 sync 988 bv %r0(%r2) 989 nop 990 .exit 991 992 .procend 993 994 .align 128 995 996 .export disable_sr_hashing_asm,code 997 998disable_sr_hashing_asm: 999 .proc 1000 .callinfo NO_CALLS 1001 .entry 1002 1003 /* Switch to real mode */ 1004 1005 ssm 0, %r0 /* relied upon translation! */ 1006 nop 1007 nop 1008 nop 1009 nop 1010 nop 1011 nop 1012 nop 1013 1014 rsm (PSW_SM_Q|PSW_SM_I), %r0 /* disable Q&I to load the iia queue */ 1015 ldil L%REAL_MODE_PSW, %r1 1016 ldo R%REAL_MODE_PSW(%r1), %r1 1017 mtctl %r1, %cr22 1018 mtctl %r0, %cr17 /* Clear IIASQ tail */ 1019 mtctl %r0, %cr17 /* Clear IIASQ head */ 1020 ldil L%PA(1f), %r1 1021 ldo R%PA(1f)(%r1), %r1 1022 mtctl %r1, %cr18 /* IIAOQ head */ 1023 ldo 4(%r1), %r1 1024 mtctl %r1, %cr18 /* IIAOQ tail */ 1025 rfi 1026 nop 1027 10281: cmpib,=,n SRHASH_PCXST, %r26,srdis_pcxs 1029 cmpib,=,n SRHASH_PCXL, %r26,srdis_pcxl 1030 cmpib,=,n SRHASH_PA20, %r26,srdis_pa20 1031 b,n srdis_done 1032 1033srdis_pcxs: 1034 1035 /* Disable Space Register Hashing for PCXS,PCXT,PCXT' */ 1036 1037 .word 0x141c1a00 /* mfdiag %dr0, %r28 */ 1038 .word 0x141c1a00 /* must issue twice */ 1039 depwi 0,18,1, %r28 /* Clear DHE (dcache hash enable) */ 1040 depwi 0,20,1, %r28 /* Clear IHE (icache hash enable) */ 1041 .word 0x141c1600 /* mtdiag %r28, %dr0 */ 1042 .word 0x141c1600 /* must issue twice */ 1043 b,n srdis_done 1044 1045srdis_pcxl: 1046 1047 /* Disable Space Register Hashing for PCXL */ 1048 1049 .word 0x141c0600 /* mfdiag %dr0, %r28 */ 1050 depwi 0,28,2, %r28 /* Clear DHASH_EN & IHASH_EN */ 1051 .word 0x141c0240 /* mtdiag %r28, %dr0 */ 1052 b,n srdis_done 1053 1054srdis_pa20: 1055 1056 /* Disable Space Register Hashing for PCXU,PCXU+,PCXW,PCXW+ */ 1057 1058 .word 0x144008bc /* mfdiag %dr2, %r28 */ 1059 depdi 0, 54,1, %r28 /* clear DIAG_SPHASH_ENAB (bit 54) */ 1060 .word 0x145c1840 /* mtdiag %r28, %dr2 */ 1061 1062srdis_done: 1063 1064 /* Switch back to virtual mode */ 1065 1066 rsm PSW_SM_Q, %r0 /* clear Q bit to load iia queue */ 1067 ldil L%KERNEL_PSW, %r1 1068 ldo R%KERNEL_PSW(%r1), %r1 1069 mtctl %r1, %cr22 1070 mtctl %r0, %cr17 /* Clear IIASQ tail */ 1071 mtctl %r0, %cr17 /* Clear IIASQ head */ 1072 ldil L%(2f), %r1 1073 ldo R%(2f)(%r1), %r1 1074 mtctl %r1, %cr18 /* IIAOQ head */ 1075 ldo 4(%r1), %r1 1076 mtctl %r1, %cr18 /* IIAOQ tail */ 1077 rfi 1078 nop 1079 10802: bv %r0(%r2) 1081 nop 1082 .exit 1083 1084 .procend 1085 1086 .end 1087