diff options
author | Helge Deller <deller@parisc-linux.org> | 2006-04-20 16:40:23 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@hera.kernel.org> | 2006-04-21 18:20:34 -0400 |
commit | 2fd83038160531245099c3c5b3511fa4b80765eb (patch) | |
tree | 6145a9e78723c76ceac722eb60267c0116983c12 /include | |
parent | d668da80d613def981c573354e1853e38bd0698d (diff) |
[PARISC] Further work for multiple page sizes
More work towards supporing multiple page sizes on 64-bit. Convert
some assumptions that 64bit uses 3 level page tables into testing
PT_NLEVELS. Also some BUG() to BUG_ON() conversions and some cleanups
to assembler.
Signed-off-by: Helge Deller <deller@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-parisc/page.h | 25 | ||||
-rw-r--r-- | include/asm-parisc/pgtable.h | 63 |
2 files changed, 65 insertions, 23 deletions
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 45e02aa5bf4b..c0dd461fb8f1 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h | |||
@@ -1,13 +1,30 @@ | |||
1 | #ifndef _PARISC_PAGE_H | 1 | #ifndef _PARISC_PAGE_H |
2 | #define _PARISC_PAGE_H | 2 | #define _PARISC_PAGE_H |
3 | 3 | ||
4 | /* PAGE_SHIFT determines the page size */ | 4 | #if !defined(__KERNEL__) |
5 | #define PAGE_SHIFT 12 | 5 | /* this is for userspace applications (4k page size) */ |
6 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | 6 | # define PAGE_SHIFT 12 /* 4k */ |
7 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 7 | # define PAGE_SIZE (1UL << PAGE_SHIFT) |
8 | # define PAGE_MASK (~(PAGE_SIZE-1)) | ||
9 | #endif | ||
10 | |||
8 | 11 | ||
9 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
10 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | |||
15 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | ||
16 | # define PAGE_SHIFT 12 /* 4k */ | ||
17 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) | ||
18 | # define PAGE_SHIFT 14 /* 16k */ | ||
19 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) | ||
20 | # define PAGE_SHIFT 16 /* 64k */ | ||
21 | #else | ||
22 | # error "unknown default kernel page size" | ||
23 | #endif | ||
24 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
25 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
26 | |||
27 | |||
11 | #ifndef __ASSEMBLY__ | 28 | #ifndef __ASSEMBLY__ |
12 | 29 | ||
13 | #include <asm/types.h> | 30 | #include <asm/types.h> |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 4e34c6b44059..aec089eb8b85 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
@@ -59,16 +59,15 @@ | |||
59 | #define ISTACK_SIZE 32768 /* Interrupt Stack Size */ | 59 | #define ISTACK_SIZE 32768 /* Interrupt Stack Size */ |
60 | #define ISTACK_ORDER 3 | 60 | #define ISTACK_ORDER 3 |
61 | 61 | ||
62 | /* This is the size of the initially mapped kernel memory (i.e. currently | 62 | /* This is the size of the initially mapped kernel memory */ |
63 | * 0 to 1<<23 == 8MB */ | ||
64 | #ifdef CONFIG_64BIT | 63 | #ifdef CONFIG_64BIT |
65 | #define KERNEL_INITIAL_ORDER 24 | 64 | #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ |
66 | #else | 65 | #else |
67 | #define KERNEL_INITIAL_ORDER 23 | 66 | #define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */ |
68 | #endif | 67 | #endif |
69 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) | 68 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) |
70 | 69 | ||
71 | #ifdef CONFIG_64BIT | 70 | #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) |
72 | #define PT_NLEVELS 3 | 71 | #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 */ |
@@ -111,11 +110,15 @@ | |||
111 | #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) | 110 | #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) |
112 | #define MAX_ADDRESS (1UL << MAX_ADDRBITS) | 111 | #define MAX_ADDRESS (1UL << MAX_ADDRBITS) |
113 | 112 | ||
114 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) | 113 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) |
115 | 114 | ||
116 | /* This calculates the number of initial pages we need for the initial | 115 | /* This calculates the number of initial pages we need for the initial |
117 | * page tables */ | 116 | * page tables */ |
118 | #define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) | 117 | #if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT) |
118 | # define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) | ||
119 | #else | ||
120 | # define PT_INITIAL (1) /* all initial PTEs fit into one page */ | ||
121 | #endif | ||
119 | 122 | ||
120 | /* | 123 | /* |
121 | * pgd entries used up by user/kernel: | 124 | * pgd entries used up by user/kernel: |
@@ -160,6 +163,10 @@ extern void *vmalloc_start; | |||
160 | * to zero */ | 163 | * to zero */ |
161 | #define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) | 164 | #define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) |
162 | 165 | ||
166 | /* PFN_PTE_SHIFT defines the shift of a PTE value to access the PFN field */ | ||
167 | #define PFN_PTE_SHIFT 12 | ||
168 | |||
169 | |||
163 | /* this is how many bits may be used by the file functions */ | 170 | /* this is how many bits may be used by the file functions */ |
164 | #define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) | 171 | #define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) |
165 | 172 | ||
@@ -188,7 +195,8 @@ extern void *vmalloc_start; | |||
188 | /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds | 195 | /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds |
189 | * are page-aligned, we don't care about the PAGE_OFFSET bits, except | 196 | * are page-aligned, we don't care about the PAGE_OFFSET bits, except |
190 | * for a few meta-information bits, so we shift the address to be | 197 | * for a few meta-information bits, so we shift the address to be |
191 | * able to effectively address 40-bits of physical address space. */ | 198 | * able to effectively address 40/42/44-bits of physical address space |
199 | * depending on 4k/16k/64k PAGE_SIZE */ | ||
192 | #define _PxD_PRESENT_BIT 31 | 200 | #define _PxD_PRESENT_BIT 31 |
193 | #define _PxD_ATTACHED_BIT 30 | 201 | #define _PxD_ATTACHED_BIT 30 |
194 | #define _PxD_VALID_BIT 29 | 202 | #define _PxD_VALID_BIT 29 |
@@ -198,7 +206,7 @@ extern void *vmalloc_start; | |||
198 | #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) | 206 | #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) |
199 | #define PxD_FLAG_MASK (0xf) | 207 | #define PxD_FLAG_MASK (0xf) |
200 | #define PxD_FLAG_SHIFT (4) | 208 | #define PxD_FLAG_SHIFT (4) |
201 | #define PxD_VALUE_SHIFT (8) | 209 | #define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */ |
202 | 210 | ||
203 | #ifndef __ASSEMBLY__ | 211 | #ifndef __ASSEMBLY__ |
204 | 212 | ||
@@ -246,6 +254,7 @@ extern void *vmalloc_start; | |||
246 | #define __S110 PAGE_RWX | 254 | #define __S110 PAGE_RWX |
247 | #define __S111 PAGE_RWX | 255 | #define __S111 PAGE_RWX |
248 | 256 | ||
257 | |||
249 | extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ | 258 | extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ |
250 | 259 | ||
251 | /* initial page tables for 0-8MB for kernel */ | 260 | /* initial page tables for 0-8MB for kernel */ |
@@ -272,7 +281,7 @@ extern unsigned long *empty_zero_page; | |||
272 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) | 281 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) |
273 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) | 282 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) |
274 | 283 | ||
275 | #ifdef CONFIG_64BIT | 284 | #if PT_NLEVELS == 3 |
276 | /* The first entry of the permanent pmd is not there if it contains | 285 | /* The first entry of the permanent pmd is not there if it contains |
277 | * the gateway marker */ | 286 | * the gateway marker */ |
278 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) | 287 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) |
@@ -282,7 +291,7 @@ extern unsigned long *empty_zero_page; | |||
282 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) | 291 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) |
283 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) | 292 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) |
284 | static inline void pmd_clear(pmd_t *pmd) { | 293 | static inline void pmd_clear(pmd_t *pmd) { |
285 | #ifdef CONFIG_64BIT | 294 | #if PT_NLEVELS == 3 |
286 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) | 295 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) |
287 | /* This is the entry pointing to the permanent pmd | 296 | /* This is the entry pointing to the permanent pmd |
288 | * attached to the pgd; cannot clear it */ | 297 | * attached to the pgd; cannot clear it */ |
@@ -303,7 +312,7 @@ static inline void pmd_clear(pmd_t *pmd) { | |||
303 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) | 312 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) |
304 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) | 313 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) |
305 | static inline void pgd_clear(pgd_t *pgd) { | 314 | static inline void pgd_clear(pgd_t *pgd) { |
306 | #ifdef CONFIG_64BIT | 315 | #if PT_NLEVELS == 3 |
307 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) | 316 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) |
308 | /* This is the permanent pmd attached to the pgd; cannot | 317 | /* This is the permanent pmd attached to the pgd; cannot |
309 | * free it */ | 318 | * free it */ |
@@ -351,7 +360,7 @@ extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return | |||
351 | ({ \ | 360 | ({ \ |
352 | pte_t __pte; \ | 361 | pte_t __pte; \ |
353 | \ | 362 | \ |
354 | pte_val(__pte) = ((addr)+pgprot_val(pgprot)); \ | 363 | pte_val(__pte) = ((((addr)>>PAGE_SHIFT)<<PFN_PTE_SHIFT) + pgprot_val(pgprot)); \ |
355 | \ | 364 | \ |
356 | __pte; \ | 365 | __pte; \ |
357 | }) | 366 | }) |
@@ -361,20 +370,16 @@ extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return | |||
361 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) | 370 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) |
362 | { | 371 | { |
363 | pte_t pte; | 372 | pte_t pte; |
364 | pte_val(pte) = (pfn << PAGE_SHIFT) | pgprot_val(pgprot); | 373 | pte_val(pte) = (pfn << PFN_PTE_SHIFT) | pgprot_val(pgprot); |
365 | return pte; | 374 | return pte; |
366 | } | 375 | } |
367 | 376 | ||
368 | /* This takes a physical page address that is used by the remapping functions */ | ||
369 | #define mk_pte_phys(physpage, pgprot) \ | ||
370 | ({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; }) | ||
371 | |||
372 | extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 377 | extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
373 | { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } | 378 | { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } |
374 | 379 | ||
375 | /* Permanent address of a page. On parisc we don't have highmem. */ | 380 | /* Permanent address of a page. On parisc we don't have highmem. */ |
376 | 381 | ||
377 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | 382 | #define pte_pfn(x) (pte_val(x) >> PFN_PTE_SHIFT) |
378 | 383 | ||
379 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) | 384 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) |
380 | 385 | ||
@@ -499,6 +504,26 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
499 | 504 | ||
500 | #endif /* !__ASSEMBLY__ */ | 505 | #endif /* !__ASSEMBLY__ */ |
501 | 506 | ||
507 | |||
508 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ | ||
509 | #define _PAGE_SIZE_ENCODING_4K 0 | ||
510 | #define _PAGE_SIZE_ENCODING_16K 1 | ||
511 | #define _PAGE_SIZE_ENCODING_64K 2 | ||
512 | #define _PAGE_SIZE_ENCODING_256K 3 | ||
513 | #define _PAGE_SIZE_ENCODING_1M 4 | ||
514 | #define _PAGE_SIZE_ENCODING_4M 5 | ||
515 | #define _PAGE_SIZE_ENCODING_16M 6 | ||
516 | #define _PAGE_SIZE_ENCODING_64M 7 | ||
517 | |||
518 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | ||
519 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K | ||
520 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) | ||
521 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16K | ||
522 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) | ||
523 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_64K | ||
524 | #endif | ||
525 | |||
526 | |||
502 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | 527 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ |
503 | remap_pfn_range(vma, vaddr, pfn, size, prot) | 528 | remap_pfn_range(vma, vaddr, pfn, size, prot) |
504 | 529 | ||