Skip to content

Commit

Permalink
powerpc: Add TLB management code for 64-bit Book3E
Browse files Browse the repository at this point in the history
This adds the TLB miss handler assembly, the low level TLB flush routines
along with the necessary hook for dealing with our virtual page tables
or indirect TLB entries that need to be flushes when PTE pages are freed.

There is currently no support for hugetlbfs

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Benjamin Herrenschmidt committed Aug 20, 2009
1 parent a8f7758 commit 25d21ad
Show file tree
Hide file tree
Showing 10 changed files with 1,055 additions and 5 deletions.
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/mmu-40x.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ typedef struct {

#endif /* !__ASSEMBLY__ */

#define mmu_virtual_psize MMU_PAGE_4K
#define mmu_linear_psize MMU_PAGE_256M

#endif /* _ASM_POWERPC_MMU_40X_H_ */
6 changes: 6 additions & 0 deletions arch/powerpc/include/asm/mmu-44x.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,22 @@ typedef struct {

#if (PAGE_SHIFT == 12)
#define PPC44x_TLBE_SIZE PPC44x_TLB_4K
#define mmu_virtual_psize MMU_PAGE_4K
#elif (PAGE_SHIFT == 14)
#define PPC44x_TLBE_SIZE PPC44x_TLB_16K
#define mmu_virtual_psize MMU_PAGE_16K
#elif (PAGE_SHIFT == 16)
#define PPC44x_TLBE_SIZE PPC44x_TLB_64K
#define mmu_virtual_psize MMU_PAGE_64K
#elif (PAGE_SHIFT == 18)
#define PPC44x_TLBE_SIZE PPC44x_TLB_256K
#define mmu_virtual_psize MMU_PAGE_256K
#else
#error "Unsupported PAGE_SIZE"
#endif

#define mmu_linear_psize MMU_PAGE_256M

#define PPC44x_PGD_OFF_SHIFT (32 - PGDIR_SHIFT + PGD_T_LOG2)
#define PPC44x_PGD_OFF_MASK_BIT (PGDIR_SHIFT - PGD_T_LOG2)
#define PPC44x_PTE_ADD_SHIFT (32 - PGDIR_SHIFT + PTE_SHIFT + PTE_T_LOG2)
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/mmu-8xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,7 @@ typedef struct {
} mm_context_t;
#endif /* !__ASSEMBLY__ */

#define mmu_virtual_psize MMU_PAGE_4K
#define mmu_linear_psize MMU_PAGE_8M

#endif /* _ASM_POWERPC_MMU_8XX_H_ */
6 changes: 6 additions & 0 deletions arch/powerpc/include/asm/mmu-hash32.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,10 @@ typedef struct {

#endif /* !__ASSEMBLY__ */

/* We happily ignore the smaller BATs on 601, we don't actually use
* those definitions on hash32 at the moment anyway
*/
#define mmu_virtual_psize MMU_PAGE_4K
#define mmu_linear_psize MMU_PAGE_256M

#endif /* _ASM_POWERPC_MMU_HASH32_H_ */
8 changes: 8 additions & 0 deletions arch/powerpc/include/asm/mmu_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
tsk->thread.pgdir = next->pgd;
#endif /* CONFIG_PPC32 */

/* 64-bit Book3E keeps track of current PGD in the PACA */
#ifdef CONFIG_PPC_BOOK3E_64
get_paca()->pgd = next->pgd;
#endif
/* Nothing else to do if we aren't actually switching */
if (prev == next)
return;
Expand Down Expand Up @@ -89,6 +93,10 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next)
static inline void enter_lazy_tlb(struct mm_struct *mm,
struct task_struct *tsk)
{
/* 64-bit Book3E keeps track of current PGD in the PACA */
#ifdef CONFIG_PPC_BOOK3E_64
get_paca()->pgd = NULL;
#endif
}

#endif /* __KERNEL__ */
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/kernel/setup_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include <asm/udbg.h>
#include <asm/kexec.h>
#include <asm/swiotlb.h>
#include <asm/mmu_context.h>

#include "setup.h"

Expand Down Expand Up @@ -147,6 +148,9 @@ void __init setup_paca(int cpu)
{
local_paca = &paca[cpu];
mtspr(SPRN_SPRG_PACA, local_paca);
#ifdef CONFIG_PPC_BOOK3E
mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
#endif
}

/*
Expand Down
14 changes: 13 additions & 1 deletion arch/powerpc/mm/mmu_decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ static inline void _tlbil_pid(unsigned int pid)
#else /* CONFIG_40x || CONFIG_8xx */
extern void _tlbil_all(void);
extern void _tlbil_pid(unsigned int pid);
#ifdef CONFIG_PPC_BOOK3E
extern void _tlbil_pid_noind(unsigned int pid);
#else
#define _tlbil_pid_noind(pid) _tlbil_pid(pid)
#endif
#endif /* !(CONFIG_40x || CONFIG_8xx) */

/*
Expand All @@ -53,7 +57,10 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid,
{
asm volatile ("tlbie %0; sync" : : "r" (address) : "memory");
}
#else /* CONFIG_8xx */
#elif defined(CONFIG_PPC_BOOK3E)
extern void _tlbil_va(unsigned long address, unsigned int pid,
unsigned int tsize, unsigned int ind);
#else
extern void __tlbil_va(unsigned long address, unsigned int pid);
static inline void _tlbil_va(unsigned long address, unsigned int pid,
unsigned int tsize, unsigned int ind)
Expand All @@ -67,11 +74,16 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid,
* implementation. When that becomes the case, this will be
* an extern.
*/
#ifdef CONFIG_PPC_BOOK3E
extern void _tlbivax_bcast(unsigned long address, unsigned int pid,
unsigned int tsize, unsigned int ind);
#else
static inline void _tlbivax_bcast(unsigned long address, unsigned int pid,
unsigned int tsize, unsigned int ind)
{
BUG();
}
#endif

#else /* CONFIG_PPC_MMU_NOHASH */

Expand Down
Loading

0 comments on commit 25d21ad

Please sign in to comment.