Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182044
b: refs/heads/master
c: 325f8a0
h: refs/heads/master
v: v3
  • Loading branch information
David Daney authored and Ralf Baechle committed Feb 27, 2010
1 parent 565d95c commit 2f59e5e
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 36 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ef6c1fd662d18c0e2ed92825c8837e94b5ec3a1f
refs/heads/master: 325f8a0a31df567dbafafc48f8e60f3c1f101a46
12 changes: 0 additions & 12 deletions trunk/arch/mips/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,6 @@ typedef struct { unsigned long pte; } pte_t;
#endif
typedef struct page *pgtable_t;

/*
* For 3-level pagetables we defines these ourselves, for 2-level the
* definitions are supplied by <asm-generic/pgtable-nopmd.h>.
*/
#ifdef CONFIG_64BIT

typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) } )

#endif

/*
* Right now we don't support 4-level pagetables, so all pud-related
* definitions come from <asm-generic/pgtable-nopud.h>.
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/mips/include/asm/pgalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
*/
extern void pmd_init(unsigned long page, unsigned long pagetable);

#ifdef CONFIG_64BIT
#ifndef __PAGETABLE_PMD_FOLDED

static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
{
Expand Down Expand Up @@ -104,7 +104,7 @@ do { \
tlb_remove_page((tlb), pte); \
} while (0)

#ifdef CONFIG_64BIT
#ifndef __PAGETABLE_PMD_FOLDED

static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
{
Expand Down
36 changes: 34 additions & 2 deletions trunk/arch/mips/include/asm/pgtable-64.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
#include <asm/cachectl.h>
#include <asm/fixmap.h>

#ifdef CONFIG_PAGE_SIZE_64KB
#include <asm-generic/pgtable-nopmd.h>
#else
#include <asm-generic/pgtable-nopud.h>
#endif

/*
* Each address space has 2 4K pages as its page directory, giving 1024
Expand All @@ -37,13 +41,20 @@
* fault address - VMALLOC_START.
*/


/* PGDIR_SHIFT determines what a third-level page table entry can map */
#ifdef __PAGETABLE_PMD_FOLDED
#define PGDIR_SHIFT (PAGE_SHIFT + PAGE_SHIFT + PTE_ORDER - 3)
#else

/* PMD_SHIFT determines the size of the area a second-level page table can map */
#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))

/* PGDIR_SHIFT determines what a third-level page table entry can map */

#define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
#endif
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))

Expand Down Expand Up @@ -92,12 +103,14 @@
#ifdef CONFIG_PAGE_SIZE_64KB
#define PGD_ORDER 0
#define PUD_ORDER aieeee_attempt_to_allocate_pud
#define PMD_ORDER 0
#define PMD_ORDER aieeee_attempt_to_allocate_pmd
#define PTE_ORDER 0
#endif

#define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
#ifndef __PAGETABLE_PMD_FOLDED
#define PTRS_PER_PMD ((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t))
#endif
#define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))

#if PGDIR_SIZE >= TASK_SIZE
Expand All @@ -122,15 +135,30 @@

#define pte_ERROR(e) \
printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
#ifndef __PAGETABLE_PMD_FOLDED
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
#endif
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))

extern pte_t invalid_pte_table[PTRS_PER_PTE];
extern pte_t empty_bad_page_table[PTRS_PER_PTE];


#ifndef __PAGETABLE_PMD_FOLDED
/*
* For 3-level pagetables we defines these ourselves, for 2-level the
* definitions are supplied by <asm-generic/pgtable-nopmd.h>.
*/
typedef struct { unsigned long pmd; } pmd_t;
#define pmd_val(x) ((x).pmd)
#define __pmd(x) ((pmd_t) { (x) } )


extern pmd_t invalid_pmd_table[PTRS_PER_PMD];
extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD];
#endif

/*
* Empty pgd/pmd entries point to the invalid_pte_table.
Expand All @@ -151,6 +179,7 @@ static inline void pmd_clear(pmd_t *pmdp)
{
pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
}
#ifndef __PAGETABLE_PMD_FOLDED

/*
* Empty pud entries point to the invalid_pmd_table.
Expand All @@ -174,6 +203,7 @@ static inline void pud_clear(pud_t *pudp)
{
pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
}
#endif

#define pte_page(x) pfn_to_page(pte_pfn(x))

Expand All @@ -198,6 +228,7 @@ static inline void pud_clear(pud_t *pudp)
/* to find an entry in a page-table-directory */
#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))

