diff options
Diffstat (limited to 'include/asm-arm/pgalloc.h')
-rw-r--r-- | include/asm-arm/pgalloc.h | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h new file mode 100644 index 000000000000..e814f8144f8b --- /dev/null +++ b/include/asm-arm/pgalloc.h | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * linux/include/asm-arm/pgalloc.h | ||
3 | * | ||
4 | * Copyright (C) 2000-2001 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef _ASMARM_PGALLOC_H | ||
11 | #define _ASMARM_PGALLOC_H | ||
12 | |||
13 | #include <asm/processor.h> | ||
14 | #include <asm/cacheflush.h> | ||
15 | #include <asm/tlbflush.h> | ||
16 | |||
17 | /* | ||
18 | * Since we have only two-level page tables, these are trivial | ||
19 | */ | ||
20 | #define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) | ||
21 | #define pmd_free(pmd) do { } while (0) | ||
22 | #define pgd_populate(mm,pmd,pte) BUG() | ||
23 | |||
24 | extern pgd_t *get_pgd_slow(struct mm_struct *mm); | ||
25 | extern void free_pgd_slow(pgd_t *pgd); | ||
26 | |||
27 | #define pgd_alloc(mm) get_pgd_slow(mm) | ||
28 | #define pgd_free(pgd) free_pgd_slow(pgd) | ||
29 | |||
30 | #define check_pgt_cache() do { } while (0) | ||
31 | |||
32 | /* | ||
33 | * Allocate one PTE table. | ||
34 | * | ||
35 | * This actually allocates two hardware PTE tables, but we wrap this up | ||
36 | * into one table thus: | ||
37 | * | ||
38 | * +------------+ | ||
39 | * | h/w pt 0 | | ||
40 | * +------------+ | ||
41 | * | h/w pt 1 | | ||
42 | * +------------+ | ||
43 | * | Linux pt 0 | | ||
44 | * +------------+ | ||
45 | * | Linux pt 1 | | ||
46 | * +------------+ | ||
47 | */ | ||
48 | static inline pte_t * | ||
49 | pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) | ||
50 | { | ||
51 | pte_t *pte; | ||
52 | |||
53 | pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); | ||
54 | if (pte) { | ||
55 | clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); | ||
56 | pte += PTRS_PER_PTE; | ||
57 | } | ||
58 | |||
59 | return pte; | ||
60 | } | ||
61 | |||
62 | static inline struct page * | ||
63 | pte_alloc_one(struct mm_struct *mm, unsigned long addr) | ||
64 | { | ||
65 | struct page *pte; | ||
66 | |||
67 | pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); | ||
68 | if (pte) { | ||
69 | void *page = page_address(pte); | ||
70 | clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); | ||
71 | } | ||
72 | |||
73 | return pte; | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Free one PTE table. | ||
78 | */ | ||
79 | static inline void pte_free_kernel(pte_t *pte) | ||
80 | { | ||
81 | if (pte) { | ||
82 | pte -= PTRS_PER_PTE; | ||
83 | free_page((unsigned long)pte); | ||
84 | } | ||
85 | } | ||
86 | |||
87 | static inline void pte_free(struct page *pte) | ||
88 | { | ||
89 | __free_page(pte); | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Populate the pmdp entry with a pointer to the pte. This pmd is part | ||
94 | * of the mm address space. | ||
95 | * | ||
96 | * Ensure that we always set both PMD entries. | ||
97 | */ | ||
98 | static inline void | ||
99 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) | ||
100 | { | ||
101 | unsigned long pte_ptr = (unsigned long)ptep; | ||
102 | unsigned long pmdval; | ||
103 | |||
104 | BUG_ON(mm != &init_mm); | ||
105 | |||
106 | /* | ||
107 | * The pmd must be loaded with the physical | ||
108 | * address of the PTE table | ||
109 | */ | ||
110 | pte_ptr -= PTRS_PER_PTE * sizeof(void *); | ||
111 | pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; | ||
112 | pmdp[0] = __pmd(pmdval); | ||
113 | pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); | ||
114 | flush_pmd_entry(pmdp); | ||
115 | } | ||
116 | |||
117 | static inline void | ||
118 | pmd_populate(struct mm_struct *mm, pmd_t *pmdp, struct page *ptep) | ||
119 | { | ||
120 | unsigned long pmdval; | ||
121 | |||
122 | BUG_ON(mm == &init_mm); | ||
123 | |||
124 | pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; | ||
125 | pmdp[0] = __pmd(pmdval); | ||
126 | pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); | ||
127 | flush_pmd_entry(pmdp); | ||
128 | } | ||
129 | |||
130 | #endif | ||