ultra.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:16k
- /* $Id: ultra.S,v 1.70 2001/11/29 16:42:10 kanoj Exp $
- * ultra.S: Don't expand these all over the place...
- *
- * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
- */
- #include <linux/config.h>
- #include <asm/asi.h>
- #include <asm/pgtable.h>
- #include <asm/page.h>
- #include <asm/spitfire.h>
- #include <asm/mmu_context.h>
- /* Basically, all this madness has to do with the
- * fact that Cheetah does not support IMMU flushes
- * out of the secondary context. Someone needs to
- * throw a south lake birthday party for the folks
- * in Microelectronics who refused to fix this shit.
- */
- #define BRANCH_IF_CHEETAH(tmp1, tmp2, label)
- rdpr %ver, %tmp1;
- sethi %hi(0x003e0014), %tmp2;
- srlx %tmp1, 32, %tmp1;
- or %tmp2, %lo(0x003e0014), %tmp2;
- cmp %tmp1, %tmp2;
- be,pn %icc, label;
- nop;
- nop;
- /* This file is meant to be read efficiently by the CPU, not humans.
- * Staraj sie tego nikomu nie pierdolnac...
- */
- .text
- .align 32
- .globl __flush_tlb_page, __flush_tlb_mm, __flush_tlb_range
- __flush_tlb_page: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=page&PAGE_MASK, %o2=SECONDARY_CONTEXT */
- /*IC1*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_page)
- __spitfire_flush_tlb_page:
- /*IC2*/ ldxa [%o2] ASI_DMMU, %g2
- cmp %g2, %o0
- bne,pn %icc, __spitfire_flush_tlb_page_slow
- or %o1, 0x10, %g3
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- retl
- flush %g6
- __cheetah_flush_tlb_page:
- /*IC3*/ rdpr %pstate, %g5
- andn %g5, PSTATE_IE, %g2
- wrpr %g2, 0x0, %pstate
- wrpr %g0, 1, %tl
- mov PRIMARY_CONTEXT, %o2
- ldxa [%o2] ASI_DMMU, %g2
- stxa %o0, [%o2] ASI_DMMU
- stxa %g0, [%o1] ASI_DMMU_DEMAP
- /*IC4*/ stxa %g0, [%o1] ASI_IMMU_DEMAP
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- wrpr %g0, 0, %tl
- retl
- wrpr %g5, 0x0, %pstate
- nop
- nop
- __flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
- /*IC5*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_mm)
- __spitfire_flush_tlb_mm:
- /*IC6*/ ldxa [%o1] ASI_DMMU, %g2
- cmp %g2, %o0
- bne,pn %icc, __spitfire_flush_tlb_mm_slow
- mov 0x50, %g3
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- retl
- flush %g6
- __cheetah_flush_tlb_mm:
- /*IC7*/ rdpr %pstate, %g5
- andn %g5, PSTATE_IE, %g2
- wrpr %g2, 0x0, %pstate
- wrpr %g0, 1, %tl
- mov PRIMARY_CONTEXT, %o2
- mov 0x40, %g3
- ldxa [%o2] ASI_DMMU, %g2
- stxa %o0, [%o2] ASI_DMMU
- /*IC8*/ stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- wrpr %g0, 0, %tl
- retl
- wrpr %g5, 0x0, %pstate
- nop
- __flush_tlb_range: /* %o0=(ctx&TAG_CONTEXT_BITS), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
- * %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
- */
- /*IC9*/ BRANCH_IF_CHEETAH(g2, g3, __cheetah_flush_tlb_range)
- __spitfire_flush_tlb_range:
- #define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */
- /*IC10*/cmp %o5, %o4
- bleu,pt %xcc, __flush_tlb_page
- srlx %o5, PAGE_SHIFT, %g5
- cmp %g5, TLB_MAGIC
- bgeu,pn %icc, __spitfire_flush_tlb_range_constant_time
- or %o1, 0x10, %g5
- ldxa [%o2] ASI_DMMU, %g2
- cmp %g2, %o0
- __spitfire_flush_tlb_range_page_by_page:
- /*IC11*/bne,pn %icc, __spitfire_flush_tlb_range_pbp_slow
- sub %o5, %o4, %o5
- 1: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
- brnz,pt %o5, 1b
- sub %o5, %o4, %o5
- retl
- flush %g6
- __spitfire_flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
- /*IC12*/rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g3
- /* XXX Spitfire dependency... */
- mov ((SPITFIRE_HIGHEST_LOCKED_TLBENT-1) << 3), %g2
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
- 1: ldxa [%g2] ASI_ITLB_TAG_READ, %o4
- and %o4, TAG_CONTEXT_BITS, %o5
- cmp %o5, %o0
- bne,pt %icc, 2f
- /*IC13*/ andn %o4, TAG_CONTEXT_BITS, %o4
- cmp %o4, %o1
- blu,pt %xcc, 2f
- cmp %o4, %o3
- blu,pn %xcc, 4f
- 2: ldxa [%g2] ASI_DTLB_TAG_READ, %o4
- and %o4, TAG_CONTEXT_BITS, %o5
- cmp %o5, %o0
- /*IC14*/andn %o4, TAG_CONTEXT_BITS, %o4
- bne,pt %icc, 3f
- cmp %o4, %o1
- blu,pt %xcc, 3f
- cmp %o4, %o3
- blu,pn %xcc, 5f
- nop
- 3: brnz,pt %g2, 1b
- /*IC15*/ sub %g2, (1 << 3), %g2
- retl
- wrpr %g1, 0x0, %pstate
- 4: stxa %g0, [%g3] ASI_IMMU
- stxa %g0, [%g2] ASI_ITLB_DATA_ACCESS
- flush %g6
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
- ba,pt %xcc, 2b
- nop
- 5: stxa %g0, [%g3] ASI_DMMU
- /*IC16*/stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
- flush %g6
- /* Spitfire Errata #32 workaround. */
- mov 0x8, %o4
- stxa %g0, [%o4] ASI_DMMU
- flush %g6
- ba,pt %xcc, 3b
- nop
- .align 32
- __cheetah_flush_tlb_range:
- cmp %o5, %o4
- bleu,pt %xcc, __cheetah_flush_tlb_page
- nop
- /*IC17*/rdpr %pstate, %g5
- andn %g5, PSTATE_IE, %g2
- wrpr %g2, 0x0, %pstate
- wrpr %g0, 1, %tl
- mov PRIMARY_CONTEXT, %o2
- sub %o5, %o4, %o5
- ldxa [%o2] ASI_DMMU, %g2
- stxa %o0, [%o2] ASI_DMMU
- /*IC18*/
- 1: stxa %g0, [%o1 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%o1 + %o5] ASI_IMMU_DEMAP
- membar #Sync
- brnz,pt %o5, 1b
- sub %o5, %o4, %o5
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- wrpr %g0, 0, %tl
- retl
- /*IC19*/ wrpr %g5, 0x0, %pstate
- __spitfire_flush_tlb_mm_slow:
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- stxa %o0, [%o1] ASI_DMMU
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- flush %g6
- stxa %g2, [%o1] ASI_DMMU
- /*IC18*/flush %g6
- retl
- wrpr %g1, 0, %pstate
- __spitfire_flush_tlb_page_slow:
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- stxa %o0, [%o2] ASI_DMMU
- stxa %g0, [%g3] ASI_DMMU_DEMAP
- stxa %g0, [%g3] ASI_IMMU_DEMAP
- /*IC20*/flush %g6
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- retl
- wrpr %g1, 0, %pstate
- __spitfire_flush_tlb_range_pbp_slow:
- rdpr %pstate, %g1
- wrpr %g1, PSTATE_IE, %pstate
- stxa %o0, [%o2] ASI_DMMU
- /*IC21*/
- 2: stxa %g0, [%g5 + %o5] ASI_DMMU_DEMAP
- stxa %g0, [%g5 + %o5] ASI_IMMU_DEMAP
- brnz,pt %o5, 2b
- sub %o5, %o4, %o5
- flush %g6
- stxa %g2, [%o2] ASI_DMMU
- flush %g6
- retl
- /*IC22*/ wrpr %g1, 0x0, %pstate
- /*
- * The following code flushes one page_size worth.
- */
- #if (PAGE_SHIFT == 13)
- #define ITAG_MASK 0xfe
- #elif (PAGE_SHIFT == 16)
- #define ITAG_MASK 0x7fe
- #else
- #error unsupported PAGE_SIZE
- #endif
- .align 32
- .globl __flush_icache_page
- __flush_icache_page: /* %o0 = phys_page */
- sethi %hi(1 << 13), %o2 ! IC_set bit
- mov 1, %g1
- srlx %o0, 5, %o0
- clr %o1 ! IC_addr
- sllx %g1, 36, %g1
- ldda [%o1] ASI_IC_TAG, %o4
- sub %g1, 1, %g2
- or %o0, %g1, %o0 ! VALID+phys-addr comparitor
- sllx %g2, 1, %g2
- andn %g2, ITAG_MASK, %g2 ! IC_tag mask
- nop
- nop
- nop
- nop
- nop
- nop
- 1: addx %g0, %g0, %g0
- ldda [%o1 + %o2] ASI_IC_TAG, %g4
- addx %g0, %g0, %g0
- and %o5, %g2, %g3
- cmp %g3, %o0
- add %o1, 0x20, %o1
- ldda [%o1] ASI_IC_TAG, %o4
- be,pn %xcc, iflush1
- 2: nop
- and %g5, %g2, %g5
- cmp %g5, %o0
- be,pn %xcc, iflush2
- 3: cmp %o1, %o2
- bne,pt %xcc, 1b
- addx %g0, %g0, %g0
- nop
- sethi %uhi(PAGE_OFFSET), %g4
- retl
- sllx %g4, 32, %g4
- iflush1:sub %o1, 0x20, %g3
- stxa %g0, [%g3] ASI_IC_TAG
- flush %g6
- ba,a,pt %xcc, 2b
- iflush2:sub %o1, 0x20, %g3
- stxa %g0, [%o1 + %o2] ASI_IC_TAG
- flush %g6
- ba,a,pt %xcc, 3b
- .align 64
- .globl __flush_dcache_page
- __flush_dcache_page: /* %o0=kaddr, %o1=flush_icache */
- sub %o0, %g4, %o0
-
- rdpr %ver, %g1
- sethi %hi(0x003e0014), %g2
- srlx %g1, 32, %g1
- or %g2, %lo(0x003e0014), %g2
- cmp %g1, %g2
- bne,pt %icc, flush_dcpage_spitfire
- nop
- flush_dcpage_cheetah:
- sethi %hi(PAGE_SIZE), %o4
- 1: subcc %o4, (1 << 5), %o4
- stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
- bne,pt %icc, 1b
- nop
- membar #Sync
- /* I-cache flush never needed on Cheetah, see callers. */
- retl
- nop
- #if (PAGE_SHIFT == 13)
- #define DTAG_MASK 0x3
- #elif (PAGE_SHIFT == 16)
- #define DTAG_MASK 0x1f
- #elif (PAGE_SHIFT == 19)
- #define DTAG_MASK 0xff
- #elif (PAGE_SHIFT == 22)
- #define DTAG_MASK 0x3ff
- #endif
- flush_dcpage_spitfire:
- clr %o4
- srlx %o0, 11, %o0
- sethi %hi(1 << 14), %o2
- 1: ldxa [%o4] ASI_DCACHE_TAG, %o3 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- ldxa [%o4] ASI_DCACHE_TAG, %g1 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- ldxa [%o4] ASI_DCACHE_TAG, %g2 ! LSU Group o3 available
- add %o4, (1 << 5), %o4 ! IEU0
- andn %o3, DTAG_MASK, %o3 ! IEU1
- ldxa [%o4] ASI_DCACHE_TAG, %g3 ! LSU Group
- add %o4, (1 << 5), %o4 ! IEU0
- andn %g1, DTAG_MASK, %g1 ! IEU1
- cmp %o0, %o3 ! IEU1 Group
- be,a,pn %xcc, dflush1 ! CTI
- sub %o4, (4 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g1 ! IEU1 Group
- andn %g2, DTAG_MASK, %g2 ! IEU0
- be,a,pn %xcc, dflush2 ! CTI
- sub %o4, (3 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g2 ! IEU1 Group
- andn %g3, DTAG_MASK, %g3 ! IEU0
- be,a,pn %xcc, dflush3 ! CTI
- sub %o4, (2 << 5), %o4 ! IEU0 (Group)
- cmp %o0, %g3 ! IEU1 Group
- be,a,pn %xcc, dflush4 ! CTI
- sub %o4, (1 << 5), %o4 ! IEU0
- 2: cmp %o4, %o2 ! IEU1 Group
- bne,pt %xcc, 1b ! CTI
- nop ! IEU0
- /* The I-cache does not snoop local stores so we
- * better flush that too when necessary.
- */
- brnz,pt %o1, __flush_icache_page
- sllx %o0, 11, %o0
- retl
- nop
- dflush1:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
- dflush2:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
- dflush3:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
- dflush4:stxa %g0, [%o4] ASI_DCACHE_TAG
- add %o4, (1 << 5), %o4
- membar #Sync
- ba,pt %xcc, 2b
- nop
- .align 32
- __prefill_dtlb:
- rdpr %pstate, %g7
- wrpr %g7, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g1
- stxa %o0, [%g1] ASI_DMMU
- stxa %o1, [%g0] ASI_DTLB_DATA_IN
- flush %g6
- retl
- wrpr %g7, %pstate
- __prefill_itlb:
- rdpr %pstate, %g7
- wrpr %g7, PSTATE_IE, %pstate
- mov TLB_TAG_ACCESS, %g1
- stxa %o0, [%g1] ASI_IMMU
- stxa %o1, [%g0] ASI_ITLB_DATA_IN
- flush %g6
- retl
- wrpr %g7, %pstate
- .globl __update_mmu_cache
- __update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */
- ldub [%g6 + AOFF_task_thread + AOFF_thread_fault_code], %o3
- srlx %o1, PAGE_SHIFT, %o1
- ldx [%o0 + 0x0], %o4 /* XXX vma->vm_mm */
- brz,pn %o3, 1f
- sllx %o1, PAGE_SHIFT, %o0
- ldx [%o4 + AOFF_mm_context], %o5
- andcc %o3, FAULT_CODE_DTLB, %g0
- mov %o2, %o1
- and %o5, TAG_CONTEXT_BITS, %o5
- bne,pt %xcc, __prefill_dtlb
- or %o0, %o5, %o0
- ba,a,pt %xcc, __prefill_itlb
- 1: retl
- nop
- #ifdef CONFIG_SMP
- /* These are all called by the slaves of a cross call, at
- * trap level 1, with interrupts fully disabled.
- *
- * Register usage:
- * %g5 mm->context (all tlb flushes)
- * %g1 address arg 1 (tlb page and range flushes)
- * %g7 address arg 2 (tlb range flush only)
- *
- * %g6 ivector table, don't touch
- * %g2 scratch 1
- * %g3 scratch 2
- * %g4 scratch 3
- *
- * TODO: Make xcall TLB range flushes use the tricks above... -DaveM
- */
- .align 32
- .globl xcall_flush_tlb_page, xcall_flush_tlb_mm, xcall_flush_tlb_range
- xcall_flush_tlb_page:
- mov PRIMARY_CONTEXT, %g2
- ldxa [%g2] ASI_DMMU, %g3
- stxa %g5, [%g2] ASI_DMMU
- stxa %g0, [%g1] ASI_DMMU_DEMAP
- stxa %g0, [%g1] ASI_IMMU_DEMAP
- stxa %g3, [%g2] ASI_DMMU
- retry
- nop
- xcall_flush_tlb_mm:
- mov PRIMARY_CONTEXT, %g2
- mov 0x40, %g4
- ldxa [%g2] ASI_DMMU, %g3
- stxa %g5, [%g2] ASI_DMMU
- stxa %g0, [%g4] ASI_DMMU_DEMAP
- stxa %g0, [%g4] ASI_IMMU_DEMAP
- stxa %g3, [%g2] ASI_DMMU
- retry
- xcall_flush_tlb_range:
- sethi %hi(PAGE_SIZE - 1), %g2
- or %g2, %lo(PAGE_SIZE - 1), %g2
- andn %g1, %g2, %g1
- andn %g7, %g2, %g7
- sub %g7, %g1, %g3
- add %g2, 1, %g2
- srlx %g3, PAGE_SHIFT, %g4
- cmp %g4, 96
- bgu,pn %icc, xcall_flush_tlb_mm
- mov PRIMARY_CONTEXT, %g4
- ldxa [%g4] ASI_DMMU, %g7
- sub %g3, %g2, %g3
- stxa %g5, [%g4] ASI_DMMU
- nop
- nop
- nop
- 1: stxa %g0, [%g1 + %g3] ASI_DMMU_DEMAP
- stxa %g0, [%g1 + %g3] ASI_IMMU_DEMAP
- membar #Sync
- brnz,pt %g3, 1b
- sub %g3, %g2, %g3
- stxa %g7, [%g4] ASI_DMMU
- retry
- nop
- nop
- .globl xcall_report_regs
- xcall_report_regs:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- sethi %hi(109f), %g7
- b,pt %xcc, etrap_irq
- 109: or %g7, %lo(109b), %g7
- call __show_regs
- add %sp, STACK_BIAS + REGWIN_SZ, %o0
- b,pt %xcc, rtrap
- clr %l6
- .align 32
- .globl xcall_flush_dcache_page_cheetah
- xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
- sethi %hi(PAGE_SIZE), %g3
- 1: subcc %g3, (1 << 5), %g3
- stxa %g0, [%g1 + %g3] ASI_DCACHE_INVALIDATE
- bne,pt %icc, 1b
- nop
- membar #Sync
- retry
- nop
- .globl xcall_flush_dcache_page_spitfire
- xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
- %g7 == kernel page virtual address
- %g5 == (page->mapping != NULL) */
- #if (L1DCACHE_SIZE > PAGE_SIZE)
- srlx %g1, (13 - 2), %g1 ! Form tag comparitor
- sethi %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
- sub %g3, (1 << 5), %g3 ! D$ linesize == 32
- 1: ldxa [%g3] ASI_DCACHE_TAG, %g2
- andcc %g2, 0x3, %g0
- be,pn %xcc, 2f
- andn %g2, 0x3, %g2
- cmp %g2, %g1
- bne,pt %xcc, 2f
- nop
- stxa %g0, [%g3] ASI_DCACHE_TAG
- membar #Sync
- 2: cmp %g3, 0
- bne,pt %xcc, 1b
- sub %g3, (1 << 5), %g3
- brz,pn %g5, 2f
- #endif /* L1DCACHE_SIZE > PAGE_SIZE */
- sethi %hi(PAGE_SIZE), %g3
- 1: flush %g7
- subcc %g3, (1 << 5), %g3
- bne,pt %icc, 1b
- add %g7, (1 << 5), %g7
- 2: retry
- nop
- nop
- .globl xcall_capture
- xcall_capture:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- sethi %hi(109f), %g7
- b,pt %xcc, etrap_irq
- 109: or %g7, %lo(109b), %g7
- call smp_penguin_jailcell
- nop
- b,pt %xcc, rtrap
- clr %l6
- .globl xcall_promstop
- xcall_promstop:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- sethi %hi(109f), %g7
- b,pt %xcc, etrap_irq
- 109: or %g7, %lo(109b), %g7
- flushw
- call prom_stopself
- nop
- /* We should not return, just spin if we do... */
- 1: b,a,pt %xcc, 1b
- nop
- .globl xcall_receive_signal
- xcall_receive_signal:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %tstate, %g1
- andcc %g1, TSTATE_PRIV, %g0
- /* If we did not trap from user space, just ignore. */
- bne,pn %xcc, 99f
- sethi %hi(109f), %g7
- b,pt %xcc, etrap
- 109: or %g7, %lo(109b), %g7
- b,pt %xcc, rtrap
- clr %l6
- 99: retry
- .data
- errata32_hwbug:
- .xword 0
- .text
- /* These two are not performance critical... */
- .globl xcall_flush_tlb_all
- xcall_flush_tlb_all:
- BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_tlb_all)
- __spitfire_xcall_flush_tlb_all:
- /* Spitfire Errata #32 workaround. */
- sethi %hi(errata32_hwbug), %g4
- stx %g0, [%g4 + %lo(errata32_hwbug)]
- clr %g2
- clr %g3
- 1: ldxa [%g3] ASI_DTLB_DATA_ACCESS, %g4
- and %g4, _PAGE_L, %g5
- brnz,pn %g5, 2f
- mov TLB_TAG_ACCESS, %g7
- stxa %g0, [%g7] ASI_DMMU
- membar #Sync
- stxa %g0, [%g3] ASI_DTLB_DATA_ACCESS
- membar #Sync
- /* Spitfire Errata #32 workaround. */
- sethi %hi(errata32_hwbug), %g4
- stx %g0, [%g4 + %lo(errata32_hwbug)]
- 2: ldxa [%g3] ASI_ITLB_DATA_ACCESS, %g4
- and %g4, _PAGE_L, %g5
- brnz,pn %g5, 2f
- mov TLB_TAG_ACCESS, %g7
- stxa %g0, [%g7] ASI_IMMU
- membar #Sync
- stxa %g0, [%g3] ASI_ITLB_DATA_ACCESS
- membar #Sync
- /* Spitfire Errata #32 workaround. */
- sethi %hi(errata32_hwbug), %g4
- stx %g0, [%g4 + %lo(errata32_hwbug)]
- 2: add %g2, 1, %g2
- cmp %g2, SPITFIRE_HIGHEST_LOCKED_TLBENT
- ble,pt %icc, 1b
- sll %g2, 3, %g3
- flush %g6
- retry
- __cheetah_xcall_flush_tlb_all:
- mov 0x80, %g2
- stxa %g0, [%g2] ASI_DMMU_DEMAP
- stxa %g0, [%g2] ASI_IMMU_DEMAP
- retry
- .globl xcall_flush_cache_all
- xcall_flush_cache_all:
- BRANCH_IF_CHEETAH(g2, g3, __cheetah_xcall_flush_cache_all)
- __spitfire_xcall_flush_cache_all:
- sethi %hi(16383), %g2
- or %g2, %lo(16383), %g2
- clr %g3
- 1: stxa %g0, [%g3] ASI_IC_TAG
- membar #Sync
- add %g3, 32, %g3
- cmp %g3, %g2
- bleu,pt %xcc, 1b
- nop
- flush %g6
- retry
- /* Cheetah's caches are fully coherent in the sense that
- * caches are flushed here. We need to verify this and
- * really just not even send out the xcall at the top level.
- */
- __cheetah_xcall_flush_cache_all:
- retry
- .globl xcall_call_function
- xcall_call_function:
- rdpr %pstate, %g2
- wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
- rdpr %pil, %g2
- wrpr %g0, 15, %pil
- sethi %hi(109f), %g7
- b,pt %xcc, etrap_irq
- 109: or %g7, %lo(109b), %g7
- call smp_call_function_client
- nop
- b,pt %xcc, rtrap
- clr %l6
- #endif /* CONFIG_SMP */