diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-10-14 15:16:56 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2009-12-16 20:57:01 -0500 |
commit | 82622284dd2f8791f9759f3cef601520a8bc63b2 (patch) | |
tree | ee47f43af373d0c021cc83ff9e22925942e9d001 /arch/mips/include/asm | |
parent | 92078e0618f525e22945040b5daea21d4b6d4a16 (diff) |
MIPS: Put PGD in C0_CONTEXT for 64-bit R2 processors.
Processors that support the mips64r2 ISA can in four instructions
convert a shifted PGD pointer stored in the upper bits of c0_context
into a usable pointer. By doing this we save a memory load and
associated potential cache miss in the TLB exception handlers.
Since the upper bits of c0_context were holding the CPU number, we
move this to the upper bits of c0_xcontext which doesn't have enough
bits to hold the PGD pointer, but has plenty for the CPU number.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/include/asm')
-rw-r--r-- | arch/mips/include/asm/mmu_context.h | 29 | ||||
-rw-r--r-- | arch/mips/include/asm/stackframe.h | 20 |
2 files changed, 38 insertions, 11 deletions
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 6083db586500..145bb81ccaa5 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
@@ -24,6 +24,33 @@ | |||
24 | #endif /* SMTC */ | 24 | #endif /* SMTC */ |
25 | #include <asm-generic/mm_hooks.h> | 25 | #include <asm-generic/mm_hooks.h> |
26 | 26 | ||
27 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT | ||
28 | |||
29 | #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ | ||
30 | tlbmiss_handler_setup_pgd((unsigned long)(pgd)) | ||
31 | |||
32 | static inline void tlbmiss_handler_setup_pgd(unsigned long pgd) | ||
33 | { | ||
34 | /* Check for swapper_pg_dir and convert to physical address. */ | ||
35 | if ((pgd & CKSEG3) == CKSEG0) | ||
36 | pgd = CPHYSADDR(pgd); | ||
37 | write_c0_context(pgd << 11); | ||
38 | } | ||
39 | |||
40 | #define TLBMISS_HANDLER_SETUP() \ | ||
41 | do { \ | ||
42 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir); \ | ||
43 | write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ | ||
44 | } while (0) | ||
45 | |||
46 | |||
47 | static inline unsigned long get_current_pgd(void) | ||
48 | { | ||
49 | return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL); | ||
50 | } | ||
51 | |||
52 | #else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ | ||
53 | |||
27 | /* | 54 | /* |
28 | * For the fast tlb miss handlers, we keep a per cpu array of pointers | 55 | * For the fast tlb miss handlers, we keep a per cpu array of pointers |
29 | * to the current pgd for each processor. Also, the proc. id is stuffed | 56 | * to the current pgd for each processor. Also, the proc. id is stuffed |
@@ -46,7 +73,7 @@ extern unsigned long pgd_current[]; | |||
46 | back_to_back_c0_hazard(); \ | 73 | back_to_back_c0_hazard(); \ |
47 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) | 74 | TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir) |
48 | #endif | 75 | #endif |
49 | 76 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ | |
50 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 77 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
51 | 78 | ||
52 | #define ASID_INC 0x40 | 79 | #define ASID_INC 0x40 |
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h index dd7e220e087b..3b6da3330e32 100644 --- a/arch/mips/include/asm/stackframe.h +++ b/arch/mips/include/asm/stackframe.h | |||
@@ -87,15 +87,19 @@ | |||
87 | #ifdef CONFIG_SMP | 87 | #ifdef CONFIG_SMP |
88 | #ifdef CONFIG_MIPS_MT_SMTC | 88 | #ifdef CONFIG_MIPS_MT_SMTC |
89 | #define PTEBASE_SHIFT 19 /* TCBIND */ | 89 | #define PTEBASE_SHIFT 19 /* TCBIND */ |
90 | #define CPU_ID_REG CP0_TCBIND | ||
91 | #define CPU_ID_MFC0 mfc0 | ||
92 | #elif defined(CONFIG_MIPS_PGD_C0_CONTEXT) | ||
93 | #define PTEBASE_SHIFT 48 /* XCONTEXT */ | ||
94 | #define CPU_ID_REG CP0_XCONTEXT | ||
95 | #define CPU_ID_MFC0 MFC0 | ||
90 | #else | 96 | #else |
91 | #define PTEBASE_SHIFT 23 /* CONTEXT */ | 97 | #define PTEBASE_SHIFT 23 /* CONTEXT */ |
98 | #define CPU_ID_REG CP0_CONTEXT | ||
99 | #define CPU_ID_MFC0 MFC0 | ||
92 | #endif | 100 | #endif |
93 | .macro get_saved_sp /* SMP variation */ | 101 | .macro get_saved_sp /* SMP variation */ |
94 | #ifdef CONFIG_MIPS_MT_SMTC | 102 | CPU_ID_MFC0 k0, CPU_ID_REG |
95 | mfc0 k0, CP0_TCBIND | ||
96 | #else | ||
97 | MFC0 k0, CP0_CONTEXT | ||
98 | #endif | ||
99 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) | 103 | #if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32) |
100 | lui k1, %hi(kernelsp) | 104 | lui k1, %hi(kernelsp) |
101 | #else | 105 | #else |
@@ -111,11 +115,7 @@ | |||
111 | .endm | 115 | .endm |
112 | 116 | ||
113 | .macro set_saved_sp stackp temp temp2 | 117 | .macro set_saved_sp stackp temp temp2 |
114 | #ifdef CONFIG_MIPS_MT_SMTC | 118 | CPU_ID_MFC0 \temp, CPU_ID_REG |
115 | mfc0 \temp, CP0_TCBIND | ||
116 | #else | ||
117 | MFC0 \temp, CP0_CONTEXT | ||
118 | #endif | ||
119 | LONG_SRL \temp, PTEBASE_SHIFT | 119 | LONG_SRL \temp, PTEBASE_SHIFT |
120 | LONG_S \stackp, kernelsp(\temp) | 120 | LONG_S \stackp, kernelsp(\temp) |
121 | .endm | 121 | .endm |