diff options
Diffstat (limited to 'arch/sparc64/mm/ultra.S')
-rw-r--r-- | arch/sparc64/mm/ultra.S | 374 |
1 files changed, 293 insertions, 81 deletions
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index e4c9151fa116..f8479fad4047 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/head.h> | 15 | #include <asm/head.h> |
16 | #include <asm/thread_info.h> | 16 | #include <asm/thread_info.h> |
17 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
18 | #include <asm/hypervisor.h> | ||
18 | 19 | ||
19 | /* Basically, most of the Spitfire vs. Cheetah madness | 20 | /* Basically, most of the Spitfire vs. Cheetah madness |
20 | * has to do with the fact that Cheetah does not support | 21 | * has to do with the fact that Cheetah does not support |
@@ -29,16 +30,18 @@ | |||
29 | .text | 30 | .text |
30 | .align 32 | 31 | .align 32 |
31 | .globl __flush_tlb_mm | 32 | .globl __flush_tlb_mm |
32 | __flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ | 33 | __flush_tlb_mm: /* 18 insns */ |
34 | /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ | ||
33 | ldxa [%o1] ASI_DMMU, %g2 | 35 | ldxa [%o1] ASI_DMMU, %g2 |
34 | cmp %g2, %o0 | 36 | cmp %g2, %o0 |
35 | bne,pn %icc, __spitfire_flush_tlb_mm_slow | 37 | bne,pn %icc, __spitfire_flush_tlb_mm_slow |
36 | mov 0x50, %g3 | 38 | mov 0x50, %g3 |
37 | stxa %g0, [%g3] ASI_DMMU_DEMAP | 39 | stxa %g0, [%g3] ASI_DMMU_DEMAP |
38 | stxa %g0, [%g3] ASI_IMMU_DEMAP | 40 | stxa %g0, [%g3] ASI_IMMU_DEMAP |
41 | sethi %hi(KERNBASE), %g3 | ||
42 | flush %g3 | ||
39 | retl | 43 | retl |
40 | flush %g6 | 44 | nop |
41 | nop | ||
42 | nop | 45 | nop |
43 | nop | 46 | nop |
44 | nop | 47 | nop |
@@ -51,7 +54,7 @@ __flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */ | |||
51 | 54 | ||
52 | .align 32 | 55 | .align 32 |
53 | .globl __flush_tlb_pending | 56 | .globl __flush_tlb_pending |
54 | __flush_tlb_pending: | 57 | __flush_tlb_pending: /* 26 insns */ |
55 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 58 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
56 | rdpr %pstate, %g7 | 59 | rdpr %pstate, %g7 |
57 | sllx %o1, 3, %o1 | 60 | sllx %o1, 3, %o1 |
@@ -72,7 +75,8 @@ __flush_tlb_pending: | |||
72 | brnz,pt %o1, 1b | 75 | brnz,pt %o1, 1b |
73 | nop | 76 | nop |
74 | stxa %g2, [%o4] ASI_DMMU | 77 | stxa %g2, [%o4] ASI_DMMU |
75 | flush %g6 | 78 | sethi %hi(KERNBASE), %o4 |
79 | flush %o4 | ||
76 | retl | 80 | retl |
77 | wrpr %g7, 0x0, %pstate | 81 | wrpr %g7, 0x0, %pstate |
78 | nop | 82 | nop |
@@ -82,7 +86,8 @@ __flush_tlb_pending: | |||
82 | 86 | ||
83 | .align 32 | 87 | .align 32 |
84 | .globl __flush_tlb_kernel_range | 88 | .globl __flush_tlb_kernel_range |
85 | __flush_tlb_kernel_range: /* %o0=start, %o1=end */ | 89 | __flush_tlb_kernel_range: /* 16 insns */ |
90 | /* %o0=start, %o1=end */ | ||
86 | cmp %o0, %o1 | 91 | cmp %o0, %o1 |
87 | be,pn %xcc, 2f | 92 | be,pn %xcc, 2f |
88 | sethi %hi(PAGE_SIZE), %o4 | 93 | sethi %hi(PAGE_SIZE), %o4 |
@@ -94,8 +99,11 @@ __flush_tlb_kernel_range: /* %o0=start, %o1=end */ | |||
94 | membar #Sync | 99 | membar #Sync |
95 | brnz,pt %o3, 1b | 100 | brnz,pt %o3, 1b |
96 | sub %o3, %o4, %o3 | 101 | sub %o3, %o4, %o3 |
97 | 2: retl | 102 | 2: sethi %hi(KERNBASE), %o3 |
98 | flush %g6 | 103 | flush %o3 |
104 | retl | ||
105 | nop | ||
106 | nop | ||
99 | 107 | ||
100 | __spitfire_flush_tlb_mm_slow: | 108 | __spitfire_flush_tlb_mm_slow: |
101 | rdpr %pstate, %g1 | 109 | rdpr %pstate, %g1 |
@@ -105,7 +113,8 @@ __spitfire_flush_tlb_mm_slow: | |||
105 | stxa %g0, [%g3] ASI_IMMU_DEMAP | 113 | stxa %g0, [%g3] ASI_IMMU_DEMAP |
106 | flush %g6 | 114 | flush %g6 |
107 | stxa %g2, [%o1] ASI_DMMU | 115 | stxa %g2, [%o1] ASI_DMMU |
108 | flush %g6 | 116 | sethi %hi(KERNBASE), %o1 |
117 | flush %o1 | ||
109 | retl | 118 | retl |
110 | wrpr %g1, 0, %pstate | 119 | wrpr %g1, 0, %pstate |
111 | 120 | ||
@@ -181,7 +190,7 @@ __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */ | |||
181 | .previous | 190 | .previous |
182 | 191 | ||
183 | /* Cheetah specific versions, patched at boot time. */ | 192 | /* Cheetah specific versions, patched at boot time. */ |
184 | __cheetah_flush_tlb_mm: /* 18 insns */ | 193 | __cheetah_flush_tlb_mm: /* 19 insns */ |
185 | rdpr %pstate, %g7 | 194 | rdpr %pstate, %g7 |
186 | andn %g7, PSTATE_IE, %g2 | 195 | andn %g7, PSTATE_IE, %g2 |
187 | wrpr %g2, 0x0, %pstate | 196 | wrpr %g2, 0x0, %pstate |
@@ -196,12 +205,13 @@ __cheetah_flush_tlb_mm: /* 18 insns */ | |||
196 | stxa %g0, [%g3] ASI_DMMU_DEMAP | 205 | stxa %g0, [%g3] ASI_DMMU_DEMAP |
197 | stxa %g0, [%g3] ASI_IMMU_DEMAP | 206 | stxa %g0, [%g3] ASI_IMMU_DEMAP |
198 | stxa %g2, [%o2] ASI_DMMU | 207 | stxa %g2, [%o2] ASI_DMMU |
199 | flush %g6 | 208 | sethi %hi(KERNBASE), %o2 |
209 | flush %o2 | ||
200 | wrpr %g0, 0, %tl | 210 | wrpr %g0, 0, %tl |
201 | retl | 211 | retl |
202 | wrpr %g7, 0x0, %pstate | 212 | wrpr %g7, 0x0, %pstate |
203 | 213 | ||
204 | __cheetah_flush_tlb_pending: /* 26 insns */ | 214 | __cheetah_flush_tlb_pending: /* 27 insns */ |
205 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 215 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
206 | rdpr %pstate, %g7 | 216 | rdpr %pstate, %g7 |
207 | sllx %o1, 3, %o1 | 217 | sllx %o1, 3, %o1 |
@@ -225,7 +235,8 @@ __cheetah_flush_tlb_pending: /* 26 insns */ | |||
225 | brnz,pt %o1, 1b | 235 | brnz,pt %o1, 1b |
226 | nop | 236 | nop |
227 | stxa %g2, [%o4] ASI_DMMU | 237 | stxa %g2, [%o4] ASI_DMMU |
228 | flush %g6 | 238 | sethi %hi(KERNBASE), %o4 |
239 | flush %o4 | ||
229 | wrpr %g0, 0, %tl | 240 | wrpr %g0, 0, %tl |
230 | retl | 241 | retl |
231 | wrpr %g7, 0x0, %pstate | 242 | wrpr %g7, 0x0, %pstate |
@@ -245,7 +256,76 @@ __cheetah_flush_dcache_page: /* 11 insns */ | |||
245 | nop | 256 | nop |
246 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 257 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
247 | 258 | ||
248 | cheetah_patch_one: | 259 | /* Hypervisor specific versions, patched at boot time. */ |
260 | __hypervisor_tlb_tl0_error: | ||
261 | save %sp, -192, %sp | ||
262 | mov %i0, %o0 | ||
263 | call hypervisor_tlbop_error | ||
264 | mov %i1, %o1 | ||
265 | ret | ||
266 | restore | ||
267 | |||
268 | __hypervisor_flush_tlb_mm: /* 10 insns */ | ||
269 | mov %o0, %o2 /* ARG2: mmu context */ | ||
270 | mov 0, %o0 /* ARG0: CPU lists unimplemented */ | ||
271 | mov 0, %o1 /* ARG1: CPU lists unimplemented */ | ||
272 | mov HV_MMU_ALL, %o3 /* ARG3: flags */ | ||
273 | mov HV_FAST_MMU_DEMAP_CTX, %o5 | ||
274 | ta HV_FAST_TRAP | ||
275 | brnz,pn %o0, __hypervisor_tlb_tl0_error | ||
276 | mov HV_FAST_MMU_DEMAP_CTX, %o1 | ||
277 | retl | ||
278 | nop | ||
279 | |||
280 | __hypervisor_flush_tlb_pending: /* 16 insns */ | ||
281 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | ||
282 | sllx %o1, 3, %g1 | ||
283 | mov %o2, %g2 | ||
284 | mov %o0, %g3 | ||
285 | 1: sub %g1, (1 << 3), %g1 | ||
286 | ldx [%g2 + %g1], %o0 /* ARG0: vaddr + IMMU-bit */ | ||
287 | mov %g3, %o1 /* ARG1: mmu context */ | ||
288 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | ||
289 | srlx %o0, PAGE_SHIFT, %o0 | ||
290 | sllx %o0, PAGE_SHIFT, %o0 | ||
291 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
292 | brnz,pn %o0, __hypervisor_tlb_tl0_error | ||
293 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | ||
294 | brnz,pt %g1, 1b | ||
295 | nop | ||
296 | retl | ||
297 | nop | ||
298 | |||
299 | __hypervisor_flush_tlb_kernel_range: /* 16 insns */ | ||
300 | /* %o0=start, %o1=end */ | ||
301 | cmp %o0, %o1 | ||
302 | be,pn %xcc, 2f | ||
303 | sethi %hi(PAGE_SIZE), %g3 | ||
304 | mov %o0, %g1 | ||
305 | sub %o1, %g1, %g2 | ||
306 | sub %g2, %g3, %g2 | ||
307 | 1: add %g1, %g2, %o0 /* ARG0: virtual address */ | ||
308 | mov 0, %o1 /* ARG1: mmu context */ | ||
309 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | ||
310 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
311 | brnz,pn %o0, __hypervisor_tlb_tl0_error | ||
312 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | ||
313 | brnz,pt %g2, 1b | ||
314 | sub %g2, %g3, %g2 | ||
315 | 2: retl | ||
316 | nop | ||
317 | |||
318 | #ifdef DCACHE_ALIASING_POSSIBLE | ||
319 | /* XXX Niagara and friends have an 8K cache, so no aliasing is | ||
320 | * XXX possible, but nothing explicit in the Hypervisor API | ||
321 | * XXX guarantees this. | ||
322 | */ | ||
323 | __hypervisor_flush_dcache_page: /* 2 insns */ | ||
324 | retl | ||
325 | nop | ||
326 | #endif | ||
327 | |||
328 | tlb_patch_one: | ||
249 | 1: lduw [%o1], %g1 | 329 | 1: lduw [%o1], %g1 |
250 | stw %g1, [%o0] | 330 | stw %g1, [%o0] |
251 | flush %o0 | 331 | flush %o0 |
@@ -264,22 +344,22 @@ cheetah_patch_cachetlbops: | |||
264 | or %o0, %lo(__flush_tlb_mm), %o0 | 344 | or %o0, %lo(__flush_tlb_mm), %o0 |
265 | sethi %hi(__cheetah_flush_tlb_mm), %o1 | 345 | sethi %hi(__cheetah_flush_tlb_mm), %o1 |
266 | or %o1, %lo(__cheetah_flush_tlb_mm), %o1 | 346 | or %o1, %lo(__cheetah_flush_tlb_mm), %o1 |
267 | call cheetah_patch_one | 347 | call tlb_patch_one |
268 | mov 18, %o2 | 348 | mov 19, %o2 |
269 | 349 | ||
270 | sethi %hi(__flush_tlb_pending), %o0 | 350 | sethi %hi(__flush_tlb_pending), %o0 |
271 | or %o0, %lo(__flush_tlb_pending), %o0 | 351 | or %o0, %lo(__flush_tlb_pending), %o0 |
272 | sethi %hi(__cheetah_flush_tlb_pending), %o1 | 352 | sethi %hi(__cheetah_flush_tlb_pending), %o1 |
273 | or %o1, %lo(__cheetah_flush_tlb_pending), %o1 | 353 | or %o1, %lo(__cheetah_flush_tlb_pending), %o1 |
274 | call cheetah_patch_one | 354 | call tlb_patch_one |
275 | mov 26, %o2 | 355 | mov 27, %o2 |
276 | 356 | ||
277 | #ifdef DCACHE_ALIASING_POSSIBLE | 357 | #ifdef DCACHE_ALIASING_POSSIBLE |
278 | sethi %hi(__flush_dcache_page), %o0 | 358 | sethi %hi(__flush_dcache_page), %o0 |
279 | or %o0, %lo(__flush_dcache_page), %o0 | 359 | or %o0, %lo(__flush_dcache_page), %o0 |
280 | sethi %hi(__cheetah_flush_dcache_page), %o1 | 360 | sethi %hi(__cheetah_flush_dcache_page), %o1 |
281 | or %o1, %lo(__cheetah_flush_dcache_page), %o1 | 361 | or %o1, %lo(__cheetah_flush_dcache_page), %o1 |
282 | call cheetah_patch_one | 362 | call tlb_patch_one |
283 | mov 11, %o2 | 363 | mov 11, %o2 |
284 | #endif /* DCACHE_ALIASING_POSSIBLE */ | 364 | #endif /* DCACHE_ALIASING_POSSIBLE */ |
285 | 365 | ||
@@ -295,16 +375,14 @@ cheetah_patch_cachetlbops: | |||
295 | * %g1 address arg 1 (tlb page and range flushes) | 375 | * %g1 address arg 1 (tlb page and range flushes) |
296 | * %g7 address arg 2 (tlb range flush only) | 376 | * %g7 address arg 2 (tlb range flush only) |
297 | * | 377 | * |
298 | * %g6 ivector table, don't touch | 378 | * %g6 scratch 1 |
299 | * %g2 scratch 1 | 379 | * %g2 scratch 2 |
300 | * %g3 scratch 2 | 380 | * %g3 scratch 3 |
301 | * %g4 scratch 3 | 381 | * %g4 scratch 4 |
302 | * | ||
303 | * TODO: Make xcall TLB range flushes use the tricks above... -DaveM | ||
304 | */ | 382 | */ |
305 | .align 32 | 383 | .align 32 |
306 | .globl xcall_flush_tlb_mm | 384 | .globl xcall_flush_tlb_mm |
307 | xcall_flush_tlb_mm: | 385 | xcall_flush_tlb_mm: /* 21 insns */ |
308 | mov PRIMARY_CONTEXT, %g2 | 386 | mov PRIMARY_CONTEXT, %g2 |
309 | ldxa [%g2] ASI_DMMU, %g3 | 387 | ldxa [%g2] ASI_DMMU, %g3 |
310 | srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4 | 388 | srlx %g3, CTX_PGSZ1_NUC_SHIFT, %g4 |
@@ -316,9 +394,19 @@ xcall_flush_tlb_mm: | |||
316 | stxa %g0, [%g4] ASI_IMMU_DEMAP | 394 | stxa %g0, [%g4] ASI_IMMU_DEMAP |
317 | stxa %g3, [%g2] ASI_DMMU | 395 | stxa %g3, [%g2] ASI_DMMU |
318 | retry | 396 | retry |
397 | nop | ||
398 | nop | ||
399 | nop | ||
400 | nop | ||
401 | nop | ||
402 | nop | ||
403 | nop | ||
404 | nop | ||
405 | nop | ||
406 | nop | ||
319 | 407 | ||
320 | .globl xcall_flush_tlb_pending | 408 | .globl xcall_flush_tlb_pending |
321 | xcall_flush_tlb_pending: | 409 | xcall_flush_tlb_pending: /* 21 insns */ |
322 | /* %g5=context, %g1=nr, %g7=vaddrs[] */ | 410 | /* %g5=context, %g1=nr, %g7=vaddrs[] */ |
323 | sllx %g1, 3, %g1 | 411 | sllx %g1, 3, %g1 |
324 | mov PRIMARY_CONTEXT, %g4 | 412 | mov PRIMARY_CONTEXT, %g4 |
@@ -341,9 +429,10 @@ xcall_flush_tlb_pending: | |||
341 | nop | 429 | nop |
342 | stxa %g2, [%g4] ASI_DMMU | 430 | stxa %g2, [%g4] ASI_DMMU |
343 | retry | 431 | retry |
432 | nop | ||
344 | 433 | ||
345 | .globl xcall_flush_tlb_kernel_range | 434 | .globl xcall_flush_tlb_kernel_range |
346 | xcall_flush_tlb_kernel_range: | 435 | xcall_flush_tlb_kernel_range: /* 25 insns */ |
347 | sethi %hi(PAGE_SIZE - 1), %g2 | 436 | sethi %hi(PAGE_SIZE - 1), %g2 |
348 | or %g2, %lo(PAGE_SIZE - 1), %g2 | 437 | or %g2, %lo(PAGE_SIZE - 1), %g2 |
349 | andn %g1, %g2, %g1 | 438 | andn %g1, %g2, %g1 |
@@ -360,14 +449,30 @@ xcall_flush_tlb_kernel_range: | |||
360 | retry | 449 | retry |
361 | nop | 450 | nop |
362 | nop | 451 | nop |
452 | nop | ||
453 | nop | ||
454 | nop | ||
455 | nop | ||
456 | nop | ||
457 | nop | ||
458 | nop | ||
459 | nop | ||
460 | nop | ||
363 | 461 | ||
364 | /* This runs in a very controlled environment, so we do | 462 | /* This runs in a very controlled environment, so we do |
365 | * not need to worry about BH races etc. | 463 | * not need to worry about BH races etc. |
366 | */ | 464 | */ |
367 | .globl xcall_sync_tick | 465 | .globl xcall_sync_tick |
368 | xcall_sync_tick: | 466 | xcall_sync_tick: |
369 | rdpr %pstate, %g2 | 467 | |
468 | 661: rdpr %pstate, %g2 | ||
370 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate | 469 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate |
470 | .section .sun4v_2insn_patch, "ax" | ||
471 | .word 661b | ||
472 | nop | ||
473 | nop | ||
474 | .previous | ||
475 | |||
371 | rdpr %pil, %g2 | 476 | rdpr %pil, %g2 |
372 | wrpr %g0, 15, %pil | 477 | wrpr %g0, 15, %pil |
373 | sethi %hi(109f), %g7 | 478 | sethi %hi(109f), %g7 |
@@ -390,8 +495,15 @@ xcall_sync_tick: | |||
390 | */ | 495 | */ |
391 | .globl xcall_report_regs | 496 | .globl xcall_report_regs |
392 | xcall_report_regs: | 497 | xcall_report_regs: |
393 | rdpr %pstate, %g2 | 498 | |
499 | 661: rdpr %pstate, %g2 | ||
394 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate | 500 | wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate |
501 | .section .sun4v_2insn_patch, "ax" | ||
502 | .word 661b | ||
503 | nop | ||
504 | nop | ||
505 | .previous | ||
506 | |||
395 | rdpr %pil, %g2 | 507 | rdpr %pil, %g2 |
396 | wrpr %g0, 15, %pil | 508 | wrpr %g0, 15, %pil |
397 | sethi %hi(109f), %g7 | 509 | sethi %hi(109f), %g7 |
@@ -453,62 +565,96 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address | |||
453 | nop | 565 | nop |
454 | nop | 566 | nop |
455 | 567 | ||
456 | .data | 568 | /* %g5: error |
457 | 569 | * %g6: tlb op | |
458 | errata32_hwbug: | 570 | */ |
459 | .xword 0 | 571 | __hypervisor_tlb_xcall_error: |
460 | 572 | mov %g5, %g4 | |
461 | .text | 573 | mov %g6, %g5 |
462 | 574 | ba,pt %xcc, etrap | |
463 | /* These two are not performance critical... */ | 575 | rd %pc, %g7 |
464 | .globl xcall_flush_tlb_all_spitfire | 576 | mov %l4, %o0 |
465 | xcall_flush_tlb_all_spitfire: | 577 | call hypervisor_tlbop_error_xcall |
466 | /* Spitfire Errata #32 workaround. */ | 578 | mov %l5, %o1 |
467 | sethi %hi(errata32_hwbug), %g4 | 579 | ba,a,pt %xcc, rtrap_clr_l6 |
468 | stx %g0, [%g4 + %lo(errata32_hwbug)] | 580 | |
469 | 581 | .globl __hypervisor_xcall_flush_tlb_mm | |
470 | clr %g2 | 582 | __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ |
471 | clr %g3 | 583 | /* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */ |
472 | 1: ldxa [%g3] ASI_DTLB_DATA_ACCESS, %g4 | 584 | mov %o0, %g2 |
473 | and %g4, _PAGE_L, %g5 | 585 | mov %o1, %g3 |
474 | brnz,pn %g5, 2f | 586 | mov %o2, %g4 |
475 | mov TLB_TAG_ACCESS, %g7 | 587 | mov %o3, %g1 |
476 | 588 | mov %o5, %g7 | |
477 | stxa %g0, [%g7] ASI_DMMU | 589 | clr %o0 /* ARG0: CPU lists unimplemented */ |
478 | membar #Sync | 590 | clr %o1 /* ARG1: CPU lists unimplemented */ |
479 | stxa %g0, [%g3] ASI_DTLB_DATA_ACCESS | 591 | mov %g5, %o2 /* ARG2: mmu context */ |
592 | mov HV_MMU_ALL, %o3 /* ARG3: flags */ | ||
593 | mov HV_FAST_MMU_DEMAP_CTX, %o5 | ||
594 | ta HV_FAST_TRAP | ||
595 | mov HV_FAST_MMU_DEMAP_CTX, %g6 | ||
596 | brnz,pn %o0, __hypervisor_tlb_xcall_error | ||
597 | mov %o0, %g5 | ||
598 | mov %g2, %o0 | ||
599 | mov %g3, %o1 | ||
600 | mov %g4, %o2 | ||
601 | mov %g1, %o3 | ||
602 | mov %g7, %o5 | ||
480 | membar #Sync | 603 | membar #Sync |
604 | retry | ||
481 | 605 | ||
482 | /* Spitfire Errata #32 workaround. */ | 606 | .globl __hypervisor_xcall_flush_tlb_pending |
483 | sethi %hi(errata32_hwbug), %g4 | 607 | __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ |
484 | stx %g0, [%g4 + %lo(errata32_hwbug)] | 608 | /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ |
485 | 609 | sllx %g1, 3, %g1 | |
486 | 2: ldxa [%g3] ASI_ITLB_DATA_ACCESS, %g4 | 610 | mov %o0, %g2 |
487 | and %g4, _PAGE_L, %g5 | 611 | mov %o1, %g3 |
488 | brnz,pn %g5, 2f | 612 | mov %o2, %g4 |
489 | mov TLB_TAG_ACCESS, %g7 | 613 | 1: sub %g1, (1 << 3), %g1 |
490 | 614 | ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ | |
491 | stxa %g0, [%g7] ASI_IMMU | 615 | mov %g5, %o1 /* ARG1: mmu context */ |
492 | membar #Sync | 616 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ |
493 | stxa %g0, [%g3] ASI_ITLB_DATA_ACCESS | 617 | srlx %o0, PAGE_SHIFT, %o0 |
618 | sllx %o0, PAGE_SHIFT, %o0 | ||
619 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
620 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 | ||
621 | brnz,a,pn %o0, __hypervisor_tlb_xcall_error | ||
622 | mov %o0, %g5 | ||
623 | brnz,pt %g1, 1b | ||
624 | nop | ||
625 | mov %g2, %o0 | ||
626 | mov %g3, %o1 | ||
627 | mov %g4, %o2 | ||
494 | membar #Sync | 628 | membar #Sync |
495 | |||
496 | /* Spitfire Errata #32 workaround. */ | ||
497 | sethi %hi(errata32_hwbug), %g4 | ||
498 | stx %g0, [%g4 + %lo(errata32_hwbug)] | ||
499 | |||
500 | 2: add %g2, 1, %g2 | ||
501 | cmp %g2, SPITFIRE_HIGHEST_LOCKED_TLBENT | ||
502 | ble,pt %icc, 1b | ||
503 | sll %g2, 3, %g3 | ||
504 | flush %g6 | ||
505 | retry | 629 | retry |
506 | 630 | ||
507 | .globl xcall_flush_tlb_all_cheetah | 631 | .globl __hypervisor_xcall_flush_tlb_kernel_range |
508 | xcall_flush_tlb_all_cheetah: | 632 | __hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */ |
509 | mov 0x80, %g2 | 633 | /* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */ |
510 | stxa %g0, [%g2] ASI_DMMU_DEMAP | 634 | sethi %hi(PAGE_SIZE - 1), %g2 |
511 | stxa %g0, [%g2] ASI_IMMU_DEMAP | 635 | or %g2, %lo(PAGE_SIZE - 1), %g2 |
636 | andn %g1, %g2, %g1 | ||
637 | andn %g7, %g2, %g7 | ||
638 | sub %g7, %g1, %g3 | ||
639 | add %g2, 1, %g2 | ||
640 | sub %g3, %g2, %g3 | ||
641 | mov %o0, %g2 | ||
642 | mov %o1, %g4 | ||
643 | mov %o2, %g7 | ||
644 | 1: add %g1, %g3, %o0 /* ARG0: virtual address */ | ||
645 | mov 0, %o1 /* ARG1: mmu context */ | ||
646 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | ||
647 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
648 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 | ||
649 | brnz,pn %o0, __hypervisor_tlb_xcall_error | ||
650 | mov %o0, %g5 | ||
651 | sethi %hi(PAGE_SIZE), %o2 | ||
652 | brnz,pt %g3, 1b | ||
653 | sub %g3, %o2, %g3 | ||
654 | mov %g2, %o0 | ||
655 | mov %g4, %o1 | ||
656 | mov %g7, %o2 | ||
657 | membar #Sync | ||
512 | retry | 658 | retry |
513 | 659 | ||
514 | /* These just get rescheduled to PIL vectors. */ | 660 | /* These just get rescheduled to PIL vectors. */ |
@@ -527,4 +673,70 @@ xcall_capture: | |||
527 | wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint | 673 | wr %g0, (1 << PIL_SMP_CAPTURE), %set_softint |
528 | retry | 674 | retry |
529 | 675 | ||
676 | .globl xcall_new_mmu_context_version | ||
677 | xcall_new_mmu_context_version: | ||
678 | wr %g0, (1 << PIL_SMP_CTX_NEW_VERSION), %set_softint | ||
679 | retry | ||
680 | |||
530 | #endif /* CONFIG_SMP */ | 681 | #endif /* CONFIG_SMP */ |
682 | |||
683 | |||
684 | .globl hypervisor_patch_cachetlbops | ||
685 | hypervisor_patch_cachetlbops: | ||
686 | save %sp, -128, %sp | ||
687 | |||
688 | sethi %hi(__flush_tlb_mm), %o0 | ||
689 | or %o0, %lo(__flush_tlb_mm), %o0 | ||
690 | sethi %hi(__hypervisor_flush_tlb_mm), %o1 | ||
691 | or %o1, %lo(__hypervisor_flush_tlb_mm), %o1 | ||
692 | call tlb_patch_one | ||
693 | mov 10, %o2 | ||
694 | |||
695 | sethi %hi(__flush_tlb_pending), %o0 | ||
696 | or %o0, %lo(__flush_tlb_pending), %o0 | ||
697 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 | ||
698 | or %o1, %lo(__hypervisor_flush_tlb_pending), %o1 | ||
699 | call tlb_patch_one | ||
700 | mov 16, %o2 | ||
701 | |||
702 | sethi %hi(__flush_tlb_kernel_range), %o0 | ||
703 | or %o0, %lo(__flush_tlb_kernel_range), %o0 | ||
704 | sethi %hi(__hypervisor_flush_tlb_kernel_range), %o1 | ||
705 | or %o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1 | ||
706 | call tlb_patch_one | ||
707 | mov 16, %o2 | ||
708 | |||
709 | #ifdef DCACHE_ALIASING_POSSIBLE | ||
710 | sethi %hi(__flush_dcache_page), %o0 | ||
711 | or %o0, %lo(__flush_dcache_page), %o0 | ||
712 | sethi %hi(__hypervisor_flush_dcache_page), %o1 | ||
713 | or %o1, %lo(__hypervisor_flush_dcache_page), %o1 | ||
714 | call tlb_patch_one | ||
715 | mov 2, %o2 | ||
716 | #endif /* DCACHE_ALIASING_POSSIBLE */ | ||
717 | |||
718 | #ifdef CONFIG_SMP | ||
719 | sethi %hi(xcall_flush_tlb_mm), %o0 | ||
720 | or %o0, %lo(xcall_flush_tlb_mm), %o0 | ||
721 | sethi %hi(__hypervisor_xcall_flush_tlb_mm), %o1 | ||
722 | or %o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1 | ||
723 | call tlb_patch_one | ||
724 | mov 21, %o2 | ||
725 | |||
726 | sethi %hi(xcall_flush_tlb_pending), %o0 | ||
727 | or %o0, %lo(xcall_flush_tlb_pending), %o0 | ||
728 | sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 | ||
729 | or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 | ||
730 | call tlb_patch_one | ||
731 | mov 21, %o2 | ||
732 | |||
733 | sethi %hi(xcall_flush_tlb_kernel_range), %o0 | ||
734 | or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 | ||
735 | sethi %hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1 | ||
736 | or %o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1 | ||
737 | call tlb_patch_one | ||
738 | mov 25, %o2 | ||
739 | #endif /* CONFIG_SMP */ | ||
740 | |||
741 | ret | ||
742 | restore | ||