aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorHelge Deller <deller@parisc-linux.org>2006-04-20 16:40:23 -0400
committerKyle McMartin <kyle@hera.kernel.org>2006-04-21 18:20:34 -0400
commit2fd83038160531245099c3c5b3511fa4b80765eb (patch)
tree6145a9e78723c76ceac722eb60267c0116983c12 /include
parentd668da80d613def981c573354e1853e38bd0698d (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.h25
-rw-r--r--include/asm-parisc/pgtable.h63
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
249extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ 258extern 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)
284static inline void pmd_clear(pmd_t *pmd) { 293static 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)
305static inline void pgd_clear(pgd_t *pgd) { 314static 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
361static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) 370static 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
372extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 377extern 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