vserver 2.0 rc7
[linux-2.6.git] / arch / sparc64 / mm / ultra.S
index af8205e..7a09343 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/pil.h>
 #include <asm/head.h>
 #include <asm/thread_info.h>
+#include <asm/cacheflush.h>
 
        /* Basically, most of the Spitfire vs. Cheetah madness
         * has to do with the fact that Cheetah does not support
@@ -49,9 +50,9 @@ __flush_tlb_mm: /* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
        .globl          __flush_tlb_pending
 __flush_tlb_pending:
        /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
-       rdpr            %pstate, %g5
+       rdpr            %pstate, %g7
        sllx            %o1, 3, %o1
-       andn            %g5, PSTATE_IE, %g2
+       andn            %g7, PSTATE_IE, %g2
        wrpr            %g2, %pstate
        mov             SECONDARY_CONTEXT, %o4
        ldxa            [%o4] ASI_DMMU, %g2
@@ -70,7 +71,7 @@ __flush_tlb_pending:
        stxa            %g2, [%o4] ASI_DMMU
        flush           %g6
        retl
-        wrpr           %g5, 0x0, %pstate
+        wrpr           %g7, 0x0, %pstate
 
        .align          32
        .globl          __flush_tlb_kernel_range
@@ -114,64 +115,27 @@ __spitfire_flush_tlb_mm_slow:
        .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
-
+       membar          #StoreStore
+       srlx            %o0, PAGE_SHIFT, %o0
+       sethi           %uhi(PAGE_OFFSET), %g1
+       sllx            %o0, PAGE_SHIFT, %o0
+       sethi           %hi(PAGE_SIZE), %g2
+       sllx            %g1, 32, %g1
+       add             %o0, %g1, %o0
+1:     subcc           %g2, 32, %g2
+       bne,pt          %icc, 1b
+        flush          %o0 + %g2
        retl
-        ldx            [%g6 + TI_TASK], %g4
+        nop
 
-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
+#ifdef DCACHE_ALIASING_POSSIBLE
 
-#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
+#if (PAGE_SHIFT != 13)
+#error only page shift of 13 is supported by dcache flush
 #endif
 
+#define DTAG_MASK 0x3
+
        .align          64
        .globl          __flush_dcache_page
 __flush_dcache_page:   /* %o0=kaddr, %o1=flush_icache */
@@ -228,6 +192,7 @@ dflush4:stxa                %g0, [%o4] ASI_DCACHE_TAG
        membar          #Sync
        ba,pt           %xcc, 2b
         nop
+#endif /* DCACHE_ALIASING_POSSIBLE */
 
        .align          32
 __prefill_dtlb:
@@ -258,10 +223,18 @@ __update_mmu_cache:       /* %o0=hw_context, %o1=address, %o2=pte, %o3=fault_code */
         or             %o5, %o0, %o5
        ba,a,pt         %xcc, __prefill_itlb
 
-       /* Cheetah specific versions, patched at boot time.  */
+       /* Cheetah specific versions, patched at boot time.
+        *
+        * This writes of the PRIMARY_CONTEXT register in this file are
+        * safe even on Cheetah+ and later wrt. the page size fields.
+        * The nucleus page size fields do not matter because we make
+        * no data references, and these instructions execute out of a
+        * locked I-TLB entry sitting in the fully assosciative I-TLB.
+        * This sequence should also never trap.
+        */
 __cheetah_flush_tlb_mm: /* 15 insns */
-       rdpr            %pstate, %g5
-       andn            %g5, PSTATE_IE, %g2
+       rdpr            %pstate, %g7
+       andn            %g7, PSTATE_IE, %g2
        wrpr            %g2, 0x0, %pstate
        wrpr            %g0, 1, %tl
        mov             PRIMARY_CONTEXT, %o2
@@ -274,13 +247,13 @@ __cheetah_flush_tlb_mm: /* 15 insns */
        flush           %g6
        wrpr            %g0, 0, %tl
        retl
-        wrpr           %g5, 0x0, %pstate
+        wrpr           %g7, 0x0, %pstate
 
 __cheetah_flush_tlb_pending:   /* 22 insns */
        /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
-       rdpr            %pstate, %g5
+       rdpr            %pstate, %g7
        sllx            %o1, 3, %o1
-       andn            %g5, PSTATE_IE, %g2
+       andn            %g7, PSTATE_IE, %g2
        wrpr            %g2, 0x0, %pstate
        wrpr            %g0, 1, %tl
        mov             PRIMARY_CONTEXT, %o4
@@ -299,8 +272,9 @@ __cheetah_flush_tlb_pending:        /* 22 insns */
        flush           %g6
        wrpr            %g0, 0, %tl
        retl
-        wrpr           %g5, 0x0, %pstate
+        wrpr           %g7, 0x0, %pstate
 
+#ifdef DCACHE_ALIASING_POSSIBLE
 flush_dcpage_cheetah: /* 11 insns */
        sethi           %uhi(PAGE_OFFSET), %g1
        sllx            %g1, 32, %g1
@@ -313,6 +287,7 @@ flush_dcpage_cheetah: /* 11 insns */
         nop
        retl            /* I-cache flush never needed on Cheetah, see callers. */
         nop
+#endif /* DCACHE_ALIASING_POSSIBLE */
 
 cheetah_patch_one:
 1:     lduw            [%o1], %g1
@@ -343,12 +318,14 @@ cheetah_patch_cachetlbops:
        call            cheetah_patch_one
         mov            22, %o2
 
+#ifdef DCACHE_ALIASING_POSSIBLE
        sethi           %hi(__flush_dcache_page), %o0
        or              %o0, %lo(__flush_dcache_page), %o0
        sethi           %hi(flush_dcpage_cheetah), %o1
        or              %o1, %lo(flush_dcpage_cheetah), %o1
        call            cheetah_patch_one
         mov            11, %o2
+#endif /* DCACHE_ALIASING_POSSIBLE */
 
        ret
         restore
@@ -464,6 +441,7 @@ xcall_report_regs:
        b               rtrap_xcall
         ldx            [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
 
+#ifdef DCACHE_ALIASING_POSSIBLE
        .align          32
        .globl          xcall_flush_dcache_page_cheetah
 xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
@@ -475,12 +453,13 @@ xcall_flush_dcache_page_cheetah: /* %g1 == physical page address */
         nop
        retry
        nop
+#endif /* DCACHE_ALIASING_POSSIBLE */
 
        .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)
+#ifdef DCACHE_ALIASING_POSSIBLE
        srlx            %g1, (13 - 2), %g1      ! Form tag comparitor
        sethi           %hi(L1DCACHE_SIZE), %g3 ! D$ size == 16K
        sub             %g3, (1 << 5), %g3      ! D$ linesize == 32
@@ -499,7 +478,7 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
         sub            %g3, (1 << 5), %g3
 
        brz,pn          %g5, 2f
-#endif /* L1DCACHE_SIZE > PAGE_SIZE */
+#endif /* DCACHE_ALIASING_POSSIBLE */
         sethi          %hi(PAGE_SIZE), %g3
 
 1:     flush           %g7