aboutsummaryrefslogtreecommitdiffstats
path: root/arch/unicore32/include/asm
diff options
context:
space:
mode:
authorGuanXuetao <gxt@mprc.pku.edu.cn>2011-01-15 05:17:56 -0500
committerGuanXuetao <gxt@mprc.pku.edu.cn>2011-03-16 21:19:09 -0400
commit56372b0b2f533c9a25bd40a0577405f6ddb7cff2 (patch)
treec428578bf7392232e946756cfe12e9144122c212 /arch/unicore32/include/asm
parentb50f1704e9c441c58cf6dc05e72953ca30e1d4d2 (diff)
unicore32 core architecture: mm related: fault handling
This patch implements fault handling of memory management. Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch/unicore32/include/asm')
-rw-r--r--arch/unicore32/include/asm/mmu.h17
-rw-r--r--arch/unicore32/include/asm/mmu_context.h87
-rw-r--r--arch/unicore32/include/asm/pgalloc.h110
-rw-r--r--arch/unicore32/include/asm/pgtable-hwdef.h55
-rw-r--r--arch/unicore32/include/asm/pgtable.h317
5 files changed, 586 insertions, 0 deletions
diff --git a/arch/unicore32/include/asm/mmu.h b/arch/unicore32/include/asm/mmu.h
new file mode 100644
index 000000000000..66fa341dc2c6
--- /dev/null
+++ b/arch/unicore32/include/asm/mmu.h
@@ -0,0 +1,17 @@
1/*
2 * linux/arch/unicore32/include/asm/mmu.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_MMU_H__
13#define __UNICORE_MMU_H__
14
15typedef unsigned long mm_context_t;
16
17#endif
diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h
new file mode 100644
index 000000000000..fb5e4c658f7a
--- /dev/null
+++ b/arch/unicore32/include/asm/mmu_context.h
@@ -0,0 +1,87 @@
1/*
2 * linux/arch/unicore32/include/asm/mmu_context.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_MMU_CONTEXT_H__
13#define __UNICORE_MMU_CONTEXT_H__
14
15#include <linux/compiler.h>
16#include <linux/sched.h>
17#include <linux/io.h>
18
19#include <asm/cacheflush.h>
20#include <asm/cpu-single.h>
21
22#define init_new_context(tsk, mm) 0
23
24#define destroy_context(mm) do { } while (0)
25
26/*
27 * This is called when "tsk" is about to enter lazy TLB mode.
28 *
29 * mm: describes the currently active mm context
30 * tsk: task which is entering lazy tlb
31 * cpu: cpu number which is entering lazy tlb
32 *
33 * tsk->mm will be NULL
34 */
35static inline void
36enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
37{
38}
39
40/*
41 * This is the actual mm switch as far as the scheduler
42 * is concerned. No registers are touched. We avoid
43 * calling the CPU specific function when the mm hasn't
44 * actually changed.
45 */
46static inline void
47switch_mm(struct mm_struct *prev, struct mm_struct *next,
48 struct task_struct *tsk)
49{
50 unsigned int cpu = smp_processor_id();
51
52 if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next)
53 cpu_switch_mm(next->pgd, next);
54}
55
56#define deactivate_mm(tsk, mm) do { } while (0)
57#define activate_mm(prev, next) switch_mm(prev, next, NULL)
58
59/*
60 * We are inserting a "fake" vma for the user-accessible vector page so
61 * gdb and friends can get to it through ptrace and /proc/<pid>/mem.
62 * But we also want to remove it before the generic code gets to see it
63 * during process exit or the unmapping of it would cause total havoc.
64 * (the macro is used as remove_vma() is static to mm/mmap.c)
65 */
66#define arch_exit_mmap(mm) \
67do { \
68 struct vm_area_struct *high_vma = find_vma(mm, 0xffff0000); \
69 if (high_vma) { \
70 BUG_ON(high_vma->vm_next); /* it should be last */ \
71 if (high_vma->vm_prev) \
72 high_vma->vm_prev->vm_next = NULL; \
73 else \
74 mm->mmap = NULL; \
75 rb_erase(&high_vma->vm_rb, &mm->mm_rb); \
76 mm->mmap_cache = NULL; \
77 mm->map_count--; \
78 remove_vma(high_vma); \
79 } \
80} while (0)
81
82static inline void arch_dup_mmap(struct mm_struct *oldmm,
83 struct mm_struct *mm)
84{
85}
86
87#endif
diff --git a/arch/unicore32/include/asm/pgalloc.h b/arch/unicore32/include/asm/pgalloc.h
new file mode 100644
index 000000000000..0213e373a895
--- /dev/null
+++ b/arch/unicore32/include/asm/pgalloc.h
@@ -0,0 +1,110 @@
1/*
2 * linux/arch/unicore32/include/asm/pgalloc.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_PGALLOC_H__
13#define __UNICORE_PGALLOC_H__
14
15#include <asm/pgtable-hwdef.h>
16#include <asm/processor.h>
17#include <asm/cacheflush.h>
18#include <asm/tlbflush.h>
19
20#define check_pgt_cache() do { } while (0)
21
22#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
23#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_PRESENT)
24
25extern pgd_t *get_pgd_slow(struct mm_struct *mm);
26extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
27
28#define pgd_alloc(mm) get_pgd_slow(mm)
29#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd)
30
31#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
32
33/*
34 * Allocate one PTE table.
35 */
36static inline pte_t *
37pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
38{
39 pte_t *pte;
40
41 pte = (pte_t *)__get_free_page(PGALLOC_GFP);
42 if (pte)
43 clean_dcache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
44
45 return pte;
46}
47
48static inline pgtable_t
49pte_alloc_one(struct mm_struct *mm, unsigned long addr)
50{
51 struct page *pte;
52
53 pte = alloc_pages(PGALLOC_GFP, 0);
54 if (pte) {
55 if (!PageHighMem(pte)) {
56 void *page = page_address(pte);
57 clean_dcache_area(page, PTRS_PER_PTE * sizeof(pte_t));
58 }
59 pgtable_page_ctor(pte);
60 }
61
62 return pte;
63}
64
65/*
66 * Free one PTE table.
67 */
68static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
69{
70 if (pte)
71 free_page((unsigned long)pte);
72}
73
74static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
75{
76 pgtable_page_dtor(pte);
77 __free_page(pte);
78}
79
80static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
81{
82 set_pmd(pmdp, __pmd(pmdval));
83 flush_pmd_entry(pmdp);
84}
85
86/*
87 * Populate the pmdp entry with a pointer to the pte. This pmd is part
88 * of the mm address space.
89 */
90static inline void
91pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
92{
93 unsigned long pte_ptr = (unsigned long)ptep;
94
95 /*
96 * The pmd must be loaded with the physical
97 * address of the PTE table
98 */
99 __pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
100}
101
102static inline void
103pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
104{
105 __pmd_populate(pmdp,
106 page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
107}
108#define pmd_pgtable(pmd) pmd_page(pmd)
109
110#endif
diff --git a/arch/unicore32/include/asm/pgtable-hwdef.h b/arch/unicore32/include/asm/pgtable-hwdef.h
new file mode 100644
index 000000000000..7314e859cca0
--- /dev/null
+++ b/arch/unicore32/include/asm/pgtable-hwdef.h
@@ -0,0 +1,55 @@
1/*
2 * linux/arch/unicore32/include/asm/pgtable-hwdef.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_PGTABLE_HWDEF_H__
13#define __UNICORE_PGTABLE_HWDEF_H__
14
15/*
16 * Hardware page table definitions.
17 *
18 * + Level 1 descriptor (PMD)
19 * - common
20 */
21#define PMD_TYPE_MASK (3 << 0)
22#define PMD_TYPE_TABLE (0 << 0)
23/*#define PMD_TYPE_LARGE (1 << 0) */
24#define PMD_TYPE_INVALID (2 << 0)
25#define PMD_TYPE_SECT (3 << 0)
26
27#define PMD_PRESENT (1 << 2)
28#define PMD_YOUNG (1 << 3)
29
30/*#define PMD_SECT_DIRTY (1 << 4) */
31#define PMD_SECT_CACHEABLE (1 << 5)
32#define PMD_SECT_EXEC (1 << 6)
33#define PMD_SECT_WRITE (1 << 7)
34#define PMD_SECT_READ (1 << 8)
35
36/*
37 * + Level 2 descriptor (PTE)
38 * - common
39 */
40#define PTE_TYPE_MASK (3 << 0)
41#define PTE_TYPE_SMALL (0 << 0)
42#define PTE_TYPE_MIDDLE (1 << 0)
43#define PTE_TYPE_LARGE (2 << 0)
44#define PTE_TYPE_INVALID (3 << 0)
45
46#define PTE_PRESENT (1 << 2)
47#define PTE_FILE (1 << 3) /* only when !PRESENT */
48#define PTE_YOUNG (1 << 3)
49#define PTE_DIRTY (1 << 4)
50#define PTE_CACHEABLE (1 << 5)
51#define PTE_EXEC (1 << 6)
52#define PTE_WRITE (1 << 7)
53#define PTE_READ (1 << 8)
54
55#endif
diff --git a/arch/unicore32/include/asm/pgtable.h b/arch/unicore32/include/asm/pgtable.h
new file mode 100644
index 000000000000..68b2f297ac97
--- /dev/null
+++ b/arch/unicore32/include/asm/pgtable.h
@@ -0,0 +1,317 @@
1/*
2 * linux/arch/unicore32/include/asm/pgtable.h
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Copyright (C) 2001-2010 GUAN Xue-tao
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#ifndef __UNICORE_PGTABLE_H__
13#define __UNICORE_PGTABLE_H__
14
15#include <asm-generic/pgtable-nopmd.h>
16#include <asm/cpu-single.h>
17
18#include <asm/memory.h>
19#include <asm/pgtable-hwdef.h>
20
21/*
22 * Just any arbitrary offset to the start of the vmalloc VM area: the
23 * current 8MB value just means that there will be a 8MB "hole" after the
24 * physical memory until the kernel virtual memory starts. That means that
25 * any out-of-bounds memory accesses will hopefully be caught.
26 * The vmalloc() routines leaves a hole of 4kB between each vmalloced
27 * area for the same reason. ;)
28 *
29 * Note that platforms may override VMALLOC_START, but they must provide
30 * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space,
31 * which may not overlap IO space.
32 */
33#ifndef VMALLOC_START
34#define VMALLOC_OFFSET SZ_8M
35#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) \
36 & ~(VMALLOC_OFFSET-1))
37#define VMALLOC_END (0xff000000UL)
38#endif
39
40#define PTRS_PER_PTE 1024
41#define PTRS_PER_PGD 1024
42
43/*
44 * PGDIR_SHIFT determines what a third-level page table entry can map
45 */
46#define PGDIR_SHIFT 22
47
48#ifndef __ASSEMBLY__
49extern void __pte_error(const char *file, int line, unsigned long val);
50extern void __pgd_error(const char *file, int line, unsigned long val);
51
52#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte))
53#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd))
54#endif /* !__ASSEMBLY__ */
55
56#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
57#define PGDIR_MASK (~(PGDIR_SIZE-1))
58
59/*
60 * This is the lowest virtual address we can permit any user space
61 * mapping to be mapped at. This is particularly important for
62 * non-high vector CPUs.
63 */
64#define FIRST_USER_ADDRESS PAGE_SIZE
65
66#define FIRST_USER_PGD_NR 1
67#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR)
68
69/*
70 * section address mask and size definitions.
71 */
72#define SECTION_SHIFT 22
73#define SECTION_SIZE (1UL << SECTION_SHIFT)
74#define SECTION_MASK (~(SECTION_SIZE-1))
75
76#ifndef __ASSEMBLY__
77
78/*
79 * The pgprot_* and protection_map entries will be fixed up in runtime
80 * to include the cachable bits based on memory policy, as well as any
81 * architecture dependent bits.
82 */
83#define _PTE_DEFAULT (PTE_PRESENT | PTE_YOUNG | PTE_CACHEABLE)
84
85extern pgprot_t pgprot_user;
86extern pgprot_t pgprot_kernel;
87
88#define PAGE_NONE pgprot_user
89#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user | PTE_READ \
90 | PTE_WRITE)
91#define PAGE_SHARED_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
92 | PTE_WRITE \
93 | PTE_EXEC)
94#define PAGE_COPY __pgprot(pgprot_val(pgprot_user | PTE_READ)
95#define PAGE_COPY_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
96 | PTE_EXEC)
97#define PAGE_READONLY __pgprot(pgprot_val(pgprot_user | PTE_READ)
98#define PAGE_READONLY_EXEC __pgprot(pgprot_val(pgprot_user | PTE_READ \
99 | PTE_EXEC)
100#define PAGE_KERNEL pgprot_kernel
101#define PAGE_KERNEL_EXEC __pgprot(pgprot_val(pgprot_kernel | PTE_EXEC))
102
103#define __PAGE_NONE __pgprot(_PTE_DEFAULT)
104#define __PAGE_SHARED __pgprot(_PTE_DEFAULT | PTE_READ \
105 | PTE_WRITE)
106#define __PAGE_SHARED_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
107 | PTE_WRITE \
108 | PTE_EXEC)
109#define __PAGE_COPY __pgprot(_PTE_DEFAULT | PTE_READ)
110#define __PAGE_COPY_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
111 | PTE_EXEC)
112#define __PAGE_READONLY __pgprot(_PTE_DEFAULT | PTE_READ)
113#define __PAGE_READONLY_EXEC __pgprot(_PTE_DEFAULT | PTE_READ \
114 | PTE_EXEC)
115
116#endif /* __ASSEMBLY__ */
117
118/*
119 * The table below defines the page protection levels that we insert into our
120 * Linux page table version. These get translated into the best that the
121 * architecture can perform. Note that on UniCore hardware:
122 * 1) We cannot do execute protection
123 * 2) If we could do execute protection, then read is implied
124 * 3) write implies read permissions
125 */
126#define __P000 __PAGE_NONE
127#define __P001 __PAGE_READONLY
128#define __P010 __PAGE_COPY
129#define __P011 __PAGE_COPY
130#define __P100 __PAGE_READONLY_EXEC
131#define __P101 __PAGE_READONLY_EXEC
132#define __P110 __PAGE_COPY_EXEC
133#define __P111 __PAGE_COPY_EXEC
134
135#define __S000 __PAGE_NONE
136#define __S001 __PAGE_READONLY
137#define __S010 __PAGE_SHARED
138#define __S011 __PAGE_SHARED
139#define __S100 __PAGE_READONLY_EXEC
140#define __S101 __PAGE_READONLY_EXEC
141#define __S110 __PAGE_SHARED_EXEC
142#define __S111 __PAGE_SHARED_EXEC
143
144#ifndef __ASSEMBLY__
145/*
146 * ZERO_PAGE is a global shared page that is always zero: used
147 * for zero-mapped memory areas etc..
148 */
149extern struct page *empty_zero_page;
150#define ZERO_PAGE(vaddr) (empty_zero_page)
151
152#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT)
153#define pfn_pte(pfn, prot) (__pte(((pfn) << PAGE_SHIFT) \
154 | pgprot_val(prot)))
155
156#define pte_none(pte) (!pte_val(pte))
157#define pte_clear(mm, addr, ptep) set_pte(ptep, __pte(0))
158#define pte_page(pte) (pfn_to_page(pte_pfn(pte)))
159#define pte_offset_kernel(dir, addr) (pmd_page_vaddr(*(dir)) \
160 + __pte_index(addr))
161
162#define pte_offset_map(dir, addr) (pmd_page_vaddr(*(dir)) \
163 + __pte_index(addr))
164#define pte_unmap(pte) do { } while (0)
165
166#define set_pte(ptep, pte) cpu_set_pte(ptep, pte)
167
168#define set_pte_at(mm, addr, ptep, pteval) \
169 do { \
170 set_pte(ptep, pteval); \
171 } while (0)
172
173/*
174 * The following only work if pte_present() is true.
175 * Undefined behaviour if not..
176 */
177#define pte_present(pte) (pte_val(pte) & PTE_PRESENT)
178#define pte_write(pte) (pte_val(pte) & PTE_WRITE)
179#define pte_dirty(pte) (pte_val(pte) & PTE_DIRTY)
180#define pte_young(pte) (pte_val(pte) & PTE_YOUNG)
181#define pte_exec(pte) (pte_val(pte) & PTE_EXEC)
182#define pte_special(pte) (0)
183
184#define PTE_BIT_FUNC(fn, op) \
185static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
186
187PTE_BIT_FUNC(wrprotect, &= ~PTE_WRITE);
188PTE_BIT_FUNC(mkwrite, |= PTE_WRITE);
189PTE_BIT_FUNC(mkclean, &= ~PTE_DIRTY);
190PTE_BIT_FUNC(mkdirty, |= PTE_DIRTY);
191PTE_BIT_FUNC(mkold, &= ~PTE_YOUNG);
192PTE_BIT_FUNC(mkyoung, |= PTE_YOUNG);
193
194static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
195
196/*
197 * Mark the prot value as uncacheable.
198 */
199#define pgprot_noncached(prot) \
200 __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
201#define pgprot_writecombine(prot) \
202 __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
203#define pgprot_dmacoherent(prot) \
204 __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
205
206#define pmd_none(pmd) (!pmd_val(pmd))
207#define pmd_present(pmd) (pmd_val(pmd) & PMD_PRESENT)
208#define pmd_bad(pmd) (((pmd_val(pmd) & \
209 (PMD_PRESENT | PMD_TYPE_MASK)) \
210 != (PMD_PRESENT | PMD_TYPE_TABLE)))
211
212#define set_pmd(pmdpd, pmdval) \
213 do { \
214 *(pmdpd) = pmdval; \
215 } while (0)
216
217#define pmd_clear(pmdp) \
218 do { \
219 set_pmd(pmdp, __pmd(0));\
220 clean_pmd_entry(pmdp); \
221 } while (0)
222
223#define pmd_page_vaddr(pmd) ((pte_t *)__va(pmd_val(pmd) & PAGE_MASK))
224#define pmd_page(pmd) pfn_to_page(__phys_to_pfn(pmd_val(pmd)))
225
226/*
227 * Conversion functions: convert a page and protection to a page entry,
228 * and a page entry and page directory to the page they refer to.
229 */
230#define mk_pte(page, prot) pfn_pte(page_to_pfn(page), prot)
231
232/* to find an entry in a page-table-directory */
233#define pgd_index(addr) ((addr) >> PGDIR_SHIFT)
234
235#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr))
236
237/* to find an entry in a kernel page-table-directory */
238#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
239
240/* Find an entry in the third-level page table.. */
241#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
242
243static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
244{
245 const unsigned long mask = PTE_EXEC | PTE_WRITE | PTE_READ;
246 pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
247 return pte;
248}
249
250extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
251
252/*
253 * Encode and decode a swap entry. Swap entries are stored in the Linux
254 * page tables as follows:
255 *
256 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
257 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
258 * <--------------- offset --------------> <--- type --> 0 0 0 0 0
259 *
260 * This gives us up to 127 swap files and 32GB per swap file. Note that
261 * the offset field is always non-zero.
262 */
263#define __SWP_TYPE_SHIFT 5
264#define __SWP_TYPE_BITS 7
265#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
266#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
267
268#define __swp_type(x) (((x).val >> __SWP_TYPE_SHIFT) \
269 & __SWP_TYPE_MASK)
270#define __swp_offset(x) ((x).val >> __SWP_OFFSET_SHIFT)
271#define __swp_entry(type, offset) ((swp_entry_t) { \
272 ((type) << __SWP_TYPE_SHIFT) | \
273 ((offset) << __SWP_OFFSET_SHIFT) })
274
275#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
276#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val })
277
278/*
279 * It is an error for the kernel to have more swap files than we can
280 * encode in the PTEs. This ensures that we know when MAX_SWAPFILES
281 * is increased beyond what we presently support.
282 */
283#define MAX_SWAPFILES_CHECK() \
284 BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
285
286/*
287 * Encode and decode a file entry. File entries are stored in the Linux
288 * page tables as follows:
289 *
290 * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
291 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
292 * <----------------------- offset ----------------------> 1 0 0 0
293 */
294#define pte_file(pte) (pte_val(pte) & PTE_FILE)
295#define pte_to_pgoff(x) (pte_val(x) >> 4)
296#define pgoff_to_pte(x) __pte(((x) << 4) | PTE_FILE)
297
298#define PTE_FILE_MAX_BITS 28
299
300/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
301/* FIXME: this is not correct */
302#define kern_addr_valid(addr) (1)
303
304#include <asm-generic/pgtable.h>
305
306/*
307 * remap a physical page `pfn' of size `size' with page protection `prot'
308 * into virtual address `from'
309 */
310#define io_remap_pfn_range(vma, from, pfn, size, prot) \
311 remap_pfn_range(vma, from, pfn, size, prot)
312
313#define pgtable_cache_init() do { } while (0)
314
315#endif /* !__ASSEMBLY__ */
316
317#endif /* __UNICORE_PGTABLE_H__ */