1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#ifndef _ASM_PGTABLE_H
22#define _ASM_PGTABLE_H
23
24
25
26
27#include <linux/swap.h>
28#include <asm/page.h>
29#include <asm-generic/pgtable-nopmd.h>
30
31
32extern unsigned long empty_zero_page;
33extern unsigned long zero_page_mask;
34
35
36
37
38
39
40
41
42#include <asm/vm_mmu.h>
43
44
45
46
47
48#define _PAGE_READ __HVM_PTE_R
49#define _PAGE_WRITE __HVM_PTE_W
50#define _PAGE_EXECUTE __HVM_PTE_X
51#define _PAGE_USER __HVM_PTE_U
52
53
54
55
56
57
58
59
60#define _PAGE_PRESENT (1<<0)
61#define _PAGE_DIRTY (1<<1)
62#define _PAGE_ACCESSED (1<<2)
63
64
65
66
67
68
69#define _PAGE_FILE _PAGE_DIRTY
70
71
72
73
74
75
76#define _PAGE_VALID _PAGE_PRESENT
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92#define PGDIR_SHIFT 22
93#define PTRS_PER_PGD 1024
94
95#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
96#define PGDIR_MASK (~(PGDIR_SIZE-1))
97
98#ifdef CONFIG_PAGE_SIZE_4KB
99#define PTRS_PER_PTE 1024
100#endif
101
102#ifdef CONFIG_PAGE_SIZE_16KB
103#define PTRS_PER_PTE 256
104#endif
105
106#ifdef CONFIG_PAGE_SIZE_64KB
107#define PTRS_PER_PTE 64
108#endif
109
110#ifdef CONFIG_PAGE_SIZE_256KB
111#define PTRS_PER_PTE 16
112#endif
113
114#ifdef CONFIG_PAGE_SIZE_1MB
115#define PTRS_PER_PTE 4
116#endif
117
118
119#define pgd_ERROR(e) \
120 printk(KERN_ERR "%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__,\
121 pgd_val(e))
122
123
124
125
126extern unsigned long _dflt_cache_att;
127
128#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_USER | \
129 _dflt_cache_att)
130#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | \
131 _PAGE_READ | _PAGE_EXECUTE | _dflt_cache_att)
132#define PAGE_COPY PAGE_READONLY
133#define PAGE_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | \
134 _PAGE_READ | _PAGE_EXECUTE | _dflt_cache_att)
135#define PAGE_COPY_EXEC PAGE_EXEC
136#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \
137 _PAGE_EXECUTE | _PAGE_WRITE | _dflt_cache_att)
138#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_READ | \
139 _PAGE_WRITE | _PAGE_EXECUTE | _dflt_cache_att)
140
141
142
143
144
145
146
147
148
149#define CACHEDEF (CACHE_DEFAULT << 6)
150
151
152#define __P000 __pgprot(_PAGE_PRESENT | _PAGE_USER | CACHEDEF)
153#define __P001 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | CACHEDEF)
154#define __P010 __P000
155#define __P011 __P001
156#define __P100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \
157 _PAGE_EXECUTE | CACHEDEF)
158#define __P101 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_EXECUTE | \
159 _PAGE_READ | CACHEDEF)
160#define __P110 __P100
161#define __P111 __P101
162
163
164#define __S000 __P000
165#define __S001 __P001
166#define __S010 __pgprot(_PAGE_PRESENT | _PAGE_USER | \
167 _PAGE_WRITE | CACHEDEF)
168#define __S011 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \
169 _PAGE_WRITE | CACHEDEF)
170#define __S100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \
171 _PAGE_EXECUTE | CACHEDEF)
172#define __S101 __P101
173#define __S110 __pgprot(_PAGE_PRESENT | _PAGE_USER | \
174 _PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF)
175#define __S111 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \
176 _PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF)
177
178extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
179
180
181#define FIRST_USER_ADDRESS 0
182#define pte_special(pte) 0
183#define pte_mkspecial(pte) (pte)
184
185
186#ifdef CONFIG_HUGETLB_PAGE
187#define pte_mkhuge(pte) __pte((pte_val(pte) & ~0x3) | HVM_HUGEPAGE_SIZE)
188#endif
189
190
191
192
193
194extern void sync_icache_dcache(pte_t pte);
195
196#define pte_present_exec_user(pte) \
197 ((pte_val(pte) & (_PAGE_EXECUTE | _PAGE_USER)) == \
198 (_PAGE_EXECUTE | _PAGE_USER))
199
200static inline void set_pte(pte_t *ptep, pte_t pteval)
201{
202
203 if (pte_present_exec_user(pteval))
204 sync_icache_dcache(pteval);
205
206 *ptep = pteval;
207}
208
209
210
211
212
213
214
215
216#define _NULL_PMD 0x7
217#define _NULL_PTE 0x0
218
219static inline void pmd_clear(pmd_t *pmd_entry_ptr)
220{
221 pmd_val(*pmd_entry_ptr) = _NULL_PMD;
222}
223
224
225
226
227static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
228 pte_t *ptep)
229{
230 pte_val(*ptep) = _NULL_PTE;
231}
232
233#ifdef NEED_PMD_INDEX_DESPITE_BEING_2_LEVEL
234
235
236
237
238#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
239
240#endif
241
242
243
244
245
246
247
248#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
249
250
251
252
253#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr))
254
255
256
257
258#define pgd_offset_k(address) pgd_offset(&init_mm, address)
259
260
261
262
263
264
265
266static inline int pmd_none(pmd_t pmd)
267{
268 return pmd_val(pmd) == _NULL_PMD;
269}
270
271
272
273
274
275
276
277static inline int pmd_present(pmd_t pmd)
278{
279 return pmd_val(pmd) != (unsigned long)_NULL_PMD;
280}
281
282
283
284
285
286
287static inline int pmd_bad(pmd_t pmd)
288{
289 return 0;
290}
291
292
293
294
295#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
296#define pmd_pgtable(pmd) pmd_page(pmd)
297
298
299
300
301
302static inline int pte_none(pte_t pte)
303{
304 return pte_val(pte) == _NULL_PTE;
305};
306
307
308
309
310static inline int pte_present(pte_t pte)
311{
312 return pte_val(pte) & _PAGE_PRESENT;
313}
314
315
316#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
317
318
319#define pte_page(x) pfn_to_page(pte_pfn(x))
320
321
322static inline pte_t pte_mkold(pte_t pte)
323{
324 pte_val(pte) &= ~_PAGE_ACCESSED;
325 return pte;
326}
327
328
329static inline pte_t pte_mkyoung(pte_t pte)
330{
331 pte_val(pte) |= _PAGE_ACCESSED;
332 return pte;
333}
334
335
336static inline pte_t pte_mkclean(pte_t pte)
337{
338 pte_val(pte) &= ~_PAGE_DIRTY;
339 return pte;
340}
341
342
343static inline pte_t pte_mkdirty(pte_t pte)
344{
345 pte_val(pte) |= _PAGE_DIRTY;
346 return pte;
347}
348
349
350static inline int pte_young(pte_t pte)
351{
352 return pte_val(pte) & _PAGE_ACCESSED;
353}
354
355
356static inline int pte_dirty(pte_t pte)
357{
358 return pte_val(pte) & _PAGE_DIRTY;
359}
360
361
362static inline pte_t pte_modify(pte_t pte, pgprot_t prot)
363{
364 pte_val(pte) &= PAGE_MASK;
365 pte_val(pte) |= pgprot_val(prot);
366 return pte;
367}
368
369
370static inline pte_t pte_wrprotect(pte_t pte)
371{
372 pte_val(pte) &= ~_PAGE_WRITE;
373 return pte;
374}
375
376
377static inline pte_t pte_mkwrite(pte_t pte)
378{
379 pte_val(pte) |= _PAGE_WRITE;
380 return pte;
381}
382
383
384static inline pte_t pte_mkexec(pte_t pte)
385{
386 pte_val(pte) |= _PAGE_EXECUTE;
387 return pte;
388}
389
390
391static inline int pte_read(pte_t pte)
392{
393 return pte_val(pte) & _PAGE_READ;
394}
395
396
397static inline int pte_write(pte_t pte)
398{
399 return pte_val(pte) & _PAGE_WRITE;
400}
401
402
403
404static inline int pte_exec(pte_t pte)
405{
406 return pte_val(pte) & _PAGE_EXECUTE;
407}
408
409
410#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
411
412
413#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
414
415
416#define pfn_pte(pfn, pgprot) __pte((pfn << PAGE_SHIFT) | pgprot_val(pgprot))
417
418
419#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
420#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
421
422
423
424
425
426
427
428#define set_pte_at(mm, addr, ptep, pte) set_pte(ptep, pte)
429
430
431
432
433#define pte_unmap(pte) do { } while (0)
434#define pte_unmap_nested(pte) do { } while (0)
435
436
437
438
439
440#define pte_offset_map(dir, address) \
441 ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
442
443#define pte_offset_map_nested(pmd, addr) pte_offset_map(pmd, addr)
444
445
446#define pte_offset_kernel(dir, address) \
447 ((pte_t *) (unsigned long) __va(pmd_val(*dir) & PAGE_MASK) \
448 + __pte_offset(address))
449
450
451#define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page))
452
453#define __pte_offset(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
454
455
456#define pgtable_cache_init() do { } while (0)
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487#define PTE_FILE_MAX_BITS 27
488
489
490#define __swp_type(swp_pte) (((swp_pte).val >> 2) & 0x1f)
491
492#define __swp_offset(swp_pte) \
493 ((((swp_pte).val >> 7) & 0x7) | (((swp_pte).val >> 10) & 0x003ffff8))
494
495#define __swp_entry(type, offset) \
496 ((swp_entry_t) { \
497 ((type << 2) | \
498 ((offset & 0x3ffff8) << 10) | ((offset & 0x7) << 7)) })
499
500
501#define pte_file(pte) \
502 ((pte_val(pte) & (_PAGE_FILE | _PAGE_PRESENT)) == _PAGE_FILE)
503
504#define pte_to_pgoff(pte) \
505 (((pte_val(pte) >> 2) & 0xff) | ((pte_val(pte) >> 5) & 0x07ffff00))
506
507#define pgoff_to_pte(off) \
508 ((pte_t) { ((((off) & 0x7ffff00) << 5) | (((off) & 0xff) << 2)\
509 | _PAGE_FILE) })
510
511
512#include <asm-generic/pgtable.h>
513
514#endif
515