1#ifndef _ASM_IA64_PGTABLE_H
2#define _ASM_IA64_PGTABLE_H
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/config.h>
16
17#include <asm/mman.h>
18#include <asm/page.h>
19#include <asm/processor.h>
20#include <asm/system.h>
21#include <asm/types.h>
22
23#define IA64_MAX_PHYS_BITS 50
24
25
26
27
28
29
30#define _PAGE_P_BIT 0
31#define _PAGE_A_BIT 5
32#define _PAGE_D_BIT 6
33
34#define _PAGE_P (1 << _PAGE_P_BIT)
35#define _PAGE_MA_WB (0x0 << 2)
36#define _PAGE_MA_UC (0x4 << 2)
37#define _PAGE_MA_UCE (0x5 << 2)
38#define _PAGE_MA_WC (0x6 << 2)
39#define _PAGE_MA_NAT (0x7 << 2)
40#define _PAGE_MA_MASK (0x7 << 2)
41#define _PAGE_PL_0 (0 << 7)
42#define _PAGE_PL_1 (1 << 7)
43#define _PAGE_PL_2 (2 << 7)
44#define _PAGE_PL_3 (3 << 7)
45#define _PAGE_PL_MASK (3 << 7)
46#define _PAGE_AR_R (0 << 9)
47#define _PAGE_AR_RX (1 << 9)
48#define _PAGE_AR_RW (2 << 9)
49#define _PAGE_AR_RWX (3 << 9)
50#define _PAGE_AR_R_RW (4 << 9)
51#define _PAGE_AR_RX_RWX (5 << 9)
52#define _PAGE_AR_RWX_RW (6 << 9)
53#define _PAGE_AR_X_RX (7 << 9)
54#define _PAGE_AR_MASK (7 << 9)
55#define _PAGE_AR_SHIFT 9
56#define _PAGE_A (1 << _PAGE_A_BIT)
57#define _PAGE_D (1 << _PAGE_D_BIT)
58#define _PAGE_PPN_MASK (((__IA64_UL(1) << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
59#define _PAGE_ED (__IA64_UL(1) << 52)
60#define _PAGE_PROTNONE (__IA64_UL(1) << 63)
61
62
63#define _PAGE_FILE (1 << 1)
64
65#define _PFN_MASK _PAGE_PPN_MASK
66
67#define _PAGE_CHG_MASK (_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
68
69#define _PAGE_SIZE_4K 12
70#define _PAGE_SIZE_8K 13
71#define _PAGE_SIZE_16K 14
72#define _PAGE_SIZE_64K 16
73#define _PAGE_SIZE_256K 18
74#define _PAGE_SIZE_1M 20
75#define _PAGE_SIZE_4M 22
76#define _PAGE_SIZE_16M 24
77#define _PAGE_SIZE_64M 26
78#define _PAGE_SIZE_256M 28
79#define _PAGE_SIZE_1G 30
80#define _PAGE_SIZE_4G 32
81
82#define __ACCESS_BITS _PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_MA_WB
83#define __DIRTY_BITS_NO_ED _PAGE_A | _PAGE_P | _PAGE_D | _PAGE_MA_WB
84#define __DIRTY_BITS _PAGE_ED | __DIRTY_BITS_NO_ED
85
86
87
88
89
90
91#define PGDIR_SHIFT (PAGE_SHIFT + 2*(PAGE_SHIFT-3))
92#define PGDIR_SIZE (__IA64_UL(1) << PGDIR_SHIFT)
93#define PGDIR_MASK (~(PGDIR_SIZE-1))
94#define PTRS_PER_PGD (1UL << (PAGE_SHIFT-3))
95#define USER_PTRS_PER_PGD (5*PTRS_PER_PGD/8)
96#define FIRST_USER_PGD_NR 0
97
98
99
100
101
102
103
104#define PMD_SHIFT (PAGE_SHIFT + (PAGE_SHIFT-3))
105#define PMD_SIZE (1UL << PMD_SHIFT)
106#define PMD_MASK (~(PMD_SIZE-1))
107#define PTRS_PER_PMD (1UL << (PAGE_SHIFT-3))
108
109
110
111
112#define PTRS_PER_PTE (__IA64_UL(1) << (PAGE_SHIFT-3))
113
114
115
116
117
118
119#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_A)
120#define PAGE_SHARED __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
121#define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
122#define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
123#define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
124#define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
125#define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
126#define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
127
128# ifndef __ASSEMBLY__
129
130#include <asm/bitops.h>
131#include <asm/cacheflush.h>
132#include <asm/mmu_context.h>
133#include <asm/processor.h>
134
135
136
137
138
139
140
141
142
143
144#define __P000 PAGE_NONE
145#define __P001 PAGE_READONLY
146#define __P010 PAGE_READONLY
147#define __P011 PAGE_READONLY
148#define __P100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)
149#define __P101 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
150#define __P110 PAGE_COPY_EXEC
151#define __P111 PAGE_COPY_EXEC
152
153#define __S000 PAGE_NONE
154#define __S001 PAGE_READONLY
155#define __S010 PAGE_SHARED
156#define __S011 PAGE_SHARED
157#define __S100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)
158#define __S101 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
159#define __S110 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
160#define __S111 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
161
162#define pgd_ERROR(e) printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
163#define pmd_ERROR(e) printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
164#define pte_ERROR(e) printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
165
166
167
168
169
170
171
172
173static inline long
174ia64_phys_addr_valid (unsigned long addr)
175{
176 return (addr & (local_cpu_data->unimpl_pa_mask)) == 0;
177}
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192#define kern_addr_valid(addr) (1)
193
194
195
196
197
198
199
200
201
202
203
204#define set_pte(ptep, pteval) (*(ptep) = (pteval))
205
206#define RGN_SIZE (1UL << 61)
207#define RGN_KERNEL 7
208
209#define VMALLOC_START 0xa000000200000000UL
210#ifdef CONFIG_VIRTUAL_MEM_MAP
211# define VMALLOC_END_INIT (0xa000000000000000UL + (1UL << (4*PAGE_SHIFT - 9)))
212# define VMALLOC_END vmalloc_end
213 extern unsigned long vmalloc_end;
214#else
215# define VMALLOC_END (0xa000000000000000UL + (1UL << (4*PAGE_SHIFT - 9)))
216#endif
217
218
219#define kc_vaddr_to_offset(v) ((v) - 0xa000000000000000UL)
220#define kc_offset_to_vaddr(o) ((o) + 0xa000000000000000UL)
221
222
223
224
225
226#define pfn_pte(pfn, pgprot) \
227({ pte_t __pte; pte_val(__pte) = ((pfn) << PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
228
229
230#define pte_pfn(_pte) ((pte_val(_pte) & _PFN_MASK) >> PAGE_SHIFT)
231
232#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
233
234
235#define mk_pte_phys(physpage, pgprot) \
236({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
237
238#define pte_modify(_pte, newprot) \
239 (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
240
241#define page_pte_prot(page,prot) mk_pte(page, prot)
242#define page_pte(page) page_pte_prot(page, __pgprot(0))
243
244#define pte_none(pte) (!pte_val(pte))
245#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
246#define pte_clear(pte) (pte_val(*(pte)) = 0UL)
247
248#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
249
250#define pmd_none(pmd) (!pmd_val(pmd))
251#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
252#define pmd_present(pmd) (pmd_val(pmd) != 0UL)
253#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
254#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
255#define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
256
257#define pud_none(pud) (!pud_val(pud))
258#define pud_bad(pud) (!ia64_phys_addr_valid(pud_val(pud)))
259#define pud_present(pud) (pud_val(pud) != 0UL)
260#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
261
262#define pud_page(pud) ((unsigned long) __va(pud_val(pud) & _PFN_MASK))
263
264
265
266
267#define pte_user(pte) ((pte_val(pte) & _PAGE_PL_MASK) == _PAGE_PL_3)
268#define pte_read(pte) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) < 6)
269#define pte_write(pte) ((unsigned) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) - 2) <= 4)
270#define pte_exec(pte) ((pte_val(pte) & _PAGE_AR_RX) != 0)
271#define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0)
272#define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0)
273#define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0)
274
275
276
277
278#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~_PAGE_AR_RW))
279#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_AR_RW))
280#define pte_mkexec(pte) (__pte(pte_val(pte) | _PAGE_AR_RX))
281#define pte_mkold(pte) (__pte(pte_val(pte) & ~_PAGE_A))
282#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_A))
283#define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D))
284#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D))
285
286
287
288
289
290
291#define pgprot_noncached(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_UC)
292
293
294
295
296
297
298
299
300
301#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WC)
302
303static inline unsigned long
304pgd_index (unsigned long address)
305{
306 unsigned long region = address >> 61;
307 unsigned long l1index = (address >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1);
308
309 return (region << (PAGE_SHIFT - 6)) | l1index;
310}
311
312
313
314static inline pgd_t*
315pgd_offset (struct mm_struct *mm, unsigned long address)
316{
317 return mm->pgd + pgd_index(address);
318}
319
320
321
322#define pgd_offset_k(addr) \
323 (init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
324
325
326
327
328#define pgd_offset_gate(mm, addr) pgd_offset_k(addr)
329
330
331#define pmd_offset(dir,addr) \
332 ((pmd_t *) pud_page(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
333
334
335
336
337
338#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
339#define pte_offset_kernel(dir,addr) ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(addr))
340#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
341#define pte_offset_map_nested(dir,addr) pte_offset_map(dir, addr)
342#define pte_unmap(pte) do { } while (0)
343#define pte_unmap_nested(pte) do { } while (0)
344
345
346
347static inline int
348ptep_test_and_clear_young (pte_t *ptep)
349{
350#ifdef CONFIG_SMP
351 if (!pte_young(*ptep))
352 return 0;
353 return test_and_clear_bit(_PAGE_A_BIT, ptep);
354#else
355 pte_t pte = *ptep;
356 if (!pte_young(pte))
357 return 0;
358 set_pte(ptep, pte_mkold(pte));
359 return 1;
360#endif
361}
362
363static inline int
364ptep_test_and_clear_dirty (pte_t *ptep)
365{
366#ifdef CONFIG_SMP
367 if (!pte_dirty(*ptep))
368 return 0;
369 return test_and_clear_bit(_PAGE_D_BIT, ptep);
370#else
371 pte_t pte = *ptep;
372 if (!pte_dirty(pte))
373 return 0;
374 set_pte(ptep, pte_mkclean(pte));
375 return 1;
376#endif
377}
378
379static inline pte_t
380ptep_get_and_clear (pte_t *ptep)
381{
382#ifdef CONFIG_SMP
383 return __pte(xchg((long *) ptep, 0));
384#else
385 pte_t pte = *ptep;
386 pte_clear(ptep);
387 return pte;
388#endif
389}
390
391static inline void
392ptep_set_wrprotect (pte_t *ptep)
393{
394#ifdef CONFIG_SMP
395 unsigned long new, old;
396
397 do {
398 old = pte_val(*ptep);
399 new = pte_val(pte_wrprotect(__pte (old)));
400 } while (cmpxchg((unsigned long *) ptep, old, new) != old);
401#else
402 pte_t old_pte = *ptep;
403 set_pte(ptep, pte_wrprotect(old_pte));
404#endif
405}
406
407static inline void
408ptep_mkdirty (pte_t *ptep)
409{
410#ifdef CONFIG_SMP
411 set_bit(_PAGE_D_BIT, ptep);
412#else
413 pte_t old_pte = *ptep;
414 set_pte(ptep, pte_mkdirty(old_pte));
415#endif
416}
417
418static inline int
419pte_same (pte_t a, pte_t b)
420{
421 return pte_val(a) == pte_val(b);
422}
423
424extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
425extern void paging_init (void);
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446#define __swp_type(entry) (((entry).val >> 2) & 0x7f)
447#define __swp_offset(entry) (((entry).val << 1) >> 10)
448#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((long) (offset) << 9) })
449#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
450#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
451
452#define PTE_FILE_MAX_BITS 61
453#define pte_to_pgoff(pte) ((pte_val(pte) << 1) >> 3)
454#define pgoff_to_pte(off) ((pte_t) { ((off) << 2) | _PAGE_FILE })
455
456
457#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
458 remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
459
460
461
462
463
464extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
465extern struct page *zero_page_memmap_ptr;
466#define ZERO_PAGE(vaddr) (zero_page_memmap_ptr)
467
468
469#define HAVE_ARCH_UNMAPPED_AREA
470
471#ifdef CONFIG_HUGETLB_PAGE
472#define HUGETLB_PGDIR_SHIFT (HPAGE_SHIFT + 2*(PAGE_SHIFT-3))
473#define HUGETLB_PGDIR_SIZE (__IA64_UL(1) << HUGETLB_PGDIR_SHIFT)
474#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
475struct mmu_gather;
476extern void hugetlb_free_pgtables(struct mmu_gather *tlb,
477 struct vm_area_struct * prev, unsigned long start, unsigned long end);
478#endif
479
480
481
482
483
484
485extern void update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte);
486
487#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510#ifdef CONFIG_SMP
511# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
512do { \
513 if (__safely_writable) { \
514 set_pte(__ptep, __entry); \
515 flush_tlb_page(__vma, __addr); \
516 } \
517} while (0)
518#else
519# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
520 ptep_establish(__vma, __addr, __ptep, __entry)
521#endif
522
523# ifdef CONFIG_VIRTUAL_MEM_MAP
524
525# define __HAVE_ARCH_MEMMAP_INIT
526 extern void memmap_init (unsigned long size, int nid, unsigned long zone,
527 unsigned long start_pfn);
528# endif
529# endif
530
531
532
533
534
535
536#if defined(CONFIG_IA64_GRANULE_64MB)
537# define IA64_GRANULE_SHIFT _PAGE_SIZE_64M
538#elif defined(CONFIG_IA64_GRANULE_16MB)
539# define IA64_GRANULE_SHIFT _PAGE_SIZE_16M
540#endif
541#define IA64_GRANULE_SIZE (1 << IA64_GRANULE_SHIFT)
542
543
544
545#define KERNEL_TR_PAGE_SHIFT _PAGE_SIZE_64M
546#define KERNEL_TR_PAGE_SIZE (1 << KERNEL_TR_PAGE_SHIFT)
547
548
549
550
551#define pgtable_cache_init() do { } while (0)
552
553
554#define FIXADDR_USER_START GATE_ADDR
555#define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
556
557#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
558#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
559#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
560#define __HAVE_ARCH_PTEP_SET_WRPROTECT
561#define __HAVE_ARCH_PTEP_MKDIRTY
562#define __HAVE_ARCH_PTE_SAME
563#define __HAVE_ARCH_PGD_OFFSET_GATE
564#include <asm-generic/pgtable.h>
565#include <asm-generic/pgtable-nopud.h>
566
567#endif
568