proc-v7m.S 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * linux/arch/arm/mm/proc-v7m.S
  4. *
  5. * Copyright (C) 2008 ARM Ltd.
  6. * Copyright (C) 2001 Deep Blue Solutions Ltd.
  7. *
  8. * This is the "shell" of the ARMv7-M processor support.
  9. */
  10. #include <linux/linkage.h>
  11. #include <linux/cfi_types.h>
  12. #include <asm/assembler.h>
  13. #include <asm/page.h>
  14. #include <asm/v7m.h>
  15. #include "proc-macros.S"
  16. SYM_TYPED_FUNC_START(cpu_v7m_proc_init)
  17. ret lr
  18. SYM_FUNC_END(cpu_v7m_proc_init)
  19. SYM_TYPED_FUNC_START(cpu_v7m_proc_fin)
  20. ret lr
  21. SYM_FUNC_END(cpu_v7m_proc_fin)
  22. /*
  23. * cpu_v7m_reset(loc)
  24. *
  25. * Perform a soft reset of the system. Put the CPU into the
  26. * same state as it would be if it had been reset, and branch
  27. * to what would be the reset vector.
  28. *
  29. * - loc - location to jump to for soft reset
  30. */
  31. .align 5
  32. SYM_TYPED_FUNC_START(cpu_v7m_reset)
  33. ret r0
  34. SYM_FUNC_END(cpu_v7m_reset)
  35. /*
  36. * cpu_v7m_do_idle()
  37. *
  38. * Idle the processor (eg, wait for interrupt).
  39. *
  40. * IRQs are already disabled.
  41. */
  42. SYM_TYPED_FUNC_START(cpu_v7m_do_idle)
  43. wfi
  44. ret lr
  45. SYM_FUNC_END(cpu_v7m_do_idle)
  46. SYM_TYPED_FUNC_START(cpu_v7m_dcache_clean_area)
  47. ret lr
  48. SYM_FUNC_END(cpu_v7m_dcache_clean_area)
  49. /*
  50. * There is no MMU, so here is nothing to do.
  51. */
  52. SYM_TYPED_FUNC_START(cpu_v7m_switch_mm)
  53. ret lr
  54. SYM_FUNC_END(cpu_v7m_switch_mm)
  55. .globl cpu_v7m_suspend_size
  56. .equ cpu_v7m_suspend_size, 0
  57. #ifdef CONFIG_ARM_CPU_SUSPEND
  58. SYM_TYPED_FUNC_START(cpu_v7m_do_suspend)
  59. ret lr
  60. SYM_FUNC_END(cpu_v7m_do_suspend)
  61. SYM_TYPED_FUNC_START(cpu_v7m_do_resume)
  62. ret lr
  63. SYM_FUNC_END(cpu_v7m_do_resume)
  64. #endif
  65. SYM_TYPED_FUNC_START(cpu_cm7_dcache_clean_area)
  66. dcache_line_size r2, r3
  67. movw r3, #:lower16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
  68. movt r3, #:upper16:BASEADDR_V7M_SCB + V7M_SCB_DCCMVAC
  69. 1: str r0, [r3] @ clean D entry
  70. add r0, r0, r2
  71. subs r1, r1, r2
  72. bhi 1b
  73. dsb
  74. ret lr
  75. SYM_FUNC_END(cpu_cm7_dcache_clean_area)
  76. SYM_TYPED_FUNC_START(cpu_cm7_proc_fin)
  77. movw r2, #:lower16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
  78. movt r2, #:upper16:(BASEADDR_V7M_SCB + V7M_SCB_CCR)
  79. ldr r0, [r2]
  80. bic r0, r0, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC)
  81. str r0, [r2]
  82. ret lr
  83. SYM_FUNC_END(cpu_cm7_proc_fin)
  84. .section ".init.text", "ax"
  85. __v7m_cm7_setup:
  86. mov r8, #(V7M_SCB_CCR_DC | V7M_SCB_CCR_IC| V7M_SCB_CCR_BP)
  87. b __v7m_setup_cont
  88. /*
  89. * __v7m_setup
  90. *
  91. * This should be able to cover all ARMv7-M cores.
  92. */
  93. __v7m_setup:
  94. mov r8, 0
  95. __v7m_setup_cont:
  96. @ Configure the vector table base address
  97. ldr r0, =BASEADDR_V7M_SCB
  98. ldr r12, =vector_table
  99. str r12, [r0, V7M_SCB_VTOR]
  100. @ enable UsageFault, BusFault and MemManage fault.
  101. ldr r5, [r0, #V7M_SCB_SHCSR]
  102. orr r5, #(V7M_SCB_SHCSR_USGFAULTENA | V7M_SCB_SHCSR_BUSFAULTENA | V7M_SCB_SHCSR_MEMFAULTENA)
  103. str r5, [r0, #V7M_SCB_SHCSR]
  104. @ Lower the priority of the SVC and PendSV exceptions
  105. mov r5, #0x80000000
  106. str r5, [r0, V7M_SCB_SHPR2] @ set SVC priority
  107. mov r5, #0x00800000
  108. str r5, [r0, V7M_SCB_SHPR3] @ set PendSV priority
  109. @ SVC to switch to handler mode. Notice that this requires sp to
  110. @ point to writeable memory because the processor saves
  111. @ some registers to the stack.
  112. badr r1, 1f
  113. ldr r5, [r12, #11 * 4] @ read the SVC vector entry
  114. str r1, [r12, #11 * 4] @ write the temporary SVC vector entry
  115. dsb
  116. mov r6, lr @ save LR
  117. ldr sp, =init_thread_union + THREAD_START_SP
  118. cpsie i
  119. svc #0
  120. 1: cpsid i
  121. /* Calculate exc_ret */
  122. orr r10, lr, #EXC_RET_THREADMODE_PROCESSSTACK
  123. ldmia sp, {r0-r3, r12}
  124. str r5, [r12, #11 * 4] @ restore the original SVC vector entry
  125. mov lr, r6 @ restore LR
  126. @ Special-purpose control register
  127. mov r1, #1
  128. msr control, r1 @ Thread mode has unpriviledged access
  129. @ Configure caches (if implemented)
  130. teq r8, #0
  131. stmiane sp, {r0-r6, lr} @ v7m_invalidate_l1 touches r0-r6
  132. blne v7m_invalidate_l1
  133. teq r8, #0 @ re-evalutae condition
  134. ldmiane sp, {r0-r6, lr}
  135. @ Configure the System Control Register to ensure 8-byte stack alignment
  136. @ Note the STKALIGN bit is either RW or RAO.
  137. ldr r0, [r0, V7M_SCB_CCR] @ system control register
  138. orr r0, #V7M_SCB_CCR_STKALIGN
  139. orr r0, r0, r8
  140. ret lr
  141. ENDPROC(__v7m_setup)
  142. /*
  143. * Cortex-M7 processor functions
  144. */
  145. globl_equ cpu_cm7_proc_init, cpu_v7m_proc_init
  146. globl_equ cpu_cm7_reset, cpu_v7m_reset
  147. globl_equ cpu_cm7_do_idle, cpu_v7m_do_idle
  148. globl_equ cpu_cm7_switch_mm, cpu_v7m_switch_mm
  149. define_processor_functions v7m, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
  150. define_processor_functions cm7, dabort=nommu_early_abort, pabort=legacy_pabort, nommu=1
  151. .section ".rodata"
  152. string cpu_arch_name, "armv7m"
  153. string cpu_elf_name "v7m"
  154. string cpu_v7m_name "ARMv7-M"
  155. .section ".proc.info.init", "a"
  156. .macro __v7m_proc name, initfunc, cache_fns = nop_cache_fns, hwcaps = 0, proc_fns = v7m_processor_functions
  157. .long 0 /* proc_info_list.__cpu_mm_mmu_flags */
  158. .long 0 /* proc_info_list.__cpu_io_mmu_flags */
  159. initfn \initfunc, \name
  160. .long cpu_arch_name
  161. .long cpu_elf_name
  162. .long HWCAP_HALF | HWCAP_THUMB | HWCAP_FAST_MULT | \hwcaps
  163. .long cpu_v7m_name
  164. .long \proc_fns
  165. .long 0 /* proc_info_list.tlb */
  166. .long 0 /* proc_info_list.user */
  167. .long \cache_fns
  168. .endm
  169. /*
  170. * Match ARM Cortex-M55 processor.
  171. */
  172. .type __v7m_cm55_proc_info, #object
  173. __v7m_cm55_proc_info:
  174. .long 0x410fd220 /* ARM Cortex-M55 0xD22 */
  175. .long 0xff0ffff0 /* Mask off revision, patch release */
  176. __v7m_proc __v7m_cm55_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions
  177. .size __v7m_cm55_proc_info, . - __v7m_cm55_proc_info
  178. /*
  179. * Match ARM Cortex-M33 processor.
  180. */
  181. .type __v7m_cm33_proc_info, #object
  182. __v7m_cm33_proc_info:
  183. .long 0x410fd210 /* ARM Cortex-M33 0xD21 */
  184. .long 0xff0ffff0 /* Mask off revision, patch release */
  185. __v7m_proc __v7m_cm33_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP
  186. .size __v7m_cm33_proc_info, . - __v7m_cm33_proc_info
  187. /*
  188. * Match ARM Cortex-M7 processor.
  189. */
  190. .type __v7m_cm7_proc_info, #object
  191. __v7m_cm7_proc_info:
  192. .long 0x410fc270 /* ARM Cortex-M7 0xC27 */
  193. .long 0xff0ffff0 /* Mask off revision, patch release */
  194. __v7m_proc __v7m_cm7_proc_info, __v7m_cm7_setup, hwcaps = HWCAP_EDSP, cache_fns = v7m_cache_fns, proc_fns = cm7_processor_functions
  195. .size __v7m_cm7_proc_info, . - __v7m_cm7_proc_info
  196. /*
  197. * Match ARM Cortex-M4 processor.
  198. */
  199. .type __v7m_cm4_proc_info, #object
  200. __v7m_cm4_proc_info:
  201. .long 0x410fc240 /* ARM Cortex-M4 0xC24 */
  202. .long 0xff0ffff0 /* Mask off revision, patch release */
  203. __v7m_proc __v7m_cm4_proc_info, __v7m_setup, hwcaps = HWCAP_EDSP
  204. .size __v7m_cm4_proc_info, . - __v7m_cm4_proc_info
  205. /*
  206. * Match ARM Cortex-M3 processor.
  207. */
  208. .type __v7m_cm3_proc_info, #object
  209. __v7m_cm3_proc_info:
  210. .long 0x410fc230 /* ARM Cortex-M3 0xC23 */
  211. .long 0xff0ffff0 /* Mask off revision, patch release */
  212. __v7m_proc __v7m_cm3_proc_info, __v7m_setup
  213. .size __v7m_cm3_proc_info, . - __v7m_cm3_proc_info
  214. /*
  215. * Match any ARMv7-M processor core.
  216. */
  217. .type __v7m_proc_info, #object
  218. __v7m_proc_info:
  219. .long 0x000f0000 @ Required ID value
  220. .long 0x000f0000 @ Mask for ID
  221. __v7m_proc __v7m_proc_info, __v7m_setup
  222. .size __v7m_proc_info, . - __v7m_proc_info