patch-2.3.48 linux/include/asm-mips/mmu_context.h

Next file: linux/include/asm-mips/msgbuf.h
Previous file: linux/include/asm-mips/mman.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.47/linux/include/asm-mips/mmu_context.h linux/include/asm-mips/mmu_context.h
@@ -1,4 +1,4 @@
-/* $Id: mmu_context.h,v 1.3 1998/10/16 19:22:54 ralf Exp $
+/* $Id: mmu_context.h,v 1.8 2000/02/23 00:41:38 ralf Exp $
  *
  * Switch a MMU context.
  *
@@ -6,61 +6,46 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 1997, 1998 by Ralf Baechle
+ * Copyright (C) 1996, 1997, 1998, 1999 by Ralf Baechle
+ * Copyright (C) 1999 Silicon Graphics, Inc.
  */
-#ifndef __ASM_MIPS_MMU_CONTEXT_H
-#define __ASM_MIPS_MMU_CONTEXT_H
+#ifndef _ASM_MMU_CONTEXT_H
+#define _ASM_MMU_CONTEXT_H
 
-static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
-{
-}
+#include <linux/config.h>
+#include <asm/pgalloc.h>
 
 /* Fuck.  The f-word is here so you can grep for it :-)  */
 extern unsigned long asid_cache;
+extern pgd_t *current_pgd;
+
+#if defined(CONFIG_CPU_R3000)
+
+#define ASID_INC	0x40
+#define ASID_MASK	0xfc0
 
-/* I patch, therefore I am ...  */
-#define ASID_INC(asid)						\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\taddiu\t%0,0\t\t\t\t# patched\n\t"		\
-           ".section\t__asid_inc,\"a\"\n\t"			\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid)					\
-           :"0" (__asid));					\
-   __asid; })
-#define ASID_MASK(asid)						\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\tandi\t%0,%1,0\t\t\t# patched\n\t"			\
-           ".section\t__asid_mask,\"a\"\n\t"			\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid)					\
-           :"r" (__asid));					\
-   __asid; })
-#define ASID_VERSION_MASK					\
- ({ unsigned long __asid;					\
-   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
-           ".section\t__asid_version_mask,\"a\"\n\t"		\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid));					\
-   __asid; })
-#define ASID_FIRST_VERSION					\
- ({ unsigned long __asid = asid;				\
-   __asm__("1:\tli\t%0,0\t\t\t\t# patched\n\t"			\
-           ".section\t__asid_first_version,\"a\"\n\t"		\
-           ".word\t1b\n\t"					\
-           ".previous"						\
-           :"=r" (__asid));					\
-   __asid; })
+#else /* FIXME: not correct for R6000, R8000 */
+
+#define ASID_INC	0x1
+#define ASID_MASK	0xff
+
+#endif
+
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
+{
+}
 
-#define ASID_FIRST_VERSION_R3000 0x1000
-#define ASID_FIRST_VERSION_R4000 0x100
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+#define ASID_VERSION_MASK  ((unsigned long)~(ASID_MASK|(ASID_MASK-1)))
+#define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1)
 
 extern inline void
 get_new_mmu_context(struct mm_struct *mm, unsigned long asid)
 {
-	if (!ASID_MASK((asid = ASID_INC(asid)))) {
+	if (! ((asid += ASID_INC) & ASID_MASK) ) {
 		flush_tlb_all(); /* start new asid cycle */
 		if (!asid)      /* fix version if needed */
 			asid = ASID_FIRST_VERSION;
@@ -68,71 +53,50 @@
 	mm->context = asid_cache = asid;
 }
 
-extern inline void
-get_mmu_context(struct task_struct *p)
-{
-	struct mm_struct *mm = p->mm;
-
-	if (mm) {
-		unsigned long asid = asid_cache;
-		/* Check if our ASID is of an older version and thus invalid */
-		if ((mm->context ^ asid) & ASID_VERSION_MASK)
-			get_new_mmu_context(mm, asid);
-	}
-}
-
 /*
  * Initialize the context related info for a new mm_struct
  * instance.
  */
-extern inline void init_new_context(struct mm_struct *mm)
+extern inline void
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
 	mm->context = 0;
 }
 
+extern inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk, unsigned cpu)
+{
+	unsigned long asid = asid_cache;
+
+	/* Check if our ASID is of an older version and thus invalid */
+	if ((next->context ^ asid) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, asid);
+
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
+}
+
 /*
  * Destroy context related info for an mm_struct that is about
  * to be put to rest.
  */
 extern inline void destroy_context(struct mm_struct *mm)
 {
-	mm->context = 0;
+	/* Nothing to do.  */
 }
 
 /*
  * After we have set current->mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
  */
-extern inline void activate_context(struct task_struct *tsk)
-{
-	get_mmu_context(tsk);
-	set_entryhi(tsk->mm->context);
-}
-
-extern void __asid_setup(unsigned int inc, unsigned int mask,
-                         unsigned int version_mask, unsigned int first_version);
-
-extern inline void r3000_asid_setup(void)
-{
-	__asid_setup(0x40, 0xfc0, 0xf000, ASID_FIRST_VERSION_R3000);
-}
-
-extern inline void r6000_asid_setup(void)
-{
-	panic("r6000_asid_setup: implement me");	/* No idea ...  */
-}
-
-extern inline void tfp_asid_setup(void)
+extern inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
-	panic("tfp_asid_setup: implement me");	/* No idea ...  */
-}
+	/* Unconditionally get a new ASID.  */
+	get_new_mmu_context(next, asid_cache);
 
-extern inline void r4xx0_asid_setup(void)
-{
-	__asid_setup(1, 0xff, 0xff00, ASID_FIRST_VERSION_R4000);
+	current_pgd = next->pgd;
+	set_entryhi(next->context);
 }
 
-/* R10000 has the same ASID mechanism as the R4000.  */
-#define andes_asid_setup r4xx0_asid_setup
-
-#endif /* __ASM_MIPS_MMU_CONTEXT_H */
+#endif /* _ASM_MMU_CONTEXT_H */

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