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...
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
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...
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
20 bne,pn %icc, __flush_tlb_page_slow
22 stxa %g0, [%g3] ASI_DMMU_DEMAP
23 stxa %g0, [%g3] ASI_IMMU_DEMAP
26 __flush_tlb_mm: /* %o0=(ctx & 0x3ff), %o1=SECONDARY_CONTEXT */
27 /*IC2*/ ldxa [%o1] ASI_DMMU, %g2
29 bne,pn %icc, __flush_tlb_mm_slow
31 stxa %g0, [%g3] ASI_DMMU_DEMAP
32 stxa %g0, [%g3] ASI_IMMU_DEMAP
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)
38 #define TLB_MAGIC 206 /* Students, do you know how I calculated this? -DaveM */
40 be,pt %xcc, __flush_tlb_page
43 bgeu,pn %icc, __flush_tlb_range_constant_time
45 ldxa [%o2] ASI_DMMU, %g2
47 __flush_tlb_range_page_by_page:
48 /*IC4*/ bne,pn %icc, __flush_tlb_range_pbp_slow
50 1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
51 stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
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
61 1: ldxa [%g2] ASI_ITLB_TAG_READ, %o4
65 /*IC6*/ andn %o4, 0x3ff, %o4
70 2: ldxa [%g2] ASI_DTLB_TAG_READ, %o4
73 /*IC7*/ andn %o4, 0x3ff, %o4
81 /*IC8*/ sub %g2, (1 << 3), %g2
83 wrpr %g1, 0x0, %pstate
84 4: stxa %g0, [%g3] ASI_IMMU
85 stxa %g0, [%g2] ASI_ITLB_DATA_ACCESS
88 5: stxa %g0, [%g3] ASI_DMMU
89 /*IC9*/ stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
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
101 stxa %g2, [%o1] ASI_DMMU
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
114 stxa %g2, [%o2] ASI_DMMU
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
129 /*IC14*/stxa %g2, [%o2] ASI_DMMU
132 wrpr %g1, 0x0, %pstate
135 .globl flush_icache_page
136 flush_icache_page: /* %o0 = phys_page */
137 sethi %hi(1 << 13), %o2 ! IC_set bit
143 or %o0, %g1, %o0 ! VALID+phys-addr comparitor
146 andn %g2, 0xfe, %g2 ! IC_tag mask
147 1: ldda [%o1] ASI_IC_TAG, %o4
152 2: ldda [%o1 + %o2] ASI_IC_TAG, %o4
164 iflush1:stxa %g0, [%o1] ASI_IC_TAG
167 iflush2:stxa %g0, [%o1 + %o2] ASI_IC_TAG
172 /* These are all called by the slaves of a cross call, at
173 * trap level 1, with interrupts fully disabled.
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)
180 * %g6 ivector table, don't touch
185 * TODO: Make xcall TLB range flushes use the tricks above... -DaveM
188 .globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
189 xcall_flush_tlb_page:
190 mov SECONDARY_CONTEXT, %g2
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
200 mov SECONDARY_CONTEXT, %g2
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
209 xcall_flush_tlb_range:
210 sethi %hi(8192 - 1), %g2
211 or %g2, %lo(8192 - 1), %g2
220 bgu,pn %icc, xcall_flush_tlb_mm
221 mov SECONDARY_CONTEXT, %g4
222 ldxa [%g4] ASI_DMMU, %g7
224 stxa %g5, [%g4] ASI_DMMU
228 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
229 stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
232 stxa %g7, [%g4] ASI_DMMU
237 .globl xcall_report_regs
240 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
245 109: or %g7, %lo(109b), %g7
247 add %sp, STACK_BIAS + REGWIN_SZ, %o0
254 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
259 109: or %g7, %lo(109b), %g7
260 call smp_penguin_jailcell
265 .globl xcall_promstop
268 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
273 109: or %g7, %lo(109b), %g7
277 /* We should not return, just spin if we do... */
281 .globl xcall_receive_signal
282 xcall_receive_signal:
284 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
286 andcc %g1, TSTATE_PRIV, %g0
287 /* If we did not trap from user space, just ignore. */
291 109: or %g7, %lo(109b), %g7
296 /* These two are not performance critical... */
297 .globl xcall_flush_tlb_all
301 1: ldxa [%g3] ASI_DTLB_DATA_ACCESS, %g4
302 and %g4, _PAGE_L, %g5
304 mov TLB_TAG_ACCESS, %g7
305 stxa %g0, [%g7] ASI_DMMU
308 stxa %g0, [%g3] ASI_DTLB_DATA_ACCESS
310 2: ldxa [%g3] ASI_ITLB_DATA_ACCESS, %g4
311 and %g4, _PAGE_L, %g5
313 mov TLB_TAG_ACCESS, %g7
314 stxa %g0, [%g7] ASI_IMMU
317 stxa %g0, [%g3] ASI_ITLB_DATA_ACCESS
325 .globl xcall_flush_cache_all
326 xcall_flush_cache_all:
327 sethi %hi(16383), %g2
328 or %g2, %lo(16383), %g2
330 1: stxa %g0, [%g3] ASI_IC_TAG