proc-macros.S 8.2 KB

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