diff options
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/page.h | 12 | ||||
-rw-r--r-- | arch/mips/include/asm/pgalloc.h | 4 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable-64.h | 36 | ||||
-rw-r--r-- | arch/mips/include/asm/pgtable.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/asm-offsets.c | 4 | ||||
-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 |
8 files changed, 71 insertions, 35 deletions
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index f266295cce51..ac32572430f4 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -107,18 +107,6 @@ typedef struct { unsigned long pte; } pte_t; | |||
107 | typedef struct page *pgtable_t; | 107 | typedef struct page *pgtable_t; |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * For 3-level pagetables we defines these ourselves, for 2-level the | ||
111 | * definitions are supplied by <asm-generic/pgtable-nopmd.h>. | ||
112 | */ | ||
113 | #ifdef CONFIG_64BIT | ||
114 | |||
115 | typedef struct { unsigned long pmd; } pmd_t; | ||
116 | #define pmd_val(x) ((x).pmd) | ||
117 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
118 | |||
119 | #endif | ||
120 | |||
121 | /* | ||
122 | * Right now we don't support 4-level pagetables, so all pud-related | 110 | * Right now we don't support 4-level pagetables, so all pud-related |
123 | * definitions come from <asm-generic/pgtable-nopud.h>. | 111 | * definitions come from <asm-generic/pgtable-nopud.h>. |
124 | */ | 112 | */ |
diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 3738f4b48cbd..881d18b4e298 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h | |||
@@ -31,7 +31,7 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, | |||
31 | */ | 31 | */ |
32 | extern void pmd_init(unsigned long page, unsigned long pagetable); | 32 | extern void pmd_init(unsigned long page, unsigned long pagetable); |
33 | 33 | ||
34 | #ifdef CONFIG_64BIT | 34 | #ifndef __PAGETABLE_PMD_FOLDED |
35 | 35 | ||
36 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | 36 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) |
37 | { | 37 | { |
@@ -104,7 +104,7 @@ do { \ | |||
104 | tlb_remove_page((tlb), pte); \ | 104 | tlb_remove_page((tlb), pte); \ |
105 | } while (0) | 105 | } while (0) |
106 | 106 | ||
107 | #ifdef CONFIG_64BIT | 107 | #ifndef __PAGETABLE_PMD_FOLDED |
108 | 108 | ||
109 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) | 109 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) |
110 | { | 110 | { |
diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h index 8eda30b467da..24314d21a708 100644 --- a/arch/mips/include/asm/pgtable-64.h +++ b/arch/mips/include/asm/pgtable-64.h | |||
@@ -16,7 +16,11 @@ | |||
16 | #include <asm/cachectl.h> | 16 | #include <asm/cachectl.h> |
17 | #include <asm/fixmap.h> | 17 | #include <asm/fixmap.h> |
18 | 18 | ||
19 | #ifdef CONFIG_PAGE_SIZE_64KB | ||
20 | #include <asm-generic/pgtable-nopmd.h> | ||
21 | #else | ||
19 | #include <asm-generic/pgtable-nopud.h> | 22 | #include <asm-generic/pgtable-nopud.h> |
23 | #endif | ||
20 | 24 | ||
21 | /* | 25 | /* |
22 | * Each address space has 2 4K pages as its page directory, giving 1024 | 26 | * Each address space has 2 4K pages as its page directory, giving 1024 |
@@ -37,13 +41,20 @@ | |||
37 | * fault address - VMALLOC_START. | 41 | * fault address - VMALLOC_START. |
38 | */ | 42 | */ |
39 | 43 | ||
44 | |||
45 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | ||
46 | #ifdef __PAGETABLE_PMD_FOLDED | ||
47 | #define PGDIR_SHIFT (PAGE_SHIFT + PAGE_SHIFT + PTE_ORDER - 3) | ||
48 | #else | ||
49 | |||
40 | /* PMD_SHIFT determines the size of the area a second-level page table can map */ | 50 | /* PMD_SHIFT determines the size of the area a second-level page table can map */ |
41 | #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3)) | 51 | #define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3)) |
42 | #define PMD_SIZE (1UL << PMD_SHIFT) | 52 | #define PMD_SIZE (1UL << PMD_SHIFT) |
43 | #define PMD_MASK (~(PMD_SIZE-1)) | 53 | #define PMD_MASK (~(PMD_SIZE-1)) |
44 | 54 | ||
45 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | 55 | |
46 | #define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3)) | 56 | #define PGDIR_SHIFT (PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3)) |
57 | #endif | ||
47 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | 58 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) |
48 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | 59 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) |
49 | 60 | ||
@@ -92,12 +103,14 @@ | |||
92 | #ifdef CONFIG_PAGE_SIZE_64KB | 103 | #ifdef CONFIG_PAGE_SIZE_64KB |
93 | #define PGD_ORDER 0 | 104 | #define PGD_ORDER 0 |
94 | #define PUD_ORDER aieeee_attempt_to_allocate_pud | 105 | #define PUD_ORDER aieeee_attempt_to_allocate_pud |
95 | #define PMD_ORDER 0 | 106 | #define PMD_ORDER aieeee_attempt_to_allocate_pmd |
96 | #define PTE_ORDER 0 | 107 | #define PTE_ORDER 0 |
97 | #endif | 108 | #endif |
98 | 109 | ||
99 | #define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t)) | 110 | #define PTRS_PER_PGD ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t)) |
111 | #ifndef __PAGETABLE_PMD_FOLDED | ||
100 | #define PTRS_PER_PMD ((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t)) | 112 | #define PTRS_PER_PMD ((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t)) |
113 | #endif | ||
101 | #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) | 114 | #define PTRS_PER_PTE ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t)) |
102 | 115 | ||
103 | #if PGDIR_SIZE >= TASK_SIZE | 116 | #if PGDIR_SIZE >= TASK_SIZE |
@@ -122,15 +135,30 @@ | |||
122 | 135 | ||
123 | #define pte_ERROR(e) \ | 136 | #define pte_ERROR(e) \ |
124 | printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) | 137 | printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) |
138 | #ifndef __PAGETABLE_PMD_FOLDED | ||
125 | #define pmd_ERROR(e) \ | 139 | #define pmd_ERROR(e) \ |
126 | printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) | 140 | printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e)) |
141 | #endif | ||
127 | #define pgd_ERROR(e) \ | 142 | #define pgd_ERROR(e) \ |
128 | printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) | 143 | printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e)) |
129 | 144 | ||
130 | extern pte_t invalid_pte_table[PTRS_PER_PTE]; | 145 | extern pte_t invalid_pte_table[PTRS_PER_PTE]; |
131 | extern pte_t empty_bad_page_table[PTRS_PER_PTE]; | 146 | extern pte_t empty_bad_page_table[PTRS_PER_PTE]; |
147 | |||
148 | |||
149 | #ifndef __PAGETABLE_PMD_FOLDED | ||
150 | /* | ||
151 | * For 3-level pagetables we defines these ourselves, for 2-level the | ||
152 | * definitions are supplied by <asm-generic/pgtable-nopmd.h>. | ||
153 | */ | ||
154 | typedef struct { unsigned long pmd; } pmd_t; | ||
155 | #define pmd_val(x) ((x).pmd) | ||
156 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
157 | |||
158 | |||
132 | extern pmd_t invalid_pmd_table[PTRS_PER_PMD]; | 159 | extern pmd_t invalid_pmd_table[PTRS_PER_PMD]; |
133 | extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD]; | 160 | extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD]; |
161 | #endif | ||
134 | 162 | ||
135 | /* | 163 | /* |
136 | * Empty pgd/pmd entries point to the invalid_pte_table. | 164 | * Empty pgd/pmd entries point to the invalid_pte_table. |
@@ -151,6 +179,7 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
151 | { | 179 | { |
152 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); | 180 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); |
153 | } | 181 | } |
182 | #ifndef __PAGETABLE_PMD_FOLDED | ||
154 | 183 | ||
155 | /* | 184 | /* |
156 | * Empty pud entries point to the invalid_pmd_table. | 185 | * Empty pud entries point to the invalid_pmd_table. |
@@ -174,6 +203,7 @@ static inline void pud_clear(pud_t *pudp) | |||
174 | { | 203 | { |
175 | pud_val(*pudp) = ((unsigned long) invalid_pmd_table); | 204 | pud_val(*pudp) = ((unsigned long) invalid_pmd_table); |
176 | } | 205 | } |
206 | #endif | ||
177 | 207 | ||
178 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 208 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
179 | 209 | ||
@@ -198,6 +228,7 @@ static inline void pud_clear(pud_t *pudp) | |||
198 | /* to find an entry in a page-table-directory */ | 228 | /* to find an entry in a page-table-directory */ |
199 | #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) | 229 | #define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) |
200 | 230 | ||
231 | #ifndef __PAGETABLE_PMD_FOLDED | ||
201 | static inline unsigned long pud_page_vaddr(pud_t pud) | 232 | static inline unsigned long pud_page_vaddr(pud_t pud) |
202 | { | 233 | { |
203 | return pud_val(pud); | 234 | return pud_val(pud); |
@@ -210,6 +241,7 @@ static inline pmd_t *pmd_offset(pud_t * pud, unsigned long address) | |||
210 | { | 241 | { |
211 | return (pmd_t *) pud_page_vaddr(*pud) + pmd_index(address); | 242 | return (pmd_t *) pud_page_vaddr(*pud) + pmd_index(address); |
212 | } | 243 | } |
244 | #endif | ||
213 | 245 | ||
214 | /* Find an entry in the third-level page table.. */ | 246 | /* Find an entry in the third-level page table.. */ |
215 | #define __pte_offset(address) \ | 247 | #define __pte_offset(address) \ |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 1854336e56a2..02335fda9e77 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -177,7 +177,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
177 | */ | 177 | */ |
178 | #define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0) | 178 | #define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while(0) |
179 | 179 | ||
180 | #ifdef CONFIG_64BIT | 180 | #ifndef __PAGETABLE_PMD_FOLDED |
181 | /* | 181 | /* |
182 | * (puds are folded into pgds so this doesn't get actually called, | 182 | * (puds are folded into pgds so this doesn't get actually called, |
183 | * but the define is needed for a generic inline function.) | 183 | * but the define is needed for a generic inline function.) |
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 2c1e1d02338b..ca6c83218caa 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -188,11 +188,15 @@ void output_mm_defines(void) | |||
188 | DEFINE(_PTE_T_SIZE, sizeof(pte_t)); | 188 | DEFINE(_PTE_T_SIZE, sizeof(pte_t)); |
189 | BLANK(); | 189 | BLANK(); |
190 | DEFINE(_PGD_T_LOG2, PGD_T_LOG2); | 190 | DEFINE(_PGD_T_LOG2, PGD_T_LOG2); |
191 | #ifndef __PAGETABLE_PMD_FOLDED | ||
191 | DEFINE(_PMD_T_LOG2, PMD_T_LOG2); | 192 | DEFINE(_PMD_T_LOG2, PMD_T_LOG2); |
193 | #endif | ||
192 | DEFINE(_PTE_T_LOG2, PTE_T_LOG2); | 194 | DEFINE(_PTE_T_LOG2, PTE_T_LOG2); |
193 | BLANK(); | 195 | BLANK(); |
194 | DEFINE(_PGD_ORDER, PGD_ORDER); | 196 | DEFINE(_PGD_ORDER, PGD_ORDER); |
197 | #ifndef __PAGETABLE_PMD_FOLDED | ||
195 | DEFINE(_PMD_ORDER, PMD_ORDER); | 198 | DEFINE(_PMD_ORDER, PMD_ORDER); |
199 | #endif | ||
196 | DEFINE(_PTE_ORDER, PTE_ORDER); | 200 | DEFINE(_PTE_ORDER, PTE_ORDER); |
197 | BLANK(); | 201 | BLANK(); |
198 | DEFINE(_PMD_SHIFT, PMD_SHIFT); | 202 | DEFINE(_PMD_SHIFT, PMD_SHIFT); |
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 | /* |