patch-2.4.3 linux/include/asm-sparc64/spitfire.h

Next file: linux/include/linux/802_11.h
Previous file: linux/include/asm-sparc64/smp.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.2/linux/include/asm-sparc64/spitfire.h linux/include/asm-sparc64/spitfire.h
@@ -1,4 +1,4 @@
-/* $Id: spitfire.h,v 1.10 2000/10/06 13:10:29 anton Exp $
+/* $Id: spitfire.h,v 1.14 2001/03/22 07:26:04 davem Exp $
  * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -29,6 +29,23 @@
 
 #ifndef __ASSEMBLY__
 
+enum ultra_tlb_layout {
+	spitfire = 0,
+	cheetah = 1
+};
+
+extern enum ultra_tlb_layout tlb_type;
+
+#define SPARC64_USE_STICK	(tlb_type == cheetah)
+
+#define SPITFIRE_HIGHEST_LOCKED_TLBENT	(64 - 1)
+#define CHEETAH_HIGHEST_LOCKED_TLBENT	(16 - 1)
+
+#define sparc64_highest_locked_tlbent()	\
+	(tlb_type == spitfire ? \
+	 SPITFIRE_HIGHEST_LOCKED_TLBENT : \
+	 CHEETAH_HIGHEST_LOCKED_TLBENT)
+
 extern __inline__ unsigned long spitfire_get_isfsr(void)
 {
 	unsigned long ret;
@@ -61,13 +78,17 @@
 
 extern __inline__ void spitfire_put_isfsr(unsigned long sfsr)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2" :
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* no outputs */
 			     : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_IMMU));
 }
 
 extern __inline__ void spitfire_put_dsfsr(unsigned long sfsr)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2" :
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* no outputs */
 			     : "r" (sfsr), "r" (TLB_SFSR), "i" (ASI_DMMU));
 }
 
@@ -83,11 +104,12 @@
 
 extern __inline__ void spitfire_set_primary_context(unsigned long ctx)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (ctx & 0x3ff),
 			       "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
-	membar("#Sync");
+	__asm__ __volatile__ ("membar #Sync" : : : "memory");
 }
 
 extern __inline__ unsigned long spitfire_get_secondary_context(void)
@@ -102,11 +124,12 @@
 
 extern __inline__ void spitfire_set_secondary_context(unsigned long ctx)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (ctx & 0x3ff),
 			       "r" (SECONDARY_CONTEXT), "i" (ASI_DMMU));
-	membar("#Sync");
+	__asm__ __volatile__ ("membar #Sync" : : : "memory");
 }
 
 /* The data cache is write through, so this just invalidates the
@@ -114,10 +137,11 @@
  */
 extern __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (tag), "r" (addr), "i" (ASI_DCACHE_TAG));
-	membar("#Sync");
+	__asm__ __volatile__ ("membar #Sync" : : : "memory");
 }
 
 /* The instruction cache lines are flushed with this, but note that
@@ -128,7 +152,8 @@
  */
 extern __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
 }
@@ -140,6 +165,10 @@
 	__asm__ __volatile__("ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" (entry << 3), "i" (ASI_DTLB_DATA_ACCESS));
+
+	/* Clear TTE diag bits. */
+	data &= ~0x0003fe0000000000UL;
+
 	return data;
 }
 
@@ -155,7 +184,8 @@
 
 extern __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (data), "r" (entry << 3),
 			       "i" (ASI_DTLB_DATA_ACCESS));
@@ -168,6 +198,10 @@
 	__asm__ __volatile__("ldxa	[%1] %2, %0"
 			     : "=r" (data)
 			     : "r" (entry << 3), "i" (ASI_ITLB_DATA_ACCESS));
+
+	/* Clear TTE diag bits. */
+	data &= ~0x0003fe0000000000UL;
+
 	return data;
 }
 
@@ -183,7 +217,8 @@
 
 extern __inline__ void spitfire_put_itlb_data(int entry, unsigned long data)
 {
-	__asm__ __volatile__("stxa	%0, [%1] %2"
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (data), "r" (entry << 3),
 			       "i" (ASI_ITLB_DATA_ACCESS));
@@ -194,42 +229,48 @@
 /* Context level flushes. */
 extern __inline__ void spitfire_flush_dtlb_primary_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x40), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_primary_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x40), "i" (ASI_IMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_dtlb_secondary_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x50), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_secondary_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x50), "i" (ASI_IMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_dtlb_nucleus_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x60), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_nucleus_context(void)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (0x60), "i" (ASI_IMMU_DEMAP));
 }
