Skip to contentSkip to conversation

Use scratch registers on XLR/XLS/XLP

PATCH In review Jayachandran C 3 participants 10 messages Jun 11, 2013 – Jun 20, 2013 MIPS

lore
Share & tools
lore
#0 lore raw

cover Use scratch registers on XLR/XLS/XLP

This set of patches enable the use of scratch registers on XLR/XLS and XLP (cop0 reg 22, sel 0-7) to optimize the generated TLB handlers.

The current code assumes scratch is 31, which is fixed by the first patch. The second patch fixes a minor issue in checking if scratch is allocated. The third patch enables use of a scratch register when it is available even on a 32-bit or non-r2 platform. The fourth patch is a cleanup to consolidate all the defines needed into one file, this patch does not have any change in logic.

In the earlier scheme, if MIPS_PGD_C0_CONTEXT was defined, the Context register or a scratch register would contain the current PGD, and the Xcontext would contain the smp_processor_id shifted to index pointers.

In the new scheme, the behavior when MIPS_PGD_C0_CONTEXT is defined remains the same. But when it is not defined, we still try to allocate a scratch register for the current pgd and the smp processor id remains in Context.

There is also an additional change is to generate the tlbmiss_handler_setup_pgd() function even when MIPS_PGD_C0_CONTEXT is not defined. This function will save the PGD in pgd_current[] and also in the scratch register if one has been allocated.

Comments/testing welcome.

Thanks,
JC.

Changes in v3:
* Add patch 2 - fix up check for a valid scratch register

Changes in v2:
* Update macros in thread-info.h, remove __ASSEMBLY__ part
* add ASM_CPUID_MFC0 and UASM_i_CPUID_MFC0 which allows us to remove a lot of conditional compilation.
* make c0_kscratch a inline function and remove global variable

Jayachandran C (4):
MIPS: Allow platform specific scratch registers
MIPS: Fixup check for invalid scratch register
MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT
MIPS: Move definition of SMP processor id register to header file

 arch/mips/include/asm/mmu_context.h |   22 ++---
 arch/mips/include/asm/stackframe.h  |   24 ++---
 arch/mips/include/asm/thread_info.h |   30 +++++-
 arch/mips/kernel/cpu-probe.c        |    1 +
 arch/mips/mm/tlbex.c                |  186 +++++++++++++++++------------------
 5 files changed, 132 insertions(+), 131 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/4 MIPS: Allow platform specific scratch registers

XLR/XLP COP0 scratch is register 22, sel 0-7. Add a function c0_kscratch() which returns the scratch register for the platform, and use the return value while generating TLB handlers.

Setup kscratch_mask to 0xf for XLR/XLP since the config4 register does not exist. This allows the kernel to allocate scratch registers 0-3 if needed.

---
 arch/mips/kernel/cpu-probe.c |    1 +
 arch/mips/mm/tlbex.c         |   41 ++++++++++++++++++++++++++---------------
 2 files changed, 27 insertions(+), 15 deletions(-)
arch/mips/kernel/cpu-probe.c +1 -0
index c6568bf..265c97d 100644
@@ -959,6 +959,7 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
 		set_isa(c, MIPS_CPU_ISA_M64R1);
 		c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
 	}
+	c->kscratch_mask = 0xf;
 }
 
 #ifdef CONFIG_64BIT
arch/mips/mm/tlbex.c +26 -15

115 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/4 MIPS: Fixup check for invalid scratch register

In reply to Jayachandran C

The invalid value for scratch register is -1, so update the checks of the form (scratch_reg > 0) to be (scratch_reg >= 0). This will fix the case in Netlogic XLP where the scratch_reg can be 0.

---
 arch/mips/mm/tlbex.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
arch/mips/mm/tlbex.c +5 -5
index b2eaa1c..4a6817c 100644
@@ -349,7 +349,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
 	int smp_processor_id_sel;
 	int smp_processor_id_shift;
 
