[PATCH v4 1/4] powerpc: Introduce local (non-broadcast) forms of tlb invalidates

2008-09-12 Thread Kumar Gala
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

Re: [PATCH v4 1/4] powerpc: Introduce local (non-broadcast) forms of tlb invalidates

2008-09-13 Thread Benjamin Herrenschmidt

>  static inline void flush_tlb_range(struct vm_area_struct *vma,
>  unsigned long start, unsigned long end)
>  {
> - _tlbia();
> + _tlbil_all();
>  }

Why not the _pid() variant here ?

> +/*
> + * Flush MMU TLB for a particular process id, but only on the local processor
> + * (no broadcast)
> + */
> +_GLOBAL(_tlbil_pid)
> + li  r3,(MMUCSR0_TLBFI)@l
> + mtspr   SPRN_MMUCSR0, r3
> +1:
> + mfspr   r3,SPRN_MMUCSR0
> + andi.   r3,r3,[EMAIL PROTECTED]
> + bne 1b
> + blr

This will do a full inval of the TLB right ? Might be worth mentioning
this implementation limitation in a comment..

Cheers,
Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev