^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* clear_page.S: UltraSparc optimized clear page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/visasm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/spitfire.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/head.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) /* What we used to do was lock a TLB entry into a specific
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * TLB slot, clear the page with interrupts disabled, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * restore the original TLB entry. This was great for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * disturbing the TLB as little as possible, but it meant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * we had to keep interrupts disabled for a long time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Now, we simply use the normal TLB loading mechanism,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * and this makes the cpu choose a slot all by itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Then we do a normal TLB flush on exit. We need only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * disable preemption during the clear.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) .text
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .globl _clear_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) EXPORT_SYMBOL(_clear_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) _clear_page: /* %o0=dest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) ba,pt %xcc, clear_page_common
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) clr %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* This thing is pretty important, it shows up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * on the profiles via do_anonymous_page().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .align 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .globl clear_user_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) EXPORT_SYMBOL(clear_user_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) clear_user_page: /* %o0=dest, %o1=vaddr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) lduw [%g6 + TI_PRE_COUNT], %o2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) sethi %hi(PAGE_OFFSET), %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) sethi %hi(PAGE_SIZE), %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ldx [%g2 + %lo(PAGE_OFFSET)], %g2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) sethi %hi(PAGE_KERNEL_LOCKED), %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ldx [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) sub %o0, %g2, %g1 ! paddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) and %o1, %o4, %o0 ! vaddr D-cache alias bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) or %g1, %g3, %g1 ! TTE data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) sethi %hi(TLBTEMP_BASE), %o3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) add %o2, 1, %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) add %o0, %o3, %o0 ! TTE vaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Disable preemption. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) mov TLB_TAG_ACCESS, %g3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) stw %o4, [%g6 + TI_PRE_COUNT]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Load TLB entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) rdpr %pstate, %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) wrpr %o4, PSTATE_IE, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) stxa %o0, [%g3] ASI_DMMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) stxa %g1, [%g0] ASI_DTLB_DATA_IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) sethi %hi(KERNBASE), %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) flush %g1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) wrpr %o4, 0x0, %pstate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) mov 1, %o4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) clear_page_common:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) VISEntryHalf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) membar #StoreLoad | #StoreStore | #LoadStore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) fzero %f0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) sethi %hi(PAGE_SIZE/64), %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) mov %o0, %g1 ! remember vaddr for tlbflush
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) fzero %f2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) or %o1, %lo(PAGE_SIZE/64), %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) faddd %f0, %f2, %f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) fmuld %f0, %f2, %f6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) faddd %f0, %f2, %f8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) fmuld %f0, %f2, %f10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) faddd %f0, %f2, %f12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) fmuld %f0, %f2, %f14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 1: stda %f0, [%o0 + %g0] ASI_BLK_P
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) subcc %o1, 1, %o1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bne,pt %icc, 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) add %o0, 0x40, %o0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) VISExitHalf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) brz,pn %o4, out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) stxa %g0, [%g1] ASI_DMMU_DEMAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) membar #Sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) stw %o2, [%g6 + TI_PRE_COUNT]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) out: retl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) nop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)