Import 2.3.41pre2
[davej-history.git] / arch / sparc64 / mm / ultra.S
blobcb281a6593ca00d5f6dbe6880143ee92255dbf6c
1 /* $Id: ultra.S,v 1.36 1999/12/15 15:45:18 davem Exp $
2  * ultra.S: Don't expand these all over the place...
3  *
4  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5  */
7 #include <asm/asi.h>
8 #include <asm/pgtable.h>
9 #include <asm/spitfire.h>
11         /* This file is meant to be read efficiently by the CPU, not humans.
12          * Staraj sie tego nikomu nie pierdolnac...
13          */
14         .text
15         .align          32
16         .globl          __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range
17 __flush_tlb_page: /* %o0=(ctx & 0x3ff), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */
18 /*IC1*/ ldxa            [%o2] ASI_DMMU, %g2
19         cmp             %g2, %o0
20         bne,pn          %icc, __flush_tlb_page_slow
21          or             %o1, 0x10, %g3
22         stxa            %g0, [%g3] ASI_DMMU_DEMAP
23         stxa            %g0, [%g3] ASI_IMMU_DEMAP
24         retl
25          flush          %g6
26 __flush_tlb_mm: /* %o0=(ctx & 0x3ff), %o1=SECONDARY_CONTEXT */
27 /*IC2*/ ldxa            [%o1] ASI_DMMU, %g2
28         cmp             %g2, %o0
29         bne,pn          %icc, __flush_tlb_mm_slow
30          mov            0x50, %g3
31         stxa            %g0, [%g3] ASI_DMMU_DEMAP
32         stxa            %g0, [%g3] ASI_IMMU_DEMAP
33         retl
34          flush          %g6
35 __flush_tlb_range: /* %o0=(ctx&0x3ff), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
36                     * %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
37                     */
38 #define TLB_MAGIC       206 /* Students, do you know how I calculated this?  -DaveM */
39 /*IC3*/ cmp             %o5, %o4
40         be,pt           %xcc, __flush_tlb_page
41          srlx           %o5, 13, %g5
42         cmp             %g5, TLB_MAGIC
43         bgeu,pn         %icc, __flush_tlb_range_constant_time
44          or             %o1, 0x10, %g5
45         ldxa            [%o2] ASI_DMMU, %g2
46         cmp             %g2, %o0
47 __flush_tlb_range_page_by_page:
48 /*IC4*/ bne,pn          %icc, __flush_tlb_range_pbp_slow
49          sub            %o5, %o4, %o5
50 1:      stxa            %g0, [%g5 + %o5] ASI_DMMU_DEMAP
51         stxa            %g0, [%g5 + %o5] ASI_IMMU_DEMAP
52         brnz,pt         %o5, 1b
53          sub            %o5, %o4, %o5
54         retl
55          flush          %g6
56 __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
57 /*IC5*/ rdpr            %pstate, %g1
58         wrpr            %g1, PSTATE_IE, %pstate
59         mov             TLB_TAG_ACCESS, %g3
60         mov             (62 << 3), %g2
61 1:      ldxa            [%g2] ASI_ITLB_TAG_READ, %o4
62         and             %o4, 0x3ff, %o5
63         cmp             %o5, %o0
64         bne,pt          %icc, 2f
65 /*IC6*/  andn           %o4, 0x3ff, %o4
66         cmp             %o4, %o1
67         blu,pt          %xcc, 2f
68          cmp            %o4, %o3
69         blu,pn          %xcc, 4f
70 2:       ldxa           [%g2] ASI_DTLB_TAG_READ, %o4
71         and             %o4, 0x3ff, %o5
72         cmp             %o5, %o0
73 /*IC7*/ andn            %o4, 0x3ff, %o4
74         bne,pt          %icc, 3f
75          cmp            %o4, %o1
76         blu,pt          %xcc, 3f
77          cmp            %o4, %o3
78         blu,pn          %xcc, 5f
79          nop
80 3:      brnz,pt         %g2, 1b
81 /*IC8*/  sub            %g2, (1 << 3), %g2
82         retl
83          wrpr           %g1, 0x0, %pstate
84 4:      stxa            %g0, [%g3] ASI_IMMU
85         stxa            %g0, [%g2] ASI_ITLB_DATA_ACCESS
86         ba,pt           %xcc, 2b
87          flush          %g6
88 5:      stxa            %g0, [%g3] ASI_DMMU
89 /*IC9*/ stxa            %g0, [%g2] ASI_DTLB_DATA_ACCESS
90         ba,pt           %xcc, 3b
91          flush          %g6
93         .align          32
94 __flush_tlb_mm_slow:
95 /*IC10*/rdpr            %pstate, %g1
96         wrpr            %g1, PSTATE_IE, %pstate
97         stxa            %o0, [%o1] ASI_DMMU
98         stxa            %g0, [%g3] ASI_DMMU_DEMAP
99         stxa            %g0, [%g3] ASI_IMMU_DEMAP
100         flush           %g6
101         stxa            %g2, [%o1] ASI_DMMU
102         flush           %g6
103 /*IC11*/retl
104          wrpr           %g1, 0, %pstate
106         .align          32
107 __flush_tlb_page_slow:
108 /*IC12*/rdpr            %pstate, %g1
109         wrpr            %g1, PSTATE_IE, %pstate
110         stxa            %o0, [%o2] ASI_DMMU
111         stxa            %g0, [%g3] ASI_DMMU_DEMAP
112         stxa            %g0, [%g3] ASI_IMMU_DEMAP
113         flush           %g6
114         stxa            %g2, [%o2] ASI_DMMU
115         flush           %g6
116 /*IC13*/retl
117          wrpr           %g1, 0, %pstate
119         .align          32
120 __flush_tlb_range_pbp_slow:
121 /*IC13*/rdpr            %pstate, %g1
122         wrpr            %g1, PSTATE_IE, %pstate
123         stxa            %o0, [%o2] ASI_DMMU
124 2:      stxa            %g0, [%g5 + %o5] ASI_DMMU_DEMAP
125         stxa            %g0, [%g5 + %o5] ASI_IMMU_DEMAP
126         brnz,pt         %o5, 2b
127          sub            %o5, %o4, %o5
128         flush           %g6
129 /*IC14*/stxa            %g2, [%o2] ASI_DMMU
130         flush           %g6
131         retl
132          wrpr           %g1, 0x0, %pstate
134         .align          32
135         .globl          flush_icache_page
136 flush_icache_page:      /* %o0 = phys_page */
137         sethi           %hi(1 << 13), %o2       ! IC_set bit
138         mov             1, %g1
139         srlx            %o0, 5, %o0
140         clr             %o1                     ! IC_addr
141         sllx            %g1, 36, %g1
142         sub             %g1, 1, %g2
143         or              %o0, %g1, %o0           ! VALID+phys-addr comparitor
144         sllx            %g2, 1, %g2
146         andn            %g2, 0xfe, %g2          ! IC_tag mask
147 1:      ldda            [%o1] ASI_IC_TAG, %o4
148         and             %o5, %g2, %o5
149         cmp             %o5, %o0
150         be,pn           %xcc, iflush1
151          add            %o1, 0x20, %g3
152 2:      ldda            [%o1 + %o2] ASI_IC_TAG, %o4
153         and             %o5, %g2, %o5
155         cmp             %o5, %o0
156         be,pn           %xcc, iflush2
157          nop
158 3:      cmp             %g3, %o2
159         bne,pt          %xcc, 1b
160          mov            %g3, %o1
161         retl
162          nop
164 iflush1:stxa            %g0, [%o1] ASI_IC_TAG
165         flush           %g6
166         ba,a,pt         %xcc, 2b
167 iflush2:stxa            %g0, [%o1 + %o2] ASI_IC_TAG
168         flush           %g6
169         ba,a,pt         %xcc, 3b
171 #ifdef __SMP__
172         /* These are all called by the slaves of a cross call, at
173          * trap level 1, with interrupts fully disabled.
174          *
175          * Register usage:
176          *   %g5        mm->context     (all tlb flushes)
177          *   %g1        address arg 1   (tlb page and range flushes)
178          *   %g7        address arg 2   (tlb range flush only)
179          *
180          *   %g6        ivector table, don't touch
181          *   %g2        scratch 1
182          *   %g3        scratch 2
183          *   %g4        scratch 3
184          *
185          * TODO: Make xcall TLB range flushes use the tricks above... -DaveM
186          */
187         .align          32
188         .globl          xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
189 xcall_flush_tlb_page:
190         mov             SECONDARY_CONTEXT, %g2
191         or              %g1, 0x10, %g4
192         ldxa            [%g2] ASI_DMMU, %g3
193         stxa            %g5, [%g2] ASI_DMMU
194         stxa            %g0, [%g4] ASI_DMMU_DEMAP
195         stxa            %g0, [%g4] ASI_IMMU_DEMAP
196         stxa            %g3, [%g2] ASI_DMMU
197         retry
199 xcall_flush_tlb_mm:
200         mov             SECONDARY_CONTEXT, %g2
201         mov             0x50, %g4
202         ldxa            [%g2] ASI_DMMU, %g3
203         stxa            %g5, [%g2] ASI_DMMU
204         stxa            %g0, [%g4] ASI_DMMU_DEMAP
205         stxa            %g0, [%g4] ASI_IMMU_DEMAP
206         stxa            %g3, [%g2] ASI_DMMU
207         retry
209 xcall_flush_tlb_range:
210         sethi           %hi(8192 - 1), %g2
211         or              %g2, %lo(8192 - 1), %g2
212         andn            %g1, %g2, %g1
213         andn            %g7, %g2, %g7
214         sub             %g7, %g1, %g3
215         add             %g2, 1, %g2
216         orcc            %g1, 0x10, %g1
217         srlx            %g3, 13, %g4
219         cmp             %g4, 96
220         bgu,pn          %icc, xcall_flush_tlb_mm
221          mov            SECONDARY_CONTEXT, %g4
222         ldxa            [%g4] ASI_DMMU, %g7
223         sub             %g3, %g2, %g3
224         stxa            %g5, [%g4] ASI_DMMU
225         nop
226         nop
228 1:      stxa            %g0, [%g1 + %g3] ASI_DMMU_DEMAP
229         stxa            %g0, [%g1 + %g3] ASI_IMMU_DEMAP
230         brnz,pt         %g3, 1b
231          sub            %g3, %g2, %g3
232         stxa            %g7, [%g4] ASI_DMMU
233         retry
234         nop
235         nop
237         .globl          xcall_report_regs
238 xcall_report_regs:
239         rdpr            %pstate, %g2
240         wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
241         rdpr            %pil, %g2
242         wrpr            %g0, 15, %pil
243         sethi           %hi(109f), %g7
244         b,pt            %xcc, etrap_irq
245 109:     or             %g7, %lo(109b), %g7
246         call            __show_regs
247          add            %sp, STACK_BIAS + REGWIN_SZ, %o0
248         b,pt            %xcc, rtrap
249          clr            %l6
251         .globl          xcall_capture
252 xcall_capture:
253         rdpr            %pstate, %g2
254         wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
255         rdpr            %pil, %g2
256         wrpr            %g0, 15, %pil
257         sethi           %hi(109f), %g7
258         b,pt            %xcc, etrap_irq
259 109:     or             %g7, %lo(109b), %g7
260         call            smp_penguin_jailcell
261          nop
262         b,pt            %xcc, rtrap
263          clr            %l6
265         .globl          xcall_promstop
266 xcall_promstop:
267         rdpr            %pstate, %g2
268         wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
269         rdpr            %pil, %g2
270         wrpr            %g0, 15, %pil
271         sethi           %hi(109f), %g7
272         b,pt            %xcc, etrap_irq
273 109:     or             %g7, %lo(109b), %g7
274         flushw
275         call            prom_stopself
276          nop
277         /* We should not return, just spin if we do... */
278 1:      b,a,pt          %xcc, 1b
279         nop
281         .globl          xcall_receive_signal
282 xcall_receive_signal:
283         rdpr            %pstate, %g2
284         wrpr            %g2, PSTATE_IG | PSTATE_AG, %pstate
285         rdpr            %tstate, %g1
286         andcc           %g1, TSTATE_PRIV, %g0
287         /* If we did not trap from user space, just ignore. */
288         bne,pn          %xcc, 99f
289          sethi          %hi(109f), %g7
290         b,pt            %xcc, etrap
291 109:     or             %g7, %lo(109b), %g7
292         b,pt            %xcc, rtrap
293          clr            %l6
294 99:     retry
296         /* These two are not performance critical... */
297         .globl          xcall_flush_tlb_all
298 xcall_flush_tlb_all:
299         clr             %g2
300         clr             %g3
301 1:      ldxa            [%g3] ASI_DTLB_DATA_ACCESS, %g4
302         and             %g4, _PAGE_L, %g5
303         brnz,pn         %g5, 2f
304          mov            TLB_TAG_ACCESS, %g7
305         stxa            %g0, [%g7] ASI_DMMU
306         membar          #Sync
308         stxa            %g0, [%g3] ASI_DTLB_DATA_ACCESS
309         membar          #Sync
310 2:      ldxa            [%g3] ASI_ITLB_DATA_ACCESS, %g4
311         and             %g4, _PAGE_L, %g5
312         brnz,pn         %g5, 2f
313          mov            TLB_TAG_ACCESS, %g7
314         stxa            %g0, [%g7] ASI_IMMU
315         membar          #Sync
317         stxa            %g0, [%g3] ASI_ITLB_DATA_ACCESS
318 2:      add             %g2, 1, %g2
319         cmp             %g2, 63
320         ble,pt          %icc, 1b
321          sll            %g2, 3, %g3
322         flush           %g6
323         retry
325         .globl          xcall_flush_cache_all
326 xcall_flush_cache_all:
327         sethi           %hi(16383), %g2
328         or              %g2, %lo(16383), %g2
329         clr             %g3
330 1:      stxa            %g0, [%g3] ASI_IC_TAG
331         add             %g3, 32, %g3
332         cmp             %g3, %g2
333         bleu,pt         %xcc, 1b
334          nop
335         flush           %g6
336         retry
337 #endif /* __SMP__ */