stm32mp1_helper.S 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <platform_def.h>
  7. #include <arch.h>
  8. #include <asm_macros.S>
  9. #include <common/bl_common.h>
  10. #include <drivers/st/stm32_gpio.h>
  11. #define GPIO_TX_SHIFT (DEBUG_UART_TX_GPIO_PORT << 1)
  12. .globl platform_mem_init
  13. .globl plat_report_exception
  14. .globl plat_report_prefetch_abort
  15. .globl plat_report_data_abort
  16. .globl plat_get_my_entrypoint
  17. .globl plat_secondary_cold_boot_setup
  18. .globl plat_reset_handler
  19. .globl plat_is_my_cpu_primary
  20. .globl plat_my_core_pos
  21. .globl plat_crash_console_init
  22. .globl plat_crash_console_flush
  23. .globl plat_crash_console_putc
  24. .globl plat_panic_handler
  25. func platform_mem_init
  26. /* Nothing to do, don't need to init SYSRAM */
  27. bx lr
  28. endfunc platform_mem_init
  29. #if DEBUG
  30. func plat_report_exception
  31. mov r8, lr
  32. /*
  33. * Test if an abort occurred
  34. * In this case the error message has already been displayed
  35. * by dedicated functions
  36. */
  37. cmp r0, #MODE32_abt
  38. beq 1f
  39. /* Test for an undefined instruction */
  40. cmp r0, #MODE32_und
  41. bne other_exception_lbl
  42. ldr r4, =undefined_str
  43. bl asm_print_str
  44. mrs r4, lr_und
  45. b print_exception_info
  46. other_exception_lbl:
  47. /* Other exceptions */
  48. mov r9, r0
  49. ldr r4, =exception_start_str
  50. bl asm_print_str
  51. mov r4, r9
  52. bl asm_print_hex
  53. ldr r4, =exception_end_str
  54. bl asm_print_str
  55. mov r4, r6
  56. print_exception_info:
  57. bl asm_print_hex
  58. ldr r4, =end_error_str
  59. bl asm_print_str
  60. 1:
  61. bx r8
  62. endfunc plat_report_exception
  63. func plat_report_prefetch_abort
  64. mov r8, lr
  65. mov r9, r0
  66. ldr r4, =prefetch_abort_str
  67. bl asm_print_str
  68. mov r4, r9
  69. sub r4, r4, #4
  70. bl asm_print_hex
  71. ldr r4, =ifsr_str
  72. bl asm_print_str
  73. ldcopr r4, IFSR
  74. bl asm_print_hex
  75. ldr r4, =ifar_str
  76. bl asm_print_str
  77. ldcopr r4, IFAR
  78. bl asm_print_hex
  79. ldr r4, =end_error_str
  80. bl asm_print_str
  81. bx r8
  82. endfunc plat_report_prefetch_abort
  83. func plat_report_data_abort
  84. mov r8, lr
  85. mov r9, r0
  86. ldr r4, =data_abort_str
  87. bl asm_print_str
  88. mov r4, r9
  89. sub r4, r4, #8
  90. bl asm_print_hex
  91. ldr r4, =dfsr_str
  92. bl asm_print_str
  93. ldcopr r4, DFSR
  94. bl asm_print_hex
  95. ldr r4, =dfar_str
  96. bl asm_print_str
  97. ldcopr r4, DFAR
  98. bl asm_print_hex
  99. ldr r4, =end_error_str
  100. bl asm_print_str
  101. bx r8
  102. endfunc plat_report_data_abort
  103. #endif /* DEBUG */
  104. func plat_reset_handler
  105. bx lr
  106. endfunc plat_reset_handler
  107. /* ------------------------------------------------------------------
  108. * unsigned long plat_get_my_entrypoint (void);
  109. *
  110. * Main job of this routine is to distinguish between a cold and warm
  111. * boot.
  112. *
  113. * Currently supports only cold boot
  114. * ------------------------------------------------------------------
  115. */
  116. func plat_get_my_entrypoint
  117. mov r0, #0
  118. bx lr
  119. endfunc plat_get_my_entrypoint
  120. /* ---------------------------------------------
  121. * void plat_secondary_cold_boot_setup (void);
  122. *
  123. * Cold-booting secondary CPUs is not supported.
  124. * ---------------------------------------------
  125. */
  126. func plat_secondary_cold_boot_setup
  127. b .
  128. endfunc plat_secondary_cold_boot_setup
  129. /* -----------------------------------------------------
  130. * unsigned int plat_is_my_cpu_primary (void);
  131. *
  132. * Find out whether the current cpu is the primary cpu.
  133. * -----------------------------------------------------
  134. */
  135. func plat_is_my_cpu_primary
  136. ldcopr r0, MPIDR
  137. ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
  138. and r0, r1
  139. cmp r0, #STM32MP_PRIMARY_CPU
  140. moveq r0, #1
  141. movne r0, #0
  142. bx lr
  143. endfunc plat_is_my_cpu_primary
  144. /* -------------------------------------------
  145. * int plat_stm32mp1_get_core_pos(int mpidr);
  146. *
  147. * Return CorePos = (ClusterId * 4) + CoreId
  148. * -------------------------------------------
  149. */
  150. func plat_stm32mp1_get_core_pos
  151. and r1, r0, #MPIDR_CPU_MASK
  152. and r0, r0, #MPIDR_CLUSTER_MASK
  153. add r0, r1, r0, LSR #6
  154. bx lr
  155. endfunc plat_stm32mp1_get_core_pos
  156. /* ------------------------------------
  157. * unsigned int plat_my_core_pos(void)
  158. * ------------------------------------
  159. */
  160. func plat_my_core_pos
  161. ldcopr r0, MPIDR
  162. b plat_stm32mp1_get_core_pos
  163. endfunc plat_my_core_pos
  164. /* ---------------------------------------------
  165. * int plat_crash_console_init(void)
  166. *
  167. * Initialize the crash console without a C Runtime stack.
  168. * ---------------------------------------------
  169. */
  170. func plat_crash_console_init
  171. /* Reset UART peripheral */
  172. ldr r1, =(RCC_BASE + DEBUG_UART_RST_REG)
  173. ldr r2, =DEBUG_UART_RST_BIT
  174. str r2, [r1]
  175. 1:
  176. ldr r0, [r1]
  177. ands r2, r0, r2
  178. beq 1b
  179. str r2, [r1, #4] /* RSTCLR register */
  180. 2:
  181. ldr r0, [r1]
  182. ands r2, r0, r2
  183. bne 2b
  184. /* Enable GPIOs for UART TX */
  185. ldr r1, =(RCC_BASE + DEBUG_UART_TX_GPIO_BANK_CLK_REG)
  186. ldr r2, [r1]
  187. /* Configure GPIO */
  188. orr r2, r2, #DEBUG_UART_TX_GPIO_BANK_CLK_EN
  189. str r2, [r1]
  190. ldr r1, =DEBUG_UART_TX_GPIO_BANK_ADDRESS
  191. /* Set GPIO mode alternate */
  192. ldr r2, [r1, #GPIO_MODE_OFFSET]
  193. bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
  194. orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
  195. str r2, [r1, #GPIO_MODE_OFFSET]
  196. /* Set GPIO speed low */
  197. ldr r2, [r1, #GPIO_SPEED_OFFSET]
  198. bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
  199. str r2, [r1, #GPIO_SPEED_OFFSET]
  200. /* Set no-pull */
  201. ldr r2, [r1, #GPIO_PUPD_OFFSET]
  202. bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
  203. str r2, [r1, #GPIO_PUPD_OFFSET]
  204. /* Set alternate */
  205. #if DEBUG_UART_TX_GPIO_PORT >= GPIO_ALT_LOWER_LIMIT
  206. ldr r2, [r1, #GPIO_AFRH_OFFSET]
  207. bic r2, r2, #(GPIO_ALTERNATE_MASK << \
  208. ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
  209. orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << \
  210. ((DEBUG_UART_TX_GPIO_PORT - GPIO_ALT_LOWER_LIMIT) << 2))
  211. str r2, [r1, #GPIO_AFRH_OFFSET]
  212. #else
  213. ldr r2, [r1, #GPIO_AFRL_OFFSET]
  214. bic r2, r2, #(GPIO_ALTERNATE_MASK << (DEBUG_UART_TX_GPIO_PORT << 2))
  215. orr r2, r2, #(DEBUG_UART_TX_GPIO_ALTERNATE << (DEBUG_UART_TX_GPIO_PORT << 2))
  216. str r2, [r1, #GPIO_AFRL_OFFSET]
  217. #endif
  218. /* Enable UART clock, with its source */
  219. ldr r1, =(RCC_BASE + DEBUG_UART_TX_CLKSRC_REG)
  220. mov r2, #DEBUG_UART_TX_CLKSRC
  221. str r2, [r1]
  222. ldr r1, =(RCC_BASE + DEBUG_UART_TX_EN_REG)
  223. ldr r2, [r1]
  224. orr r2, r2, #DEBUG_UART_TX_EN
  225. str r2, [r1]
  226. ldr r0, =STM32MP_DEBUG_USART_BASE
  227. ldr r1, =STM32MP_DEBUG_USART_CLK_FRQ
  228. ldr r2, =STM32MP_UART_BAUDRATE
  229. b console_stm32_core_init
  230. endfunc plat_crash_console_init
  231. /* ---------------------------------------------
  232. * void plat_crash_console_flush(void)
  233. *
  234. * Flush the crash console without a C Runtime stack.
  235. * ---------------------------------------------
  236. */
  237. func plat_crash_console_flush
  238. ldr r0, =STM32MP_DEBUG_USART_BASE
  239. b console_stm32_core_flush
  240. endfunc plat_crash_console_flush
  241. /* ---------------------------------------------
  242. * int plat_crash_console_putc(int c)
  243. *
  244. * Print a character on the crash console without a C Runtime stack.
  245. * Clobber list : r1 - r3
  246. *
  247. * In case of bootloading through uart, we keep console crash as this.
  248. * Characters could be sent to the programmer, but will be ignored.
  249. * No specific code in that case.
  250. * ---------------------------------------------
  251. */
  252. func plat_crash_console_putc
  253. ldr r1, =STM32MP_DEBUG_USART_BASE
  254. b console_stm32_core_putc
  255. endfunc plat_crash_console_putc
  256. /* ----------------------------------------------------------
  257. * void plat_panic_handler(void) __dead2;
  258. * Report exception + endless loop.
  259. *
  260. * r6 holds the address where the fault occurred.
  261. * Filling lr with this value allows debuggers to reconstruct
  262. * the backtrace.
  263. * ----------------------------------------------------------
  264. */
  265. func plat_panic_handler
  266. mrs r0, cpsr
  267. and r0, #MODE32_MASK
  268. bl plat_report_exception
  269. mov lr, r6
  270. b .
  271. endfunc plat_panic_handler
  272. #if DEBUG
  273. .section .rodata.rev_err_str, "aS"
  274. prefetch_abort_str:
  275. .asciz "\nPrefetch Abort at: 0x"
  276. data_abort_str:
  277. .asciz "\nData Abort at: 0x"
  278. undefined_str:
  279. .asciz "\nUndefined instruction at: 0x"
  280. exception_start_str:
  281. .asciz "\nException mode=0x"
  282. exception_end_str:
  283. .asciz " at: 0x"
  284. dfsr_str:
  285. .asciz " DFSR = 0x"
  286. dfar_str:
  287. .asciz " DFAR = 0x"
  288. ifsr_str:
  289. .asciz " IFSR = 0x"
  290. ifar_str:
  291. .asciz " IFAR = 0x"
  292. end_error_str:
  293. .asciz "\n\r"
  294. #endif