1 /* $Id: blockops.S,v 1.41 2001/12/05 06:05:35 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>
12 #include <asm/spitfire.h>
13 #include <asm/pgtable.h>
14 #include <asm/asm_offsets.h>
16 #define TOUCH(reg0, reg1, reg2, reg3, reg4, reg5, reg6, reg7) \
17 fmovd %reg0, %f48; fmovd %reg1, %f50; \
18 fmovd %reg2, %f52; fmovd %reg3, %f54; \
19 fmovd %reg4, %f56; fmovd %reg5, %f58; \
20 fmovd %reg6, %f60; fmovd %reg7, %f62;
22 #define DCACHE_SIZE (PAGE_SIZE * 2)
23 #define TLBTEMP_ENT1 (60 << 3)
24 #define TLBTEMP_ENT2 (61 << 3)
25 #define TLBTEMP_ENTSZ (1 << 3)
27 #if (PAGE_SHIFT == 13) || (PAGE_SHIFT == 19)
28 #define PAGE_SIZE_REM 0x80
29 #elif (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
30 #define PAGE_SIZE_REM 0x100
32 #error Wrong PAGE_SHIFT specified
39 .type copy_user_page,@function
40 copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */
42 sethi %hi(PAGE_SIZE), %g3
45 sethi %hi(TLBTEMP_BASE), %o3
46 sethi %uhi(_PAGE_VALID | _PAGE_SZBITS), %g3
49 mov TLB_TAG_ACCESS, %o2
50 or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
51 sethi %hi(DCACHE_SIZE), %o1
56 #define FIX_INSN_1 0x96102060 /* mov (12 << 3), %o3 */
60 wrpr %g3, PSTATE_IE, %pstate
62 /* Do this now, before loading the fixed TLB entries for copying,
63 * so we do not risk a multiple TLB match condition later when
64 * restoring those entries.
66 ldub [%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g3
68 /* Spitfire Errata #32 workaround */
69 mov PRIMARY_CONTEXT, %o4
70 stxa %g0, [%o4] ASI_DMMU
73 ldxa [%o3] ASI_DTLB_TAG_READ, %o4
75 /* Spitfire Errata #32 workaround */
76 mov PRIMARY_CONTEXT, %o5
77 stxa %g0, [%o5] ASI_DMMU
80 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g0
81 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %o5
82 stxa %o0, [%o2] ASI_DMMU
83 stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
85 add %o3, (TLBTEMP_ENTSZ), %o3
87 /* Spitfire Errata #32 workaround */
88 mov PRIMARY_CONTEXT, %g5
89 stxa %g0, [%g5] ASI_DMMU
92 ldxa [%o3] ASI_DTLB_TAG_READ, %g5
94 /* Spitfire Errata #32 workaround */
95 mov PRIMARY_CONTEXT, %g7
96 stxa %g0, [%g7] ASI_DMMU
99 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g0
100 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
101 stxa %o1, [%o2] ASI_DMMU
102 stxa %g2, [%o3] ASI_DTLB_DATA_ACCESS
106 bne,pn %xcc, copy_page_using_blkcommit
109 BRANCH_IF_ANY_CHEETAH(g3,o2,cheetah_copy_user_page)
110 ba,pt %xcc, spitfire_copy_user_page
113 cheetah_copy_user_page:
114 .globl cheetah_copy_user_page_nop_1_6
115 cheetah_copy_user_page_nop_1_6:
116 ldxa [%g0] ASI_DCU_CONTROL_REG, %g3
117 sethi %uhi(DCU_PE), %o2
120 stxa %o2, [%g0] ASI_DCU_CONTROL_REG ! Enable P-cache
123 sethi %hi((PAGE_SIZE/64)-7), %o2 ! A0 Group
124 prefetch [%o1 + 0x000], #one_read ! MS
125 or %o2, %lo((PAGE_SIZE/64)-7), %o2 ! A1 Group
126 prefetch [%o1 + 0x040], #one_read ! MS
127 prefetch [%o1 + 0x080], #one_read ! MS Group
128 prefetch [%o1 + 0x0c0], #one_read ! MS Group
129 ldd [%o1 + 0x000], %f0 ! MS Group
130 prefetch [%o1 + 0x100], #one_read ! MS Group
131 ldd [%o1 + 0x008], %f2 ! AX
132 prefetch [%o1 + 0x140], #one_read ! MS Group
133 ldd [%o1 + 0x010], %f4 ! AX
134 prefetch [%o1 + 0x180], #one_read ! MS Group
135 fmovd %f0, %f32 ! FGA Group
136 ldd [%o1 + 0x018], %f6 ! AX
137 fmovd %f2, %f34 ! FGA Group
138 ldd [%o1 + 0x020], %f8 ! MS
139 fmovd %f4, %f36 ! FGA Group
140 ldd [%o1 + 0x028], %f10 ! AX
141 membar #StoreStore ! MS
142 fmovd %f6, %f38 ! FGA Group
143 ldd [%o1 + 0x030], %f12 ! MS
144 fmovd %f8, %f40 ! FGA Group
145 ldd [%o1 + 0x038], %f14 ! AX
146 fmovd %f10, %f42 ! FGA Group
147 ldd [%o1 + 0x040], %f16 ! MS
148 1: ldd [%o1 + 0x048], %f2 ! AX (Group)
149 fmovd %f12, %f44 ! FGA
150 ldd [%o1 + 0x050], %f4 ! MS
151 fmovd %f14, %f46 ! FGA Group
152 stda %f32, [%o0] ASI_BLK_P ! MS
153 ldd [%o1 + 0x058], %f6 ! AX
154 fmovd %f16, %f32 ! FGA Group (8-cycle stall)
155 ldd [%o1 + 0x060], %f8 ! MS
156 fmovd %f2, %f34 ! FGA Group
157 ldd [%o1 + 0x068], %f10 ! AX
158 fmovd %f4, %f36 ! FGA Group
159 ldd [%o1 + 0x070], %f12 ! MS
160 fmovd %f6, %f38 ! FGA Group
161 ldd [%o1 + 0x078], %f14 ! AX
162 fmovd %f8, %f40 ! FGA Group
163 ldd [%o1 + 0x080], %f16 ! AX
164 prefetch [%o1 + 0x180], #one_read ! MS
165 fmovd %f10, %f42 ! FGA Group
166 subcc %o2, 1, %o2 ! A0
167 add %o0, 0x40, %o0 ! A1
169 add %o1, 0x40, %o1 ! A0 Group
171 mov 5, %o2 ! A0 Group
172 1: ldd [%o1 + 0x048], %f2 ! AX
173 fmovd %f12, %f44 ! FGA
174 ldd [%o1 + 0x050], %f4 ! MS
175 fmovd %f14, %f46 ! FGA Group
176 stda %f32, [%o0] ASI_BLK_P ! MS
177 ldd [%o1 + 0x058], %f6 ! AX
178 fmovd %f16, %f32 ! FGA Group (8-cycle stall)
179 ldd [%o1 + 0x060], %f8 ! MS
180 fmovd %f2, %f34 ! FGA Group
181 ldd [%o1 + 0x068], %f10 ! AX
182 fmovd %f4, %f36 ! FGA Group
183 ldd [%o1 + 0x070], %f12 ! MS
184 fmovd %f6, %f38 ! FGA Group
185 ldd [%o1 + 0x078], %f14 ! AX
186 fmovd %f8, %f40 ! FGA Group
187 ldd [%o1 + 0x080], %f16 ! MS
188 fmovd %f10, %f42 ! FGA Group
189 subcc %o2, 1, %o2 ! A0
190 add %o0, 0x40, %o0 ! A1
192 add %o1, 0x40, %o1 ! A0 Group
194 ldd [%o1 + 0x048], %f2 ! AX
195 fmovd %f12, %f44 ! FGA
196 ldd [%o1 + 0x050], %f4 ! MS
197 fmovd %f14, %f46 ! FGA Group
198 stda %f32, [%o0] ASI_BLK_P ! MS
199 ldd [%o1 + 0x058], %f6 ! AX
200 fmovd %f16, %f32 ! FGA Group (8-cycle stall)
201 ldd [%o1 + 0x060], %f8 ! MS
202 fmovd %f2, %f34 ! FGA Group
203 ldd [%o1 + 0x068], %f10 ! AX
204 fmovd %f4, %f36 ! FGA Group
205 ldd [%o1 + 0x070], %f12 ! MS
206 fmovd %f6, %f38 ! FGA Group
207 add %o0, 0x40, %o0 ! A0
208 ldd [%o1 + 0x078], %f14 ! AX
209 fmovd %f8, %f40 ! FGA Group
210 fmovd %f10, %f42 ! FGA Group
211 fmovd %f12, %f44 ! FGA Group
212 fmovd %f14, %f46 ! FGA Group
213 stda %f32, [%o0] ASI_BLK_P ! MS
214 .globl cheetah_copy_user_page_nop_2_3
215 cheetah_copy_user_page_nop_2_3:
216 mov PRIMARY_CONTEXT, %o2
217 stxa %g0, [%o2] ASI_DMMU ! Flush P-cache
218 stxa %g3, [%g0] ASI_DCU_CONTROL_REG ! Disable P-cache
219 ba,a,pt %xcc, copy_user_page_continue
221 spitfire_copy_user_page:
222 ldda [%o1] ASI_BLK_P, %f0
224 ldda [%o1] ASI_BLK_P, %f16
226 sethi %hi(PAGE_SIZE), %o2
227 1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
228 ldda [%o1] ASI_BLK_P, %f32
229 stda %f48, [%o0] ASI_BLK_P
233 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
234 ldda [%o1] ASI_BLK_P, %f0
235 stda %f48, [%o0] ASI_BLK_P
239 TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
240 ldda [%o1] ASI_BLK_P, %f16
241 stda %f48, [%o0] ASI_BLK_P
244 cmp %o2, PAGE_SIZE_REM
247 #if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
248 TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
249 ldda [%o1] ASI_BLK_P, %f32
250 stda %f48, [%o0] ASI_BLK_P
254 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
255 ldda [%o1] ASI_BLK_P, %f0
256 stda %f48, [%o0] ASI_BLK_P
261 stda %f32, [%o0] ASI_BLK_P
263 stda %f0, [%o0] ASI_BLK_P
266 stda %f0, [%o0] ASI_BLK_P
268 stda %f16, [%o0] ASI_BLK_P
270 copy_user_page_continue:
274 mov TLB_TAG_ACCESS, %o2
275 stxa %g5, [%o2] ASI_DMMU
276 stxa %g7, [%o3] ASI_DTLB_DATA_ACCESS
278 sub %o3, (TLBTEMP_ENTSZ), %o3
279 stxa %o4, [%o2] ASI_DMMU
280 stxa %o5, [%o3] ASI_DTLB_DATA_ACCESS
284 wrpr %g3, PSTATE_IE, %pstate
286 copy_page_using_blkcommit:
287 membar #LoadStore | #StoreStore | #StoreLoad
288 ldda [%o1] ASI_BLK_P, %f0
290 ldda [%o1] ASI_BLK_P, %f16
292 sethi %hi(PAGE_SIZE), %o2
293 1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
294 ldda [%o1] ASI_BLK_P, %f32
295 stda %f48, [%o0] ASI_BLK_COMMIT_P
299 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
300 ldda [%o1] ASI_BLK_P, %f0
301 stda %f48, [%o0] ASI_BLK_COMMIT_P
305 TOUCH(f32, f34, f36, f38, f40, f42, f44, f46)
306 ldda [%o1] ASI_BLK_P, %f16
307 stda %f48, [%o0] ASI_BLK_COMMIT_P
310 cmp %o2, PAGE_SIZE_REM
313 #if (PAGE_SHIFT == 16) || (PAGE_SHIFT == 22)
314 TOUCH(f0, f2, f4, f6, f8, f10, f12, f14)
315 ldda [%o1] ASI_BLK_P, %f32
316 stda %f48, [%o0] ASI_BLK_COMMIT_P
320 TOUCH(f16, f18, f20, f22, f24, f26, f28, f30)
321 ldda [%o1] ASI_BLK_P, %f0
322 stda %f48, [%o0] ASI_BLK_COMMIT_P
327 stda %f32, [%o0] ASI_BLK_COMMIT_P
329 ba,pt %xcc, copy_user_page_continue
330 stda %f0, [%o0] ASI_BLK_COMMIT_P
333 stda %f0, [%o0] ASI_BLK_COMMIT_P
335 ba,pt %xcc, copy_user_page_continue
336 stda %f16, [%o0] ASI_BLK_COMMIT_P
341 .type _clear_page,@function
342 _clear_page: /* %o0=dest */
344 ba,pt %xcc, clear_page_common
348 .globl clear_user_page
349 .type clear_user_page,@function
350 clear_user_page: /* %o0=dest, %o1=vaddr */
352 sethi %hi(PAGE_SIZE), %g3
355 mov TLB_TAG_ACCESS, %o2
356 sethi %uhi(_PAGE_VALID | _PAGE_SZBITS), %g3
357 sethi %hi(TLBTEMP_BASE), %o3
359 or %g3, (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_L | _PAGE_W), %g3
362 #define FIX_INSN_2 0x96102068 /* mov (13 << 3), %o3 */
364 mov TLBTEMP_ENT2, %o3
366 wrpr %g3, PSTATE_IE, %pstate
368 /* Spitfire Errata #32 workaround */
369 mov PRIMARY_CONTEXT, %g5
370 stxa %g0, [%g5] ASI_DMMU
373 ldxa [%o3] ASI_DTLB_TAG_READ, %g5
375 /* Spitfire Errata #32 workaround */
376 mov PRIMARY_CONTEXT, %g7
377 stxa %g0, [%g7] ASI_DMMU
380 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g0
381 ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
382 stxa %o0, [%o2] ASI_DMMU
383 stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
389 membar #StoreLoad | #StoreStore | #LoadStore ! LSU Group
390 fzero %f0 ! FPA Group
391 sethi %hi(PAGE_SIZE/256), %o1 ! IEU0
392 fzero %f2 ! FPA Group
393 or %o1, %lo(PAGE_SIZE/256), %o1 ! IEU0
394 faddd %f0, %f2, %f4 ! FPA Group
395 fmuld %f0, %f2, %f6 ! FPM
396 faddd %f0, %f2, %f8 ! FPA Group
397 fmuld %f0, %f2, %f10 ! FPM
399 faddd %f0, %f2, %f12 ! FPA Group
400 fmuld %f0, %f2, %f14 ! FPM
401 1: stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
402 add %o0, 0x40, %o0 ! IEU0
403 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
404 add %o0, 0x40, %o0 ! IEU0
405 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
407 add %o0, 0x40, %o0 ! IEU0 Group
408 stda %f0, [%o0 + %g0] ASI_BLK_P ! Store Group
409 subcc %o1, 1, %o1 ! IEU1
410 bne,pt %icc, 1b ! CTI
411 add %o0, 0x40, %o0 ! IEU0 Group
412 membar #Sync ! LSU Group
422 stxa %g5, [%o2] ASI_DMMU
423 stxa %g7, [%o3] ASI_DTLB_DATA_ACCESS
426 wrpr %g3, 0x0, %pstate
428 .globl cheetah_patch_pgcopyops
429 cheetah_patch_pgcopyops:
430 sethi %hi(FIX_INSN_1), %g1
431 or %g1, %lo(FIX_INSN_1), %g1
432 sethi %hi(cheetah_patch_1), %g2
433 or %g2, %lo(cheetah_patch_1), %g2
436 sethi %hi(FIX_INSN_2), %g1
437 or %g1, %lo(FIX_INSN_2), %g1
438 sethi %hi(cheetah_patch_2), %g2
439 or %g2, %lo(cheetah_patch_2), %g2