Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* clear_page.S: UltraSparc optimized copy page.
0003  *
0004  * Copyright (C) 1996, 1998, 1999, 2000, 2004 David S. Miller (davem@redhat.com)
0005  * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com)
0006  */
0007 
0008 #include <asm/visasm.h>
0009 #include <asm/thread_info.h>
0010 #include <asm/page.h>
0011 #include <linux/pgtable.h>
0012 #include <asm/spitfire.h>
0013 #include <asm/head.h>
0014 #include <asm/export.h>
0015 
0016     /* What we used to do was lock a TLB entry into a specific
0017      * TLB slot, clear the page with interrupts disabled, then
0018      * restore the original TLB entry.  This was great for
0019      * disturbing the TLB as little as possible, but it meant
0020      * we had to keep interrupts disabled for a long time.
0021      *
0022      * Now, we simply use the normal TLB loading mechanism,
0023      * and this makes the cpu choose a slot all by itself.
0024      * Then we do a normal TLB flush on exit.  We need only
0025      * disable preemption during the clear.
0026      */
0027 
0028 #define DCACHE_SIZE (PAGE_SIZE * 2)
0029 
0030 #if (PAGE_SHIFT == 13)
0031 #define PAGE_SIZE_REM   0x80
0032 #elif (PAGE_SHIFT == 16)
0033 #define PAGE_SIZE_REM   0x100
0034 #else
0035 #error Wrong PAGE_SHIFT specified
0036 #endif
0037 
0038 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7)   \
0039     fsrc2   %reg0, %f48;    fsrc2   %reg1, %f50;        \
0040     fsrc2   %reg2, %f52;    fsrc2   %reg3, %f54;        \
0041     fsrc2   %reg4, %f56;    fsrc2   %reg5, %f58;        \
0042     fsrc2   %reg6, %f60;    fsrc2   %reg7, %f62;
0043 
0044     .text
0045 
0046     .align      32
0047     .globl      copy_user_page
0048     .type       copy_user_page,#function
0049     EXPORT_SYMBOL(copy_user_page)
0050 copy_user_page:     /* %o0=dest, %o1=src, %o2=vaddr */
0051     lduw        [%g6 + TI_PRE_COUNT], %o4
0052     sethi       %hi(PAGE_OFFSET), %g2
0053     sethi       %hi(PAGE_SIZE), %o3
0054 
0055     ldx     [%g2 + %lo(PAGE_OFFSET)], %g2
0056     sethi       %hi(PAGE_KERNEL_LOCKED), %g3
0057 
0058     ldx     [%g3 + %lo(PAGE_KERNEL_LOCKED)], %g3
0059     sub     %o0, %g2, %g1       ! dest paddr
0060 
0061     sub     %o1, %g2, %g2       ! src paddr
0062 
0063     and     %o2, %o3, %o0       ! vaddr D-cache alias bit
0064     or      %g1, %g3, %g1       ! dest TTE data
0065 
0066     or      %g2, %g3, %g2       ! src TTE data
0067     sethi       %hi(TLBTEMP_BASE), %o3
0068 
0069     sethi       %hi(DCACHE_SIZE), %o1
0070     add     %o0, %o3, %o0       ! dest TTE vaddr
0071 
0072     add     %o4, 1, %o2
0073     add     %o0, %o1, %o1       ! src TTE vaddr
0074 
0075     /* Disable preemption.  */
0076     mov     TLB_TAG_ACCESS, %g3
0077     stw     %o2, [%g6 + TI_PRE_COUNT]
0078 
0079     /* Load TLB entries.  */
0080     rdpr        %pstate, %o2
0081     wrpr        %o2, PSTATE_IE, %pstate
0082     stxa        %o0, [%g3] ASI_DMMU
0083     stxa        %g1, [%g0] ASI_DTLB_DATA_IN
0084     membar      #Sync
0085     stxa        %o1, [%g3] ASI_DMMU
0086     stxa        %g2, [%g0] ASI_DTLB_DATA_IN
0087     membar      #Sync
0088     wrpr        %o2, 0x0, %pstate
0089 
0090 cheetah_copy_page_insn:
0091     ba,pt       %xcc, 9f
0092      nop
0093 
0094 1:
0095     VISEntryHalf
0096     membar      #StoreLoad | #StoreStore | #LoadStore
0097     sethi       %hi((PAGE_SIZE/64)-2), %o2
0098     mov     %o0, %g1
0099     prefetch    [%o1 + 0x000], #one_read
0100     or      %o2, %lo((PAGE_SIZE/64)-2), %o2
0101     prefetch    [%o1 + 0x040], #one_read
0102     prefetch    [%o1 + 0x080], #one_read
0103     prefetch    [%o1 + 0x0c0], #one_read
0104     ldd     [%o1 + 0x000], %f0
0105     prefetch    [%o1 + 0x100], #one_read
0106     ldd     [%o1 + 0x008], %f2
0107     prefetch    [%o1 + 0x140], #one_read
0108     ldd     [%o1 + 0x010], %f4
0109     prefetch    [%o1 + 0x180], #one_read
0110     fsrc2       %f0, %f16
0111     ldd     [%o1 + 0x018], %f6
0112     fsrc2       %f2, %f18
0113     ldd     [%o1 + 0x020], %f8
0114     fsrc2       %f4, %f20
0115     ldd     [%o1 + 0x028], %f10
0116     fsrc2       %f6, %f22
0117     ldd     [%o1 + 0x030], %f12
0118     fsrc2       %f8, %f24
0119     ldd     [%o1 + 0x038], %f14
0120     fsrc2       %f10, %f26
0121     ldd     [%o1 + 0x040], %f0
0122 1:  ldd     [%o1 + 0x048], %f2
0123     fsrc2       %f12, %f28
0124     ldd     [%o1 + 0x050], %f4
0125     fsrc2       %f14, %f30
0126     stda        %f16, [%o0] ASI_BLK_P
0127     ldd     [%o1 + 0x058], %f6
0128     fsrc2       %f0, %f16
0129     ldd     [%o1 + 0x060], %f8
0130     fsrc2       %f2, %f18
0131     ldd     [%o1 + 0x068], %f10
0132     fsrc2       %f4, %f20
0133     ldd     [%o1 + 0x070], %f12
0134     fsrc2       %f6, %f22
0135     ldd     [%o1 + 0x078], %f14
0136     fsrc2       %f8, %f24
0137     ldd     [%o1 + 0x080], %f0
0138     prefetch    [%o1 + 0x180], #one_read
0139     fsrc2       %f10, %f26
0140     subcc       %o2, 1, %o2
0141     add     %o0, 0x40, %o0
0142     bne,pt      %xcc, 1b
0143      add        %o1, 0x40, %o1
0144 
0145     ldd     [%o1 + 0x048], %f2
0146     fsrc2       %f12, %f28
0147     ldd     [%o1 + 0x050], %f4
0148     fsrc2       %f14, %f30
0149     stda        %f16, [%o0] ASI_BLK_P
0150     ldd     [%o1 + 0x058], %f6
0151     fsrc2       %f0, %f16
0152     ldd     [%o1 + 0x060], %f8
0153     fsrc2       %f2, %f18
0154     ldd     [%o1 + 0x068], %f10
0155     fsrc2       %f4, %f20
0156     ldd     [%o1 + 0x070], %f12
0157     fsrc2       %f6, %f22
0158     add     %o0, 0x40, %o0
0159     ldd     [%o1 + 0x078], %f14
0160     fsrc2       %f8, %f24
0161     fsrc2       %f10, %f26
0162     fsrc2       %f12, %f28
0163     fsrc2       %f14, %f30
0164     stda        %f16, [%o0] ASI_BLK_P
0165     membar      #Sync
0166     VISExitHalf
0167     ba,pt       %xcc, 5f
0168      nop
0169 
0170 9:
0171     VISEntry
0172     ldub        [%g6 + TI_FAULT_CODE], %g3
0173     mov     %o0, %g1
0174     cmp     %g3, 0
0175     rd      %asi, %g3
0176     be,a,pt     %icc, 1f
0177      wr     %g0, ASI_BLK_P, %asi
0178     wr      %g0, ASI_BLK_COMMIT_P, %asi
0179 1:  ldda        [%o1] ASI_BLK_P, %f0
0180     add     %o1, 0x40, %o1
0181     ldda        [%o1] ASI_BLK_P, %f16
0182     add     %o1, 0x40, %o1
0183     sethi       %hi(PAGE_SIZE), %o2
0184 1:  TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
0185     ldda        [%o1] ASI_BLK_P, %f32
0186     stda        %f48, [%o0] %asi
0187     add     %o1, 0x40, %o1
0188     sub     %o2, 0x40, %o2
0189     add     %o0, 0x40, %o0
0190     TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
0191     ldda        [%o1] ASI_BLK_P, %f0
0192     stda        %f48, [%o0] %asi
0193     add     %o1, 0x40, %o1
0194     sub     %o2, 0x40, %o2
0195     add     %o0, 0x40, %o0
0196     TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
0197     ldda        [%o1] ASI_BLK_P, %f16
0198     stda        %f48, [%o0] %asi
0199     sub     %o2, 0x40, %o2
0200     add     %o1, 0x40, %o1
0201     cmp     %o2, PAGE_SIZE_REM
0202     bne,pt      %xcc, 1b
0203      add        %o0, 0x40, %o0
0204 #if (PAGE_SHIFT == 16)
0205     TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
0206     ldda        [%o1] ASI_BLK_P, %f32
0207     stda        %f48, [%o0] %asi
0208     add     %o1, 0x40, %o1
0209     sub     %o2, 0x40, %o2
0210     add     %o0, 0x40, %o0
0211     TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
0212     ldda        [%o1] ASI_BLK_P, %f0
0213     stda        %f48, [%o0] %asi
0214     add     %o1, 0x40, %o1
0215     sub     %o2, 0x40, %o2
0216     add     %o0, 0x40, %o0
0217     membar      #Sync
0218     stda        %f32, [%o0] %asi
0219     add     %o0, 0x40, %o0
0220     stda        %f0, [%o0] %asi
0221 #else
0222     membar      #Sync
0223     stda        %f0, [%o0] %asi
0224     add     %o0, 0x40, %o0
0225     stda        %f16, [%o0] %asi
0226 #endif
0227     membar      #Sync
0228     wr      %g3, 0x0, %asi
0229     VISExit
0230 
0231 5:
0232     stxa        %g0, [%g1] ASI_DMMU_DEMAP
0233     membar      #Sync
0234 
0235     sethi       %hi(DCACHE_SIZE), %g2
0236     stxa        %g0, [%g1 + %g2] ASI_DMMU_DEMAP
0237     membar      #Sync
0238 
0239     retl
0240      stw        %o4, [%g6 + TI_PRE_COUNT]
0241 
0242     .size       copy_user_page, .-copy_user_page
0243 
0244     .globl      cheetah_patch_copy_page
0245 cheetah_patch_copy_page:
0246     sethi       %hi(0x01000000), %o1    ! NOP
0247     sethi       %hi(cheetah_copy_page_insn), %o0
0248     or      %o0, %lo(cheetah_copy_page_insn), %o0
0249     stw     %o1, [%o0]
0250     membar      #StoreStore
0251     flush       %o0
0252     retl
0253      nop