#ifndef __PAGETABLE_PMD_FOLDED
static inline unsigned long pud_page_vaddr(pud_t pud)
{
return pud_val(pud);
Expand All @@ -210,6 +241,7 @@ static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address)
{
return (pmd_t *) pud_page_vaddr(*pud) + pmd_index(address);
}
#endif

/* Find an entry in the third-level page table.. */
#define __pte_offset(address) \
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
*/
#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0)

#ifdef CONFIG_64BIT
#ifndef __PAGETABLE_PMD_FOLDED
/*
* (puds are folded into pgds so this doesn't get actually called,
* but the define is needed for a generic inline function.)
Expand Down
4 changes: 4 additions & 0 deletions trunk/arch/mips/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,15 @@ void output_mm_defines(void)
DEFINE(_PTE_T_SIZE, sizeof(pte_t));
BLANK();
DEFINE(_PGD_T_LOG2, PGD_T_LOG2);
#ifndef __PAGETABLE_PMD_FOLDED
DEFINE(_PMD_T_LOG2, PMD_T_LOG2);
#endif
DEFINE(_PTE_T_LOG2, PTE_T_LOG2);
BLANK();
DEFINE(_PGD_ORDER, PGD_ORDER);
#ifndef __PAGETABLE_PMD_FOLDED
DEFINE(_PMD_ORDER, PMD_ORDER);
#endif
DEFINE(_PTE_ORDER, PTE_ORDER);
BLANK();
DEFINE(_PMD_SHIFT, PMD_SHIFT);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/mips/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ unsigned long pgd_current[NR_CPUS];
* will officially be retired.
*/
pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER);
#ifdef CONFIG_64BIT
#ifndef __PAGETABLE_PMD_FOLDED
pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER);
#endif
pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER);
44 changes: 27 additions & 17 deletions trunk/arch/mips/mm/pgtable-64.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,31 @@
void pgd_init(unsigned long page)
{
unsigned long *p, *end;
unsigned long entry;

#ifdef __PAGETABLE_PMD_FOLDED
entry = (unsigned long)invalid_pte_table;
#else
entry = (unsigned long)invalid_pmd_table;
#endif

p = (unsigned long *) page;
end = p + PTRS_PER_PGD;

while (p < end) {
p[0] = (unsigned long) invalid_pmd_table;
p[1] = (unsigned long) invalid_pmd_table;
p[2] = (unsigned long) invalid_pmd_table;
p[3] = (unsigned long) invalid_pmd_table;
p[4] = (unsigned long) invalid_pmd_table;
p[5] = (unsigned long) invalid_pmd_table;
p[6] = (unsigned long) invalid_pmd_table;
p[7] = (unsigned long) invalid_pmd_table;
p[0] = entry;
p[1] = entry;
p[2] = entry;
p[3] = entry;
p[4] = entry;
p[5] = entry;
p[6] = entry;
p[7] = entry;
p += 8;
}
}

#ifndef __PAGETABLE_PMD_FOLDED
void pmd_init(unsigned long addr, unsigned long pagetable)
{
unsigned long *p, *end;
Expand All @@ -40,17 +48,18 @@ void pmd_init(unsigned long addr, unsigned long pagetable)
end = p + PTRS_PER_PMD;

while (p < end) {
p[0] = (unsigned long)pagetable;
p[1] = (unsigned long)pagetable;
p[2] = (unsigned long)pagetable;
p[3] = (unsigned long)pagetable;
p[4] = (unsigned long)pagetable;
p[5] = (unsigned long)pagetable;
p[6] = (unsigned long)pagetable;
p[7] = (unsigned long)pagetable;
p[0] = pagetable;
p[1] = pagetable;
p[2] = pagetable;
p[3] = pagetable;
p[4] = pagetable;
p[5] = pagetable;
p[6] = pagetable;
p[7] = pagetable;
p += 8;
}
}
#endif

void __init pagetable_init(void)
{
Expand All @@ -59,8 +68,9 @@ void __init pagetable_init(void)

/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
#ifndef __PAGETABLE_PMD_FOLDED
pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table);

#endif
pgd_base = swapper_pg_dir;
/*
* Fixed mappings:
Expand Down
2 changes: 2 additions & 0 deletions trunk/arch/mips/mm/tlbex.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,11 +549,13 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,

uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3);
uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */
#ifndef __PAGETABLE_PMD_FOLDED
uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */
uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */
uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */
uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3);
uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */
#endif
}

/*
Expand Down

0 comments on commit 2f59e5e

Please sign in to comment.