patch-2.1.34 linux/include/asm-sparc64/mmu_context.h

Next file: linux/include/asm-sparc64/mostek.h
Previous file: linux/include/asm-sparc64/machines.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.33/linux/include/asm-sparc64/mmu_context.h linux/include/asm-sparc64/mmu_context.h
@@ -1,34 +1,74 @@
-/* $Id: mmu_context.h,v 1.4 1996/12/28 18:39:51 davem Exp $ */
+/* $Id: mmu_context.h,v 1.7 1997/04/04 00:50:23 davem Exp $ */
 #ifndef __SPARC64_MMU_CONTEXT_H
 #define __SPARC64_MMU_CONTEXT_H
 
+/* Derived heavily from Linus's Alpha/AXP ASN code... */
+
 #include <asm/system.h>
 #include <asm/spitfire.h>
 
-#define NO_CONTEXT     -1
+#define NO_CONTEXT     0
 
 #ifndef __ASSEMBLY__
 
 /* Initialize the context related info for a new mm_struct
  * instance.
  */
-#define init_new_context(mm) ((mm)->context = NO_CONTEXT)
+#define init_new_context(mm)	((mm)->context = NO_CONTEXT)
+
+#define destroy_context(mm)	do { } while(0)
+
+extern unsigned long tlb_context_cache;
+
+#define MAX_CTX			PAGE_SIZE
 
-extern void spitfire_get_new_context(struct mm_struct *mm);
+#define CTX_VERSION_SHIFT	PAGE_SHIFT
+#define CTX_VERSION_MASK	((~0UL) << CTX_VERSION_SHIFT)
+#define CTX_FIRST_VERSION	((1UL << CTX_VERSION_SHIFT) + 1UL)
+
+extern __inline__ void get_new_mmu_context(struct mm_struct *mm,
+					   unsigned long ctx)
+{
+	if((ctx & ~CTX_VERSION_MASK) > MAX_CTX) {
+		unsigned long flags;
+		int entry;
+
+		save_and_cli(flags);
+		__asm__ __volatile__("stxa	%%g0, [%0] %1\n\t"
+				     "stxa	%%g0, [%0] %2"
+				     : /* No outputs */
+				     : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU),
+				       "i" (ASI_DMMU));
+		for(entry = 0; entry < 62; entry++) {
+			spitfire_put_dtlb_data(entry, 0x0UL);
+			spitfire_put_itlb_data(entry, 0x0UL);
+		}
+		membar("#Sync");
+		flushi(PAGE_OFFSET);
+		restore_flags(flags);
+
+		ctx = (ctx & CTX_VERSION_MASK) + CTX_FIRST_VERSION;
+		if(!ctx)
+			ctx = CTX_FIRST_VERSION;
+	}
+	tlb_context_cache = ctx + 1;
+	mm->context = ctx;
+}
 
 extern __inline__ void get_mmu_context(struct task_struct *tsk)
 {
 	struct mm_struct *mm = tsk->mm;
 
-	if(tsk->mm->context == NO_CONTEXT)
-		spitfire_get_new_context(mm);
-
-	/* Get current set of user windows out of the cpu. */
-	flushw_user();
-
-	/* Jump into new ASN. */
-	spitfire_set_primary_context(mm->context);
-	spitfire_set_secondary_context(mm->context);
+	if(mm						&&
+	   !(tsk->tss.flags & SPARC_FLAG_KTHREAD)	&&
+	   !(tsk->flags & PF_EXITING)) {
+		unsigned long ctx = tlb_context_cache;
+
+		flushw_user();
+		if((mm->context ^ ctx) & CTX_VERSION_MASK)
+			get_new_mmu_context(mm, ctx);
+		spitfire_set_secondary_context(mm->context);
+	}
 }
 
 #endif /* !(__ASSEMBLY__) */

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