@@ -237,44 +278,207 @@
 /* Page level flushes. */
 extern __inline__ void spitfire_flush_dtlb_primary_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_primary_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page), "i" (ASI_IMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_dtlb_secondary_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page | 0x10), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_secondary_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page | 0x10), "i" (ASI_IMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
 }
 
 extern __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page)
 {
-	__asm__ __volatile__("stxa	%%g0, [%0] %1"
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
 			     : /* No outputs */
 			     : "r" (page | 0x20), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Cheetah has "all non-locked" tlb flushes. */
+extern __inline__ void cheetah_flush_dtlb_all(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (0x80), "i" (ASI_DMMU_DEMAP));
+}
+
+extern __inline__ void cheetah_flush_itlb_all(void)
+{
+	__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (0x80), "i" (ASI_IMMU_DEMAP));
+}
+
+/* Cheetah has a 4-tlb layout so direct access is a bit different.
+ * The first two TLBs are fully assosciative, hold 16 entries, and are
+ * used only for locked and >8K sized translations.  One exists for
+ * data accesses and one for instruction accesses.
+ *
+ * The third TLB is for data accesses to 8K non-locked translations, is
+ * 2 way assosciative, and holds 512 entries.  The fourth TLB is for
+ * instruction accesses to 8K non-locked translations, is 2 way
+ * assosciative, and holds 128 entries.
+ */
+extern __inline__ unsigned long cheetah_get_ldtlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" ((0 << 16) | (entry << 3)),
+			     "i" (ASI_DTLB_DATA_ACCESS));
+
+	return data;
+}
+
+extern __inline__ unsigned long cheetah_get_litlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" ((0 << 16) | (entry << 3)),
+			     "i" (ASI_ITLB_DATA_ACCESS));
+
+	return data;
+}
+
+extern __inline__ unsigned long cheetah_get_ldtlb_tag(int entry)
+{
+	unsigned long tag;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (tag)
+			     : "r" ((0 << 16) | (entry << 3)),
+			     "i" (ASI_DTLB_TAG_READ));
+
+	return tag;
+}
+
+extern __inline__ unsigned long cheetah_get_litlb_tag(int entry)
+{
+	unsigned long tag;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (tag)
+			     : "r" ((0 << 16) | (entry << 3)),
+			     "i" (ASI_ITLB_TAG_READ));
+
+	return tag;
+}
+
+extern __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (data),
+			       "r" ((0 << 16) | (entry << 3)),
+			       "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+extern __inline__ void cheetah_put_litlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (data),
+			       "r" ((0 << 16) | (entry << 3)),
+			       "i" (ASI_ITLB_DATA_ACCESS));
+}
+
+extern __inline__ unsigned long cheetah_get_dtlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" ((2 << 16) | (entry << 3)), "i" (ASI_DTLB_DATA_ACCESS));
+
+	return data;
+}
+
+extern __inline__ unsigned long cheetah_get_dtlb_tag(int entry)
+{
+	unsigned long tag;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (tag)
+			     : "r" ((2 << 16) | (entry << 3)), "i" (ASI_DTLB_TAG_READ));
+	return tag;
+}
+
+extern __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (data),
+			       "r" ((2 << 16) | (entry << 3)),
+			       "i" (ASI_DTLB_DATA_ACCESS));
+}
+
+extern __inline__ unsigned long cheetah_get_itlb_data(int entry)
+{
+	unsigned long data;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (data)
+			     : "r" ((2 << 16) | (entry << 3)),
+                               "i" (ASI_ITLB_DATA_ACCESS));
+
+	return data;
+}
+
+extern __inline__ unsigned long cheetah_get_itlb_tag(int entry)
+{
+	unsigned long tag;
+
+	__asm__ __volatile__("ldxa	[%1] %2, %0"
+			     : "=r" (tag)
+			     : "r" ((2 << 16) | (entry << 3)), "i" (ASI_ITLB_TAG_READ));
+	return tag;
+}
+
+extern __inline__ void cheetah_put_itlb_data(int entry, unsigned long data)
+{
+	__asm__ __volatile__("stxa	%0, [%1] %2\n\t"
+			     "membar	#Sync"
+			     : /* No outputs */
+			     : "r" (data), "r" ((2 << 16) | (entry << 3)),
+			       "i" (ASI_ITLB_DATA_ACCESS));
 }
 
 #endif /* !(__ASSEMBLY__) */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)