stm32_console.S 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <asm_macros.S>
  7. #include <assert_macros.S>
  8. #include <console_macros.S>
  9. #include <drivers/st/stm32_console.h>
  10. #include <drivers/st/stm32_uart_regs.h>
  11. #define USART_TIMEOUT 0x1000
  12. /*
  13. * "core" functions are low-level implementations that don't require
  14. * writeable memory and are thus safe to call in BL1 crash context.
  15. */
  16. .globl console_stm32_core_init
  17. .globl console_stm32_core_putc
  18. .globl console_stm32_core_getc
  19. .globl console_stm32_core_flush
  20. .globl console_stm32_putc
  21. .globl console_stm32_flush
  22. /* -----------------------------------------------------------------
  23. * int console_core_init(uintptr_t base_addr,
  24. * unsigned int uart_clk,
  25. * unsigned int baud_rate)
  26. *
  27. * Function to initialize the console without a C Runtime to print
  28. * debug information. This function will be accessed by console_init
  29. * and crash reporting.
  30. *
  31. * In: r0 - console base address
  32. * r1 - Uart clock in Hz
  33. * r2 - Baud rate
  34. * Out: return 1 on success else 0 on error
  35. * Clobber list : r1, r2, r3
  36. * -----------------------------------------------------------------
  37. */
  38. func console_stm32_core_init
  39. /* Check the input base address */
  40. cmp r0, #0
  41. beq core_init_fail
  42. #if !defined(IMAGE_BL2)
  43. #if STM32MP_RECONFIGURE_CONSOLE
  44. /* UART clock rate is set to 0 in BL32, skip init in that case */
  45. cmp r1, #0
  46. beq 1f
  47. #else /* STM32MP_RECONFIGURE_CONSOLE */
  48. /* Skip UART initialization if it is already enabled */
  49. ldr r3, [r0, #USART_CR1]
  50. ands r3, r3, #USART_CR1_UE
  51. bne 1f
  52. #endif /* STM32MP_RECONFIGURE_CONSOLE */
  53. #endif /* IMAGE_BL2 */
  54. /* Check baud rate and uart clock for sanity */
  55. cmp r1, #0
  56. beq core_init_fail
  57. cmp r2, #0
  58. beq core_init_fail
  59. /* Disable UART */
  60. ldr r3, [r0, #USART_CR1]
  61. bic r3, r3, #USART_CR1_UE
  62. str r3, [r0, #USART_CR1]
  63. /* Configure UART */
  64. orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
  65. str r3, [r0, #USART_CR1]
  66. ldr r3, [r0, #USART_CR2]
  67. bic r3, r3, #USART_CR2_STOP
  68. str r3, [r0, #USART_CR2]
  69. /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
  70. lsr r3, r2, #1
  71. add r3, r1, r3
  72. udiv r3, r3, r2
  73. cmp r3, #16
  74. bhi 2f
  75. /* Oversampling 8 */
  76. /* Divisor = (2 * Uart clock + (baudrate / 2)) / baudrate */
  77. lsr r3, r2, #1
  78. add r3, r3, r1, lsl #1
  79. udiv r3, r3, r2
  80. and r1, r3, #USART_BRR_DIV_FRACTION
  81. lsr r1, r1, #1
  82. bic r3, r3, #USART_BRR_DIV_FRACTION
  83. orr r3, r3, r1
  84. ldr r1, [r0, #USART_CR1]
  85. orr r1, r1, #USART_CR1_OVER8
  86. str r1, [r0, #USART_CR1]
  87. 2:
  88. str r3, [r0, #USART_BRR]
  89. /* Enable UART */
  90. ldr r3, [r0, #USART_CR1]
  91. orr r3, r3, #USART_CR1_UE
  92. str r3, [r0, #USART_CR1]
  93. /* Check TEACK bit */
  94. mov r2, #USART_TIMEOUT
  95. teack_loop:
  96. subs r2, r2, #1
  97. beq core_init_fail
  98. ldr r3, [r0, #USART_ISR]
  99. tst r3, #USART_ISR_TEACK
  100. beq teack_loop
  101. 1:
  102. mov r0, #1
  103. bx lr
  104. core_init_fail:
  105. mov r0, #0
  106. bx lr
  107. endfunc console_stm32_core_init
  108. .globl console_stm32_register
  109. /* -------------------------------------------------------
  110. * int console_stm32_register(uintptr_t baseaddr,
  111. * uint32_t clock, uint32_t baud,
  112. * console_t *console);
  113. * Function to initialize and register a new STM32
  114. * console. Storage passed in for the console struct
  115. * *must* be persistent (i.e. not from the stack).
  116. * In: r0 - UART register base address
  117. * r1 - UART clock in Hz
  118. * r2 - Baud rate
  119. * r3 - pointer to empty console_t struct
  120. * Out: return 1 on success, 0 on error
  121. * Clobber list : r0, r1, r2
  122. * -------------------------------------------------------
  123. */
  124. func console_stm32_register
  125. push {r4, lr}
  126. mov r4, r3
  127. cmp r4, #0
  128. beq register_fail
  129. str r0, [r4, #CONSOLE_T_BASE]
  130. bl console_stm32_core_init
  131. cmp r0, #0
  132. beq register_fail
  133. mov r0, r4
  134. pop {r4, lr}
  135. finish_console_register stm32 putc=1, getc=0, flush=1
  136. register_fail:
  137. pop {r4, pc}
  138. endfunc console_stm32_register
  139. /* ---------------------------------------------------------------
  140. * int console_core_putc(int c, uintptr_t base_addr)
  141. *
  142. * Function to output a character over the console. It returns the
  143. * character printed on success or -1 on error.
  144. *
  145. * In : r0 - character to be printed
  146. * r1 - console base address
  147. * Out : return -1 on error else return character.
  148. * Clobber list : r2
  149. * ---------------------------------------------------------------
  150. */
  151. func console_stm32_core_putc
  152. /* Check the input parameter */
  153. cmp r1, #0
  154. beq putc_error
  155. /* Check Transmit Data Register Empty */
  156. txe_loop:
  157. ldr r2, [r1, #USART_ISR]
  158. tst r2, #USART_ISR_TXE
  159. beq txe_loop
  160. str r0, [r1, #USART_TDR]
  161. /* Check transmit complete flag */
  162. tc_loop:
  163. ldr r2, [r1, #USART_ISR]
  164. tst r2, #USART_ISR_TC
  165. beq tc_loop
  166. bx lr
  167. putc_error:
  168. mov r0, #-1
  169. bx lr
  170. endfunc console_stm32_core_putc
  171. /* ------------------------------------------------------------
  172. * int console_stm32_putc(int c, console_t *console)
  173. * Function to output a character over the console. It
  174. * returns the character printed on success or -1 on error.
  175. * In: r0 - character to be printed
  176. * r1 - pointer to console_t structure
  177. * Out : return -1 on error else return character.
  178. * Clobber list: r2
  179. * ------------------------------------------------------------
  180. */
  181. func console_stm32_putc
  182. #if ENABLE_ASSERTIONS
  183. cmp r1, #0
  184. ASM_ASSERT(ne)
  185. #endif /* ENABLE_ASSERTIONS */
  186. ldr r1, [r1, #CONSOLE_T_BASE]
  187. b console_stm32_core_putc
  188. endfunc console_stm32_putc
  189. /* -----------------------------------------------------------
  190. * int console_core_getc(uintptr_t base_addr)
  191. *
  192. * Function to get a character from the console.
  193. * It returns the character grabbed on success or -1 on error.
  194. *
  195. * In : r0 - console base address
  196. * Out : return -1.
  197. * Clobber list : r0, r1
  198. * -----------------------------------------------------------
  199. */
  200. func console_stm32_core_getc
  201. /* Not supported */
  202. mov r0, #-1
  203. bx lr
  204. endfunc console_stm32_core_getc
  205. /* ---------------------------------------------------------------
  206. * void console_core_flush(uintptr_t base_addr)
  207. *
  208. * Function to force a write of all buffered data that hasn't been
  209. * output.
  210. *
  211. * In : r0 - console base address
  212. * Out : void.
  213. * Clobber list : r0, r1
  214. * ---------------------------------------------------------------
  215. */
  216. func console_stm32_core_flush
  217. #if ENABLE_ASSERTIONS
  218. cmp r0, #0
  219. ASM_ASSERT(ne)
  220. #endif /* ENABLE_ASSERTIONS */
  221. /* Skip flush if UART is not enabled */
  222. ldr r1, [r0, #USART_CR1]
  223. tst r1, #USART_CR1_UE
  224. beq 1f
  225. /* Check Transmit Data Register Empty */
  226. txe_loop_3:
  227. ldr r1, [r0, #USART_ISR]
  228. tst r1, #USART_ISR_TXE
  229. beq txe_loop_3
  230. 1:
  231. bx lr
  232. endfunc console_stm32_core_flush
  233. /* ------------------------------------------------------
  234. * void console_stm32_flush(console_t *console)
  235. * Function to force a write of all buffered
  236. * data that hasn't been output.
  237. * In : r0 - pointer to console_t structure
  238. * Out : void.
  239. * Clobber list: r0, r1
  240. * ------------------------------------------------------
  241. */
  242. func console_stm32_flush
  243. #if ENABLE_ASSERTIONS
  244. cmp r0, #0
  245. ASM_ASSERT(ne)
  246. #endif /* ENABLE_ASSERTIONS */
  247. ldr r0, [r0, #CONSOLE_T_BASE]
  248. b console_stm32_core_flush
  249. endfunc console_stm32_flush