18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* clear_page.S: UltraSparc optimized clear page. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com) 58c2ecf20Sopenharmony_ci * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com) 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 98c2ecf20Sopenharmony_ci#include <asm/visasm.h> 108c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 118c2ecf20Sopenharmony_ci#include <asm/page.h> 128c2ecf20Sopenharmony_ci#include <asm/spitfire.h> 138c2ecf20Sopenharmony_ci#include <asm/head.h> 148c2ecf20Sopenharmony_ci#include <asm/export.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci /* What we used to do was lock a TLB entry into a specific 178c2ecf20Sopenharmony_ci * TLB slot, clear the page with interrupts disabled, then 188c2ecf20Sopenharmony_ci * restore the original TLB entry. This was great for 198c2ecf20Sopenharmony_ci * disturbing the TLB as little as possible, but it meant 208c2ecf20Sopenharmony_ci * we had to keep interrupts disabled for a long time. 218c2ecf20Sopenharmony_ci * 228c2ecf20Sopenharmony_ci * Now, we simply use the normal TLB loading mechanism, 238c2ecf20Sopenharmony_ci * and this makes the cpu choose a slot all by itself. 248c2ecf20Sopenharmony_ci * Then we do a normal TLB flush on exit. We need only 258c2ecf20Sopenharmony_ci * disable preemption during the clear. 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci .text 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci .globl _clear_page 318c2ecf20Sopenharmony_ci EXPORT_SYMBOL(_clear_page) 328c2ecf20Sopenharmony_ci_clear_page: /* %o0=dest */ 338c2ecf20Sopenharmony_ci ba,pt %xcc, clear_page_common 348c2ecf20Sopenharmony_ci clr %o4 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci /* This thing is pretty important, it shows up 378c2ecf20Sopenharmony_ci * on the profiles via do_anonymous_page(). 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci .align 32 408c2ecf20Sopenharmony_ci .globl clear_user_page 418c2ecf20Sopenharmony_ci EXPORT_SYMBOL(clear_user_page) 428c2ecf20Sopenharmony_ciclear_user_page: /* %o0=dest, %o1=vaddr */ 438c2ecf20Sopenharmony_ci lduw [%g6 + TI_PRE_COUNT], %o2 448c2ecf20Sopenharmony_ci sethi %hi(PAGE_OFFSET), %g2 458c2ecf20Sopenharmony_ci sethi %hi(PAGE_SIZE), %o4 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci ldx [%g2 + %lo(PAGE_OFFSET)], %g2 488c2ecf20Sopenharmony_ci sethi %hi(PAGE_KERNEL_LOCKED), %g3 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci ldx [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3 518c2ecf20Sopenharmony_ci sub %o0, %g2, %g1 ! paddr 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci and %o1, %o4, %o0 ! vaddr D-cache alias bit 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci or %g1, %g3, %g1 ! TTE data 568c2ecf20Sopenharmony_ci sethi %hi(TLBTEMP_BASE), %o3 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci add %o2, 1, %o4 598c2ecf20Sopenharmony_ci add %o0, %o3, %o0 ! TTE vaddr 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* Disable preemption. */ 628c2ecf20Sopenharmony_ci mov TLB_TAG_ACCESS, %g3 638c2ecf20Sopenharmony_ci stw %o4, [%g6 + TI_PRE_COUNT] 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci /* Load TLB entry. */ 668c2ecf20Sopenharmony_ci rdpr %pstate, %o4 678c2ecf20Sopenharmony_ci wrpr %o4, PSTATE_IE, %pstate 688c2ecf20Sopenharmony_ci stxa %o0, [%g3] ASI_DMMU 698c2ecf20Sopenharmony_ci stxa %g1, [%g0] ASI_DTLB_DATA_IN 708c2ecf20Sopenharmony_ci sethi %hi(KERNBASE), %g1 718c2ecf20Sopenharmony_ci flush %g1 728c2ecf20Sopenharmony_ci wrpr %o4, 0x0, %pstate 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci mov 1, %o4 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciclear_page_common: 778c2ecf20Sopenharmony_ci VISEntryHalf 788c2ecf20Sopenharmony_ci membar #StoreLoad | #StoreStore | #LoadStore 798c2ecf20Sopenharmony_ci fzero %f0 808c2ecf20Sopenharmony_ci sethi %hi(PAGE_SIZE/64), %o1 818c2ecf20Sopenharmony_ci mov %o0, %g1 ! remember vaddr for tlbflush 828c2ecf20Sopenharmony_ci fzero %f2 838c2ecf20Sopenharmony_ci or %o1, %lo(PAGE_SIZE/64), %o1 848c2ecf20Sopenharmony_ci faddd %f0, %f2, %f4 858c2ecf20Sopenharmony_ci fmuld %f0, %f2, %f6 868c2ecf20Sopenharmony_ci faddd %f0, %f2, %f8 878c2ecf20Sopenharmony_ci fmuld %f0, %f2, %f10 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci faddd %f0, %f2, %f12 908c2ecf20Sopenharmony_ci fmuld %f0, %f2, %f14 918c2ecf20Sopenharmony_ci1: stda %f0, [%o0 + %g0] ASI_BLK_P 928c2ecf20Sopenharmony_ci subcc %o1, 1, %o1 938c2ecf20Sopenharmony_ci bne,pt %icc, 1b 948c2ecf20Sopenharmony_ci add %o0, 0x40, %o0 958c2ecf20Sopenharmony_ci membar #Sync 968c2ecf20Sopenharmony_ci VISExitHalf 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci brz,pn %o4, out 998c2ecf20Sopenharmony_ci nop 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci stxa %g0, [%g1] ASI_DMMU_DEMAP 1028c2ecf20Sopenharmony_ci membar #Sync 1038c2ecf20Sopenharmony_ci stw %o2, [%g6 + TI_PRE_COUNT] 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ciout: retl 1068c2ecf20Sopenharmony_ci nop 1078c2ecf20Sopenharmony_ci 108