11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* clear_page.S: UltraSparc optimized clear page. 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com) 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com) 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/visasm.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/thread_info.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/page.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/pgtable.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/spitfire.h> 124da808c352c290d3f762933d44d4ab90c2fd65f3David S. Miller#include <asm/head.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* What we used to do was lock a TLB entry into a specific 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TLB slot, clear the page with interrupts disabled, then 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * restore the original TLB entry. This was great for 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disturbing the TLB as little as possible, but it meant 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we had to keep interrupts disabled for a long time. 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Now, we simply use the normal TLB loading mechanism, 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and this makes the cpu choose a slot all by itself. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Then we do a normal TLB flush on exit. We need only 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * disable preemption during the clear. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .text 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .globl _clear_page 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds_clear_page: /* %o0=dest */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ba,pt %xcc, clear_page_common 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds clr %o4 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* This thing is pretty important, it shows up 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on the profiles via do_anonymous_page(). 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .align 32 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .globl clear_user_page 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_user_page: /* %o0=dest, %o1=vaddr */ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lduw [%g6 + TI_PRE_COUNT], %o2 40b2d438348024b75a1ee8b66b85d77f569a5dfed8David S. Miller sethi %hi(PAGE_OFFSET), %g2 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sethi %hi(PAGE_SIZE), %o4 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43b2d438348024b75a1ee8b66b85d77f569a5dfed8David S. Miller ldx [%g2 + %lo(PAGE_OFFSET)], %g2 44c4bce90ea2069e5a87beac806de3090ab32128d5David S. Miller sethi %hi(PAGE_KERNEL_LOCKED), %g3 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46c4bce90ea2069e5a87beac806de3090ab32128d5David S. Miller ldx [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sub %o0, %g2, %g1 ! paddr 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds and %o1, %o4, %o0 ! vaddr D-cache alias bit 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds or %g1, %g3, %g1 ! TTE data 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sethi %hi(TLBTEMP_BASE), %o3 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add %o2, 1, %o4 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add %o0, %o3, %o0 ! TTE vaddr 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable preemption. */ 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mov TLB_TAG_ACCESS, %g3 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stw %o4, [%g6 + TI_PRE_COUNT] 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Load TLB entry. */ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rdpr %pstate, %o4 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wrpr %o4, PSTATE_IE, %pstate 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stxa %o0, [%g3] ASI_DMMU 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stxa %g1, [%g0] ASI_DTLB_DATA_IN 664da808c352c290d3f762933d44d4ab90c2fd65f3David S. Miller sethi %hi(KERNBASE), %g1 674da808c352c290d3f762933d44d4ab90c2fd65f3David S. Miller flush %g1 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wrpr %o4, 0x0, %pstate 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mov 1, %o4 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsclear_page_common: 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VISEntryHalf 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds membar #StoreLoad | #StoreStore | #LoadStore 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fzero %f0 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sethi %hi(PAGE_SIZE/64), %o1 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mov %o0, %g1 ! remember vaddr for tlbflush 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fzero %f2 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds or %o1, %lo(PAGE_SIZE/64), %o1 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds faddd %f0, %f2, %f4 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fmuld %f0, %f2, %f6 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds faddd %f0, %f2, %f8 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fmuld %f0, %f2, %f10 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds faddd %f0, %f2, %f12 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fmuld %f0, %f2, %f14 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds1: stda %f0, [%o0 + %g0] ASI_BLK_P 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subcc %o1, 1, %o1 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bne,pt %icc, 1b 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds add %o0, 0x40, %o0 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds membar #Sync 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds VISExitHalf 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds brz,pn %o4, out 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nop 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stxa %g0, [%g1] ASI_DMMU_DEMAP 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds membar #Sync 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stw %o2, [%g6 + TI_PRE_COUNT] 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: retl 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds nop 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 104