diff options
Diffstat (limited to 'include/asm-ppc64/page.h')
-rw-r--r-- | include/asm-ppc64/page.h | 147 |
1 files changed, 112 insertions, 35 deletions
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index d404431f0a9a..82ce187e5be8 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h | |||
@@ -13,32 +13,59 @@ | |||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | #include <asm/ppc_asm.h> /* for ASM_CONST */ | 14 | #include <asm/ppc_asm.h> /* for ASM_CONST */ |
15 | 15 | ||
16 | /* PAGE_SHIFT determines the page size */ | 16 | /* |
17 | #define PAGE_SHIFT 12 | 17 | * We support either 4k or 64k software page size. When using 64k pages |
18 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) | 18 | * however, wether we are really supporting 64k pages in HW or not is |
19 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 19 | * irrelevant to those definitions. We always define HW_PAGE_SHIFT to 12 |
20 | * as use of 64k pages remains a linux kernel specific, every notion of | ||
21 | * page number shared with the firmware, TCEs, iommu, etc... still assumes | ||
22 | * a page size of 4096. | ||
23 | */ | ||
24 | #ifdef CONFIG_PPC_64K_PAGES | ||
25 | #define PAGE_SHIFT 16 | ||
26 | #else | ||
27 | #define PAGE_SHIFT 12 | ||
28 | #endif | ||
20 | 29 | ||
21 | #define SID_SHIFT 28 | 30 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) |
22 | #define SID_MASK 0xfffffffffUL | 31 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
23 | #define ESID_MASK 0xfffffffff0000000UL | ||
24 | #define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK) | ||
25 | 32 | ||
26 | #define HPAGE_SHIFT 24 | 33 | /* HW_PAGE_SHIFT is always 4k pages */ |
27 | #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) | 34 | #define HW_PAGE_SHIFT 12 |
28 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | 35 | #define HW_PAGE_SIZE (ASM_CONST(1) << HW_PAGE_SHIFT) |
36 | #define HW_PAGE_MASK (~(HW_PAGE_SIZE-1)) | ||
29 | 37 | ||
30 | #ifdef CONFIG_HUGETLB_PAGE | 38 | /* PAGE_FACTOR is the number of bits factor between PAGE_SHIFT and |
39 | * HW_PAGE_SHIFT, that is 4k pages | ||
40 | */ | ||
41 | #define PAGE_FACTOR (PAGE_SHIFT - HW_PAGE_SHIFT) | ||
42 | |||
43 | /* Segment size */ | ||
44 | #define SID_SHIFT 28 | ||
45 | #define SID_MASK 0xfffffffffUL | ||
46 | #define ESID_MASK 0xfffffffff0000000UL | ||
47 | #define GET_ESID(x) (((x) >> SID_SHIFT) & SID_MASK) | ||
31 | 48 | ||
49 | /* Large pages size */ | ||
50 | |||
51 | #ifndef __ASSEMBLY__ | ||
52 | extern unsigned int HPAGE_SHIFT; | ||
53 | #define HPAGE_SIZE ((1UL) << HPAGE_SHIFT) | ||
54 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | ||
32 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | 55 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) |
56 | #endif /* __ASSEMBLY__ */ | ||
57 | |||
58 | #ifdef CONFIG_HUGETLB_PAGE | ||
59 | |||
33 | 60 | ||
34 | #define HTLB_AREA_SHIFT 40 | 61 | #define HTLB_AREA_SHIFT 40 |
35 | #define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT) | 62 | #define HTLB_AREA_SIZE (1UL << HTLB_AREA_SHIFT) |
36 | #define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT) | 63 | #define GET_HTLB_AREA(x) ((x) >> HTLB_AREA_SHIFT) |
37 | 64 | ||
38 | #define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ | 65 | #define LOW_ESID_MASK(addr, len) (((1U << (GET_ESID(addr+len-1)+1)) \ |
39 | - (1U << GET_ESID(addr))) & 0xffff) | 66 | - (1U << GET_ESID(addr))) & 0xffff) |
40 | #define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \ | 67 | #define HTLB_AREA_MASK(addr, len) (((1U << (GET_HTLB_AREA(addr+len-1)+1)) \ |
41 | - (1U << GET_HTLB_AREA(addr))) & 0xffff) | 68 | - (1U << GET_HTLB_AREA(addr))) & 0xffff) |
42 | 69 | ||
43 | #define ARCH_HAS_HUGEPAGE_ONLY_RANGE | 70 | #define ARCH_HAS_HUGEPAGE_ONLY_RANGE |
44 | #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE | 71 | #define ARCH_HAS_PREPARE_HUGEPAGE_RANGE |
@@ -114,7 +141,25 @@ static __inline__ void clear_page(void *addr) | |||
114 | : "ctr", "memory"); | 141 | : "ctr", "memory"); |
115 | } | 142 | } |
116 | 143 | ||
117 | extern void copy_page(void *to, void *from); | 144 | extern void copy_4K_page(void *to, void *from); |
145 | |||
146 | #ifdef CONFIG_PPC_64K_PAGES | ||
147 | static inline void copy_page(void *to, void *from) | ||
148 | { | ||
149 | unsigned int i; | ||
150 | for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) { | ||
151 | copy_4K_page(to, from); | ||
152 | to += 4096; | ||
153 | from += 4096; | ||
154 | } | ||
155 | } | ||
156 | #else /* CONFIG_PPC_64K_PAGES */ | ||
157 | static inline void copy_page(void *to, void *from) | ||
158 | { | ||
159 | copy_4K_page(to, from); | ||
160 | } | ||
161 | #endif /* CONFIG_PPC_64K_PAGES */ | ||
162 | |||
118 | struct page; | 163 | struct page; |
119 | extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); | 164 | extern void clear_user_page(void *page, unsigned long vaddr, struct page *pg); |
120 | extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p); | 165 | extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *p); |
@@ -124,43 +169,75 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr, struct pag | |||
124 | * These are used to make use of C type-checking. | 169 | * These are used to make use of C type-checking. |
125 | * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b. | 170 | * Entries in the pte table are 64b, while entries in the pgd & pmd are 32b. |
126 | */ | 171 | */ |
127 | typedef struct { unsigned long pte; } pte_t; | ||
128 | typedef struct { unsigned long pmd; } pmd_t; | ||
129 | typedef struct { unsigned long pud; } pud_t; | ||
130 | typedef struct { unsigned long pgd; } pgd_t; | ||
131 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
132 | 172 | ||
173 | /* PTE level */ | ||
174 | typedef struct { unsigned long pte; } pte_t; | ||
133 | #define pte_val(x) ((x).pte) | 175 | #define pte_val(x) ((x).pte) |
134 | #define pmd_val(x) ((x).pmd) | ||
135 | #define pud_val(x) ((x).pud) | ||
136 | #define pgd_val(x) ((x).pgd) | ||
137 | #define pgprot_val(x) ((x).pgprot) | ||
138 | |||
139 | #define __pte(x) ((pte_t) { (x) }) | 176 | #define __pte(x) ((pte_t) { (x) }) |
177 | |||
178 | /* 64k pages additionally define a bigger "real PTE" type that gathers | ||
179 | * the "second half" part of the PTE for pseudo 64k pages | ||
180 | */ | ||
181 | #ifdef CONFIG_PPC_64K_PAGES | ||
182 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | ||
183 | #else | ||
184 | typedef struct { pte_t pte; } real_pte_t; | ||
185 | #endif | ||
186 | |||
187 | /* PMD level */ | ||
188 | typedef struct { unsigned long pmd; } pmd_t; | ||
189 | #define pmd_val(x) ((x).pmd) | ||
140 | #define __pmd(x) ((pmd_t) { (x) }) | 190 | #define __pmd(x) ((pmd_t) { (x) }) |
191 | |||
192 | /* PUD level exusts only on 4k pages */ | ||
193 | #ifndef CONFIG_PPC_64K_PAGES | ||
194 | typedef struct { unsigned long pud; } pud_t; | ||
195 | #define pud_val(x) ((x).pud) | ||
141 | #define __pud(x) ((pud_t) { (x) }) | 196 | #define __pud(x) ((pud_t) { (x) }) |
197 | #endif | ||
198 | |||
199 | /* PGD level */ | ||
200 | typedef struct { unsigned long pgd; } pgd_t; | ||
201 | #define pgd_val(x) ((x).pgd) | ||
142 | #define __pgd(x) ((pgd_t) { (x) }) | 202 | #define __pgd(x) ((pgd_t) { (x) }) |
203 | |||
204 | /* Page protection bits */ | ||
205 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
206 | #define pgprot_val(x) ((x).pgprot) | ||
143 | #define __pgprot(x) ((pgprot_t) { (x) }) | 207 | #define __pgprot(x) ((pgprot_t) { (x) }) |
144 | 208 | ||
145 | #else | 209 | #else |
210 | |||
146 | /* | 211 | /* |
147 | * .. while these make it easier on the compiler | 212 | * .. while these make it easier on the compiler |
148 | */ | 213 | */ |
149 | typedef unsigned long pte_t; | ||
150 | typedef unsigned long pmd_t; | ||
151 | typedef unsigned long pud_t; | ||
152 | typedef unsigned long pgd_t; | ||
153 | typedef unsigned long pgprot_t; | ||
154 | 214 | ||
215 | typedef unsigned long pte_t; | ||
155 | #define pte_val(x) (x) | 216 | #define pte_val(x) (x) |
217 | #define __pte(x) (x) | ||
218 | |||
219 | #ifdef CONFIG_PPC_64K_PAGES | ||
220 | typedef struct { pte_t pte; unsigned long hidx; } real_pte_t; | ||
221 | #else | ||
222 | typedef unsigned long real_pte_t; | ||
223 | #endif | ||
224 | |||
225 | |||
226 | typedef unsigned long pmd_t; | ||
156 | #define pmd_val(x) (x) | 227 | #define pmd_val(x) (x) |
228 | #define __pmd(x) (x) | ||
229 | |||
230 | #ifndef CONFIG_PPC_64K_PAGES | ||
231 | typedef unsigned long pud_t; | ||
157 | #define pud_val(x) (x) | 232 | #define pud_val(x) (x) |
233 | #define __pud(x) (x) | ||
234 | #endif | ||
235 | |||
236 | typedef unsigned long pgd_t; | ||
158 | #define pgd_val(x) (x) | 237 | #define pgd_val(x) (x) |
159 | #define pgprot_val(x) (x) | 238 | #define pgprot_val(x) (x) |
160 | 239 | ||
161 | #define __pte(x) (x) | 240 | typedef unsigned long pgprot_t; |
162 | #define __pmd(x) (x) | ||
163 | #define __pud(x) (x) | ||
164 | #define __pgd(x) (x) | 241 | #define __pgd(x) (x) |
165 | #define __pgprot(x) (x) | 242 | #define __pgprot(x) (x) |
166 | 243 | ||