1 /* $Id: blockops.S,v 1.27 2000/07/14 01:12:49 davem Exp $
2 * blockops.S: UltraSparc block zero optimized routines.
4 * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
5 * Copyright (C) 1997 Jakub Jelinek (jakub@redhat.com)
9 #include <asm/visasm.h>
11 #include <asm/pgtable.h>
12 #include <asm/asm_offsets.h>
14 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \
15 fmovd %reg0, %f48; fmovd %reg1, %f50; \
16 fmovd %reg2, %f52; fmovd %reg3, %f54; \
17 fmovd %reg4, %f56; fmovd %reg5, %f58; \
18 fmovd %reg6, %f60; fmovd %reg7, %f62;
20 #define TLBTEMP_BASE (8 * 1024 * 1024)
21 #define DCACHE_SIZE (PAGE_SIZE * 2)
22 #define TLBTEMP_ENT1 (61 << 3)
23 #define TLBTEMP_ENT2 (62 << 3)
24 #define TLBTEMP_ENTSZ (1 << 3)
30 .type _copy_page,@function
31 _copy_page: /* %o0=dest, %o1=src */
33 membar #LoadStore | #StoreStore | #StoreLoad
34 ldda [%o1] ASI_BLK_P, %f0
36 ldda [%o1] ASI_BLK_P, %f16
39 1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
40 ldda [%o1] ASI_BLK_P, %f32
41 stda %f48, [%o0] ASI_BLK_P
45 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
46 ldda [%o1] ASI_BLK_P, %f0
47 stda %f48, [%o0] ASI_BLK_P
51 TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
52 ldda [%o1] ASI_BLK_P, %f16
53 stda %f48, [%o0] ASI_BLK_P
60 stda %f0, [%o0] ASI_BLK_P
62 stda %f16, [%o0] ASI_BLK_P
69 .type copy_user_page,@function
70 copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
72 sethi %hi(PAGE_SIZE), %g3
75 sethi %hi(TLBTEMP_BASE), %o3
76 sethi %uhi(_PAGE_VALID), %g3
79 mov TLB_TAG_ACCESS, %o2
80 or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
81 sethi %hi(DCACHE_SIZE), %o1
88 wrpr %g3, PSTATE_IE, %pstate
90 /* Do this now, before loading the fixed TLB entries for copying,
91 * so we do not risk a multiple TLB match condition later when
92 * restoring those entries.
94 ldub [%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g3
96 /* Spitfire Errata #32 workaround */
98 stxa %g0, [%o4] ASI_DMMU
99 sethi %hi(empty_zero_page), %o4
102 ldxa [%o3] ASI_DTLB_TAG_READ, %o4
104 /* Spitfire Errata #32 workaround */
106 stxa %g0, [%o5] ASI_DMMU
107 sethi %hi(empty_zero_page), %o5
110 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %o5
111 stxa %o0, [%o2] ASI_DMMU
112 stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
114 add %o3, (TLBTEMP_ENTSZ), %o3
116 /* Spitfire Errata #32 workaround */
118 stxa %g0, [%g5] ASI_DMMU
119 sethi %hi(empty_zero_page), %g5
122 ldxa [%o3] ASI_DTLB_TAG_READ, %g5
124 /* Spitfire Errata #32 workaround */
126 stxa %g0, [%g7] ASI_DMMU
127 sethi %hi(empty_zero_page), %g7
130 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
131 stxa %o1, [%o2] ASI_DMMU
132 stxa %g2, [%o3] ASI_DTLB_DATA_ACCESS
136 bne,pn %xcc, copy_page_using_blkcommit
139 ldda [%o1] ASI_BLK_P, %f0
141 ldda [%o1] ASI_BLK_P, %f16
144 1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
145 ldda [%o1] ASI_BLK_P, %f32
146 stda %f48, [%o0] ASI_BLK_P
150 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
151 ldda [%o1] ASI_BLK_P, %f0
152 stda %f48, [%o0] ASI_BLK_P
156 TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
157 ldda [%o1] ASI_BLK_P, %f16
158 stda %f48, [%o0] ASI_BLK_P
165 stda %f0, [%o0] ASI_BLK_P
167 stda %f16, [%o0] ASI_BLK_P
168 copy_user_page_continue:
172 mov TLB_TAG_ACCESS, %o2
173 stxa %g5, [%o2] ASI_DMMU
174 stxa %g7, [%o3] ASI_DTLB_DATA_ACCESS
176 sub %o3, (TLBTEMP_ENTSZ), %o3
177 stxa %o4, [%o2] ASI_DMMU
178 stxa %o5, [%o3] ASI_DTLB_DATA_ACCESS
182 wrpr %g3, PSTATE_IE, %pstate
184 copy_page_using_blkcommit:
185 membar #LoadStore | #StoreStore | #StoreLoad
186 ldda [%o1] ASI_BLK_P, %f0
188 ldda [%o1] ASI_BLK_P, %f16
191 1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
192 ldda [%o1] ASI_BLK_P, %f32
193 stda %f48, [%o0] ASI_BLK_COMMIT_P
197 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
198 ldda [%o1] ASI_BLK_P, %f0
199 stda %f48, [%o0] ASI_BLK_COMMIT_P
203 TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
204 ldda [%o1] ASI_BLK_P, %f16
205 stda %f48, [%o0] ASI_BLK_COMMIT_P
212 stda %f0, [%o0] ASI_BLK_COMMIT_P
214 ba,pt %xcc, copy_user_page_continue
215 stda %f16, [%o0] ASI_BLK_COMMIT_P
219 .type _clear_page,@function
220 _clear_page: /* %o0=dest */
222 ba,pt %xcc, clear_page_common
226 .globl clear_user_page
227 .type clear_user_page,@function
228 clear_user_page: /* %o0=dest, %o1=vaddr */
230 sethi %hi(PAGE_SIZE), %g3
233 mov TLB_TAG_ACCESS, %o2
234 sethi %uhi(_PAGE_VALID), %g3
235 sethi %hi(TLBTEMP_BASE), %o3
237 or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
240 mov TLBTEMP_ENT2, %o3
242 wrpr %g3, PSTATE_IE, %pstate
244 /* Spitfire Errata #32 workaround */
246 stxa %g0, [%g5] ASI_DMMU
247 sethi %hi(empty_zero_page), %g5
250 ldxa [%o3] ASI_DTLB_TAG_READ, %g5
252 /* Spitfire Errata #32 workaround */
254 stxa %g0, [%g7] ASI_DMMU
255 sethi %hi(empty_zero_page), %g7
258 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
259 stxa %o0, [%o2] ASI_DMMU
260 stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
266 membar #StoreLoad | #StoreStore | #LoadStore ! LSU Group
267 fzero %f0 ! FPA Group
269 fzero %f2 ! FPA Group
270 faddd %f0, %f2, %f4 ! FPA Group
271 fmuld %f0, %f2, %f6 ! FPM
272 faddd %f0, %f2, %f8 ! FPA Group
273 fmuld %f0, %f2, %f10 ! FPM
275 faddd %f0, %f2, %f12 ! FPA Group
276 fmuld %f0, %f2, %f14 ! FPM
277 1: stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
278 add %o0, 0x40, %o0 ! IEU0
279 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
280 add %o0, 0x40, %o0 ! IEU0
281 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
283 add %o0, 0x40, %o0 ! IEU0 Group
284 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
285 subcc %o1, 1, %o1 ! IEU1
286 bne,pt %icc, 1b ! CTI
287 add %o0, 0x40, %o0 ! IEU0 Group
288 membar #Sync ! LSU Group
297 1: stxa %g5, [%o2] ASI_DMMU
298 stxa %g7, [%o3] ASI_DTLB_DATA_ACCESS
301 wrpr %g3, 0x0, %pstate