-	if (scratch_reg > 0) {
+	if (scratch_reg >= 0) {
 		/* Save in CPU local C0_KScratch? */
 		UASM_i_MTC0(p, 1, c0_kscratch(), scratch_reg);
 		r.r1 = K0;
@@ -399,7 +399,7 @@ static struct work_registers __cpuinit build_get_work_registers(u32 **p)
 
 static void __cpuinit build_restore_work_registers(u32 **p)
 {
-	if (scratch_reg > 0) {
+	if (scratch_reg >= 0) {
 		UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 		return;
 	}
@@ -688,7 +688,7 @@ static __cpuinit void build_restore_pagemask(u32 **p,
 			uasm_i_mtc0(p, 0, C0_PAGEMASK);
 			uasm_il_b(p, r, lid);
 		}
-		if (scratch_reg > 0)
+		if (scratch_reg >= 0)
 			UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 		else
 			UASM_i_LW(p, 1, scratchpad_offset(0), 0);
@@ -944,7 +944,7 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 		uasm_i_jr(p, ptr);
 
 		if (mode == refill_scratch) {
-			if (scratch_reg > 0)
+			if (scratch_reg >= 0)
 				UASM_i_MFC0(p, 1, c0_kscratch(), scratch_reg);
 			else
 				UASM_i_LW(p, 1, scratchpad_offset(0), 0);
@@ -1301,7 +1301,7 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
 	memset(relocs, 0, sizeof(relocs));
 	memset(final_handler, 0, sizeof(final_handler));
 
-	if ((scratch_reg > 0 || scratchpad_available()) && use_bbit_insns()) {
+	if ((scratch_reg >= 0 || scratchpad_available()) && use_bbit_insns()) {
 		htlb_info = build_fast_tlb_refill_handler(&p, &l, &r, K0, K1,
 							  scratch_reg);
 		vmalloc_mode = refill_scratch;
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/4 MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT

In reply to Jayachandran C

Allow usage of scratch register for current pgd even when MIPS_PGD_C0_CONTEXT is not configured. MIPS_PGD_C0_CONTEXT is set for 64r2 platforms to indicate availability of Xcontext for saving cpuid, thus freeing Context to be used for saving PGD. This option was also tied to using a scratch register for storing PGD.

This commit will allow usage of scratch register to store the current pgd if one can be allocated for the platform, even when MIPS_PGD_C0_CONTEXT is not set. The cpuid will be kept in the CP0 Context register in this case.

The code to store the current pgd for the TLB miss handler is now generated in all cases. When scratch register is available, the PGD is also stored in the scratch register.

---
 arch/mips/include/asm/mmu_context.h |    7 +-
 arch/mips/mm/tlbex.c                |  142 ++++++++++++++++++++++-------------
 2 files changed, 92 insertions(+), 57 deletions(-)
arch/mips/include/asm/mmu_context.h +2 -5
index 8201160..3e20577 100644
@@ -24,8 +24,6 @@
 #endif /* SMTC */
 #include <asm-generic/mm_hooks.h>
 
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-
 #define TLBMISS_HANDLER_SETUP_PGD(pgd)					\
 do {									\
 	void (*tlbmiss_handler_setup_pgd)(unsigned long);		\
@@ -36,6 +34,8 @@ do {									\
 	tlbmiss_handler_setup_pgd((unsigned long)(pgd));		\
 } while (0)
 
+
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 #define TLBMISS_HANDLER_SETUP()						\
 	do {								\
 		TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);		\
@@ -51,9 +51,6 @@ do {									\
  */
 extern unsigned long pgd_current[];
 
-#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
-	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
-
 #ifdef CONFIG_32BIT
 #define TLBMISS_HANDLER_SETUP()						\
 	write_c0_context((unsigned long) smp_processor_id() << 25);	\
arch/mips/mm/tlbex.c +90 -52

221 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 3/4 MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT

Allow usage of scratch register for current pgd even when MIPS_PGD_C0_CONTEXT is not configured. MIPS_PGD_C0_CONTEXT is set for 64r2 platforms to indicate availability of Xcontext for saving cpuid, thus freeing Context to be used for saving PGD. This option was also tied to using a scratch register for storing PGD.

This commit will allow usage of scratch register to store the current pgd if one can be allocated for the platform, even when MIPS_PGD_C0_CONTEXT is not set. The cpuid will be kept in the CP0 Context register in this case.

The code to store the current pgd for the TLB miss handler is now generated in all cases. When scratch register is available, the PGD is also stored in the scratch register.

---
[ The previous version had a bug that made it hang on mips32
systems, this version fixes that. ]

 arch/mips/include/asm/mmu_context.h |    7 +-
 arch/mips/mm/tlbex.c                |  142 ++++++++++++++++++++++-------------
 2 files changed, 92 insertions(+), 57 deletions(-)
arch/mips/include/asm/mmu_context.h +2 -5
index 516e6e9..fc282ef 100644
@@ -24,8 +24,6 @@
 #endif /* SMTC */
 #include <asm-generic/mm_hooks.h>
 
-#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
-
 #define TLBMISS_HANDLER_SETUP_PGD(pgd)					\
 do {									\
 	void (*tlbmiss_handler_setup_pgd)(unsigned long);		\
@@ -36,6 +34,8 @@ do {									\
 	tlbmiss_handler_setup_pgd((unsigned long)(pgd));		\
 } while (0)
 
+
+#ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 #define TLBMISS_HANDLER_SETUP()						\
 	do {								\
 		TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);		\
@@ -51,9 +51,6 @@ do {									\
  */
 extern unsigned long pgd_current[];
 
-#define TLBMISS_HANDLER_SETUP_PGD(pgd) \
-	pgd_current[smp_processor_id()] = (unsigned long)(pgd)
-
 #ifdef CONFIG_32BIT
 #define TLBMISS_HANDLER_SETUP()						\
 	write_c0_context((unsigned long) smp_processor_id() << 25);	\
arch/mips/mm/tlbex.c +90 -52

221 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#5 lore raw

PATCH 4/4 MIPS: Move definition of SMP processor id register to header file

The definition of the CP0 register used to save the smp processor id is repicated in many files, move them all to thread_info.h.

---

[ Updated to apply cleanly on the new 3/4 patch ]

 arch/mips/include/asm/mmu_context.h |   17 +++-----
 arch/mips/include/asm/stackframe.h  |   24 +++--------
 arch/mips/include/asm/thread_info.h |   30 +++++++++++++-
 arch/mips/mm/tlbex.c                |   75 +++++------------------------------
 4 files changed, 50 insertions(+), 96 deletions(-)
arch/mips/include/asm/mmu_context.h +5 -12
index fc282ef..aa59e31 100644
@@ -34,15 +34,15 @@ do {									\
 	tlbmiss_handler_setup_pgd((unsigned long)(pgd));		\
 } while (0)
 
-
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 #define TLBMISS_HANDLER_SETUP()						\
 	do {								\
 		TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);		\
-		write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+		write_c0_xcontext((unsigned long) smp_processor_id() <<	\
+						SMP_CPUID_REGSHIFT);	\
 	} while (0)
 
-#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
+#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
 
 /*
  * For the fast tlb miss handlers, we keep a per cpu array of pointers
@@ -51,18 +51,11 @@ do {									\
  */
 extern unsigned long pgd_current[];
 
-#ifdef CONFIG_32BIT
-#define TLBMISS_HANDLER_SETUP()						\
-	write_c0_context((unsigned long) smp_processor_id() << 25);	\
-	back_to_back_c0_hazard();					\
-	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
-#ifdef CONFIG_64BIT
 #define TLBMISS_HANDLER_SETUP()						\
-	write_c0_context((unsigned long) smp_processor_id() << 26);	\
+	write_c0_context((unsigned long) smp_processor_id() <<		\
+						SMP_CPUID_REGSHIFT);	\
 	back_to_back_c0_hazard();					\
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
arch/mips/include/asm/stackframe.h +6 -18
index a89d1b1..faefe31 100644
@@ -17,6 +17,7 @@
 #include <asm/asmmacro.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
 
 /*
  * For SMTC kernel, global IE should be left set, and interrupts
@@ -85,21 +86,8 @@
 		.endm
 
 #ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
-#define PTEBASE_SHIFT	19	/* TCBIND */
-#define CPU_ID_REG CP0_TCBIND
-#define CPU_ID_MFC0 mfc0
-#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
-#define PTEBASE_SHIFT	48	/* XCONTEXT */
-#define CPU_ID_REG CP0_XCONTEXT
-#define CPU_ID_MFC0 MFC0
-#else
-#define PTEBASE_SHIFT	23	/* CONTEXT */
-#define CPU_ID_REG CP0_CONTEXT
-#define CPU_ID_MFC0 MFC0
-#endif
 		.macro	get_saved_sp	/* SMP variation */
-		CPU_ID_MFC0	k0, CPU_ID_REG
+		ASM_CPUID_MFC0	k0, $SMP_CPUID_REG
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 		lui	k1, %hi(kernelsp)
 #else
@@ -109,17 +97,17 @@
 		daddiu	k1, %hi(kernelsp)
 		dsll	k1, 16
 #endif
-		LONG_SRL	k0, PTEBASE_SHIFT
+		LONG_SRL	k0, SMP_CPUID_PTRSHIFT
 		LONG_ADDU	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 		.endm
 
 		.macro	set_saved_sp stackp temp temp2
-		CPU_ID_MFC0	\temp, CPU_ID_REG
-		LONG_SRL	\temp, PTEBASE_SHIFT
+		ASM_CPUID_MFC0	\temp, $SMP_CPUID_REG
+		LONG_SRL	\temp, SMP_CPUID_PTRSHIFT
 		LONG_S	\stackp, kernelsp(\temp)
 		.endm
-#else
+#else /* !CONFIG_SMP */
 		.macro	get_saved_sp	/* Uniprocessor variation */
 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS
 		/*
arch/mips/include/asm/thread_info.h +29 -1
index 61215a3..ddff267 100644
@@ -147,6 +147,34 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK |		\
 				 _TIF_WORK_SYSCALL_EXIT)
 
-#endif /* __KERNEL__ */
+/*
+ * We stash processor id into a COP0 register to retrieve it fast
+ * at kernel exception entry.
+ */
+#if defined(CONFIG_MIPS_MT_SMTC)
+#define SMP_CPUID_REG		2, 2	/* TCBIND */
+#define SMP_CPUID_PTRSHIFT	19
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#define SMP_CPUID_REG		20, 0	/* XCONTEXT */
+#define SMP_CPUID_PTRSHIFT	48
+#else
+#define SMP_CPUID_REG		4, 0	/* CONTEXT */
+#define SMP_CPUID_PTRSHIFT	23
+#endif
 
+#ifdef CONFIG_64BIT
+#define SMP_CPUID_REGSHIFT	(SMP_CPUID_PTRSHIFT + 3)
+#else
+#define SMP_CPUID_REGSHIFT	(SMP_CPUID_PTRSHIFT + 2)
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#define ASM_CPUID_MFC0		mfc0
+#define UASM_i_CPUID_MFC0	uasm_i_mfc0
+#else
+#define ASM_CPUID_MFC0		MFC0
+#define UASM_i_CPUID_MFC0	UASM_i_MFC0
+#endif
+
+#endif /* __KERNEL__ */
 #endif /* _ASM_THREAD_INFO_H */
arch/mips/mm/tlbex.c +10 -65

114 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#6 lore raw

Re: [PATCH UPDATED 4/4] MIPS: Move definition of SMP processor id register to header file

Quoted 4 lines · Jayachandran C

The definition of the CP0 register used to save the smp processor id is repicated in many files, move them all to thread_info.h.

This breaks the ip27_defconfig build:

AS arch/mips/kernel/genex.o
/home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S: Assembler messages:
/home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:199: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:250: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:334: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:377: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:461: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:462: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:463: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:464: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:465: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:466: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:467: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:468: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:469: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:470: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:471: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:479: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:481: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:482: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:483: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:484: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:546: Error: Illegal operands dmfc0 $26,$4,0' /home/ralf/src/linux/upstream-sfr/arch/mips/kernel/genex.S:581: Error: Illegal operands dmfc0 $26,$4,0' make[4]: *** [arch/mips/kernel/genex.o] Error 1

So I've removed it again for now.

Maciej, I wonder why does gas in MIPS III/IV mode accept

	dmfc0	$reg1, $cp0reg

but not

	dmfc0	$reg1, $cp0reg, 0

The generated code is the same after all. Same for MIPS I/II mode and mfc0.

Ralf

#7 lore raw

Re: [PATCH UPDATED 4/4] MIPS: Move definition of SMP processor id register to header file

Quoted 4 lines · Ralf Baechle

So I've removed it again for now.

Maciej, I wonder why does gas in MIPS III/IV mode accept

Quoted 8 lines
	dmfc0	$reg1, $cp0reg

but not

	dmfc0	$reg1, $cp0reg, 0

The generated code is the same after all. Same for MIPS I/II mode and mfc0.

The <sel> operand and instruction field was only added to these
instructions with the MIPS64 ISA (MIPS32 ISA for MFC0/MTC0). Previously processors did not decode this field and consequently the assembler notation only supports two operands.

Since AFAICT the offending pieces are macros I suggest simply dumping the
redundant ", 0" part, the two-argument form is as you've observed equivalent.

Maciej

#8 lore raw

Re: [PATCH UPDATED 3/4] MIPS: mm: Use scratch for PGD when !CONFIG_MIPS_PGD_C0_CONTEXT

In reply to Jayachandran C
Quoted 6 lines · Jayachandran C

Allow usage of scratch register for current pgd even when MIPS_PGD_C0_CONTEXT is not configured. MIPS_PGD_C0_CONTEXT is set for 64r2 platforms to indicate availability of Xcontext for saving cpuid, thus freeing Context to be used for saving PGD. This option was also tied to using a scratch register for storing PGD.

Quoted 8 lines

This commit will allow usage of scratch register to store the current pgd if one can be allocated for the platform, even when MIPS_PGD_C0_CONTEXT is not set. The cpuid will be kept in the CP0 Context register in this case.

The code to store the current pgd for the TLB miss handler is now generated in all cases. When scratch register is available, the PGD is also stored in the scratch register.

I also pulled this one again as it was causing to others.

Ralf

#9 lore raw

PATCH 4/4 MIPS: Move definition of SMP processor id register to header file

In reply to Jayachandran C

The definition of the CP0 register used to save the smp processor id is repicated in many files, move them all to thread_info.h.

---
 arch/mips/include/asm/mmu_context.h |   17 +++-----
 arch/mips/include/asm/stackframe.h  |   24 +++--------
 arch/mips/include/asm/thread_info.h |   30 +++++++++++++-
 arch/mips/mm/tlbex.c                |   75 +++++------------------------------
 4 files changed, 50 insertions(+), 96 deletions(-)
arch/mips/include/asm/mmu_context.h +5 -12
index 3e20577..8b138cf 100644
@@ -34,15 +34,15 @@ do {									\
 	tlbmiss_handler_setup_pgd((unsigned long)(pgd));		\
 } while (0)
 
-
 #ifdef CONFIG_MIPS_PGD_C0_CONTEXT
 #define TLBMISS_HANDLER_SETUP()						\
 	do {								\
 		TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);		\
-		write_c0_xcontext((unsigned long) smp_processor_id() << 51); \
+		write_c0_xcontext((unsigned long) smp_processor_id() <<	\
+						SMP_CPUID_REGSHIFT);	\
 	} while (0)
 
-#else /* CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
+#else /* !CONFIG_MIPS_PGD_C0_CONTEXT: using  pgd_current*/
 
 /*
  * For the fast tlb miss handlers, we keep a per cpu array of pointers
@@ -51,18 +51,11 @@ do {									\
  */
 extern unsigned long pgd_current[];
 
-#ifdef CONFIG_32BIT
-#define TLBMISS_HANDLER_SETUP()						\
-	write_c0_context((unsigned long) smp_processor_id() << 25);	\
-	back_to_back_c0_hazard();					\
-	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
-#ifdef CONFIG_64BIT
 #define TLBMISS_HANDLER_SETUP()						\
-	write_c0_context((unsigned long) smp_processor_id() << 26);	\
+	write_c0_context((unsigned long) smp_processor_id() <<		\
+						SMP_CPUID_REGSHIFT);	\
 	back_to_back_c0_hazard();					\
 	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir)
-#endif
 #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/
 #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
 
arch/mips/include/asm/stackframe.h +6 -18
index a89d1b1..faefe31 100644
@@ -17,6 +17,7 @@
 #include <asm/asmmacro.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
 
 /*
  * For SMTC kernel, global IE should be left set, and interrupts
@@ -85,21 +86,8 @@
 		.endm
 
 #ifdef CONFIG_SMP
-#ifdef CONFIG_MIPS_MT_SMTC
-#define PTEBASE_SHIFT	19	/* TCBIND */
-#define CPU_ID_REG CP0_TCBIND
-#define CPU_ID_MFC0 mfc0
-#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
-#define PTEBASE_SHIFT	48	/* XCONTEXT */
-#define CPU_ID_REG CP0_XCONTEXT
-#define CPU_ID_MFC0 MFC0
-#else
-#define PTEBASE_SHIFT	23	/* CONTEXT */
-#define CPU_ID_REG CP0_CONTEXT
-#define CPU_ID_MFC0 MFC0
-#endif
 		.macro	get_saved_sp	/* SMP variation */
-		CPU_ID_MFC0	k0, CPU_ID_REG
+		ASM_CPUID_MFC0	k0, $SMP_CPUID_REG
 #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
 		lui	k1, %hi(kernelsp)
 #else
@@ -109,17 +97,17 @@
 		daddiu	k1, %hi(kernelsp)
 		dsll	k1, 16
 #endif
-		LONG_SRL	k0, PTEBASE_SHIFT
+		LONG_SRL	k0, SMP_CPUID_PTRSHIFT
 		LONG_ADDU	k1, k0
 		LONG_L	k1, %lo(kernelsp)(k1)
 		.endm
 
 		.macro	set_saved_sp stackp temp temp2
-		CPU_ID_MFC0	\temp, CPU_ID_REG
-		LONG_SRL	\temp, PTEBASE_SHIFT
+		ASM_CPUID_MFC0	\temp, $SMP_CPUID_REG
+		LONG_SRL	\temp, SMP_CPUID_PTRSHIFT
 		LONG_S	\stackp, kernelsp(\temp)
 		.endm
-#else
+#else /* !CONFIG_SMP */
 		.macro	get_saved_sp	/* Uniprocessor variation */
 #ifdef CONFIG_CPU_JUMP_WORKAROUNDS
 		/*
arch/mips/include/asm/thread_info.h +29 -1
index 61215a3..ddff267 100644
@@ -147,6 +147,34 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_ALLWORK_MASK	(_TIF_NOHZ | _TIF_WORK_MASK |		\
 				 _TIF_WORK_SYSCALL_EXIT)
 
-#endif /* __KERNEL__ */
+/*
+ * We stash processor id into a COP0 register to retrieve it fast
+ * at kernel exception entry.
+ */
+#if defined(CONFIG_MIPS_MT_SMTC)
+#define SMP_CPUID_REG		2, 2	/* TCBIND */
+#define SMP_CPUID_PTRSHIFT	19
+#elif defined(CONFIG_MIPS_PGD_C0_CONTEXT)
+#define SMP_CPUID_REG		20, 0	/* XCONTEXT */
+#define SMP_CPUID_PTRSHIFT	48
+#else
+#define SMP_CPUID_REG		4, 0	/* CONTEXT */
+#define SMP_CPUID_PTRSHIFT	23
+#endif
 
+#ifdef CONFIG_64BIT
+#define SMP_CPUID_REGSHIFT	(SMP_CPUID_PTRSHIFT + 3)
+#else
+#define SMP_CPUID_REGSHIFT	(SMP_CPUID_PTRSHIFT + 2)
+#endif
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#define ASM_CPUID_MFC0		mfc0
+#define UASM_i_CPUID_MFC0	uasm_i_mfc0
+#else
+#define ASM_CPUID_MFC0		MFC0
+#define UASM_i_CPUID_MFC0	UASM_i_MFC0
+#endif
+
+#endif /* __KERNEL__ */
 #endif /* _ASM_THREAD_INFO_H */
arch/mips/mm/tlbex.c +10 -65

114 lines not on this page · raw message

Signature · 1 line
1.7.9.5