Linux-libre 4.4.228-gnu
[librecmc/linux-libre.git] / arch / arm / mm / proc-macros.S
1 /*
2  * We need constants.h for:
3  *  VMA_VM_MM
4  *  VMA_VM_FLAGS
5  *  VM_EXEC
6  */
7 #include <linux/const.h>
8 #include <asm/asm-offsets.h>
9 #include <asm/thread_info.h>
10
11 /*
12  * vma_vm_mm - get mm pointer from vma pointer (vma->vm_mm)
13  */
14         .macro  vma_vm_mm, rd, rn
15         ldr     \rd, [\rn, #VMA_VM_MM]
16         .endm
17
18 /*
19  * vma_vm_flags - get vma->vm_flags
20  */
21         .macro  vma_vm_flags, rd, rn
22         ldr     \rd, [\rn, #VMA_VM_FLAGS]
23         .endm
24
25         .macro  tsk_mm, rd, rn
26         ldr     \rd, [\rn, #TI_TASK]
27         ldr     \rd, [\rd, #TSK_ACTIVE_MM]
28         .endm
29
30 /*
31  * act_mm - get current->active_mm
32  */
33         .macro  act_mm, rd
34         bic     \rd, sp, #(THREAD_SIZE - 1) & ~63
35         bic     \rd, \rd, #63
36         ldr     \rd, [\rd, #TI_TASK]
37         ldr     \rd, [\rd, #TSK_ACTIVE_MM]
38         .endm
39
40 /*
41  * mmid - get context id from mm pointer (mm->context.id)
42  * note, this field is 64bit, so in big-endian the two words are swapped too.
43  */
44         .macro  mmid, rd, rn
45 #ifdef __ARMEB__
46         ldr     \rd, [\rn, #MM_CONTEXT_ID + 4 ]
47 #else
48         ldr     \rd, [\rn, #MM_CONTEXT_ID]
49 #endif
50         .endm
51
52 /*
53  * mask_asid - mask the ASID from the context ID
54  */
55         .macro  asid, rd, rn
56         and     \rd, \rn, #255
57         .endm
58
59         .macro  crval, clear, mmuset, ucset
60 #ifdef CONFIG_MMU
61         .word   \clear
62         .word   \mmuset
63 #else
64         .word   \clear
65         .word   \ucset
66 #endif
67         .endm
68
69 /*
70  * dcache_line_size - get the minimum D-cache line size from the CTR register
71  * on ARMv7.
72  */
73         .macro  dcache_line_size, reg, tmp
74         mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
75         lsr     \tmp, \tmp, #16
76         and     \tmp, \tmp, #0xf                @ cache line size encoding
77         mov     \reg, #4                        @ bytes per word
78         mov     \reg, \reg, lsl \tmp            @ actual cache line size
79         .endm
80
81 /*
82  * icache_line_size - get the minimum I-cache line size from the CTR register
83  * on ARMv7.
84  */
85         .macro  icache_line_size, reg, tmp
86         mrc     p15, 0, \tmp, c0, c0, 1         @ read ctr
87         and     \tmp, \tmp, #0xf                @ cache line size encoding
88         mov     \reg, #4                        @ bytes per word
89         mov     \reg, \reg, lsl \tmp            @ actual cache line size
90         .endm
91
92 /*
93  * Sanity check the PTE configuration for the code below - which makes
94  * certain assumptions about how these bits are laid out.
95  */
96 #ifdef CONFIG_MMU
97 #if L_PTE_SHARED != PTE_EXT_SHARED
98 #error PTE shared bit mismatch
99 #endif
100 #if !defined (CONFIG_ARM_LPAE) && \
101         (L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
102          L_PTE_PRESENT) > L_PTE_SHARED
103 #error Invalid Linux PTE bit settings
104 #endif
105 #endif  /* CONFIG_MMU */
106
107 /*
108  * The ARMv6 and ARMv7 set_pte_ext translation function.
109  *
110  * Permission translation:
111  *  YUWD  APX AP1 AP0   SVC     User
112  *  0xxx   0   0   0    no acc  no acc
113  *  100x   1   0   1    r/o     no acc
114  *  10x0   1   0   1    r/o     no acc
115  *  1011   0   0   1    r/w     no acc
116  *  110x   1   1   1    r/o     r/o
117  *  11x0   1   1   1    r/o     r/o
118  *  1111   0   1   1    r/w     r/w
119  */
120         .macro  armv6_mt_table pfx
121 \pfx\()_mt_table:
122         .long   0x00                                            @ L_PTE_MT_UNCACHED
123         .long   PTE_EXT_TEX(1)                                  @ L_PTE_MT_BUFFERABLE
124         .long   PTE_CACHEABLE                                   @ L_PTE_MT_WRITETHROUGH
125         .long   PTE_CACHEABLE | PTE_BUFFERABLE                  @ L_PTE_MT_WRITEBACK
126         .long   PTE_BUFFERABLE                                  @ L_PTE_MT_DEV_SHARED
127         .long   0x00                                            @ unused
128         .long   0x00                                            @ L_PTE_MT_MINICACHE (not present)
129         .long   PTE_EXT_TEX(1) | PTE_CACHEABLE | PTE_BUFFERABLE @ L_PTE_MT_WRITEALLOC
130         .long   0x00                                            @ unused
131         .long   PTE_EXT_TEX(1)                                  @ L_PTE_MT_DEV_WC
132         .long   0x00                                            @ unused
133         .long   PTE_CACHEABLE | PTE_BUFFERABLE                  @ L_PTE_MT_DEV_CACHED
134         .long   PTE_EXT_TEX(2)                                  @ L_PTE_MT_DEV_NONSHARED
135         .long   0x00                                            @ unused
136         .long   0x00                                            @ unused
137         .long   PTE_CACHEABLE | PTE_BUFFERABLE | PTE_EXT_APX    @ L_PTE_MT_VECTORS
138         .endm
139
140         .macro  armv6_set_pte_ext pfx
141         str     r1, [r0], #2048                 @ linux version
142
143         bic     r3, r1, #0x000003fc
144         bic     r3, r3, #PTE_TYPE_MASK
145         orr     r3, r3, r2
146         orr     r3, r3, #PTE_EXT_AP0 | 2
147
148         adr     ip, \pfx\()_mt_table
149         and     r2, r1, #L_PTE_MT_MASK
150         ldr     r2, [ip, r2]
151
152         eor     r1, r1, #L_PTE_DIRTY
153         tst     r1, #L_PTE_DIRTY|L_PTE_RDONLY
154         orrne   r3, r3, #PTE_EXT_APX
155
156         tst     r1, #L_PTE_USER
157         orrne   r3, r3, #PTE_EXT_AP1
158         tstne   r3, #PTE_EXT_APX
159
160         @ user read-only -> kernel read-only
161         bicne   r3, r3, #PTE_EXT_AP0
162
163         tst     r1, #L_PTE_XN
164         orrne   r3, r3, #PTE_EXT_XN
165
166         eor     r3, r3, r2
167
168         tst     r1, #L_PTE_YOUNG
169         tstne   r1, #L_PTE_PRESENT
170         moveq   r3, #0
171         tstne   r1, #L_PTE_NONE
172         movne   r3, #0
173
174         str     r3, [r0]
175         mcr     p15, 0, r0, c7, c10, 1          @ flush_pte
176         .endm
177
178
179 /*
180  * The ARMv3, ARMv4 and ARMv5 set_pte_ext translation function,
181  * covering most CPUs except Xscale and Xscale 3.
182  *
183  * Permission translation:
184  *  YUWD   AP   SVC     User
185  *  0xxx  0x00  no acc  no acc
186  *  100x  0x00  r/o     no acc
187  *  10x0  0x00  r/o     no acc
188  *  1011  0x55  r/w     no acc
189  *  110x  0xaa  r/w     r/o
190  *  11x0  0xaa  r/w     r/o
191  *  1111  0xff  r/w     r/w
192  */
193         .macro  armv3_set_pte_ext wc_disable=1
194         str     r1, [r0], #2048                 @ linux version
195
196         eor     r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
197
198         bic     r2, r1, #PTE_SMALL_AP_MASK      @ keep C, B bits
199         bic     r2, r2, #PTE_TYPE_MASK
200         orr     r2, r2, #PTE_TYPE_SMALL
201
202         tst     r3, #L_PTE_USER                 @ user?
203         orrne   r2, r2, #PTE_SMALL_AP_URO_SRW
204
205         tst     r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
206         orreq   r2, r2, #PTE_SMALL_AP_UNO_SRW
207
208         tst     r3, #L_PTE_PRESENT | L_PTE_YOUNG        @ present and young?
209         movne   r2, #0
210
211         .if     \wc_disable
212 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
213         tst     r2, #PTE_CACHEABLE
214         bicne   r2, r2, #PTE_BUFFERABLE
215 #endif
216         .endif
217         str     r2, [r0]                @ hardware version
218         .endm
219
220
221 /*
222  * Xscale set_pte_ext translation, split into two halves to cope
223  * with work-arounds.  r3 must be preserved by code between these
224  * two macros.
225  *
226  * Permission translation:
227  *  YUWD  AP    SVC     User
228  *  0xxx  00    no acc  no acc
229  *  100x  00    r/o     no acc
230  *  10x0  00    r/o     no acc
231  *  1011  01    r/w     no acc
232  *  110x  10    r/w     r/o
233  *  11x0  10    r/w     r/o
234  *  1111  11    r/w     r/w
235  */
236         .macro  xscale_set_pte_ext_prologue
237         str     r1, [r0]                        @ linux version
238
239         eor     r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY
240
241         bic     r2, r1, #PTE_SMALL_AP_MASK      @ keep C, B bits
242         orr     r2, r2, #PTE_TYPE_EXT           @ extended page
243
244         tst     r3, #L_PTE_USER                 @ user?
245         orrne   r2, r2, #PTE_EXT_AP_URO_SRW     @ yes -> user r/o, system r/w
246
247         tst     r3, #L_PTE_RDONLY | L_PTE_DIRTY @ write and dirty?
248         orreq   r2, r2, #PTE_EXT_AP_UNO_SRW     @ yes -> user n/a, system r/w
249                                                 @ combined with user -> user r/w
250         .endm
251
252         .macro  xscale_set_pte_ext_epilogue
253         tst     r3, #L_PTE_PRESENT | L_PTE_YOUNG        @ present and young?
254         movne   r2, #0                          @ no -> fault
255
256         str     r2, [r0, #2048]!                @ hardware version
257         mov     ip, #0
258         mcr     p15, 0, r0, c7, c10, 1          @ clean L1 D line
259         mcr     p15, 0, ip, c7, c10, 4          @ data write barrier
260         .endm
261
262 .macro define_processor_functions name:req, dabort:req, pabort:req, nommu=0, suspend=0, bugs=0
263 /*
264  * If we are building for big.Little with branch predictor hardening,
265  * we need the processor function tables to remain available after boot.
266  */
267 #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
268         .section ".rodata"
269 #endif
270         .type   \name\()_processor_functions, #object
271         .align 2
272 ENTRY(\name\()_processor_functions)
273         .word   \dabort
274         .word   \pabort
275         .word   cpu_\name\()_proc_init
276         .word   \bugs
277         .word   cpu_\name\()_proc_fin
278         .word   cpu_\name\()_reset
279         .word   cpu_\name\()_do_idle
280         .word   cpu_\name\()_dcache_clean_area
281         .word   cpu_\name\()_switch_mm
282
283         .if \nommu
284         .word   0
285         .else
286         .word   cpu_\name\()_set_pte_ext
287         .endif
288
289         .if \suspend
290         .word   cpu_\name\()_suspend_size
291 #ifdef CONFIG_ARM_CPU_SUSPEND
292         .word   cpu_\name\()_do_suspend
293         .word   cpu_\name\()_do_resume
294 #else
295         .word   0
296         .word   0
297 #endif
298         .else
299         .word   0
300         .word   0
301         .word   0
302         .endif
303
304         .size   \name\()_processor_functions, . - \name\()_processor_functions
305 #if defined(CONFIG_BIG_LITTLE) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
306         .previous
307 #endif
308 .endm
309
310 .macro define_cache_functions name:req
311         .align 2
312         .type   \name\()_cache_fns, #object
313 ENTRY(\name\()_cache_fns)
314         .long   \name\()_flush_icache_all
315         .long   \name\()_flush_kern_cache_all
316         .long   \name\()_flush_kern_cache_louis
317         .long   \name\()_flush_user_cache_all
318         .long   \name\()_flush_user_cache_range
319         .long   \name\()_coherent_kern_range
320         .long   \name\()_coherent_user_range
321         .long   \name\()_flush_kern_dcache_area
322         .long   \name\()_dma_map_area
323         .long   \name\()_dma_unmap_area
324         .long   \name\()_dma_flush_range
325         .size   \name\()_cache_fns, . - \name\()_cache_fns
326 .endm
327
328 .macro define_tlb_functions name:req, flags_up:req, flags_smp
329         .type   \name\()_tlb_fns, #object
330 ENTRY(\name\()_tlb_fns)
331         .long   \name\()_flush_user_tlb_range
332         .long   \name\()_flush_kern_tlb_range
333         .ifnb \flags_smp
334                 ALT_SMP(.long   \flags_smp )
335                 ALT_UP(.long    \flags_up )
336         .else
337                 .long   \flags_up
338         .endif
339         .size   \name\()_tlb_fns, . - \name\()_tlb_fns
340 .endm
341
342 .macro globl_equ x, y
343         .globl  \x
344         .equ    \x, \y
345 .endm
346
347 .macro  initfn, func, base
348         .long   \func - \base
349 .endm
350
351         /*
352          * Macro to calculate the log2 size for the protection region
353          * registers. This calculates rd = log2(size) - 1.  tmp must
354          * not be the same register as rd.
355          */
356 .macro  pr_sz, rd, size, tmp
357         mov     \tmp, \size, lsr #12
358         mov     \rd, #11
359 1:      movs    \tmp, \tmp, lsr #1
360         addne   \rd, \rd, #1
361         bne     1b
362 .endm
363
364         /*
365          * Macro to generate a protection region register value
366          * given a pre-masked address, size, and enable bit.
367          * Corrupts size.
368          */
369 .macro  pr_val, dest, addr, size, enable
370         pr_sz   \dest, \size, \size             @ calculate log2(size) - 1
371         orr     \dest, \addr, \dest, lsl #1     @ mask in the region size
372         orr     \dest, \dest, \enable
373 .endm