diff options
author | David Daney <ddaney@caviumnetworks.com> | 2009-12-04 16:52:36 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-02-27 06:53:03 -0500 |
commit | 325f8a0a31df567dbafafc48f8e60f3c1f101a46 (patch) | |
tree | b36383f4d483ecc6d057cdd41ef50b6403e89b9c /arch/mips/mm | |
parent | ef6c1fd662d18c0e2ed92825c8837e94b5ec3a1f (diff) |
MIPS: Two-level pagetables for 64-bit kernels with 64KB pages.
For 64-bit kernels with 64KB pages and two level page tables, there are
42 bits worth of virtual address space This is larger than the 40 bits of
virtual address space obtained with the default 4KB Page size and three
levels, so there are no draw backs for using two level tables with this
configuration.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
Cc: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/761/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/init.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/pgtable-64.c | 44 | ||||
-rw-r--r-- | arch/mips/mm/tlbex.c | 2 |
3 files changed, 30 insertions, 18 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 1651942f7feb..3c5b7de10af5 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -477,7 +477,7 @@ unsigned long pgd_current[NR_CPUS]; | |||
477 | * will officially be retired. | 477 | * will officially be retired. |
478 | */ | 478 | */ |
479 | pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); | 479 | pgd_t swapper_pg_dir[_PTRS_PER_PGD] __page_aligned(_PGD_ORDER); |
480 | #ifdef CONFIG_64BIT | 480 | #ifndef __PAGETABLE_PMD_FOLDED |
481 | pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER); | 481 | pmd_t invalid_pmd_table[PTRS_PER_PMD] __page_aligned(PMD_ORDER); |
482 | #endif | 482 | #endif |
483 | pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER); | 483 | pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned(PTE_ORDER); |
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 1121019fa456..78eaa4f0b0ec 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c | |||
@@ -15,23 +15,31 @@ | |||
15 | void pgd_init(unsigned long page) | 15 | void pgd_init(unsigned long page) |
16 | { | 16 | { |
17 | unsigned long *p, *end; | 17 | unsigned long *p, *end; |
18 | unsigned long entry; | ||
19 | |||
20 | #ifdef __PAGETABLE_PMD_FOLDED | ||
21 | entry = (unsigned long)invalid_pte_table; | ||
22 | #else | ||
23 | entry = (unsigned long)invalid_pmd_table; | ||
24 | #endif | ||
18 | 25 | ||
19 | p = (unsigned long *) page; | 26 | p = (unsigned long *) page; |
20 | end = p + PTRS_PER_PGD; | 27 | end = p + PTRS_PER_PGD; |
21 | 28 | ||
22 | while (p < end) { | 29 | while (p < end) { |
23 | p[0] = (unsigned long) invalid_pmd_table; | 30 | p[0] = entry; |
24 | p[1] = (unsigned long) invalid_pmd_table; | 31 | p[1] = entry; |
25 | p[2] = (unsigned long) invalid_pmd_table; | 32 | p[2] = entry; |
26 | p[3] = (unsigned long) invalid_pmd_table; | 33 | p[3] = entry; |
27 | p[4] = (unsigned long) invalid_pmd_table; | 34 | p[4] = entry; |
28 | p[5] = (unsigned long) invalid_pmd_table; | 35 | p[5] = entry; |
29 | p[6] = (unsigned long) invalid_pmd_table; | 36 | p[6] = entry; |
30 | p[7] = (unsigned long) invalid_pmd_table; | 37 | p[7] = entry; |
31 | p += 8; | 38 | p += 8; |
32 | } | 39 | } |
33 | } | 40 | } |
34 | 41 | ||
42 | #ifndef __PAGETABLE_PMD_FOLDED | ||
35 | void pmd_init(unsigned long addr, unsigned long pagetable) | 43 | void pmd_init(unsigned long addr, unsigned long pagetable) |
36 | { | 44 | { |
37 | unsigned long *p, *end; | 45 | unsigned long *p, *end; |
@@ -40,17 +48,18 @@ void pmd_init(unsigned long addr, unsigned long pagetable) | |||
40 | end = p + PTRS_PER_PMD; | 48 | end = p + PTRS_PER_PMD; |
41 | 49 | ||
42 | while (p < end) { | 50 | while (p < end) { |
43 | p[0] = (unsigned long)pagetable; | 51 | p[0] = pagetable; |
44 | p[1] = (unsigned long)pagetable; | 52 | p[1] = pagetable; |
45 | p[2] = (unsigned long)pagetable; | 53 | p[2] = pagetable; |
46 | p[3] = (unsigned long)pagetable; | 54 | p[3] = pagetable; |
47 | p[4] = (unsigned long)pagetable; | 55 | p[4] = pagetable; |
48 | p[5] = (unsigned long)pagetable; | 56 | p[5] = pagetable; |
49 | p[6] = (unsigned long)pagetable; | 57 | p[6] = pagetable; |
50 | p[7] = (unsigned long)pagetable; | 58 | p[7] = pagetable; |
51 | p += 8; | 59 | p += 8; |
52 | } | 60 | } |
53 | } | 61 | } |
62 | #endif | ||
54 | 63 | ||
55 | void __init pagetable_init(void) | 64 | void __init pagetable_init(void) |
56 | { | 65 | { |
@@ -59,8 +68,9 @@ void __init pagetable_init(void) | |||
59 | 68 | ||
60 | /* Initialize the entire pgd. */ | 69 | /* Initialize the entire pgd. */ |
61 | pgd_init((unsigned long)swapper_pg_dir); | 70 | pgd_init((unsigned long)swapper_pg_dir); |
71 | #ifndef __PAGETABLE_PMD_FOLDED | ||
62 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); | 72 | pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); |
63 | 73 | #endif | |
64 | pgd_base = swapper_pg_dir; | 74 | pgd_base = swapper_pg_dir; |
65 | /* | 75 | /* |
66 | * Fixed mappings: | 76 | * Fixed mappings: |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index badcf5e8d695..eae45f0f9a16 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -549,11 +549,13 @@ build_get_pmde64(u32 **p, struct uasm_label **l, struct uasm_reloc **r, | |||
549 | 549 | ||
550 | uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); | 550 | uasm_i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); |
551 | uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ | 551 | uasm_i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ |
552 | #ifndef __PAGETABLE_PMD_FOLDED | ||
552 | uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ | 553 | uasm_i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ |
553 | uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */ | 554 | uasm_i_ld(p, ptr, 0, ptr); /* get pmd pointer */ |
554 | uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */ | 555 | uasm_i_dsrl(p, tmp, tmp, PMD_SHIFT-3); /* get pmd offset in bytes */ |
555 | uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3); | 556 | uasm_i_andi(p, tmp, tmp, (PTRS_PER_PMD - 1)<<3); |
556 | uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */ | 557 | uasm_i_daddu(p, ptr, ptr, tmp); /* add in pmd offset */ |
558 | #endif | ||
557 | } | 559 | } |
558 | 560 | ||
559 | /* | 561 | /* |