#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
.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
stxa %g2, [%o4] ASI_DMMU
flush %g6
retl
- wrpr %g5, 0x0, %pstate
+ wrpr %g7, 0x0, %pstate
.align 32
.globl __flush_tlb_kernel_range
.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 */
membar #Sync
ba,pt %xcc, 2b
nop
+#endif /* DCACHE_ALIASING_POSSIBLE */
.align 32
__prefill_dtlb:
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
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
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
nop
retl /* I-cache flush never needed on Cheetah, see callers. */
nop
+#endif /* DCACHE_ALIASING_POSSIBLE */
cheetah_patch_one:
1: lduw [%o1], %g1
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
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 */
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
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