Introduced a new set of low level tlb invalidate functions that do not
broadcast invalidates on the bus:
_tlbil_all - invalidate all
_tlbil_pid - invalidate based on process id (or mm context)
_tlbil_va - invalidate based on virtual address (ea + pid)
On non-SMP configs _tlbil_all should be functionally equivalent to _tlbia and
_tlbil_va should be functionally equivalent to _tlbie.
The intent of this change is to handle SMP based invalidates via IPIs instead
of broadcasts as the mechanism scales better for larger number of cores.
On e500 (fsl-booke mmu) based cores move to using MMUCSR for invalidate alls
and tlbsx/tlbwe for invalidate virtual address.
Signed-off-by: Kumar Gala <[EMAIL PROTECTED]>
---
arch/powerpc/include/asm/reg_booke.h |7
arch/powerpc/include/asm/tlbflush.h | 13 +---
arch/powerpc/kernel/misc_32.S| 52 ++
arch/powerpc/kernel/ppc_ksyms.c |3 ++
4 files changed, 70 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/reg_booke.h
b/arch/powerpc/include/asm/reg_booke.h
index be980f4..6745376 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -109,6 +109,7 @@
#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */
#define SPRN_L1CSR00x3F2 /* L1 Cache Control and Status Register 0 */
#define SPRN_L1CSR10x3F3 /* L1 Cache Control and Status Register 1 */
+#define SPRN_MMUCSR0 0x3F4 /* MMU Control and Status Register 0 */
#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
#define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */
#define SPRN_L2CSR00x3F9 /* L2 Data Cache Control and Status Register 0
*/
@@ -410,6 +411,12 @@
#define L2CSR0_L2LOA 0x0080 /* L2 Cache Lock Overflow Allocate */
#define L2CSR0_L2LO0x0020 /* L2 Cache Lock Overflow */
+/* Bit definitions for MMUCSR0 */
+#define MMUCSR0_TLB1FI 0x0002 /* TLB1 Flash invalidate */
+#define MMUCSR0_TLB0FI 0x0004 /* TLB0 Flash invalidate */
+#define MMUCSR0_TLB2FI 0x0040 /* TLB2 Flash invalidate */
+#define MMUCSR0_TLB3FI 0x0020 /* TLB3 Flash invalidate */
+
/* Bit definitions for SGR. */
#define SGR_NORMAL 0 /* Speculative fetching allowed. */
#define SGR_GUARDED1 /* Speculative fetching disallowed. */
diff --git a/arch/powerpc/include/asm/tlbflush.h
b/arch/powerpc/include/asm/tlbflush.h
index 361cd5c..2639559 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -29,6 +29,9 @@
#include
extern void _tlbie(unsigned long address, unsigned int pid);
+extern void _tlbil_all(void);
+extern void _tlbil_pid(unsigned int pid);
+extern void _tlbil_va(unsigned long address, unsigned int pid);
#if defined(CONFIG_40x) || defined(CONFIG_8xx)
#define _tlbia() asm volatile ("tlbia; sync" : : : "memory")
@@ -38,31 +41,31 @@ extern void _tlbia(void);
static inline void flush_tlb_mm(struct mm_struct *mm)
{
- _tlbia();
+ _tlbil_pid(mm->context.id);
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long vmaddr)
{
- _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
+ _tlbil_va(vmaddr, vma ? vma->vm_mm->context.id : 0);
}
static inline void flush_tlb_page_nohash(struct vm_area_struct *vma,
unsigned long vmaddr)
{
- _tlbie(vmaddr, vma ? vma->vm_mm->context.id : 0);
+ flush_tlb_page(vma, vmaddr);
}
static inline void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- _tlbia();
+ _tlbil_all();
}
static inline void flush_tlb_kernel_range(unsigned long start,
unsigned long end)
{
- _tlbia();
+ _tlbil_all();
}
#elif defined(CONFIG_PPC32)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 7a6dfbc..430bbce 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -274,6 +274,9 @@ _GLOBAL(real_writeb)
/*
* Flush MMU TLB
*/
+#ifndef CONFIG_FSL_BOOKE
+_GLOBAL(_tlbil_all)
+#endif
_GLOBAL(_tlbia)
#if defined(CONFIG_40x)
sync/* Flush to memory before changing mapping */
@@ -344,6 +347,9 @@ _GLOBAL(_tlbia)
/*
* Flush MMU TLB for a particular address
*/
+#ifndef CONFIG_FSL_BOOKE
+_GLOBAL(_tlbil_va)
+#endif
_GLOBAL(_tlbie)
#if defined(CONFIG_40x)
/* We run the search with interrupts disabled because we have to change
@@ -436,6 +442,52 @@ _GLOBAL(_tlbie)
#endif /* ! CONFIG_40x */
blr
+#if defined(CONFIG_FSL_BOOKE)
+/*
+ * Flush MMU TLB, but only on the local processor (no broadcast)
+ */
+_GLOBAL(_tlbil_all)
+#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
+MMUCSR0_TLB2FI | MMUCSR0_TLB