Merge /spare/repo/linux-2.6/
[linux-2.6] / arch / sparc / mm / viking.S
1 /* $Id: viking.S,v 1.19 2001/12/21 04:56:15 davem Exp $
2  * viking.S: High speed Viking cache/mmu operations
3  *
4  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
5  * Copyright (C) 1997,1998,1999  Jakub Jelinek  (jj@ultra.linux.cz)
6  * Copyright (C) 1999  Pavel Semerad  (semerad@ss1000.ms.mff.cuni.cz)
7  */
8
9 #include <linux/config.h>
10 #include <asm/ptrace.h>
11 #include <asm/psr.h>
12 #include <asm/asm-offsets.h>
13 #include <asm/asi.h>
14 #include <asm/mxcc.h>
15 #include <asm/page.h>
16 #include <asm/pgtsrmmu.h>
17 #include <asm/viking.h>
18 #include <asm/btfixup.h>
19
20 #ifdef CONFIG_SMP
21         .data
22         .align  4
23 sun4dsmp_flush_tlb_spin:
24         .word   0
25 #endif
26
27         .text
28         .align  4
29
30         .globl  viking_flush_cache_all, viking_flush_cache_mm
31         .globl  viking_flush_cache_range, viking_flush_cache_page
32         .globl  viking_flush_page, viking_mxcc_flush_page
33         .globl  viking_flush_page_for_dma, viking_flush_page_to_ram
34         .globl  viking_flush_sig_insns
35         .globl  viking_flush_tlb_all, viking_flush_tlb_mm
36         .globl  viking_flush_tlb_range, viking_flush_tlb_page
37
38 viking_flush_page:
39         sethi   %hi(PAGE_OFFSET), %g2
40         sub     %o0, %g2, %g3
41         srl     %g3, 12, %g1            ! ppage >> 12
42
43         clr     %o1                     ! set counter, 0 - 127
44         sethi   %hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3
45         sethi   %hi(0x80000000), %o4
46         sethi   %hi(VIKING_PTAG_VALID), %o5
47         sethi   %hi(2*PAGE_SIZE), %o0
48         sethi   %hi(PAGE_SIZE), %g7
49         clr     %o2                     ! block counter, 0 - 3
50 5:
51         sll     %o1, 5, %g4
52         or      %g4, %o4, %g4           ! 0x80000000 | (set << 5)
53
54         sll     %o2, 26, %g5            ! block << 26
55 6:
56         or      %g5, %g4, %g5
57         ldda    [%g5] ASI_M_DATAC_TAG, %g2
58         cmp     %g3, %g1                ! ptag == ppage?
59         bne     7f
60          inc    %o2
61
62         andcc   %g2, %o5, %g0           ! ptag VALID?
63         be      7f
64          add    %g4, %o3, %g2           ! (PAGE_OFFSET + PAGE_SIZE) | (set << 5)
65         ld      [%g2], %g3
66         ld      [%g2 + %g7], %g3
67         add     %g2, %o0, %g2
68         ld      [%g2], %g3
69         ld      [%g2 + %g7], %g3
70         add     %g2, %o0, %g2
71         ld      [%g2], %g3
72         ld      [%g2 + %g7], %g3
73         add     %g2, %o0, %g2
74         ld      [%g2], %g3
75         b       8f
76          ld     [%g2 + %g7], %g3
77
78 7:
79         cmp     %o2, 3
80         ble     6b
81          sll    %o2, 26, %g5                    ! block << 26
82
83 8:      inc     %o1
84         cmp     %o1, 0x7f
85         ble     5b
86          clr    %o2
87
88 9:      retl
89          nop
90
91 viking_mxcc_flush_page:
92         sethi   %hi(PAGE_OFFSET), %g2
93         sub     %o0, %g2, %g3
94         sub     %g3, -PAGE_SIZE, %g3            ! ppage + PAGE_SIZE
95         sethi   %hi(MXCC_SRCSTREAM), %o3        ! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM)
96         mov     0x10, %g2                       ! set cacheable bit
97         or      %o3, %lo(MXCC_SRCSTREAM), %o2
98         or      %o3, %lo(MXCC_DESSTREAM), %o3
99         sub     %g3, MXCC_STREAM_SIZE, %g3
100 6:
101         stda    %g2, [%o2] ASI_M_MXCC
102         stda    %g2, [%o3] ASI_M_MXCC
103         andncc  %g3, PAGE_MASK, %g0
104         bne     6b
105          sub    %g3, MXCC_STREAM_SIZE, %g3
106
107 9:      retl
108          nop
109
110 viking_flush_cache_page:
111 viking_flush_cache_range:
112 #ifndef CONFIG_SMP
113         ld      [%o0 + 0x0], %o0                /* XXX vma->vm_mm, GROSS XXX */
114 #endif
115 viking_flush_cache_mm:
116 #ifndef CONFIG_SMP
117         ld      [%o0 + AOFF_mm_context], %g1
118         cmp     %g1, -1
119         bne     viking_flush_cache_all
120          nop
121         b,a     viking_flush_cache_out
122 #endif
123 viking_flush_cache_all:
124         WINDOW_FLUSH(%g4, %g5)
125 viking_flush_cache_out:
126         retl
127          nop
128
129 viking_flush_tlb_all:
130         mov     0x400, %g1
131         retl
132          sta    %g0, [%g1] ASI_M_FLUSH_PROBE
133
134 viking_flush_tlb_mm:
135         mov     SRMMU_CTX_REG, %g1
136         ld      [%o0 + AOFF_mm_context], %o1
137         lda     [%g1] ASI_M_MMUREGS, %g5
138 #ifndef CONFIG_SMP
139         cmp     %o1, -1
140         be      1f
141 #endif
142         mov     0x300, %g2
143         sta     %o1, [%g1] ASI_M_MMUREGS
144         sta     %g0, [%g2] ASI_M_FLUSH_PROBE
145         retl
146          sta    %g5, [%g1] ASI_M_MMUREGS
147 #ifndef CONFIG_SMP
148 1:      retl
149          nop
150 #endif
151
152 viking_flush_tlb_range:
153         ld      [%o0 + 0x00], %o0       /* XXX vma->vm_mm GROSS XXX */
154         mov     SRMMU_CTX_REG, %g1
155         ld      [%o0 + AOFF_mm_context], %o3
156         lda     [%g1] ASI_M_MMUREGS, %g5
157 #ifndef CONFIG_SMP
158         cmp     %o3, -1
159         be      2f
160 #endif
161         sethi   %hi(~((1 << SRMMU_PGDIR_SHIFT) - 1)), %o4
162         sta     %o3, [%g1] ASI_M_MMUREGS
163         and     %o1, %o4, %o1
164         add     %o1, 0x200, %o1
165         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
166 1:      sub     %o1, %o4, %o1
167         cmp     %o1, %o2
168         blu,a   1b
169          sta    %g0, [%o1] ASI_M_FLUSH_PROBE
170         retl
171          sta    %g5, [%g1] ASI_M_MMUREGS
172 #ifndef CONFIG_SMP
173 2:      retl
174          nop
175 #endif
176
177 viking_flush_tlb_page:
178         ld      [%o0 + 0x00], %o0       /* XXX vma->vm_mm GROSS XXX */
179         mov     SRMMU_CTX_REG, %g1
180         ld      [%o0 + AOFF_mm_context], %o3
181         lda     [%g1] ASI_M_MMUREGS, %g5
182 #ifndef CONFIG_SMP
183         cmp     %o3, -1
184         be      1f
185 #endif
186         and     %o1, PAGE_MASK, %o1
187         sta     %o3, [%g1] ASI_M_MMUREGS
188         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
189         retl
190          sta    %g5, [%g1] ASI_M_MMUREGS
191 #ifndef CONFIG_SMP
192 1:      retl
193          nop
194 #endif
195
196 viking_flush_page_to_ram:
197 viking_flush_page_for_dma:
198 viking_flush_sig_insns:
199         retl
200          nop
201
202 #ifdef CONFIG_SMP
203         .globl  sun4dsmp_flush_tlb_all, sun4dsmp_flush_tlb_mm
204         .globl  sun4dsmp_flush_tlb_range, sun4dsmp_flush_tlb_page
205 sun4dsmp_flush_tlb_all:
206         sethi   %hi(sun4dsmp_flush_tlb_spin), %g3
207 1:      ldstub  [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
208         tst     %g5
209         bne     2f
210          mov    0x400, %g1
211         sta     %g0, [%g1] ASI_M_FLUSH_PROBE
212         retl
213          stb    %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
214 2:      tst     %g5
215         bne,a   2b
216          ldub   [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
217         b,a     1b
218
219 sun4dsmp_flush_tlb_mm:
220         sethi   %hi(sun4dsmp_flush_tlb_spin), %g3
221 1:      ldstub  [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
222         tst     %g5
223         bne     2f
224          mov    SRMMU_CTX_REG, %g1
225         ld      [%o0 + AOFF_mm_context], %o1
226         lda     [%g1] ASI_M_MMUREGS, %g5
227         mov     0x300, %g2
228         sta     %o1, [%g1] ASI_M_MMUREGS
229         sta     %g0, [%g2] ASI_M_FLUSH_PROBE
230         sta     %g5, [%g1] ASI_M_MMUREGS
231         retl
232          stb    %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
233 2:      tst     %g5
234         bne,a   2b
235          ldub   [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
236         b,a     1b
237
238 sun4dsmp_flush_tlb_range:
239         sethi   %hi(sun4dsmp_flush_tlb_spin), %g3
240 1:      ldstub  [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
241         tst     %g5
242         bne     3f
243          mov    SRMMU_CTX_REG, %g1
244         ld      [%o0 + 0x00], %o0       /* XXX vma->vm_mm GROSS XXX */
245         ld      [%o0 + AOFF_mm_context], %o3
246         lda     [%g1] ASI_M_MMUREGS, %g5
247         sethi   %hi(~((1 << SRMMU_PGDIR_SHIFT) - 1)), %o4
248         sta     %o3, [%g1] ASI_M_MMUREGS
249         and     %o1, %o4, %o1
250         add     %o1, 0x200, %o1
251         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
252 2:      sub     %o1, %o4, %o1
253         cmp     %o1, %o2
254         blu,a   2b
255          sta    %g0, [%o1] ASI_M_FLUSH_PROBE
256         sta     %g5, [%g1] ASI_M_MMUREGS
257         retl
258          stb    %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
259 3:      tst     %g5
260         bne,a   3b
261          ldub   [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
262         b,a     1b
263
264 sun4dsmp_flush_tlb_page:
265         sethi   %hi(sun4dsmp_flush_tlb_spin), %g3
266 1:      ldstub  [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
267         tst     %g5
268         bne     2f
269          mov    SRMMU_CTX_REG, %g1
270         ld      [%o0 + 0x00], %o0       /* XXX vma->vm_mm GROSS XXX */
271         ld      [%o0 + AOFF_mm_context], %o3
272         lda     [%g1] ASI_M_MMUREGS, %g5
273         and     %o1, PAGE_MASK, %o1
274         sta     %o3, [%g1] ASI_M_MMUREGS
275         sta     %g0, [%o1] ASI_M_FLUSH_PROBE
276         sta     %g5, [%g1] ASI_M_MMUREGS
277         retl
278          stb    %g0, [%g3 + %lo(sun4dsmp_flush_tlb_spin)]
279 2:      tst     %g5
280         bne,a   2b
281          ldub   [%g3 + %lo(sun4dsmp_flush_tlb_spin)], %g5
282         b,a     1b
283          nop
284 #endif