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