patch-2.1.115 linux/arch/sparc64/kernel/dtlb_backend.S

Next file: linux/arch/sparc64/kernel/dtlb_base.S
Previous file: linux/arch/sparc64/kernel/devices.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.114/linux/arch/sparc64/kernel/dtlb_backend.S linux/arch/sparc64/kernel/dtlb_backend.S
@@ -0,0 +1,69 @@
+/* $Id: dtlb_backend.S,v 1.4 1998/06/15 16:59:34 jj Exp $
+ * dtlb_backend.S: Back end to DTLB miss replacement strategy.
+ *                 This is included directly into the trap table.
+ *
+ * Copyright (C) 1996,1998 David S. Miller (davem@dm.cobaltmicro.com)
+ * Copyright (C) 1997,1998 Jakub Jelinek   (jj@ultra.linux.cz)
+ */
+
+#define TAG_CONTEXT_BITS	0x3ff
+#define VPTE_SHIFT		(PAGE_SHIFT - 3)
+#define PMD_SHIFT		(23 - PAGE_SHIFT + 3)
+#define PGD_SHIFT		(34 - PAGE_SHIFT + 3)
+#define VPTE_BITS		(_PAGE_CP | _PAGE_P | _PAGE_W)
+
+/* Ways we can get here:
+ *
+ * 1) Nucleus loads and stores to/from PA-->VA direct mappings at tl>1.
+ * 2) Nucleus loads and stores to/from user/kernel window save areas.
+ * 3) VPTE misses from dtlb_base, dtlb_prot, and itlb_base.  But this only
+ *    happens for non-nucleus contexts.  Nucleus VPTE's cannot work because
+ *    of how OBP uses the same part of the address space in ctx 0.
+ */
+
+/* TLB1 ** ICACHE line 1: tl1 DTLB and quick VPTE miss	*/
+	ldxa		[%g1 + %g1] ASI_DMMU, %g4	! Get TAG_ACCESS
+	add		%g3, %g3, %g5			! Compute VPTE base
+	cmp		%g4, %g5			! VPTE miss?
+	blu,pn		%xcc, .-0x4004			! Fall to tl0 miss
+	 andcc		%g4, TAG_CONTEXT_BITS, %g5	! From Nucleus? (for tl0 miss)
+	sllx		%g6, VPTE_SHIFT, %g4		! Position TAG_ACCESS
+	or		%g4, %g5, %g4			! Prepare TAG_ACCESS
+	mov		TSB_REG, %g1			! Grab TSB reg
+
+/* TLB1 ** ICACHE line 2: Quick VPTE miss	  	*/
+	ldxa		[%g1] ASI_DMMU, %g5		! Doing PGD caching?
+	srlx		%g6, (PMD_SHIFT - 1), %g1	! Position PMD offset
+	be,pn		%xcc, sparc64_vpte_nucleus	! Is it from Nucleus?
+	 and		%g1, 0xffe, %g1			! Mask PMD offset bits
+	brnz,pt		%g5, sparc64_vpte_continue	! Yep, go like smoke
+	 nop						! Pipe bubble...
+	srlx		%g6, (PGD_SHIFT - 2), %g5	! Position PGD offset
+	and		%g5, 0xffc, %g5			! Mask PGD offset
+
+/* TLB1 ** ICACHE line 3: Quick VPTE miss	  	*/
+	lduwa		[%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
+	brz,pn		%g5, 2f				! Valid?
+sparc64_vpte_continue:
+	 add		%g1, %g1, %g1			! Position PMD offset once again
+	lduwa		[%g5 + %g1] ASI_PHYS_USE_EC, %g5! Load PMD
+	brz,pn		%g5, 2f				! Valid?
+	 sllx		%g2, 62, %g1			! Put _PAGE_VALID into %g1
+	or		%g5, VPTE_BITS, %g5		! Prepare VPTE data
+	or		%g5, %g1, %g5			! ...
+
+/* TLB1 ** ICACHE line 4: Quick VPTE miss	  	*/
+	mov		TLB_SFSR, %g1			! Restore %g1 value
+	stxa		%g5, [%g0] ASI_DTLB_DATA_IN	! Load VPTE into TLB
+	membar		#Sync				! Synchronize ASI stores
+	stxa		%g4, [%g1 + %g1] ASI_DMMU	! Restore previous TAG_ACCESS
+	retry						! Load PTE once again
+2:	mov		TLB_SFSR, %g1			! Restore %g1 value
+	stxa		%g4, [%g1 + %g1] ASI_DMMU	! Restore previous TAG_ACCESS
+	done						! Slick trick
+
+#undef TAG_CONTEXT_BITS
+#undef VPTE_SHIFT
+#undef PMD_SHIFT
+#undef PGD_SHIFT
+#undef VPTE_BITS

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov