blob: 86773e89dc1bbf29cf71831948e6d79b5d43188b [file] [log] [blame]
Adrian Bunkb00dc832008-05-19 16:52:27 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * ultra.S: Don't expand these all over the place...
3 *
David S. Miller93dae5b2008-05-19 23:46:00 -07004 * Copyright (C) 1997, 2000, 2008 David S. Miller (davem@davemloft.net)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
6
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <asm/asi.h>
8#include <asm/pgtable.h>
9#include <asm/page.h>
10#include <asm/spitfire.h>
11#include <asm/mmu_context.h>
David S. Miller2ef27772005-08-30 20:21:34 -070012#include <asm/mmu.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <asm/pil.h>
14#include <asm/head.h>
15#include <asm/thread_info.h>
16#include <asm/cacheflush.h>
David S. Miller52bf0822006-02-04 03:08:37 -080017#include <asm/hypervisor.h>
David S. Miller93dae5b2008-05-19 23:46:00 -070018#include <asm/cpudata.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019
20 /* Basically, most of the Spitfire vs. Cheetah madness
21 * has to do with the fact that Cheetah does not support
22 * IMMU flushes out of the secondary context. Someone needs
23 * to throw a south lake birthday party for the folks
24 * in Microelectronics who refused to fix this shit.
25 */
26
27 /* This file is meant to be read efficiently by the CPU, not humans.
28 * Staraj sie tego nikomu nie pierdolnac...
29 */
30 .text
31 .align 32
32 .globl __flush_tlb_mm
David S. Miller52bf0822006-02-04 03:08:37 -080033__flush_tlb_mm: /* 18 insns */
34 /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 ldxa [%o1] ASI_DMMU, %g2
36 cmp %g2, %o0
37 bne,pn %icc, __spitfire_flush_tlb_mm_slow
38 mov 0x50, %g3
39 stxa %g0, [%g3] ASI_DMMU_DEMAP
40 stxa %g0, [%g3] ASI_IMMU_DEMAP
David S. Miller4da808c2006-01-31 18:33:00 -080041 sethi %hi(KERNBASE), %g3
42 flush %g3
Linus Torvalds1da177e2005-04-16 15:20:36 -070043 retl
David S. Miller4da808c2006-01-31 18:33:00 -080044 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 nop
46 nop
47 nop
48 nop
49 nop
50 nop
51 nop
David S. Miller2ef27772005-08-30 20:21:34 -070052 nop
53 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55 .align 32
56 .globl __flush_tlb_pending
David S. Miller52bf0822006-02-04 03:08:37 -080057__flush_tlb_pending: /* 26 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
59 rdpr %pstate, %g7
60 sllx %o1, 3, %o1
61 andn %g7, PSTATE_IE, %g2
62 wrpr %g2, %pstate
63 mov SECONDARY_CONTEXT, %o4
64 ldxa [%o4] ASI_DMMU, %g2
65 stxa %o0, [%o4] ASI_DMMU
661: sub %o1, (1 << 3), %o1
67 ldx [%o2 + %o1], %o3
68 andcc %o3, 1, %g0
69 andn %o3, 1, %o3
70 be,pn %icc, 2f
71 or %o3, 0x10, %o3
72 stxa %g0, [%o3] ASI_IMMU_DEMAP
732: stxa %g0, [%o3] ASI_DMMU_DEMAP
74 membar #Sync
75 brnz,pt %o1, 1b
76 nop
77 stxa %g2, [%o4] ASI_DMMU
David S. Miller4da808c2006-01-31 18:33:00 -080078 sethi %hi(KERNBASE), %o4
79 flush %o4
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 retl
81 wrpr %g7, 0x0, %pstate
David S. Millerfef43da2005-07-05 19:45:24 -070082 nop
David S. Miller2ef27772005-08-30 20:21:34 -070083 nop
84 nop
85 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87 .align 32
88 .globl __flush_tlb_kernel_range
David S. Miller1daef082006-02-15 20:35:10 -080089__flush_tlb_kernel_range: /* 16 insns */
David S. Miller52bf0822006-02-04 03:08:37 -080090 /* %o0=start, %o1=end */
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 cmp %o0, %o1
92 be,pn %xcc, 2f
93 sethi %hi(PAGE_SIZE), %o4
94 sub %o1, %o0, %o3
95 sub %o3, %o4, %o3
96 or %o0, 0x20, %o0 ! Nucleus
971: stxa %g0, [%o0 + %o3] ASI_DMMU_DEMAP
98 stxa %g0, [%o0 + %o3] ASI_IMMU_DEMAP
99 membar #Sync
100 brnz,pt %o3, 1b
101 sub %o3, %o4, %o3
David S. Miller4da808c2006-01-31 18:33:00 -08001022: sethi %hi(KERNBASE), %o3
103 flush %o3
104 retl
105 nop
David S. Miller52bf0822006-02-04 03:08:37 -0800106 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108__spitfire_flush_tlb_mm_slow:
109 rdpr %pstate, %g1
110 wrpr %g1, PSTATE_IE, %pstate
111 stxa %o0, [%o1] ASI_DMMU
112 stxa %g0, [%g3] ASI_DMMU_DEMAP
113 stxa %g0, [%g3] ASI_IMMU_DEMAP
114 flush %g6
115 stxa %g2, [%o1] ASI_DMMU
David S. Miller4da808c2006-01-31 18:33:00 -0800116 sethi %hi(KERNBASE), %o1
117 flush %o1
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 retl
119 wrpr %g1, 0, %pstate
120
121/*
122 * The following code flushes one page_size worth.
123 */
Prasanna S Panchamukhi83005162005-09-06 15:19:31 -0700124 .section .kprobes.text, "ax"
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 .align 32
126 .globl __flush_icache_page
127__flush_icache_page: /* %o0 = phys_page */
128 membar #StoreStore
129 srlx %o0, PAGE_SHIFT, %o0
130 sethi %uhi(PAGE_OFFSET), %g1
131 sllx %o0, PAGE_SHIFT, %o0
132 sethi %hi(PAGE_SIZE), %g2
133 sllx %g1, 32, %g1
134 add %o0, %g1, %o0
1351: subcc %g2, 32, %g2
136 bne,pt %icc, 1b
137 flush %o0 + %g2
138 retl
139 nop
140
141#ifdef DCACHE_ALIASING_POSSIBLE
142
143#if (PAGE_SHIFT != 13)
144#error only page shift of 13 is supported by dcache flush
145#endif
146
147#define DTAG_MASK 0x3
148
David S. Millerc5bd50a2005-09-26 16:06:03 -0700149 /* This routine is Spitfire specific so the hardcoded
150 * D-cache size and line-size are OK.
151 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 .align 64
153 .globl __flush_dcache_page
154__flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
155 sethi %uhi(PAGE_OFFSET), %g1
156 sllx %g1, 32, %g1
David S. Millerc5bd50a2005-09-26 16:06:03 -0700157 sub %o0, %g1, %o0 ! physical address
158 srlx %o0, 11, %o0 ! make D-cache TAG
159 sethi %hi(1 << 14), %o2 ! D-cache size
160 sub %o2, (1 << 5), %o2 ! D-cache line size
1611: ldxa [%o2] ASI_DCACHE_TAG, %o3 ! load D-cache TAG
162 andcc %o3, DTAG_MASK, %g0 ! Valid?
163 be,pn %xcc, 2f ! Nope, branch
164 andn %o3, DTAG_MASK, %o3 ! Clear valid bits
165 cmp %o3, %o0 ! TAG match?
166 bne,pt %xcc, 2f ! Nope, branch
167 nop
168 stxa %g0, [%o2] ASI_DCACHE_TAG ! Invalidate TAG
169 membar #Sync
1702: brnz,pt %o2, 1b
171 sub %o2, (1 << 5), %o2 ! D-cache line size
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172
173 /* The I-cache does not snoop local stores so we
174 * better flush that too when necessary.
175 */
176 brnz,pt %o1, __flush_icache_page
177 sllx %o0, 11, %o0
178 retl
179 nop
180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181#endif /* DCACHE_ALIASING_POSSIBLE */
182
David S. Millerc5bd50a2005-09-26 16:06:03 -0700183 .previous
184
David S. Miller2ef27772005-08-30 20:21:34 -0700185 /* Cheetah specific versions, patched at boot time. */
David S. Miller4da808c2006-01-31 18:33:00 -0800186__cheetah_flush_tlb_mm: /* 19 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 rdpr %pstate, %g7
188 andn %g7, PSTATE_IE, %g2
189 wrpr %g2, 0x0, %pstate
190 wrpr %g0, 1, %tl
191 mov PRIMARY_CONTEXT, %o2
192 mov 0x40, %g3
193 ldxa [%o2] ASI_DMMU, %g2
David S. Miller2ef27772005-08-30 20:21:34 -0700194 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o1
195 sllx %o1, CTX_PGSZ1_NUC_SHIFT, %o1
196 or %o0, %o1, %o0 /* Preserve nucleus page size fields */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 stxa %o0, [%o2] ASI_DMMU
198 stxa %g0, [%g3] ASI_DMMU_DEMAP
199 stxa %g0, [%g3] ASI_IMMU_DEMAP
200 stxa %g2, [%o2] ASI_DMMU
David S. Miller4da808c2006-01-31 18:33:00 -0800201 sethi %hi(KERNBASE), %o2
202 flush %o2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 wrpr %g0, 0, %tl
204 retl
205 wrpr %g7, 0x0, %pstate
206
David S. Miller4da808c2006-01-31 18:33:00 -0800207__cheetah_flush_tlb_pending: /* 27 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
209 rdpr %pstate, %g7
210 sllx %o1, 3, %o1
211 andn %g7, PSTATE_IE, %g2
212 wrpr %g2, 0x0, %pstate
213 wrpr %g0, 1, %tl
214 mov PRIMARY_CONTEXT, %o4
215 ldxa [%o4] ASI_DMMU, %g2
David S. Miller2ef27772005-08-30 20:21:34 -0700216 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3
217 sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3
218 or %o0, %o3, %o0 /* Preserve nucleus page size fields */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 stxa %o0, [%o4] ASI_DMMU
2201: sub %o1, (1 << 3), %o1
221 ldx [%o2 + %o1], %o3
222 andcc %o3, 1, %g0
223 be,pn %icc, 2f
224 andn %o3, 1, %o3
225 stxa %g0, [%o3] ASI_IMMU_DEMAP
2262: stxa %g0, [%o3] ASI_DMMU_DEMAP
David S. Millerb445e262005-06-27 15:42:04 -0700227 membar #Sync
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 brnz,pt %o1, 1b
David S. Millerb445e262005-06-27 15:42:04 -0700229 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700230 stxa %g2, [%o4] ASI_DMMU
David S. Miller4da808c2006-01-31 18:33:00 -0800231 sethi %hi(KERNBASE), %o4
232 flush %o4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 wrpr %g0, 0, %tl
234 retl
235 wrpr %g7, 0x0, %pstate
236
237#ifdef DCACHE_ALIASING_POSSIBLE
David S. Millerc5bd50a2005-09-26 16:06:03 -0700238__cheetah_flush_dcache_page: /* 11 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 sethi %uhi(PAGE_OFFSET), %g1
240 sllx %g1, 32, %g1
241 sub %o0, %g1, %o0
242 sethi %hi(PAGE_SIZE), %o4
2431: subcc %o4, (1 << 5), %o4
244 stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
245 membar #Sync
246 bne,pt %icc, 1b
247 nop
248 retl /* I-cache flush never needed on Cheetah, see callers. */
249 nop
250#endif /* DCACHE_ALIASING_POSSIBLE */
251
David S. Miller52bf0822006-02-04 03:08:37 -0800252 /* Hypervisor specific versions, patched at boot time. */
David S. Miller2a3a5f52006-02-26 19:31:49 -0800253__hypervisor_tlb_tl0_error:
254 save %sp, -192, %sp
255 mov %i0, %o0
256 call hypervisor_tlbop_error
257 mov %i1, %o1
258 ret
259 restore
260
261__hypervisor_flush_tlb_mm: /* 10 insns */
David S. Miller52bf0822006-02-04 03:08:37 -0800262 mov %o0, %o2 /* ARG2: mmu context */
263 mov 0, %o0 /* ARG0: CPU lists unimplemented */
264 mov 0, %o1 /* ARG1: CPU lists unimplemented */
265 mov HV_MMU_ALL, %o3 /* ARG3: flags */
266 mov HV_FAST_MMU_DEMAP_CTX, %o5
267 ta HV_FAST_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800268 brnz,pn %o0, __hypervisor_tlb_tl0_error
269 mov HV_FAST_MMU_DEMAP_CTX, %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800270 retl
271 nop
272
David S. Miller2a3a5f52006-02-26 19:31:49 -0800273__hypervisor_flush_tlb_pending: /* 16 insns */
David S. Miller52bf0822006-02-04 03:08:37 -0800274 /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
275 sllx %o1, 3, %g1
276 mov %o2, %g2
277 mov %o0, %g3
2781: sub %g1, (1 << 3), %g1
279 ldx [%g2 + %g1], %o0 /* ARG0: vaddr + IMMU-bit */
280 mov %g3, %o1 /* ARG1: mmu context */
David S. Miller2a3a5f52006-02-26 19:31:49 -0800281 mov HV_MMU_ALL, %o2 /* ARG2: flags */
282 srlx %o0, PAGE_SHIFT, %o0
283 sllx %o0, PAGE_SHIFT, %o0
David S. Miller52bf0822006-02-04 03:08:37 -0800284 ta HV_MMU_UNMAP_ADDR_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800285 brnz,pn %o0, __hypervisor_tlb_tl0_error
286 mov HV_MMU_UNMAP_ADDR_TRAP, %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800287 brnz,pt %g1, 1b
288 nop
289 retl
290 nop
291
David S. Miller2a3a5f52006-02-26 19:31:49 -0800292__hypervisor_flush_tlb_kernel_range: /* 16 insns */
David S. Miller52bf0822006-02-04 03:08:37 -0800293 /* %o0=start, %o1=end */
294 cmp %o0, %o1
295 be,pn %xcc, 2f
296 sethi %hi(PAGE_SIZE), %g3
297 mov %o0, %g1
298 sub %o1, %g1, %g2
299 sub %g2, %g3, %g2
3001: add %g1, %g2, %o0 /* ARG0: virtual address */
301 mov 0, %o1 /* ARG1: mmu context */
302 mov HV_MMU_ALL, %o2 /* ARG2: flags */
303 ta HV_MMU_UNMAP_ADDR_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800304 brnz,pn %o0, __hypervisor_tlb_tl0_error
305 mov HV_MMU_UNMAP_ADDR_TRAP, %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800306 brnz,pt %g2, 1b
307 sub %g2, %g3, %g2
3082: retl
309 nop
310
311#ifdef DCACHE_ALIASING_POSSIBLE
312 /* XXX Niagara and friends have an 8K cache, so no aliasing is
313 * XXX possible, but nothing explicit in the Hypervisor API
314 * XXX guarantees this.
315 */
316__hypervisor_flush_dcache_page: /* 2 insns */
317 retl
318 nop
319#endif
320
321tlb_patch_one:
Linus Torvalds1da177e2005-04-16 15:20:36 -07003221: lduw [%o1], %g1
323 stw %g1, [%o0]
324 flush %o0
325 subcc %o2, 1, %o2
326 add %o1, 4, %o1
327 bne,pt %icc, 1b
328 add %o0, 4, %o0
329 retl
330 nop
331
332 .globl cheetah_patch_cachetlbops
333cheetah_patch_cachetlbops:
334 save %sp, -128, %sp
335
336 sethi %hi(__flush_tlb_mm), %o0
337 or %o0, %lo(__flush_tlb_mm), %o0
338 sethi %hi(__cheetah_flush_tlb_mm), %o1
339 or %o1, %lo(__cheetah_flush_tlb_mm), %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800340 call tlb_patch_one
David S. Miller4da808c2006-01-31 18:33:00 -0800341 mov 19, %o2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
343 sethi %hi(__flush_tlb_pending), %o0
344 or %o0, %lo(__flush_tlb_pending), %o0
345 sethi %hi(__cheetah_flush_tlb_pending), %o1
346 or %o1, %lo(__cheetah_flush_tlb_pending), %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800347 call tlb_patch_one
David S. Miller4da808c2006-01-31 18:33:00 -0800348 mov 27, %o2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349
350#ifdef DCACHE_ALIASING_POSSIBLE
351 sethi %hi(__flush_dcache_page), %o0
352 or %o0, %lo(__flush_dcache_page), %o0
David S. Millerc5bd50a2005-09-26 16:06:03 -0700353 sethi %hi(__cheetah_flush_dcache_page), %o1
354 or %o1, %lo(__cheetah_flush_dcache_page), %o1
David S. Miller52bf0822006-02-04 03:08:37 -0800355 call tlb_patch_one
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 mov 11, %o2
357#endif /* DCACHE_ALIASING_POSSIBLE */
358
359 ret
360 restore
361
362#ifdef CONFIG_SMP
363 /* These are all called by the slaves of a cross call, at
364 * trap level 1, with interrupts fully disabled.
365 *
366 * Register usage:
367 * %g5 mm->context (all tlb flushes)
368 * %g1 address arg 1 (tlb page and range flushes)
369 * %g7 address arg 2 (tlb range flush only)
370 *
David S. Miller56fb4df2006-02-26 23:24:22 -0800371 * %g6 scratch 1
372 * %g2 scratch 2
373 * %g3 scratch 3
374 * %g4 scratch 4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 */
376 .align 32
377 .globl xcall_flush_tlb_mm
David S. Miller2a3a5f52006-02-26 19:31:49 -0800378xcall_flush_tlb_mm: /* 21 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 mov PRIMARY_CONTEXT, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 ldxa [%g2] ASI_DMMU, %g3
David S. Miller2ef27772005-08-30 20:21:34 -0700381 srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4
382 sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
383 or %g5, %g4, %g5 /* Preserve nucleus page size fields */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384 stxa %g5, [%g2] ASI_DMMU
David S. Miller2ef27772005-08-30 20:21:34 -0700385 mov 0x40, %g4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 stxa %g0, [%g4] ASI_DMMU_DEMAP
387 stxa %g0, [%g4] ASI_IMMU_DEMAP
388 stxa %g3, [%g2] ASI_DMMU
389 retry
David S. Miller52bf0822006-02-04 03:08:37 -0800390 nop
391 nop
392 nop
393 nop
394 nop
395 nop
396 nop
David S. Miller2a3a5f52006-02-26 19:31:49 -0800397 nop
398 nop
399 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400
401 .globl xcall_flush_tlb_pending
David S. Miller2a3a5f52006-02-26 19:31:49 -0800402xcall_flush_tlb_pending: /* 21 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 /* %g5=context, %g1=nr, %g7=vaddrs[] */
404 sllx %g1, 3, %g1
405 mov PRIMARY_CONTEXT, %g4
406 ldxa [%g4] ASI_DMMU, %g2
David S. Miller2ef27772005-08-30 20:21:34 -0700407 srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4
408 sllx %g4, CTX_PGSZ1_NUC_SHIFT, %g4
409 or %g5, %g4, %g5
410 mov PRIMARY_CONTEXT, %g4
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 stxa %g5, [%g4] ASI_DMMU
4121: sub %g1, (1 << 3), %g1
413 ldx [%g7 + %g1], %g5
414 andcc %g5, 0x1, %g0
415 be,pn %icc, 2f
416
417 andn %g5, 0x1, %g5
418 stxa %g0, [%g5] ASI_IMMU_DEMAP
4192: stxa %g0, [%g5] ASI_DMMU_DEMAP
420 membar #Sync
421 brnz,pt %g1, 1b
422 nop
423 stxa %g2, [%g4] ASI_DMMU
424 retry
David S. Miller2a3a5f52006-02-26 19:31:49 -0800425 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426
427 .globl xcall_flush_tlb_kernel_range
David S. Miller2a3a5f52006-02-26 19:31:49 -0800428xcall_flush_tlb_kernel_range: /* 25 insns */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 sethi %hi(PAGE_SIZE - 1), %g2
430 or %g2, %lo(PAGE_SIZE - 1), %g2
431 andn %g1, %g2, %g1
432 andn %g7, %g2, %g7
433 sub %g7, %g1, %g3
434 add %g2, 1, %g2
435 sub %g3, %g2, %g3
436 or %g1, 0x20, %g1 ! Nucleus
4371: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
438 stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
439 membar #Sync
440 brnz,pt %g3, 1b
441 sub %g3, %g2, %g3
442 retry
443 nop
444 nop
David S. Miller52bf0822006-02-04 03:08:37 -0800445 nop
446 nop
447 nop
448 nop
449 nop
450 nop
David S. Miller2a3a5f52006-02-26 19:31:49 -0800451 nop
452 nop
453 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455 /* This runs in a very controlled environment, so we do
456 * not need to worry about BH races etc.
457 */
458 .globl xcall_sync_tick
459xcall_sync_tick:
David S. Miller45fec052006-02-05 22:27:28 -0800460
461661: rdpr %pstate, %g2
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
David S. Millerdf7d6ae2006-02-07 00:00:16 -0800463 .section .sun4v_2insn_patch, "ax"
David S. Miller45fec052006-02-05 22:27:28 -0800464 .word 661b
465 nop
466 nop
467 .previous
468
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 rdpr %pil, %g2
470 wrpr %g0, 15, %pil
471 sethi %hi(109f), %g7
472 b,pt %xcc, etrap_irq
473109: or %g7, %lo(109b), %g7
David S. Miller10e26722006-11-16 13:38:57 -0800474#ifdef CONFIG_TRACE_IRQFLAGS
475 call trace_hardirqs_off
476 nop
477#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 call smp_synchronize_tick_client
479 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 b rtrap_xcall
481 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
482
David S. Miller93dae5b2008-05-19 23:46:00 -0700483 .globl xcall_fetch_glob_regs
484xcall_fetch_glob_regs:
485 sethi %hi(global_reg_snapshot), %g1
486 or %g1, %lo(global_reg_snapshot), %g1
487 __GET_CPUID(%g2)
488 sllx %g2, 6, %g3
489 add %g1, %g3, %g1
490 rdpr %tstate, %g7
491 stx %g7, [%g1 + GR_SNAP_TSTATE]
492 rdpr %tpc, %g7
493 stx %g7, [%g1 + GR_SNAP_TPC]
494 rdpr %tnpc, %g7
495 stx %g7, [%g1 + GR_SNAP_TNPC]
496 stx %o7, [%g1 + GR_SNAP_O7]
497 stx %i7, [%g1 + GR_SNAP_I7]
David S. Miller5afe2732008-07-30 21:57:59 -0700498 /* Don't try this at home kids... */
499 rdpr %cwp, %g2
500 sub %g2, 1, %g7
501 wrpr %g7, %cwp
502 mov %i7, %g7
503 wrpr %g2, %cwp
504 stx %g7, [%g1 + GR_SNAP_RPC]
David S. Miller93dae5b2008-05-19 23:46:00 -0700505 sethi %hi(trap_block), %g7
506 or %g7, %lo(trap_block), %g7
507 sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2
508 add %g7, %g2, %g7
509 ldx [%g7 + TRAP_PER_CPU_THREAD], %g3
510 membar #StoreStore
511 stx %g3, [%g1 + GR_SNAP_THREAD]
512 retry
David S. Miller93dae5b2008-05-19 23:46:00 -0700513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514#ifdef DCACHE_ALIASING_POSSIBLE
515 .align 32
516 .globl xcall_flush_dcache_page_cheetah
517xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
518 sethi %hi(PAGE_SIZE), %g3
5191: subcc %g3, (1 << 5), %g3
520 stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
521 membar #Sync
522 bne,pt %icc, 1b
523 nop
524 retry
525 nop
526#endif /* DCACHE_ALIASING_POSSIBLE */
527
528 .globl xcall_flush_dcache_page_spitfire
529xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
530 %g7 == kernel page virtual address
531 %g5 == (page->mapping != NULL) */
532#ifdef DCACHE_ALIASING_POSSIBLE
533 srlx %g1, (13 - 2), %g1 ! Form tag comparitor
534 sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
535 sub %g3, (1 << 5), %g3 ! D$ linesize == 32
5361: ldxa [%g3] ASI_DCACHE_TAG, %g2
537 andcc %g2, 0x3, %g0
538 be,pn %xcc, 2f
539 andn %g2, 0x3, %g2
540 cmp %g2, %g1
541
542 bne,pt %xcc, 2f
543 nop
544 stxa %g0, [%g3] ASI_DCACHE_TAG
545 membar #Sync
5462: cmp %g3, 0
547 bne,pt %xcc, 1b
548 sub %g3, (1 << 5), %g3
549
550 brz,pn %g5, 2f
551#endif /* DCACHE_ALIASING_POSSIBLE */
552 sethi %hi(PAGE_SIZE), %g3
553
5541: flush %g7
555 subcc %g3, (1 << 5), %g3
556 bne,pt %icc, 1b
557 add %g7, (1 << 5), %g7
558
5592: retry
560 nop
561 nop
562
David S. Miller2a3a5f52006-02-26 19:31:49 -0800563 /* %g5: error
564 * %g6: tlb op
565 */
566__hypervisor_tlb_xcall_error:
567 mov %g5, %g4
568 mov %g6, %g5
569 ba,pt %xcc, etrap
570 rd %pc, %g7
571 mov %l4, %o0
572 call hypervisor_tlbop_error_xcall
573 mov %l5, %o1
David S. Miller7697daa2008-04-24 03:15:22 -0700574 ba,a,pt %xcc, rtrap
David S. Miller2a3a5f52006-02-26 19:31:49 -0800575
David S. Miller52bf0822006-02-04 03:08:37 -0800576 .globl __hypervisor_xcall_flush_tlb_mm
David S. Miller2a3a5f52006-02-26 19:31:49 -0800577__hypervisor_xcall_flush_tlb_mm: /* 21 insns */
David S. Miller52bf0822006-02-04 03:08:37 -0800578 /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
579 mov %o0, %g2
580 mov %o1, %g3
581 mov %o2, %g4
582 mov %o3, %g1
583 mov %o5, %g7
584 clr %o0 /* ARG0: CPU lists unimplemented */
585 clr %o1 /* ARG1: CPU lists unimplemented */
586 mov %g5, %o2 /* ARG2: mmu context */
587 mov HV_MMU_ALL, %o3 /* ARG3: flags */
588 mov HV_FAST_MMU_DEMAP_CTX, %o5
589 ta HV_FAST_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800590 mov HV_FAST_MMU_DEMAP_CTX, %g6
591 brnz,pn %o0, __hypervisor_tlb_xcall_error
592 mov %o0, %g5
David S. Miller52bf0822006-02-04 03:08:37 -0800593 mov %g2, %o0
594 mov %g3, %o1
595 mov %g4, %o2
596 mov %g1, %o3
597 mov %g7, %o5
598 membar #Sync
599 retry
600
601 .globl __hypervisor_xcall_flush_tlb_pending
David S. Miller2a3a5f52006-02-26 19:31:49 -0800602__hypervisor_xcall_flush_tlb_pending: /* 21 insns */
603 /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */
David S. Miller52bf0822006-02-04 03:08:37 -0800604 sllx %g1, 3, %g1
605 mov %o0, %g2
606 mov %o1, %g3
607 mov %o2, %g4
6081: sub %g1, (1 << 3), %g1
609 ldx [%g7 + %g1], %o0 /* ARG0: virtual address */
610 mov %g5, %o1 /* ARG1: mmu context */
David S. Miller2a3a5f52006-02-26 19:31:49 -0800611 mov HV_MMU_ALL, %o2 /* ARG2: flags */
612 srlx %o0, PAGE_SHIFT, %o0
613 sllx %o0, PAGE_SHIFT, %o0
David S. Miller52bf0822006-02-04 03:08:37 -0800614 ta HV_MMU_UNMAP_ADDR_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800615 mov HV_MMU_UNMAP_ADDR_TRAP, %g6
616 brnz,a,pn %o0, __hypervisor_tlb_xcall_error
617 mov %o0, %g5
David S. Miller52bf0822006-02-04 03:08:37 -0800618 brnz,pt %g1, 1b
619 nop
620 mov %g2, %o0
621 mov %g3, %o1
622 mov %g4, %o2
623 membar #Sync
624 retry
625
626 .globl __hypervisor_xcall_flush_tlb_kernel_range
David S. Miller2a3a5f52006-02-26 19:31:49 -0800627__hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */
628 /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */
David S. Miller52bf0822006-02-04 03:08:37 -0800629 sethi %hi(PAGE_SIZE - 1), %g2
630 or %g2, %lo(PAGE_SIZE - 1), %g2
631 andn %g1, %g2, %g1
632 andn %g7, %g2, %g7
633 sub %g7, %g1, %g3
634 add %g2, 1, %g2
635 sub %g3, %g2, %g3
636 mov %o0, %g2
637 mov %o1, %g4
David S. Miller2a3a5f52006-02-26 19:31:49 -0800638 mov %o2, %g7
David S. Miller52bf0822006-02-04 03:08:37 -08006391: add %g1, %g3, %o0 /* ARG0: virtual address */
640 mov 0, %o1 /* ARG1: mmu context */
641 mov HV_MMU_ALL, %o2 /* ARG2: flags */
642 ta HV_MMU_UNMAP_ADDR_TRAP
David S. Miller2a3a5f52006-02-26 19:31:49 -0800643 mov HV_MMU_UNMAP_ADDR_TRAP, %g6
644 brnz,pn %o0, __hypervisor_tlb_xcall_error
645 mov %o0, %g5
David S. Miller52bf0822006-02-04 03:08:37 -0800646 sethi %hi(PAGE_SIZE), %o2
647 brnz,pt %g3, 1b
648 sub %g3, %o2, %g3
649 mov %g2, %o0
650 mov %g4, %o1
David S. Miller2a3a5f52006-02-26 19:31:49 -0800651 mov %g7, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800652 membar #Sync
653 retry
654
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 /* These just get rescheduled to PIL vectors. */
656 .globl xcall_call_function
657xcall_call_function:
658 wr %g0, (1 << PIL_SMP_CALL_FUNC), %set_softint
659 retry
660
David S. Millerd172ad12008-07-17 23:44:50 -0700661 .globl xcall_call_function_single
662xcall_call_function_single:
663 wr %g0, (1 << PIL_SMP_CALL_FUNC_SNGL), %set_softint
664 retry
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 .globl xcall_receive_signal
667xcall_receive_signal:
668 wr %g0, (1 << PIL_SMP_RECEIVE_SIGNAL), %set_softint
669 retry
670
671 .globl xcall_capture
672xcall_capture:
673 wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint
674 retry
675
David S. Milleree290742006-03-06 22:50:44 -0800676 .globl xcall_new_mmu_context_version
677xcall_new_mmu_context_version:
678 wr %g0, (1 << PIL_SMP_CTX_NEW_VERSION), %set_softint
679 retry
680
David S. Millere2fdd7f2008-04-29 02:38:50 -0700681#ifdef CONFIG_KGDB
682 .globl xcall_kgdb_capture
683xcall_kgdb_capture:
684661: rdpr %pstate, %g2
685 wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
686 .section .sun4v_2insn_patch, "ax"
687 .word 661b
688 nop
689 nop
690 .previous
691
692 rdpr %pil, %g2
693 wrpr %g0, 15, %pil
694 sethi %hi(109f), %g7
695 ba,pt %xcc, etrap_irq
696109: or %g7, %lo(109b), %g7
697#ifdef CONFIG_TRACE_IRQFLAGS
698 call trace_hardirqs_off
699 nop
700#endif
701 call smp_kgdb_capture_client
702 add %sp, PTREGS_OFF, %o0
703 /* Has to be a non-v9 branch due to the large distance. */
704 ba rtrap_xcall
705 ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
706#endif
707
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708#endif /* CONFIG_SMP */
David S. Miller52bf0822006-02-04 03:08:37 -0800709
710
711 .globl hypervisor_patch_cachetlbops
712hypervisor_patch_cachetlbops:
713 save %sp, -128, %sp
714
715 sethi %hi(__flush_tlb_mm), %o0
716 or %o0, %lo(__flush_tlb_mm), %o0
717 sethi %hi(__hypervisor_flush_tlb_mm), %o1
718 or %o1, %lo(__hypervisor_flush_tlb_mm), %o1
719 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800720 mov 10, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800721
722 sethi %hi(__flush_tlb_pending), %o0
723 or %o0, %lo(__flush_tlb_pending), %o0
724 sethi %hi(__hypervisor_flush_tlb_pending), %o1
725 or %o1, %lo(__hypervisor_flush_tlb_pending), %o1
726 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800727 mov 16, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800728
729 sethi %hi(__flush_tlb_kernel_range), %o0
730 or %o0, %lo(__flush_tlb_kernel_range), %o0
731 sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1
732 or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
733 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800734 mov 16, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800735
736#ifdef DCACHE_ALIASING_POSSIBLE
737 sethi %hi(__flush_dcache_page), %o0
738 or %o0, %lo(__flush_dcache_page), %o0
739 sethi %hi(__hypervisor_flush_dcache_page), %o1
740 or %o1, %lo(__hypervisor_flush_dcache_page), %o1
741 call tlb_patch_one
742 mov 2, %o2
743#endif /* DCACHE_ALIASING_POSSIBLE */
744
745#ifdef CONFIG_SMP
746 sethi %hi(xcall_flush_tlb_mm), %o0
747 or %o0, %lo(xcall_flush_tlb_mm), %o0
748 sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1
749 or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
750 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800751 mov 21, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800752
753 sethi %hi(xcall_flush_tlb_pending), %o0
754 or %o0, %lo(xcall_flush_tlb_pending), %o0
755 sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1
756 or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1
757 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800758 mov 21, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800759
760 sethi %hi(xcall_flush_tlb_kernel_range), %o0
761 or %o0, %lo(xcall_flush_tlb_kernel_range), %o0
762 sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
763 or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
764 call tlb_patch_one
David S. Miller2a3a5f52006-02-26 19:31:49 -0800765 mov 25, %o2
David S. Miller52bf0822006-02-04 03:08:37 -0800766#endif /* CONFIG_SMP */
767
768 ret
769 restore