diff options
Diffstat (limited to 'arch/arm/mm/proc-macros.S')
-rw-r--r-- | arch/arm/mm/proc-macros.S | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index b13150052a76..54b1f721dec8 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -71,3 +71,173 @@ | |||
71 | mov \reg, #16 @ size offset | 71 | mov \reg, #16 @ size offset |
72 | mov \reg, \reg, lsl \tmp @ actual cache line size | 72 | mov \reg, \reg, lsl \tmp @ actual cache line size |
73 | .endm | 73 | .endm |
74 | |||
75 | |||
76 | /* | ||
77 | * Sanity check the PTE configuration for the code below - which makes | ||
78 | * certain assumptions about how these bits are layed out. | ||
79 | */ | ||
80 | #if L_PTE_SHARED != PTE_EXT_SHARED | ||
81 | #error PTE shared bit mismatch | ||
82 | #endif | ||
83 | #if L_PTE_BUFFERABLE != PTE_BUFFERABLE | ||
84 | #error PTE bufferable bit mismatch | ||
85 | #endif | ||
86 | #if L_PTE_CACHEABLE != PTE_CACHEABLE | ||
87 | #error PTE cacheable bit mismatch | ||
88 | #endif | ||
89 | #if (L_PTE_EXEC+L_PTE_USER+L_PTE_WRITE+L_PTE_DIRTY+L_PTE_YOUNG+\ | ||
90 | L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED | ||
91 | #error Invalid Linux PTE bit settings | ||
92 | #endif | ||
93 | |||
94 | /* | ||
95 | * The ARMv6 and ARMv7 set_pte_ext translation function. | ||
96 | * | ||
97 | * Permission translation: | ||
98 | * YUWD APX AP1 AP0 SVC User | ||
99 | * 0xxx 0 0 0 no acc no acc | ||
100 | * 100x 1 0 1 r/o no acc | ||
101 | * 10x0 1 0 1 r/o no acc | ||
102 | * 1011 0 0 1 r/w no acc | ||
103 | * 110x 0 1 0 r/w r/o | ||
104 | * 11x0 0 1 0 r/w r/o | ||
105 | * 1111 0 1 1 r/w r/w | ||
106 | */ | ||
107 | .macro armv6_mt_table pfx | ||
108 | \pfx\()_mt_table: | ||
109 | .long 0x00 @ L_PTE_MT_UNCACHED | ||
110 | .long PTE_EXT_TEX(1) @ L_PTE_MT_BUFFERABLE | ||
111 | .long PTE_CACHEABLE @ L_PTE_MT_WRITETHROUGH | ||
112 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEBACK | ||
113 | .long PTE_BUFFERABLE @ L_PTE_MT_DEV_SHARED | ||
114 | .long 0x00 @ unused | ||
115 | .long 0x00 @ L_PTE_MT_MINICACHE (not present) | ||
116 | .long PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC | ||
117 | .long 0x00 @ unused | ||
118 | .long PTE_EXT_TEX(1) @ L_PTE_MT_DEV_WC | ||
119 | .long 0x00 @ unused | ||
120 | .long PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_DEV_CACHED | ||
121 | .long PTE_EXT_TEX(2) @ L_PTE_MT_DEV_NONSHARED | ||
122 | .long 0x00 @ unused | ||
123 | .long 0x00 @ unused | ||
124 | .long 0x00 @ unused | ||
125 | .endm | ||
126 | |||
127 | .macro armv6_set_pte_ext pfx | ||
128 | str r1, [r0], #-2048 @ linux version | ||
129 | |||
130 | bic r3, r1, #0x000003fc | ||
131 | bic r3, r3, #PTE_TYPE_MASK | ||
132 | orr r3, r3, r2 | ||
133 | orr r3, r3, #PTE_EXT_AP0 | 2 | ||
134 | |||
135 | adr ip, \pfx\()_mt_table | ||
136 | and r2, r1, #L_PTE_MT_MASK | ||
137 | ldr r2, [ip, r2] | ||
138 | |||
139 | tst r1, #L_PTE_WRITE | ||
140 | tstne r1, #L_PTE_DIRTY | ||
141 | orreq r3, r3, #PTE_EXT_APX | ||
142 | |||
143 | tst r1, #L_PTE_USER | ||
144 | orrne r3, r3, #PTE_EXT_AP1 | ||
145 | tstne r3, #PTE_EXT_APX | ||
146 | bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0 | ||
147 | |||
148 | tst r1, #L_PTE_EXEC | ||
149 | orreq r3, r3, #PTE_EXT_XN | ||
150 | |||
151 | orr r3, r3, r2 | ||
152 | |||
153 | tst r1, #L_PTE_YOUNG | ||
154 | tstne r1, #L_PTE_PRESENT | ||
155 | moveq r3, #0 | ||
156 | |||
157 | str r3, [r0] | ||
158 | mcr p15, 0, r0, c7, c10, 1 @ flush_pte | ||
159 | .endm | ||
160 | |||
161 | |||
162 | /* | ||
163 | * The ARMv3, ARMv4 and ARMv5 set_pte_ext translation function, | ||
164 | * covering most CPUs except Xscale and Xscale 3. | ||
165 | * | ||
166 | * Permission translation: | ||
167 | * YUWD AP SVC User | ||
168 | * 0xxx 0x00 no acc no acc | ||
169 | * 100x 0x00 r/o no acc | ||
170 | * 10x0 0x00 r/o no acc | ||
171 | * 1011 0x55 r/w no acc | ||
172 | * 110x 0xaa r/w r/o | ||
173 | * 11x0 0xaa r/w r/o | ||
174 | * 1111 0xff r/w r/w | ||
175 | */ | ||
176 | .macro armv3_set_pte_ext wc_disable=1 | ||
177 | str r1, [r0], #-2048 @ linux version | ||
178 | |||
179 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | ||
180 | |||
181 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits | ||
182 | bic r2, r2, #PTE_TYPE_MASK | ||
183 | orr r2, r2, #PTE_TYPE_SMALL | ||
184 | |||
185 | tst r3, #L_PTE_USER @ user? | ||
186 | orrne r2, r2, #PTE_SMALL_AP_URO_SRW | ||
187 | |||
188 | tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? | ||
189 | orreq r2, r2, #PTE_SMALL_AP_UNO_SRW | ||
190 | |||
191 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? | ||
192 | movne r2, #0 | ||
193 | |||
194 | .if \wc_disable | ||
195 | #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH | ||
196 | tst r2, #PTE_CACHEABLE | ||
197 | bicne r2, r2, #PTE_BUFFERABLE | ||
198 | #endif | ||
199 | .endif | ||
200 | str r2, [r0] @ hardware version | ||
201 | .endm | ||
202 | |||
203 | |||
204 | /* | ||
205 | * Xscale set_pte_ext translation, split into two halves to cope | ||
206 | * with work-arounds. r3 must be preserved by code between these | ||
207 | * two macros. | ||
208 | * | ||
209 | * Permission translation: | ||
210 | * YUWD AP SVC User | ||
211 | * 0xxx 00 no acc no acc | ||
212 | * 100x 00 r/o no acc | ||
213 | * 10x0 00 r/o no acc | ||
214 | * 1011 01 r/w no acc | ||
215 | * 110x 10 r/w r/o | ||
216 | * 11x0 10 r/w r/o | ||
217 | * 1111 11 r/w r/w | ||
218 | */ | ||
219 | .macro xscale_set_pte_ext_prologue | ||
220 | str r1, [r0], #-2048 @ linux version | ||
221 | |||
222 | eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY | ||
223 | |||
224 | bic r2, r1, #PTE_SMALL_AP_MASK @ keep C, B bits | ||
225 | orr r2, r2, #PTE_TYPE_EXT @ extended page | ||
226 | |||
227 | tst r3, #L_PTE_USER @ user? | ||
228 | orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w | ||
229 | |||
230 | tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty? | ||
231 | orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w | ||
232 | @ combined with user -> user r/w | ||
233 | .endm | ||
234 | |||
235 | .macro xscale_set_pte_ext_epilogue | ||
236 | tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young? | ||
237 | movne r2, #0 @ no -> fault | ||
238 | |||
239 | str r2, [r0] @ hardware version | ||
240 | mov ip, #0 | ||
241 | mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line | ||
242 | mcr p15, 0, ip, c7, c10, 4 @ data write barrier | ||
243 | .endm | ||