aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/include/asm/pgtable.h
diff options
context:
space:
mode:
authorTony Luck <tony.luck@intel.com>2008-08-01 13:13:32 -0400
committerTony Luck <tony.luck@intel.com>2008-08-01 13:21:21 -0400
commit7f30491ccd28627742e37899453ae20e3da8e18f (patch)
tree7291c0a26ed3a31acf9542857af3981d278f5de8 /arch/ia64/include/asm/pgtable.h
parent94ad374a0751f40d25e22e036c37f7263569d24c (diff)
[IA64] Move include/asm-ia64 to arch/ia64/include/asm
After moving the the include files there were a few clean-ups: 1) Some files used #include <asm-ia64/xyz.h>, changed to <asm/xyz.h> 2) Some comments alerted maintainers to look at various header files to make matching updates if certain code were to be changed. Updated these comments to use the new include paths. 3) Some header files mentioned their own names in initial comments. Just deleted these self references. Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/include/asm/pgtable.h')
-rw-r--r--arch/ia64/include/asm/pgtable.h615
1 files changed, 615 insertions, 0 deletions
diff --git a/arch/ia64/include/asm/pgtable.h b/arch/ia64/include/asm/pgtable.h
new file mode 100644
index 000000000000..7a9bff47564f
--- /dev/null
+++ b/arch/ia64/include/asm/pgtable.h
@@ -0,0 +1,615 @@
1#ifndef _ASM_IA64_PGTABLE_H
2#define _ASM_IA64_PGTABLE_H
3
4/*
5 * This file contains the functions and defines necessary to modify and use
6 * the IA-64 page table tree.
7 *
8 * This hopefully works with any (fixed) IA-64 page-size, as defined
9 * in <asm/page.h>.
10 *
11 * Copyright (C) 1998-2005 Hewlett-Packard Co
12 * David Mosberger-Tang <davidm@hpl.hp.com>
13 */
14
15
16#include <asm/mman.h>
17#include <asm/page.h>
18#include <asm/processor.h>
19#include <asm/system.h>
20#include <asm/types.h>
21
22#define IA64_MAX_PHYS_BITS 50 /* max. number of physical address bits (architected) */
23
24/*
25 * First, define the various bits in a PTE. Note that the PTE format
26 * matches the VHPT short format, the firt doubleword of the VHPD long
27 * format, and the first doubleword of the TLB insertion format.
28 */
29#define _PAGE_P_BIT 0
30#define _PAGE_A_BIT 5
31#define _PAGE_D_BIT 6
32
33#define _PAGE_P (1 << _PAGE_P_BIT) /* page present bit */
34#define _PAGE_MA_WB (0x0 << 2) /* write back memory attribute */
35#define _PAGE_MA_UC (0x4 << 2) /* uncacheable memory attribute */
36#define _PAGE_MA_UCE (0x5 << 2) /* UC exported attribute */
37#define _PAGE_MA_WC (0x6 << 2) /* write coalescing memory attribute */
38#define _PAGE_MA_NAT (0x7 << 2) /* not-a-thing attribute */
39#define _PAGE_MA_MASK (0x7 << 2)
40#define _PAGE_PL_0 (0 << 7) /* privilege level 0 (kernel) */
41#define _PAGE_PL_1 (1 << 7) /* privilege level 1 (unused) */
42#define _PAGE_PL_2 (2 << 7) /* privilege level 2 (unused) */
43#define _PAGE_PL_3 (3 << 7) /* privilege level 3 (user) */
44#define _PAGE_PL_MASK (3 << 7)
45#define _PAGE_AR_R (0 << 9) /* read only */
46#define _PAGE_AR_RX (1 << 9) /* read & execute */
47#define _PAGE_AR_RW (2 << 9) /* read & write */
48#define _PAGE_AR_RWX (3 << 9) /* read, write & execute */
49#define _PAGE_AR_R_RW (4 << 9) /* read / read & write */
50#define _PAGE_AR_RX_RWX (5 << 9) /* read & exec / read, write & exec */
51#define _PAGE_AR_RWX_RW (6 << 9) /* read, write & exec / read & write */
52#define _PAGE_AR_X_RX (7 << 9) /* exec & promote / read & exec */
53#define _PAGE_AR_MASK (7 << 9)
54#define _PAGE_AR_SHIFT 9
55#define _PAGE_A (1 << _PAGE_A_BIT) /* page accessed bit */
56#define _PAGE_D (1 << _PAGE_D_BIT) /* page dirty bit */
57#define _PAGE_PPN_MASK (((__IA64_UL(1) << IA64_MAX_PHYS_BITS) - 1) & ~0xfffUL)
58#define _PAGE_ED (__IA64_UL(1) << 52) /* exception deferral */
59#define _PAGE_PROTNONE (__IA64_UL(1) << 63)
60
61/* Valid only for a PTE with the present bit cleared: */
62#define _PAGE_FILE (1 << 1) /* see swap & file pte remarks below */
63
64#define _PFN_MASK _PAGE_PPN_MASK
65/* Mask of bits which may be changed by pte_modify(); the odd bits are there for _PAGE_PROTNONE */
66#define _PAGE_CHG_MASK (_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
67
68#define _PAGE_SIZE_4K 12
69#define _PAGE_SIZE_8K 13
70#define _PAGE_SIZE_16K 14
71#define _PAGE_SIZE_64K 16
72#define _PAGE_SIZE_256K 18
73#define _PAGE_SIZE_1M 20
74#define _PAGE_SIZE_4M 22
75#define _PAGE_SIZE_16M 24
76#define _PAGE_SIZE_64M 26
77#define _PAGE_SIZE_256M 28
78#define _PAGE_SIZE_1G 30
79#define _PAGE_SIZE_4G 32
80
81#define __ACCESS_BITS _PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_MA_WB
82#define __DIRTY_BITS_NO_ED _PAGE_A | _PAGE_P | _PAGE_D | _PAGE_MA_WB
83#define __DIRTY_BITS _PAGE_ED | __DIRTY_BITS_NO_ED
84
85/*
86 * How many pointers will a page table level hold expressed in shift
87 */
88#define PTRS_PER_PTD_SHIFT (PAGE_SHIFT-3)
89
90/*
91 * Definitions for fourth level:
92 */
93#define PTRS_PER_PTE (__IA64_UL(1) << (PTRS_PER_PTD_SHIFT))
94
95/*
96 * Definitions for third level:
97 *
98 * PMD_SHIFT determines the size of the area a third-level page table
99 * can map.
100 */
101#define PMD_SHIFT (PAGE_SHIFT + (PTRS_PER_PTD_SHIFT))
102#define PMD_SIZE (1UL << PMD_SHIFT)
103#define PMD_MASK (~(PMD_SIZE-1))
104#define PTRS_PER_PMD (1UL << (PTRS_PER_PTD_SHIFT))
105
106#ifdef CONFIG_PGTABLE_4
107/*
108 * Definitions for second level:
109 *
110 * PUD_SHIFT determines the size of the area a second-level page table
111 * can map.
112 */
113#define PUD_SHIFT (PMD_SHIFT + (PTRS_PER_PTD_SHIFT))
114#define PUD_SIZE (1UL << PUD_SHIFT)
115#define PUD_MASK (~(PUD_SIZE-1))
116#define PTRS_PER_PUD (1UL << (PTRS_PER_PTD_SHIFT))
117#endif
118
119/*
120 * Definitions for first level:
121 *
122 * PGDIR_SHIFT determines what a first-level page table entry can map.
123 */
124#ifdef CONFIG_PGTABLE_4
125#define PGDIR_SHIFT (PUD_SHIFT + (PTRS_PER_PTD_SHIFT))
126#else
127#define PGDIR_SHIFT (PMD_SHIFT + (PTRS_PER_PTD_SHIFT))
128#endif
129#define PGDIR_SIZE (__IA64_UL(1) << PGDIR_SHIFT)
130#define PGDIR_MASK (~(PGDIR_SIZE-1))
131#define PTRS_PER_PGD_SHIFT PTRS_PER_PTD_SHIFT
132#define PTRS_PER_PGD (1UL << PTRS_PER_PGD_SHIFT)
133#define USER_PTRS_PER_PGD (5*PTRS_PER_PGD/8) /* regions 0-4 are user regions */
134#define FIRST_USER_ADDRESS 0
135
136/*
137 * All the normal masks have the "page accessed" bits on, as any time
138 * they are used, the page is accessed. They are cleared only by the
139 * page-out routines.
140 */
141#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_A)
142#define PAGE_SHARED __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
143#define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
144#define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
145#define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
146#define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
147#define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
148#define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
149
150# ifndef __ASSEMBLY__
151
152#include <linux/sched.h> /* for mm_struct */
153#include <linux/bitops.h>
154#include <asm/cacheflush.h>
155#include <asm/mmu_context.h>
156#include <asm/processor.h>
157
158/*
159 * Next come the mappings that determine how mmap() protection bits
160 * (PROT_EXEC, PROT_READ, PROT_WRITE, PROT_NONE) get implemented. The
161 * _P version gets used for a private shared memory segment, the _S
162 * version gets used for a shared memory segment with MAP_SHARED on.
163 * In a private shared memory segment, we do a copy-on-write if a task
164 * attempts to write to the page.
165 */
166 /* xwr */
167#define __P000 PAGE_NONE
168#define __P001 PAGE_READONLY
169#define __P010 PAGE_READONLY /* write to priv pg -> copy & make writable */
170#define __P011 PAGE_READONLY /* ditto */
171#define __P100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)
172#define __P101 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
173#define __P110 PAGE_COPY_EXEC
174#define __P111 PAGE_COPY_EXEC
175
176#define __S000 PAGE_NONE
177#define __S001 PAGE_READONLY
178#define __S010 PAGE_SHARED /* we don't have (and don't need) write-only */
179#define __S011 PAGE_SHARED
180#define __S100 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_X_RX)
181#define __S101 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
182#define __S110 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
183#define __S111 __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RWX)
184
185#define pgd_ERROR(e) printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
186#ifdef CONFIG_PGTABLE_4
187#define pud_ERROR(e) printk("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
188#endif
189#define pmd_ERROR(e) printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
190#define pte_ERROR(e) printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
191
192
193/*
194 * Some definitions to translate between mem_map, PTEs, and page addresses:
195 */
196
197
198/* Quick test to see if ADDR is a (potentially) valid physical address. */
199static inline long
200ia64_phys_addr_valid (unsigned long addr)
201{
202 return (addr & (local_cpu_data->unimpl_pa_mask)) == 0;
203}
204
205/*
206 * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
207 * memory. For the return value to be meaningful, ADDR must be >=
208 * PAGE_OFFSET. This operation can be relatively expensive (e.g.,
209 * require a hash-, or multi-level tree-lookup or something of that
210 * sort) but it guarantees to return TRUE only if accessing the page
211 * at that address does not cause an error. Note that there may be
212 * addresses for which kern_addr_valid() returns FALSE even though an
213 * access would not cause an error (e.g., this is typically true for
214 * memory mapped I/O regions.
215 *
216 * XXX Need to implement this for IA-64.
217 */
218#define kern_addr_valid(addr) (1)
219
220
221/*
222 * Now come the defines and routines to manage and access the three-level
223 * page table.
224 */
225
226
227#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL)
228#ifdef CONFIG_VIRTUAL_MEM_MAP
229# define VMALLOC_END_INIT (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
230# define VMALLOC_END vmalloc_end
231 extern unsigned long vmalloc_end;
232#else
233#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_SPARSEMEM_VMEMMAP)
234/* SPARSEMEM_VMEMMAP uses half of vmalloc... */
235# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 10)))
236# define vmemmap ((struct page *)VMALLOC_END)
237#else
238# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
239#endif
240#endif
241
242/* fs/proc/kcore.c */
243#define kc_vaddr_to_offset(v) ((v) - RGN_BASE(RGN_GATE))
244#define kc_offset_to_vaddr(o) ((o) + RGN_BASE(RGN_GATE))
245
246#define RGN_MAP_SHIFT (PGDIR_SHIFT + PTRS_PER_PGD_SHIFT - 3)
247#define RGN_MAP_LIMIT ((1UL << RGN_MAP_SHIFT) - PAGE_SIZE) /* per region addr limit */
248
249/*
250 * Conversion functions: convert page frame number (pfn) and a protection value to a page
251 * table entry (pte).
252 */
253#define pfn_pte(pfn, pgprot) \
254({ pte_t __pte; pte_val(__pte) = ((pfn) << PAGE_SHIFT) | pgprot_val(pgprot); __pte; })
255
256/* Extract pfn from pte. */
257#define pte_pfn(_pte) ((pte_val(_pte) & _PFN_MASK) >> PAGE_SHIFT)
258
259#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
260
261/* This takes a physical page address that is used by the remapping functions */
262#define mk_pte_phys(physpage, pgprot) \
263({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
264
265#define pte_modify(_pte, newprot) \
266 (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
267
268#define pte_none(pte) (!pte_val(pte))
269#define pte_present(pte) (pte_val(pte) & (_PAGE_P | _PAGE_PROTNONE))
270#define pte_clear(mm,addr,pte) (pte_val(*(pte)) = 0UL)
271/* pte_page() returns the "struct page *" corresponding to the PTE: */
272#define pte_page(pte) virt_to_page(((pte_val(pte) & _PFN_MASK) + PAGE_OFFSET))
273
274#define pmd_none(pmd) (!pmd_val(pmd))
275#define pmd_bad(pmd) (!ia64_phys_addr_valid(pmd_val(pmd)))
276#define pmd_present(pmd) (pmd_val(pmd) != 0UL)
277#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL)
278#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & _PFN_MASK))
279#define pmd_page(pmd) virt_to_page((pmd_val(pmd) + PAGE_OFFSET))
280
281#define pud_none(pud) (!pud_val(pud))
282#define pud_bad(pud) (!ia64_phys_addr_valid(pud_val(pud)))
283#define pud_present(pud) (pud_val(pud) != 0UL)
284#define pud_clear(pudp) (pud_val(*(pudp)) = 0UL)
285#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & _PFN_MASK))
286#define pud_page(pud) virt_to_page((pud_val(pud) + PAGE_OFFSET))
287
288#ifdef CONFIG_PGTABLE_4
289#define pgd_none(pgd) (!pgd_val(pgd))
290#define pgd_bad(pgd) (!ia64_phys_addr_valid(pgd_val(pgd)))
291#define pgd_present(pgd) (pgd_val(pgd) != 0UL)
292#define pgd_clear(pgdp) (pgd_val(*(pgdp)) = 0UL)
293#define pgd_page_vaddr(pgd) ((unsigned long) __va(pgd_val(pgd) & _PFN_MASK))
294#define pgd_page(pgd) virt_to_page((pgd_val(pgd) + PAGE_OFFSET))
295#endif
296
297/*
298 * The following have defined behavior only work if pte_present() is true.
299 */
300#define pte_write(pte) ((unsigned) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) - 2) <= 4)
301#define pte_exec(pte) ((pte_val(pte) & _PAGE_AR_RX) != 0)
302#define pte_dirty(pte) ((pte_val(pte) & _PAGE_D) != 0)
303#define pte_young(pte) ((pte_val(pte) & _PAGE_A) != 0)
304#define pte_file(pte) ((pte_val(pte) & _PAGE_FILE) != 0)
305#define pte_special(pte) 0
306
307/*
308 * Note: we convert AR_RWX to AR_RX and AR_RW to AR_R by clearing the 2nd bit in the
309 * access rights:
310 */
311#define pte_wrprotect(pte) (__pte(pte_val(pte) & ~_PAGE_AR_RW))
312#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_AR_RW))
313#define pte_mkold(pte) (__pte(pte_val(pte) & ~_PAGE_A))
314#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_A))
315#define pte_mkclean(pte) (__pte(pte_val(pte) & ~_PAGE_D))
316#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_D))
317#define pte_mkhuge(pte) (__pte(pte_val(pte)))
318#define pte_mkspecial(pte) (pte)
319
320/*
321 * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to
322 * sync icache and dcache when we insert *new* executable page.
323 * __ia64_sync_icache_dcache() check Pg_arch_1 bit and flush icache
324 * if necessary.
325 *
326 * set_pte() is also called by the kernel, but we can expect that the kernel
327 * flushes icache explicitly if necessary.
328 */
329#define pte_present_exec_user(pte)\
330 ((pte_val(pte) & (_PAGE_P | _PAGE_PL_MASK | _PAGE_AR_RX)) == \
331 (_PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX))
332
333extern void __ia64_sync_icache_dcache(pte_t pteval);
334static inline void set_pte(pte_t *ptep, pte_t pteval)
335{
336 /* page is present && page is user && page is executable
337 * && (page swapin or new page or page migraton
338 * || copy_on_write with page copying.)
339 */
340 if (pte_present_exec_user(pteval) &&
341 (!pte_present(*ptep) ||
342 pte_pfn(*ptep) != pte_pfn(pteval)))
343 /* load_module() calles flush_icache_range() explicitly*/
344 __ia64_sync_icache_dcache(pteval);
345 *ptep = pteval;
346}
347
348#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
349
350/*
351 * Make page protection values cacheable, uncacheable, or write-
352 * combining. Note that "protection" is really a misnomer here as the
353 * protection value contains the memory attribute bits, dirty bits, and
354 * various other bits as well.
355 */
356#define pgprot_cacheable(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WB)
357#define pgprot_noncached(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_UC)
358#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_WC)
359
360struct file;
361extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
362 unsigned long size, pgprot_t vma_prot);
363#define __HAVE_PHYS_MEM_ACCESS_PROT
364
365static inline unsigned long
366pgd_index (unsigned long address)
367{
368 unsigned long region = address >> 61;
369 unsigned long l1index = (address >> PGDIR_SHIFT) & ((PTRS_PER_PGD >> 3) - 1);
370
371 return (region << (PAGE_SHIFT - 6)) | l1index;
372}
373
374/* The offset in the 1-level directory is given by the 3 region bits
375 (61..63) and the level-1 bits. */
376static inline pgd_t*
377pgd_offset (const struct mm_struct *mm, unsigned long address)
378{
379 return mm->pgd + pgd_index(address);
380}
381
382/* In the kernel's mapped region we completely ignore the region number
383 (since we know it's in region number 5). */
384#define pgd_offset_k(addr) \
385 (init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
386
387/* Look up a pgd entry in the gate area. On IA-64, the gate-area
388 resides in the kernel-mapped segment, hence we use pgd_offset_k()
389 here. */
390#define pgd_offset_gate(mm, addr) pgd_offset_k(addr)
391
392#ifdef CONFIG_PGTABLE_4
393/* Find an entry in the second-level page table.. */
394#define pud_offset(dir,addr) \
395 ((pud_t *) pgd_page_vaddr(*(dir)) + (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1)))
396#endif
397
398/* Find an entry in the third-level page table.. */
399#define pmd_offset(dir,addr) \
400 ((pmd_t *) pud_page_vaddr(*(dir)) + (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1)))
401
402/*
403 * Find an entry in the third-level page table. This looks more complicated than it
404 * should be because some platforms place page tables in high memory.
405 */
406#define pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
407#define pte_offset_kernel(dir,addr) ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(addr))
408#define pte_offset_map(dir,addr) pte_offset_kernel(dir, addr)
409#define pte_offset_map_nested(dir,addr) pte_offset_map(dir, addr)
410#define pte_unmap(pte) do { } while (0)
411#define pte_unmap_nested(pte) do { } while (0)
412
413/* atomic versions of the some PTE manipulations: */
414
415static inline int
416ptep_test_and_clear_young (struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
417{
418#ifdef CONFIG_SMP
419 if (!pte_young(*ptep))
420 return 0;
421 return test_and_clear_bit(_PAGE_A_BIT, ptep);
422#else
423 pte_t pte = *ptep;
424 if (!pte_young(pte))
425 return 0;
426 set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte));
427 return 1;
428#endif
429}
430
431static inline pte_t
432ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
433{
434#ifdef CONFIG_SMP
435 return __pte(xchg((long *) ptep, 0));
436#else
437 pte_t pte = *ptep;
438 pte_clear(mm, addr, ptep);
439 return pte;
440#endif
441}
442
443static inline void
444ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
445{
446#ifdef CONFIG_SMP
447 unsigned long new, old;
448
449 do {
450 old = pte_val(*ptep);
451 new = pte_val(pte_wrprotect(__pte (old)));
452 } while (cmpxchg((unsigned long *) ptep, old, new) != old);
453#else
454 pte_t old_pte = *ptep;
455 set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
456#endif
457}
458
459static inline int
460pte_same (pte_t a, pte_t b)
461{
462 return pte_val(a) == pte_val(b);
463}
464
465#define update_mmu_cache(vma, address, pte) do { } while (0)
466
467extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
468extern void paging_init (void);
469
470/*
471 * Note: The macros below rely on the fact that MAX_SWAPFILES_SHIFT <= number of
472 * bits in the swap-type field of the swap pte. It would be nice to
473 * enforce that, but we can't easily include <linux/swap.h> here.
474 * (Of course, better still would be to define MAX_SWAPFILES_SHIFT here...).
475 *
476 * Format of swap pte:
477 * bit 0 : present bit (must be zero)
478 * bit 1 : _PAGE_FILE (must be zero)
479 * bits 2- 8: swap-type
480 * bits 9-62: swap offset
481 * bit 63 : _PAGE_PROTNONE bit
482 *
483 * Format of file pte:
484 * bit 0 : present bit (must be zero)
485 * bit 1 : _PAGE_FILE (must be one)
486 * bits 2-62: file_offset/PAGE_SIZE
487 * bit 63 : _PAGE_PROTNONE bit
488 */
489#define __swp_type(entry) (((entry).val >> 2) & 0x7f)
490#define __swp_offset(entry) (((entry).val << 1) >> 10)
491#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((long) (offset) << 9) })
492#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
493#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
494
495#define PTE_FILE_MAX_BITS 61
496#define pte_to_pgoff(pte) ((pte_val(pte) << 1) >> 3)
497#define pgoff_to_pte(off) ((pte_t) { ((off) << 2) | _PAGE_FILE })
498
499#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
500 remap_pfn_range(vma, vaddr, pfn, size, prot)
501
502/*
503 * ZERO_PAGE is a global shared page that is always zero: used
504 * for zero-mapped memory areas etc..
505 */
506extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
507extern struct page *zero_page_memmap_ptr;
508#define ZERO_PAGE(vaddr) (zero_page_memmap_ptr)
509
510/* We provide our own get_unmapped_area to cope with VA holes for userland */
511#define HAVE_ARCH_UNMAPPED_AREA
512
513#ifdef CONFIG_HUGETLB_PAGE
514#define HUGETLB_PGDIR_SHIFT (HPAGE_SHIFT + 2*(PAGE_SHIFT-3))
515#define HUGETLB_PGDIR_SIZE (__IA64_UL(1) << HUGETLB_PGDIR_SHIFT)
516#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
517#endif
518
519
520#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
521/*
522 * Update PTEP with ENTRY, which is guaranteed to be a less
523 * restrictive PTE. That is, ENTRY may have the ACCESSED, DIRTY, and
524 * WRITABLE bits turned on, when the value at PTEP did not. The
525 * WRITABLE bit may only be turned if SAFELY_WRITABLE is TRUE.
526 *
527 * SAFELY_WRITABLE is TRUE if we can update the value at PTEP without
528 * having to worry about races. On SMP machines, there are only two
529 * cases where this is true:
530 *
531 * (1) *PTEP has the PRESENT bit turned OFF
532 * (2) ENTRY has the DIRTY bit turned ON
533 *
534 * On ia64, we could implement this routine with a cmpxchg()-loop
535 * which ORs in the _PAGE_A/_PAGE_D bit if they're set in ENTRY.
536 * However, like on x86, we can get a more streamlined version by
537 * observing that it is OK to drop ACCESSED bit updates when
538 * SAFELY_WRITABLE is FALSE. Besides being rare, all that would do is
539 * result in an extra Access-bit fault, which would then turn on the
540 * ACCESSED bit in the low-level fault handler (iaccess_bit or
541 * daccess_bit in ivt.S).
542 */
543#ifdef CONFIG_SMP
544# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
545({ \
546 int __changed = !pte_same(*(__ptep), __entry); \
547 if (__changed && __safely_writable) { \
548 set_pte(__ptep, __entry); \
549 flush_tlb_page(__vma, __addr); \
550 } \
551 __changed; \
552})
553#else
554# define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __safely_writable) \
555({ \
556 int __changed = !pte_same(*(__ptep), __entry); \
557 if (__changed) { \
558 set_pte_at((__vma)->vm_mm, (__addr), __ptep, __entry); \
559 flush_tlb_page(__vma, __addr); \
560 } \
561 __changed; \
562})
563#endif
564
565# ifdef CONFIG_VIRTUAL_MEM_MAP
566 /* arch mem_map init routine is needed due to holes in a virtual mem_map */
567# define __HAVE_ARCH_MEMMAP_INIT
568 extern void memmap_init (unsigned long size, int nid, unsigned long zone,
569 unsigned long start_pfn);
570# endif /* CONFIG_VIRTUAL_MEM_MAP */
571# endif /* !__ASSEMBLY__ */
572
573/*
574 * Identity-mapped regions use a large page size. We'll call such large pages
575 * "granules". If you can think of a better name that's unambiguous, let me
576 * know...
577 */
578#if defined(CONFIG_IA64_GRANULE_64MB)
579# define IA64_GRANULE_SHIFT _PAGE_SIZE_64M
580#elif defined(CONFIG_IA64_GRANULE_16MB)
581# define IA64_GRANULE_SHIFT _PAGE_SIZE_16M
582#endif
583#define IA64_GRANULE_SIZE (1 << IA64_GRANULE_SHIFT)
584/*
585 * log2() of the page size we use to map the kernel image (IA64_TR_KERNEL):
586 */
587#define KERNEL_TR_PAGE_SHIFT _PAGE_SIZE_64M
588#define KERNEL_TR_PAGE_SIZE (1 << KERNEL_TR_PAGE_SHIFT)
589
590/*
591 * No page table caches to initialise
592 */
593#define pgtable_cache_init() do { } while (0)
594
595/* These tell get_user_pages() that the first gate page is accessible from user-level. */
596#define FIXADDR_USER_START GATE_ADDR
597#ifdef HAVE_BUGGY_SEGREL
598# define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE)
599#else
600# define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE)
601#endif
602
603#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
604#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
605#define __HAVE_ARCH_PTEP_SET_WRPROTECT
606#define __HAVE_ARCH_PTE_SAME
607#define __HAVE_ARCH_PGD_OFFSET_GATE
608
609
610#ifndef CONFIG_PGTABLE_4
611#include <asm-generic/pgtable-nopud.h>
612#endif
613#include <asm-generic/pgtable.h>
614
615#endif /* _ASM_IA64_PGTABLE_H */