diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/parisc/Kconfig | 5 | ||||
-rw-r--r-- | arch/parisc/include/asm/pgalloc.h | 2 | ||||
-rw-r--r-- | arch/parisc/include/asm/pgtable.h | 16 | ||||
-rw-r--r-- | arch/parisc/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/parisc/kernel/head.S | 4 | ||||
-rw-r--r-- | arch/parisc/mm/init.c | 2 |
6 files changed, 18 insertions, 15 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 8014727a2743..c36546959e86 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -103,6 +103,11 @@ config ARCH_MAY_HAVE_PC_FDC | |||
103 | depends on BROKEN | 103 | depends on BROKEN |
104 | default y | 104 | default y |
105 | 105 | ||
106 | config PGTABLE_LEVELS | ||
107 | int | ||
108 | default 3 if 64BIT && PARISC_PAGE_SIZE_4KB | ||
109 | default 2 | ||
110 | |||
106 | source "init/Kconfig" | 111 | source "init/Kconfig" |
107 | 112 | ||
108 | source "kernel/Kconfig.freezer" | 113 | source "kernel/Kconfig.freezer" |
diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h index d17437238a2c..1ba29369257c 100644 --- a/arch/parisc/include/asm/pgalloc.h +++ b/arch/parisc/include/asm/pgalloc.h | |||
@@ -51,7 +51,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
51 | free_pages((unsigned long)pgd, PGD_ALLOC_ORDER); | 51 | free_pages((unsigned long)pgd, PGD_ALLOC_ORDER); |
52 | } | 52 | } |
53 | 53 | ||
54 | #if PT_NLEVELS == 3 | 54 | #if CONFIG_PGTABLE_LEVELS == 3 |
55 | 55 | ||
56 | /* Three Level Page Table Support for pmd's */ | 56 | /* Three Level Page Table Support for pmd's */ |
57 | 57 | ||
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 15207b9362bf..0a183756d6ec 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h | |||
@@ -68,13 +68,11 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); | |||
68 | #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ | 68 | #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ |
69 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) | 69 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) |
70 | 70 | ||
71 | #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) | 71 | #if CONFIG_PGTABLE_LEVELS == 3 |
72 | #define PT_NLEVELS 3 | ||
73 | #define PGD_ORDER 1 /* Number of pages per pgd */ | 72 | #define PGD_ORDER 1 /* Number of pages per pgd */ |
74 | #define PMD_ORDER 1 /* Number of pages per pmd */ | 73 | #define PMD_ORDER 1 /* Number of pages per pmd */ |
75 | #define PGD_ALLOC_ORDER 2 /* first pgd contains pmd */ | 74 | #define PGD_ALLOC_ORDER 2 /* first pgd contains pmd */ |
76 | #else | 75 | #else |
77 | #define PT_NLEVELS 2 | ||
78 | #define PGD_ORDER 1 /* Number of pages per pgd */ | 76 | #define PGD_ORDER 1 /* Number of pages per pgd */ |
79 | #define PGD_ALLOC_ORDER PGD_ORDER | 77 | #define PGD_ALLOC_ORDER PGD_ORDER |
80 | #endif | 78 | #endif |
@@ -93,7 +91,7 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); | |||
93 | #define PMD_SHIFT (PLD_SHIFT + BITS_PER_PTE) | 91 | #define PMD_SHIFT (PLD_SHIFT + BITS_PER_PTE) |
94 | #define PMD_SIZE (1UL << PMD_SHIFT) | 92 | #define PMD_SIZE (1UL << PMD_SHIFT) |
95 | #define PMD_MASK (~(PMD_SIZE-1)) | 93 | #define PMD_MASK (~(PMD_SIZE-1)) |
96 | #if PT_NLEVELS == 3 | 94 | #if CONFIG_PGTABLE_LEVELS == 3 |
97 | #define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY) | 95 | #define BITS_PER_PMD (PAGE_SHIFT + PMD_ORDER - BITS_PER_PMD_ENTRY) |
98 | #else | 96 | #else |
99 | #define __PAGETABLE_PMD_FOLDED | 97 | #define __PAGETABLE_PMD_FOLDED |
@@ -277,7 +275,7 @@ extern unsigned long *empty_zero_page; | |||
277 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) | 275 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) |
278 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) | 276 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) |
279 | 277 | ||
280 | #if PT_NLEVELS == 3 | 278 | #if CONFIG_PGTABLE_LEVELS == 3 |
281 | /* The first entry of the permanent pmd is not there if it contains | 279 | /* The first entry of the permanent pmd is not there if it contains |
282 | * the gateway marker */ | 280 | * the gateway marker */ |
283 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) | 281 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) |
@@ -287,7 +285,7 @@ extern unsigned long *empty_zero_page; | |||
287 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) | 285 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) |
288 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) | 286 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) |
289 | static inline void pmd_clear(pmd_t *pmd) { | 287 | static inline void pmd_clear(pmd_t *pmd) { |
290 | #if PT_NLEVELS == 3 | 288 | #if CONFIG_PGTABLE_LEVELS == 3 |
291 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) | 289 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) |
292 | /* This is the entry pointing to the permanent pmd | 290 | /* This is the entry pointing to the permanent pmd |
293 | * attached to the pgd; cannot clear it */ | 291 | * attached to the pgd; cannot clear it */ |
@@ -299,7 +297,7 @@ static inline void pmd_clear(pmd_t *pmd) { | |||
299 | 297 | ||
300 | 298 | ||
301 | 299 | ||
302 | #if PT_NLEVELS == 3 | 300 | #if CONFIG_PGTABLE_LEVELS == 3 |
303 | #define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_address(pgd))) | 301 | #define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_address(pgd))) |
304 | #define pgd_page(pgd) virt_to_page((void *)pgd_page_vaddr(pgd)) | 302 | #define pgd_page(pgd) virt_to_page((void *)pgd_page_vaddr(pgd)) |
305 | 303 | ||
@@ -309,7 +307,7 @@ static inline void pmd_clear(pmd_t *pmd) { | |||
309 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) | 307 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) |
310 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) | 308 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) |
311 | static inline void pgd_clear(pgd_t *pgd) { | 309 | static inline void pgd_clear(pgd_t *pgd) { |
312 | #if PT_NLEVELS == 3 | 310 | #if CONFIG_PGTABLE_LEVELS == 3 |
313 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) | 311 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) |
314 | /* This is the permanent pmd attached to the pgd; cannot | 312 | /* This is the permanent pmd attached to the pgd; cannot |
315 | * free it */ | 313 | * free it */ |
@@ -393,7 +391,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
393 | 391 | ||
394 | /* Find an entry in the second-level page table.. */ | 392 | /* Find an entry in the second-level page table.. */ |
395 | 393 | ||
396 | #if PT_NLEVELS == 3 | 394 | #if CONFIG_PGTABLE_LEVELS == 3 |
397 | #define pmd_offset(dir,address) \ | 395 | #define pmd_offset(dir,address) \ |
398 | ((pmd_t *) pgd_page_vaddr(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1))) | 396 | ((pmd_t *) pgd_page_vaddr(*(dir)) + (((address)>>PMD_SHIFT) & (PTRS_PER_PMD-1))) |
399 | #else | 397 | #else |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 2ab16bb160a8..75819617f93b 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -398,7 +398,7 @@ | |||
398 | * can address up to 1TB | 398 | * can address up to 1TB |
399 | */ | 399 | */ |
400 | .macro L2_ptep pmd,pte,index,va,fault | 400 | .macro L2_ptep pmd,pte,index,va,fault |
401 | #if PT_NLEVELS == 3 | 401 | #if CONFIG_PGTABLE_LEVELS == 3 |
402 | extru \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index | 402 | extru \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index |
403 | #else | 403 | #else |
404 | # if defined(CONFIG_64BIT) | 404 | # if defined(CONFIG_64BIT) |
@@ -436,7 +436,7 @@ | |||
436 | * all ILP32 processes and all the kernel for machines with | 436 | * all ILP32 processes and all the kernel for machines with |
437 | * under 4GB of memory) */ | 437 | * under 4GB of memory) */ |
438 | .macro L3_ptep pgd,pte,index,va,fault | 438 | .macro L3_ptep pgd,pte,index,va,fault |
439 | #if PT_NLEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */ | 439 | #if CONFIG_PGTABLE_LEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */ |
440 | extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | 440 | extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index |
441 | copy %r0,\pte | 441 | copy %r0,\pte |
442 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 | 442 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index d4dc588c0dc1..e7d64527aff9 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S | |||
@@ -74,7 +74,7 @@ $bss_loop: | |||
74 | mtctl %r4,%cr24 /* Initialize kernel root pointer */ | 74 | mtctl %r4,%cr24 /* Initialize kernel root pointer */ |
75 | mtctl %r4,%cr25 /* Initialize user root pointer */ | 75 | mtctl %r4,%cr25 /* Initialize user root pointer */ |
76 | 76 | ||
77 | #if PT_NLEVELS == 3 | 77 | #if CONFIG_PGTABLE_LEVELS == 3 |
78 | /* Set pmd in pgd */ | 78 | /* Set pmd in pgd */ |
79 | load32 PA(pmd0),%r5 | 79 | load32 PA(pmd0),%r5 |
80 | shrd %r5,PxD_VALUE_SHIFT,%r3 | 80 | shrd %r5,PxD_VALUE_SHIFT,%r3 |
@@ -97,7 +97,7 @@ $bss_loop: | |||
97 | stw %r3,0(%r4) | 97 | stw %r3,0(%r4) |
98 | ldo (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3 | 98 | ldo (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3 |
99 | addib,> -1,%r1,1b | 99 | addib,> -1,%r1,1b |
100 | #if PT_NLEVELS == 3 | 100 | #if CONFIG_PGTABLE_LEVELS == 3 |
101 | ldo ASM_PMD_ENTRY_SIZE(%r4),%r4 | 101 | ldo ASM_PMD_ENTRY_SIZE(%r4),%r4 |
102 | #else | 102 | #else |
103 | ldo ASM_PGD_ENTRY_SIZE(%r4),%r4 | 103 | ldo ASM_PGD_ENTRY_SIZE(%r4),%r4 |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 15dbe81cf5f3..c229427fa546 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
@@ -34,7 +34,7 @@ | |||
34 | extern int data_start; | 34 | extern int data_start; |
35 | extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ | 35 | extern void parisc_kernel_start(void); /* Kernel entry point in head.S */ |
36 | 36 | ||
37 | #if PT_NLEVELS == 3 | 37 | #if CONFIG_PGTABLE_LEVELS == 3 |
38 | /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout | 38 | /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout |
39 | * with the first pmd adjacent to the pgd and below it. gcc doesn't actually | 39 | * with the first pmd adjacent to the pgd and below it. gcc doesn't actually |
40 | * guarantee that global objects will be laid out in memory in the same order | 40 | * guarantee that global objects will be laid out in memory in the same order |