1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * ultra.S: Don't expand these all over the place... 4 * 5 * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net) 6 */ 7 8 #include <linux/pgtable.h> 9 #include <asm/asi.h> 10 #include <asm/page.h> 11 #include <asm/spitfire.h> 12 #include <asm/mmu_context.h> 13 #include <asm/mmu.h> 14 #include <asm/pil.h> 15 #include <asm/head.h> 16 #include <asm/thread_info.h> 17 #include <asm/cacheflush.h> 18 #include <asm/hypervisor.h> 19 #include <asm/cpudata.h> 20 21 /* Basically, most of the Spitfire vs. Cheetah madness 22 * has to do with the fact that Cheetah does not support 23 * IMMU flushes out of the secondary context. Someone needs 24 * to throw a south lake birthday party for the folks 25 * in Microelectronics who refused to fix this shit. 26 */ 27 28 /* This file is meant to be read efficiently by the CPU, not humans. 29 * Staraj sie tego nikomu nie pierdolnac... 30 */ 31 .text 32 .align 32 33 .globl __flush_tlb_mm 34 __flush_tlb_mm: /* 19 insns */ 35 /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ 36 ldxa [%o1] ASI_DMMU, %g2 37 cmp %g2, %o0 38 bne,pn %icc, __spitfire_flush_tlb_mm_slow 39 mov 0x50, %g3 40 stxa %g0, [%g3] ASI_DMMU_DEMAP 41 stxa %g0, [%g3] ASI_IMMU_DEMAP 42 sethi %hi(KERNBASE), %g3 43 flush %g3 44 retl 45 nop 46 nop 47 nop 48 nop 49 nop 50 nop 51 nop 52 nop 53 nop 54 nop 55 56 .align 32 57 .globl __flush_tlb_page 58 __flush_tlb_page: /* 22 insns */ 59 /* %o0 = context, %o1 = vaddr */ 60 rdpr %pstate, %g7 61 andn %g7, PSTATE_IE, %g2 62 wrpr %g2, %pstate 63 mov SECONDARY_CONTEXT, %o4 64 ldxa [%o4] ASI_DMMU, %g2 65 stxa %o0, [%o4] ASI_DMMU 66 andcc %o1, 1, %g0 67 andn %o1, 1, %o3 68 be,pn %icc, 1f 69 or %o3, 0x10, %o3 70 stxa %g0, [%o3] ASI_IMMU_DEMAP 71 1: stxa %g0, [%o3] ASI_DMMU_DEMAP 72 membar #Sync 73 stxa %g2, [%o4] ASI_DMMU 74 sethi %hi(KERNBASE), %o4 75 flush %o4 76 retl 77 wrpr %g7, 0x0, %pstate 78 nop 79 nop 80 nop 81 nop 82 83 .align 32 84 .globl __flush_tlb_pending 85 __flush_tlb_pending: /* 27 insns */ 86 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ 87 rdpr %pstate, %g7 88 sllx %o1, 3, %o1 89 andn %g7, PSTATE_IE, %g2 90 wrpr %g2, %pstate 91 mov SECONDARY_CONTEXT, %o4 92 ldxa [%o4] ASI_DMMU, %g2 93 stxa %o0, [%o4] ASI_DMMU 94 1: sub %o1, (1 << 3), %o1 95 ldx [%o2 + %o1], %o3 96 andcc %o3, 1, %g0 97 andn %o3, 1, %o3 98 be,pn %icc, 2f 99 or %o3, 0x10, %o3 100 stxa %g0, [%o3] ASI_IMMU_DEMAP 101 2: stxa %g0, [%o3] ASI_DMMU_DEMAP 102 membar #Sync 103 brnz,pt %o1, 1b 104 nop 105 stxa %g2, [%o4] ASI_DMMU 106 sethi %hi(KERNBASE), %o4 107 flush %o4 108 retl 109 wrpr %g7, 0x0, %pstate 110 nop 111 nop 112 nop 113 nop 114 115 .align 32 116 .globl __flush_tlb_kernel_range 117 __flush_tlb_kernel_range: /* 31 insns */ 118 /* %o0=start, %o1=end */ 119 cmp %o0, %o1 120 be,pn %xcc, 2f 121 sub %o1, %o0, %o3 122 srlx %o3, 18, %o4 123 brnz,pn %o4, __spitfire_flush_tlb_kernel_range_slow 124 sethi %hi(PAGE_SIZE), %o4 125 sub %o3, %o4, %o3 126 or %o0, 0x20, %o0 ! Nucleus 127 1: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP 128 stxa %g0, [%o0 + %o3] ASI_IMMU_DEMAP 129 membar #Sync 130 brnz,pt %o3, 1b 131 sub %o3, %o4, %o3 132 2: sethi %hi(KERNBASE), %o3 133 flush %o3 134 retl 135 nop 136 nop 137 nop 138 nop 139 nop 140 nop 141 nop 142 nop 143 nop 144 nop 145 nop 146 nop 147 nop 148 nop 149 nop 150 151 __spitfire_flush_tlb_kernel_range_slow: 152 mov 63 * 8, %o4 153 1: ldxa [%o4] ASI_ITLB_DATA_ACCESS, %o3 154 andcc %o3, 0x40, %g0 /* _PAGE_L_4U */ 155 bne,pn %xcc, 2f 156 mov TLB_TAG_ACCESS, %o3 157 stxa %g0, [%o3] ASI_IMMU 158 stxa %g0, [%o4] ASI_ITLB_DATA_ACCESS 159 membar #Sync 160 2: ldxa [%o4] ASI_DTLB_DATA_ACCESS, %o3 161 andcc %o3, 0x40, %g0 162 bne,pn %xcc, 2f 163 mov TLB_TAG_ACCESS, %o3 164 stxa %g0, [%o3] ASI_DMMU 165 stxa %g0, [%o4] ASI_DTLB_DATA_ACCESS 166 membar #Sync 167 2: sub %o4, 8, %o4 168 brgez,pt %o4, 1b 169 nop 170 retl 171 nop 172 173 __spitfire_flush_tlb_mm_slow: 174 rdpr %pstate, %g1 175 wrpr %g1, PSTATE_IE, %pstate 176 stxa %o0, [%o1] ASI_DMMU 177 stxa %g0, [%g3] ASI_DMMU_DEMAP 178 stxa %g0, [%g3] ASI_IMMU_DEMAP 179 flush %g6 180 stxa %g2, [%o1] ASI_DMMU 181 sethi %hi(KERNBASE), %o1 182 flush %o1 183 retl 184 wrpr %g1, 0, %pstate 185 186 /* 187 * The following code flushes one page_size worth. 188 */ 189 .section .kprobes.text, "ax" 190 .align 32 191 .globl __flush_icache_page 192 __flush_icache_page: /* %o0 = phys_page */ 193 srlx %o0, PAGE_SHIFT, %o0 194 sethi %hi(PAGE_OFFSET), %g1 195 sllx %o0, PAGE_SHIFT, %o0 196 sethi %hi(PAGE_SIZE), %g2 197 ldx [%g1 + %lo(PAGE_OFFSET)], %g1 198 add %o0, %g1, %o0 199 1: subcc %g2, 32, %g2 200 bne,pt %icc, 1b 201 flush %o0 + %g2 202 retl 203 nop 204 205 #ifdef DCACHE_ALIASING_POSSIBLE 206 207 #if (PAGE_SHIFT != 13) 208 #error only page shift of 13 is supported by dcache flush 209 #endif 210 211 #define DTAG_MASK 0x3 212 213 /* This routine is Spitfire specific so the hardcoded 214 * D-cache size and line-size are OK. 215 */ 216 .align 64 217 .globl __flush_dcache_page 218 __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ 219 sethi %hi(PAGE_OFFSET), %g1 220 ldx [%g1 + %lo(PAGE_OFFSET)], %g1 221 sub %o0, %g1, %o0 ! physical address 222 srlx %o0, 11, %o0 ! make D-cache TAG 223 sethi %hi(1 << 14), %o2 ! D-cache size 224 sub %o2, (1 << 5), %o2 ! D-cache line size 225 1: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG 226 andcc %o3, DTAG_MASK, %g0 ! Valid? 227 be,pn %xcc, 2f ! Nope, branch 228 andn %o3, DTAG_MASK, %o3 ! Clear valid bits 229 cmp %o3, %o0 ! TAG match? 230 bne,pt %xcc, 2f ! Nope, branch 231 nop 232 stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG 233 membar #Sync 234 2: brnz,pt %o2, 1b 235 sub %o2, (1 << 5), %o2 ! D-cache line size 236 237 /* The I-cache does not snoop local stores so we 238 * better flush that too when necessary. 239 */ 240 brnz,pt %o1, __flush_icache_page 241 sllx %o0, 11, %o0 242 retl 243 nop 244 245 #endif /* DCACHE_ALIASING_POSSIBLE */ 246 247 .previous 248 249 /* Cheetah specific versions, patched at boot time. */ 250 __cheetah_flush_tlb_mm: /* 19 insns */ 251 rdpr %pstate, %g7 252 andn %g7, PSTATE_IE, %g2 253 wrpr %g2, 0x0, %pstate 254 wrpr %g0, 1, %tl 255 mov PRIMARY_CONTEXT, %o2 256 mov 0x40, %g3 257 ldxa [%o2] ASI_DMMU, %g2 258 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o1 259 sllx %o1, CTX_PGSZ1_NUC_SHIFT, %o1 260 or %o0, %o1, %o0 /* Preserve nucleus page size fields */ 261 stxa %o0, [%o2] ASI_DMMU 262 stxa %g0, [%g3] ASI_DMMU_DEMAP 263 stxa %g0, [%g3] ASI_IMMU_DEMAP 264 stxa %g2, [%o2] ASI_DMMU 265 sethi %hi(KERNBASE), %o2 266 flush %o2 267 wrpr %g0, 0, %tl 268 retl 269 wrpr %g7, 0x0, %pstate 270 271 __cheetah_flush_tlb_page: /* 22 insns */ 272 /* %o0 = context, %o1 = vaddr */ 273 rdpr %pstate, %g7 274 andn %g7, PSTATE_IE, %g2 275 wrpr %g2, 0x0, %pstate 276 wrpr %g0, 1, %tl 277 mov PRIMARY_CONTEXT, %o4 278 ldxa [%o4] ASI_DMMU, %g2 279 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 280 sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 281 or %o0, %o3, %o0 /* Preserve nucleus page size fields */ 282 stxa %o0, [%o4] ASI_DMMU 283 andcc %o1, 1, %g0 284 be,pn %icc, 1f 285 andn %o1, 1, %o3 286 stxa %g0, [%o3] ASI_IMMU_DEMAP 287 1: stxa %g0, [%o3] ASI_DMMU_DEMAP 288 membar #Sync 289 stxa %g2, [%o4] ASI_DMMU 290 sethi %hi(KERNBASE), %o4 291 flush %o4 292 wrpr %g0, 0, %tl 293 retl 294 wrpr %g7, 0x0, %pstate 295 296 __cheetah_flush_tlb_pending: /* 27 insns */ 297 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ 298 rdpr %pstate, %g7 299 sllx %o1, 3, %o1 300 andn %g7, PSTATE_IE, %g2 301 wrpr %g2, 0x0, %pstate 302 wrpr %g0, 1, %tl 303 mov PRIMARY_CONTEXT, %o4 304 ldxa [%o4] ASI_DMMU, %g2 305 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 306 sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 307 or %o0, %o3, %o0 /* Preserve nucleus page size fields */ 308 stxa %o0, [%o4] ASI_DMMU 309 1: sub %o1, (1 << 3), %o1 310 ldx [%o2 + %o1], %o3 311 andcc %o3, 1, %g0 312 be,pn %icc, 2f 313 andn %o3, 1, %o3 314 stxa %g0, [%o3] ASI_IMMU_DEMAP 315 2: stxa %g0, [%o3] ASI_DMMU_DEMAP 316 membar #Sync 317 brnz,pt %o1, 1b 318 nop 319 stxa %g2, [%o4] ASI_DMMU 320 sethi %hi(KERNBASE), %o4 321 flush %o4 322 wrpr %g0, 0, %tl 323 retl 324 wrpr %g7, 0x0, %pstate 325 326 __cheetah_flush_tlb_kernel_range: /* 31 insns */ 327 /* %o0=start, %o1=end */ 328 cmp %o0, %o1 329 be,pn %xcc, 2f 330 sub %o1, %o0, %o3 331 srlx %o3, 18, %o4 332 brnz,pn %o4, 3f 333 sethi %hi(PAGE_SIZE), %o4 334 sub %o3, %o4, %o3 335 or %o0, 0x20, %o0 ! Nucleus 336 1: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP 337 stxa %g0, [%o0 + %o3] ASI_IMMU_DEMAP 338 membar #Sync 339 brnz,pt %o3, 1b 340 sub %o3, %o4, %o3 341 2: sethi %hi(KERNBASE), %o3 342 flush %o3 343 retl 344 nop 345 3: mov 0x80, %o4 346 stxa %g0, [%o4] ASI_DMMU_DEMAP 347 membar #Sync 348 stxa %g0, [%o4] ASI_IMMU_DEMAP 349 membar #Sync 350 retl 351 nop 352 nop 353 nop 354 nop 355 nop 356 nop 357 nop 358 nop 359 360 #ifdef DCACHE_ALIASING_POSSIBLE 361 __cheetah_flush_dcache_page: /* 11 insns */ 362 sethi %hi(PAGE_OFFSET), %g1 363 ldx [%g1 + %lo(PAGE_OFFSET)], %g1 364 sub %o0, %g1, %o0 365 sethi %hi(PAGE_SIZE), %o4 366 1: subcc %o4, (1 << 5), %o4 367 stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE 368 membar #Sync 369 bne,pt %icc, 1b 370 nop 371 retl /* I-cache flush never needed on Cheetah, see callers. */ 372 nop 373 #endif /* DCACHE_ALIASING_POSSIBLE */ 374 375 /* Hypervisor specific versions, patched at boot time. */ 376 __hypervisor_tlb_tl0_error: 377 save %sp, -192, %sp 378 mov %i0, %o0 379 call hypervisor_tlbop_error 380 mov %i1, %o1 381 ret 382 restore 383 384 __hypervisor_flush_tlb_mm: /* 19 insns */ 385 mov %o0, %o2 /* ARG2: mmu context */ 386 mov 0, %o0 /* ARG0: CPU lists unimplemented */ 387 mov 0, %o1 /* ARG1: CPU lists unimplemented */ 388 mov HV_MMU_ALL, %o3 /* ARG3: flags */ 389 mov HV_FAST_MMU_DEMAP_CTX, %o5 390 ta HV_FAST_TRAP 391 brnz,pn %o0, 1f 392 mov HV_FAST_MMU_DEMAP_CTX, %o1 393 retl 394 nop 395 1: sethi %hi(__hypervisor_tlb_tl0_error), %o5 396 jmpl %o5 + %lo(__hypervisor_tlb_tl0_error), %g0 397 nop 398 nop 399 nop 400 nop 401 nop 402 nop 403 nop 404 405 __hypervisor_flush_tlb_page: /* 22 insns */ 406 /* %o0 = context, %o1 = vaddr */ 407 mov %o0, %g2 408 mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ 409 mov %g2, %o1 /* ARG1: mmu context */ 410 mov HV_MMU_ALL, %o2 /* ARG2: flags */ 411 srlx %o0, PAGE_SHIFT, %o0 412 sllx %o0, PAGE_SHIFT, %o0 413 ta HV_MMU_UNMAP_ADDR_TRAP 414 brnz,pn %o0, 1f 415 mov HV_MMU_UNMAP_ADDR_TRAP, %o1 416 retl 417 nop 418 1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 419 jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 420 nop 421 nop 422 nop 423 nop 424 nop 425 nop 426 nop 427 nop 428 nop 429 430 __hypervisor_flush_tlb_pending: /* 27 insns */ 431 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ 432 sllx %o1, 3, %g1 433 mov %o2, %g2 434 mov %o0, %g3 435 1: sub %g1, (1 << 3), %g1 436 ldx [%g2 + %g1], %o0 /* ARG0: vaddr + IMMU-bit */ 437 mov %g3, %o1 /* ARG1: mmu context */ 438 mov HV_MMU_ALL, %o2 /* ARG2: flags */ 439 srlx %o0, PAGE_SHIFT, %o0 440 sllx %o0, PAGE_SHIFT, %o0 441 ta HV_MMU_UNMAP_ADDR_TRAP 442 brnz,pn %o0, 1f 443 mov HV_MMU_UNMAP_ADDR_TRAP, %o1 444 brnz,pt %g1, 1b 445 nop 446 retl 447 nop 448 1: sethi %hi(__hypervisor_tlb_tl0_error), %o2 449 jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 450 nop 451 nop 452 nop 453 nop 454 nop 455 nop 456 nop 457 nop 458 nop 459 460 __hypervisor_flush_tlb_kernel_range: /* 31 insns */ 461 /* %o0=start, %o1=end */ 462 cmp %o0, %o1 463 be,pn %xcc, 2f 464 sub %o1, %o0, %g2 465 srlx %g2, 18, %g3 466 brnz,pn %g3, 4f 467 mov %o0, %g1 468 sethi %hi(PAGE_SIZE), %g3 469 sub %g2, %g3, %g2 470 1: add %g1, %g2, %o0 /* ARG0: virtual address */ 471 mov 0, %o1 /* ARG1: mmu context */ 472 mov HV_MMU_ALL, %o2 /* ARG2: flags */ 473 ta HV_MMU_UNMAP_ADDR_TRAP 474 brnz,pn %o0, 3f 475 mov HV_MMU_UNMAP_ADDR_TRAP, %o1 476 brnz,pt %g2, 1b 477 sub %g2, %g3, %g2 478 2: retl 479 nop 480 3: sethi %hi(__hypervisor_tlb_tl0_error), %o2 481 jmpl %o2 + %lo(__hypervisor_tlb_tl0_error), %g0 482 nop 483 4: mov 0, %o0 /* ARG0: CPU lists unimplemented */ 484 mov 0, %o1 /* ARG1: CPU lists unimplemented */ 485 mov 0, %o2 /* ARG2: mmu context == nucleus */ 486 mov HV_MMU_ALL, %o3 /* ARG3: flags */ 487 mov HV_FAST_MMU_DEMAP_CTX, %o5 488 ta HV_FAST_TRAP 489 brnz,pn %o0, 3b 490 mov HV_FAST_MMU_DEMAP_CTX, %o1 491 retl 492 nop 493 494 #ifdef DCACHE_ALIASING_POSSIBLE 495 /* XXX Niagara and friends have an 8K cache, so no aliasing is 496 * XXX possible, but nothing explicit in the Hypervisor API 497 * XXX guarantees this. 498 */ 499 __hypervisor_flush_dcache_page: /* 2 insns */ 500 retl 501 nop 502 #endif 503 504 tlb_patch_one: 505 1: lduw [%o1], %g1 506 stw %g1, [%o0] 507 flush %o0 508 subcc %o2, 1, %o2 509 add %o1, 4, %o1 510 bne,pt %icc, 1b 511 add %o0, 4, %o0 512 retl 513 nop 514 515 #ifdef CONFIG_SMP 516 /* These are all called by the slaves of a cross call, at 517 * trap level 1, with interrupts fully disabled. 518 * 519 * Register usage: 520 * %g5 mm->context (all tlb flushes) 521 * %g1 address arg 1 (tlb page and range flushes) 522 * %g7 address arg 2 (tlb range flush only) 523 * 524 * %g6 scratch 1 525 * %g2 scratch 2 526 * %g3 scratch 3 527 * %g4 scratch 4 528 */ 529 .align 32 530 .globl xcall_flush_tlb_mm 531 xcall_flush_tlb_mm: /* 24 insns */ 532 mov PRIMARY_CONTEXT, %g2 533 ldxa [%g2] ASI_DMMU, %g3 534 srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4 535 sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4 536 or %g5, %g4, %g5 /* Preserve nucleus page size fields */ 537 stxa %g5, [%g2] ASI_DMMU 538 mov 0x40, %g4 539 stxa %g0, [%g4] ASI_DMMU_DEMAP 540 stxa %g0, [%g4] ASI_IMMU_DEMAP 541 stxa %g3, [%g2] ASI_DMMU 542 retry 543 nop 544 nop 545 nop 546 nop 547 nop 548 nop 549 nop 550 nop 551 nop 552 nop 553 nop 554 nop 555 nop 556 557 .globl xcall_flush_tlb_page 558 xcall_flush_tlb_page: /* 20 insns */ 559 /* %g5=context, %g1=vaddr */ 560 mov PRIMARY_CONTEXT, %g4 561 ldxa [%g4] ASI_DMMU, %g2 562 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 563 sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4 564 or %g5, %g4, %g5 565 mov PRIMARY_CONTEXT, %g4 566 stxa %g5, [%g4] ASI_DMMU 567 andcc %g1, 0x1, %g0 568 be,pn %icc, 2f 569 andn %g1, 0x1, %g5 570 stxa %g0, [%g5] ASI_IMMU_DEMAP 571 2: stxa %g0, [%g5] ASI_DMMU_DEMAP 572 membar #Sync 573 stxa %g2, [%g4] ASI_DMMU 574 retry 575 nop 576 nop 577 nop 578 nop 579 nop 580 581 .globl xcall_flush_tlb_kernel_range 582 xcall_flush_tlb_kernel_range: /* 44 insns */ 583 sethi %hi(PAGE_SIZE - 1), %g2 584 or %g2, %lo(PAGE_SIZE - 1), %g2 585 andn %g1, %g2, %g1 586 andn %g7, %g2, %g7 587 sub %g7, %g1, %g3 588 srlx %g3, 18, %g2 589 brnz,pn %g2, 2f 590 sethi %hi(PAGE_SIZE), %g2 591 sub %g3, %g2, %g3 592 or %g1, 0x20, %g1 ! Nucleus 593 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP 594 stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP 595 membar #Sync 596 brnz,pt %g3, 1b 597 sub %g3, %g2, %g3 598 retry 599 2: mov 63 * 8, %g1 600 1: ldxa [%g1] ASI_ITLB_DATA_ACCESS, %g2 601 andcc %g2, 0x40, %g0 /* _PAGE_L_4U */ 602 bne,pn %xcc, 2f 603 mov TLB_TAG_ACCESS, %g2 604 stxa %g0, [%g2] ASI_IMMU 605 stxa %g0, [%g1] ASI_ITLB_DATA_ACCESS 606 membar #Sync 607 2: ldxa [%g1] ASI_DTLB_DATA_ACCESS, %g2 608 andcc %g2, 0x40, %g0 609 bne,pn %xcc, 2f 610 mov TLB_TAG_ACCESS, %g2 611 stxa %g0, [%g2] ASI_DMMU 612 stxa %g0, [%g1] ASI_DTLB_DATA_ACCESS 613 membar #Sync 614 2: sub %g1, 8, %g1 615 brgez,pt %g1, 1b 616 nop 617 retry 618 nop 619 nop 620 nop 621 nop 622 nop 623 nop 624 nop 625 nop 626 nop 627 628 /* This runs in a very controlled environment, so we do 629 * not need to worry about BH races etc. 630 */ 631 .globl xcall_sync_tick 632 xcall_sync_tick: 633 634 661: rdpr %pstate, %g2 635 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate 636 .section .sun4v_2insn_patch, "ax" 637 .word 661b 638 nop 639 nop 640 .previous 641 642 rdpr %pil, %g2 643 wrpr %g0, PIL_NORMAL_MAX, %pil 644 sethi %hi(109f), %g7 645 b,pt %xcc, etrap_irq 646 109: or %g7, %lo(109b), %g7 647 #ifdef CONFIG_TRACE_IRQFLAGS 648 call trace_hardirqs_off 649 nop 650 #endif 651 call smp_synchronize_tick_client 652 nop 653 b rtrap_xcall 654 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 655 656 .globl xcall_fetch_glob_regs 657 xcall_fetch_glob_regs: 658 sethi %hi(global_cpu_snapshot), %g1 659 or %g1, %lo(global_cpu_snapshot), %g1 660 __GET_CPUID(%g2) 661 sllx %g2, 6, %g3 662 add %g1, %g3, %g1 663 rdpr %tstate, %g7 664 stx %g7, [%g1 + GR_SNAP_TSTATE] 665 rdpr %tpc, %g7 666 stx %g7, [%g1 + GR_SNAP_TPC] 667 rdpr %tnpc, %g7 668 stx %g7, [%g1 + GR_SNAP_TNPC] 669 stx %o7, [%g1 + GR_SNAP_O7] 670 stx %i7, [%g1 + GR_SNAP_I7] 671 /* Don't try this at home kids... */ 672 rdpr %cwp, %g3 673 sub %g3, 1, %g7 674 wrpr %g7, %cwp 675 mov %i7, %g7 676 wrpr %g3, %cwp 677 stx %g7, [%g1 + GR_SNAP_RPC] 678 sethi %hi(trap_block), %g7 679 or %g7, %lo(trap_block), %g7 680 sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2 681 add %g7, %g2, %g7 682 ldx [%g7 + TRAP_PER_CPU_THREAD], %g3 683 stx %g3, [%g1 + GR_SNAP_THREAD] 684 retry 685 686 .globl xcall_fetch_glob_pmu 687 xcall_fetch_glob_pmu: 688 sethi %hi(global_cpu_snapshot), %g1 689 or %g1, %lo(global_cpu_snapshot), %g1 690 __GET_CPUID(%g2) 691 sllx %g2, 6, %g3 692 add %g1, %g3, %g1 693 rd %pic, %g7 694 stx %g7, [%g1 + (4 * 8)] 695 rd %pcr, %g7 696 stx %g7, [%g1 + (0 * 8)] 697 retry 698 699 .globl xcall_fetch_glob_pmu_n4 700 xcall_fetch_glob_pmu_n4: 701 sethi %hi(global_cpu_snapshot), %g1 702 or %g1, %lo(global_cpu_snapshot), %g1 703 __GET_CPUID(%g2) 704 sllx %g2, 6, %g3 705 add %g1, %g3, %g1 706 707 ldxa [%g0] ASI_PIC, %g7 708 stx %g7, [%g1 + (4 * 8)] 709 mov 0x08, %g3 710 ldxa [%g3] ASI_PIC, %g7 711 stx %g7, [%g1 + (5 * 8)] 712 mov 0x10, %g3 713 ldxa [%g3] ASI_PIC, %g7 714 stx %g7, [%g1 + (6 * 8)] 715 mov 0x18, %g3 716 ldxa [%g3] ASI_PIC, %g7 717 stx %g7, [%g1 + (7 * 8)] 718 719 mov %o0, %g2 720 mov %o1, %g3 721 mov %o5, %g7 722 723 mov HV_FAST_VT_GET_PERFREG, %o5 724 mov 3, %o0 725 ta HV_FAST_TRAP 726 stx %o1, [%g1 + (3 * 8)] 727 mov HV_FAST_VT_GET_PERFREG, %o5 728 mov 2, %o0 729 ta HV_FAST_TRAP 730 stx %o1, [%g1 + (2 * 8)] 731 mov HV_FAST_VT_GET_PERFREG, %o5 732 mov 1, %o0 733 ta HV_FAST_TRAP 734 stx %o1, [%g1 + (1 * 8)] 735 mov HV_FAST_VT_GET_PERFREG, %o5 736 mov 0, %o0 737 ta HV_FAST_TRAP 738 stx %o1, [%g1 + (0 * 8)] 739 740 mov %g2, %o0 741 mov %g3, %o1 742 mov %g7, %o5 743 744 retry 745 746 __cheetah_xcall_flush_tlb_kernel_range: /* 44 insns */ 747 sethi %hi(PAGE_SIZE - 1), %g2 748 or %g2, %lo(PAGE_SIZE - 1), %g2 749 andn %g1, %g2, %g1 750 andn %g7, %g2, %g7 751 sub %g7, %g1, %g3 752 srlx %g3, 18, %g2 753 brnz,pn %g2, 2f 754 sethi %hi(PAGE_SIZE), %g2 755 sub %g3, %g2, %g3 756 or %g1, 0x20, %g1 ! Nucleus 757 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP 758 stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP 759 membar #Sync 760 brnz,pt %g3, 1b 761 sub %g3, %g2, %g3 762 retry 763 2: mov 0x80, %g2 764 stxa %g0, [%g2] ASI_DMMU_DEMAP 765 membar #Sync 766 stxa %g0, [%g2] ASI_IMMU_DEMAP 767 membar #Sync 768 retry 769 nop 770 nop 771 nop 772 nop 773 nop 774 nop 775 nop 776 nop 777 nop 778 nop 779 nop 780 nop 781 nop 782 nop 783 nop 784 nop 785 nop 786 nop 787 nop 788 nop 789 nop 790 nop 791 792 #ifdef DCACHE_ALIASING_POSSIBLE 793 .align 32 794 .globl xcall_flush_dcache_page_cheetah 795 xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */ 796 sethi %hi(PAGE_SIZE), %g3 797 1: subcc %g3, (1 << 5), %g3 798 stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE 799 membar #Sync 800 bne,pt %icc, 1b 801 nop 802 retry 803 nop 804 #endif /* DCACHE_ALIASING_POSSIBLE */ 805 806 .globl xcall_flush_dcache_page_spitfire 807 xcall_flush_dcache_page_spitfire: /* %g1 == physical page address 808 %g7 == kernel page virtual address 809 %g5 == (page->mapping != NULL) */ 810 #ifdef DCACHE_ALIASING_POSSIBLE 811 srlx %g1, (13 - 2), %g1 ! Form tag comparitor 812 sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K 813 sub %g3, (1 << 5), %g3 ! D$ linesize == 32 814 1: ldxa [%g3] ASI_DCACHE_TAG, %g2 815 andcc %g2, 0x3, %g0 816 be,pn %xcc, 2f 817 andn %g2, 0x3, %g2 818 cmp %g2, %g1 819 820 bne,pt %xcc, 2f 821 nop 822 stxa %g0, [%g3] ASI_DCACHE_TAG 823 membar #Sync 824 2: cmp %g3, 0 825 bne,pt %xcc, 1b 826 sub %g3, (1 << 5), %g3 827 828 brz,pn %g5, 2f 829 #endif /* DCACHE_ALIASING_POSSIBLE */ 830 sethi %hi(PAGE_SIZE), %g3 831 832 1: flush %g7 833 subcc %g3, (1 << 5), %g3 834 bne,pt %icc, 1b 835 add %g7, (1 << 5), %g7 836 837 2: retry 838 nop 839 nop 840 841 /* %g5: error 842 * %g6: tlb op 843 */ 844 __hypervisor_tlb_xcall_error: 845 mov %g5, %g4 846 mov %g6, %g5 847 ba,pt %xcc, etrap 848 rd %pc, %g7 849 mov %l4, %o0 850 call hypervisor_tlbop_error_xcall 851 mov %l5, %o1 852 ba,a,pt %xcc, rtrap 853 854 .globl __hypervisor_xcall_flush_tlb_mm 855 __hypervisor_xcall_flush_tlb_mm: /* 24 insns */ 856 /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */ 857 mov %o0, %g2 858 mov %o1, %g3 859 mov %o2, %g4 860 mov %o3, %g1 861 mov %o5, %g7 862 clr %o0 /* ARG0: CPU lists unimplemented */ 863 clr %o1 /* ARG1: CPU lists unimplemented */ 864 mov %g5, %o2 /* ARG2: mmu context */ 865 mov HV_MMU_ALL, %o3 /* ARG3: flags */ 866 mov HV_FAST_MMU_DEMAP_CTX, %o5 867 ta HV_FAST_TRAP 868 mov HV_FAST_MMU_DEMAP_CTX, %g6 869 brnz,pn %o0, 1f 870 mov %o0, %g5 871 mov %g2, %o0 872 mov %g3, %o1 873 mov %g4, %o2 874 mov %g1, %o3 875 mov %g7, %o5 876 membar #Sync 877 retry 878 1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 879 jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 880 nop 881 882 .globl __hypervisor_xcall_flush_tlb_page 883 __hypervisor_xcall_flush_tlb_page: /* 20 insns */ 884 /* %g5=ctx, %g1=vaddr */ 885 mov %o0, %g2 886 mov %o1, %g3 887 mov %o2, %g4 888 mov %g1, %o0 /* ARG0: virtual address */ 889 mov %g5, %o1 /* ARG1: mmu context */ 890 mov HV_MMU_ALL, %o2 /* ARG2: flags */ 891 srlx %o0, PAGE_SHIFT, %o0 892 sllx %o0, PAGE_SHIFT, %o0 893 ta HV_MMU_UNMAP_ADDR_TRAP 894 mov HV_MMU_UNMAP_ADDR_TRAP, %g6 895 brnz,a,pn %o0, 1f 896 mov %o0, %g5 897 mov %g2, %o0 898 mov %g3, %o1 899 mov %g4, %o2 900 membar #Sync 901 retry 902 1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 903 jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 904 nop 905 906 .globl __hypervisor_xcall_flush_tlb_kernel_range 907 __hypervisor_xcall_flush_tlb_kernel_range: /* 44 insns */ 908 /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */ 909 sethi %hi(PAGE_SIZE - 1), %g2 910 or %g2, %lo(PAGE_SIZE - 1), %g2 911 andn %g1, %g2, %g1 912 andn %g7, %g2, %g7 913 sub %g7, %g1, %g3 914 srlx %g3, 18, %g7 915 add %g2, 1, %g2 916 sub %g3, %g2, %g3 917 mov %o0, %g2 918 mov %o1, %g4 919 brnz,pn %g7, 2f 920 mov %o2, %g7 921 1: add %g1, %g3, %o0 /* ARG0: virtual address */ 922 mov 0, %o1 /* ARG1: mmu context */ 923 mov HV_MMU_ALL, %o2 /* ARG2: flags */ 924 ta HV_MMU_UNMAP_ADDR_TRAP 925 mov HV_MMU_UNMAP_ADDR_TRAP, %g6 926 brnz,pn %o0, 1f 927 mov %o0, %g5 928 sethi %hi(PAGE_SIZE), %o2 929 brnz,pt %g3, 1b 930 sub %g3, %o2, %g3 931 5: mov %g2, %o0 932 mov %g4, %o1 933 mov %g7, %o2 934 membar #Sync 935 retry 936 1: sethi %hi(__hypervisor_tlb_xcall_error), %g4 937 jmpl %g4 + %lo(__hypervisor_tlb_xcall_error), %g0 938 nop 939 2: mov %o3, %g1 940 mov %o5, %g3 941 mov 0, %o0 /* ARG0: CPU lists unimplemented */ 942 mov 0, %o1 /* ARG1: CPU lists unimplemented */ 943 mov 0, %o2 /* ARG2: mmu context == nucleus */ 944 mov HV_MMU_ALL, %o3 /* ARG3: flags */ 945 mov HV_FAST_MMU_DEMAP_CTX, %o5 946 ta HV_FAST_TRAP 947 mov %g1, %o3 948 brz,pt %o0, 5b 949 mov %g3, %o5 950 mov HV_FAST_MMU_DEMAP_CTX, %g6 951 ba,pt %xcc, 1b 952 clr %g5 953 954 /* These just get rescheduled to PIL vectors. */ 955 .globl xcall_call_function 956 xcall_call_function: 957 wr %g0, (1 << PIL_SMP_CALL_FUNC), %set_softint 958 retry 959 960 .globl xcall_call_function_single 961 xcall_call_function_single: 962 wr %g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint 963 retry 964 965 .globl xcall_receive_signal 966 xcall_receive_signal: 967 wr %g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint 968 retry 969 970 .globl xcall_capture 971 xcall_capture: 972 wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint 973 retry 974 975 #ifdef CONFIG_KGDB 976 .globl xcall_kgdb_capture 977 xcall_kgdb_capture: 978 wr %g0, (1 << PIL_KGDB_CAPTURE), %set_softint 979 retry 980 #endif 981 982 #endif /* CONFIG_SMP */ 983 984 .globl cheetah_patch_cachetlbops 985 cheetah_patch_cachetlbops: 986 save %sp, -128, %sp 987 988 sethi %hi(__flush_tlb_mm), %o0 989 or %o0, %lo(__flush_tlb_mm), %o0 990 sethi %hi(__cheetah_flush_tlb_mm), %o1 991 or %o1, %lo(__cheetah_flush_tlb_mm), %o1 992 call tlb_patch_one 993 mov 19, %o2 994 995 sethi %hi(__flush_tlb_page), %o0 996 or %o0, %lo(__flush_tlb_page), %o0 997 sethi %hi(__cheetah_flush_tlb_page), %o1 998 or %o1, %lo(__cheetah_flush_tlb_page), %o1 999 call tlb_patch_one 1000 mov 22, %o2 1001 1002 sethi %hi(__flush_tlb_pending), %o0 1003 or %o0, %lo(__flush_tlb_pending), %o0 1004 sethi %hi(__cheetah_flush_tlb_pending), %o1 1005 or %o1, %lo(__cheetah_flush_tlb_pending), %o1 1006 call tlb_patch_one 1007 mov 27, %o2 1008 1009 sethi %hi(__flush_tlb_kernel_range), %o0 1010 or %o0, %lo(__flush_tlb_kernel_range), %o0 1011 sethi %hi(__cheetah_flush_tlb_kernel_range), %o1 1012 or %o1, %lo(__cheetah_flush_tlb_kernel_range), %o1 1013 call tlb_patch_one 1014 mov 31, %o2 1015 1016 #ifdef DCACHE_ALIASING_POSSIBLE 1017 sethi %hi(__flush_dcache_page), %o0 1018 or %o0, %lo(__flush_dcache_page), %o0 1019 sethi %hi(__cheetah_flush_dcache_page), %o1 1020 or %o1, %lo(__cheetah_flush_dcache_page), %o1 1021 call tlb_patch_one 1022 mov 11, %o2 1023 #endif /* DCACHE_ALIASING_POSSIBLE */ 1024 1025 #ifdef CONFIG_SMP 1026 sethi %hi(xcall_flush_tlb_kernel_range), %o0 1027 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 1028 sethi %hi(__cheetah_xcall_flush_tlb_kernel_range), %o1 1029 or %o1, %lo(__cheetah_xcall_flush_tlb_kernel_range), %o1 1030 call tlb_patch_one 1031 mov 44, %o2 1032 #endif /* CONFIG_SMP */ 1033 1034 ret 1035 restore 1036 1037 .globl hypervisor_patch_cachetlbops 1038 hypervisor_patch_cachetlbops: 1039 save %sp, -128, %sp 1040 1041 sethi %hi(__flush_tlb_mm), %o0 1042 or %o0, %lo(__flush_tlb_mm), %o0 1043 sethi %hi(__hypervisor_flush_tlb_mm), %o1 1044 or %o1, %lo(__hypervisor_flush_tlb_mm), %o1 1045 call tlb_patch_one 1046 mov 19, %o2 1047 1048 sethi %hi(__flush_tlb_page), %o0 1049 or %o0, %lo(__flush_tlb_page), %o0 1050 sethi %hi(__hypervisor_flush_tlb_page), %o1 1051 or %o1, %lo(__hypervisor_flush_tlb_page), %o1 1052 call tlb_patch_one 1053 mov 22, %o2 1054 1055 sethi %hi(__flush_tlb_pending), %o0 1056 or %o0, %lo(__flush_tlb_pending), %o0 1057 sethi %hi(__hypervisor_flush_tlb_pending), %o1 1058 or %o1, %lo(__hypervisor_flush_tlb_pending), %o1 1059 call tlb_patch_one 1060 mov 27, %o2 1061 1062 sethi %hi(__flush_tlb_kernel_range), %o0 1063 or %o0, %lo(__flush_tlb_kernel_range), %o0 1064 sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1 1065 or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1 1066 call tlb_patch_one 1067 mov 31, %o2 1068 1069 #ifdef DCACHE_ALIASING_POSSIBLE 1070 sethi %hi(__flush_dcache_page), %o0 1071 or %o0, %lo(__flush_dcache_page), %o0 1072 sethi %hi(__hypervisor_flush_dcache_page), %o1 1073 or %o1, %lo(__hypervisor_flush_dcache_page), %o1 1074 call tlb_patch_one 1075 mov 2, %o2 1076 #endif /* DCACHE_ALIASING_POSSIBLE */ 1077 1078 #ifdef CONFIG_SMP 1079 sethi %hi(xcall_flush_tlb_mm), %o0 1080 or %o0, %lo(xcall_flush_tlb_mm), %o0 1081 sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1 1082 or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1 1083 call tlb_patch_one 1084 mov 24, %o2 1085 1086 sethi %hi(xcall_flush_tlb_page), %o0 1087 or %o0, %lo(xcall_flush_tlb_page), %o0 1088 sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 1089 or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 1090 call tlb_patch_one 1091 mov 20, %o2 1092 1093 sethi %hi(xcall_flush_tlb_kernel_range), %o0 1094 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 1095 sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1 1096 or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1 1097 call tlb_patch_one 1098 mov 44, %o2 1099 #endif /* CONFIG_SMP */ 1100 1101 ret 1102 restore
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.