0001
0002
0003
0004
0005
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
0017
0018
0019
0020
0021
0022
0023
0024
0025
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:
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
0076 mov TLB_TAG_ACCESS, %g3
0077 stw %o2, [%g6 + TI_PRE_COUNT]
0078
0079
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