stm32_console.S 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. * Copyright (C) 2023, STMicroelectronics - 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: x0 - console base address
  32. * w1 - Uart clock in Hz
  33. * w2 - Baud rate
  34. * Out: return 1 on success else 0 on error
  35. * Clobber list : x1, x2, x3, x4
  36. * -----------------------------------------------
  37. */
  38. func console_stm32_core_init
  39. /* Check the input base address */
  40. cbz x0, core_init_fail
  41. #if !defined(IMAGE_BL2)
  42. #if STM32MP_RECONFIGURE_CONSOLE
  43. /* UART clock rate is set to 0 in BL32, skip init in that case */
  44. cbz x1, 1f
  45. #else /* STM32MP_RECONFIGURE_CONSOLE */
  46. /* Skip UART initialization if it is already enabled */
  47. ldr w3, [x0, #USART_CR1]
  48. tst w3, #USART_CR1_UE
  49. b.ne 1f
  50. #endif /* STM32MP_RECONFIGURE_CONSOLE */
  51. #endif /* IMAGE_BL2 */
  52. /* Check baud rate and uart clock for sanity */
  53. cbz w1, core_init_fail
  54. cbz w2, core_init_fail
  55. /* Disable UART */
  56. ldr w3, [x0, #USART_CR1]
  57. mov w4, #USART_CR1_UE
  58. bic w3, w3, w4
  59. str w3, [x0, #USART_CR1]
  60. /* Configure UART */
  61. mov w4, #(USART_CR1_TE)
  62. orr w4, w4, #(USART_CR1_FIFOEN)
  63. orr w3, w3, w4
  64. str w3, [x0, #USART_CR1]
  65. ldr w3, [x0, #USART_CR2]
  66. mov w4, #USART_CR2_STOP
  67. bic w3, w3, w4
  68. str w3, [x0, #USART_CR2]
  69. /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
  70. lsr w3, w2, #1
  71. add w3, w1, w3
  72. udiv w3, w3, w2
  73. cmp w3, #16
  74. b.hi 2f
  75. /* Oversampling 8 */
  76. /* Divisor = (2 * Uart clock + (baudrate / 2)) / baudrate */
  77. lsr w3, w2, #1
  78. add w3, w3, w1, lsl #1
  79. udiv w3, w3, w2
  80. and w1, w3, #USART_BRR_DIV_FRACTION
  81. lsr w1, w1, #1
  82. bic w3, w3, #USART_BRR_DIV_FRACTION
  83. orr w3, w3, w1
  84. ldr w1, [x0, #USART_CR1]
  85. orr w1, w1, #USART_CR1_OVER8
  86. str w1, [x0, #USART_CR1]
  87. 2:
  88. str w3, [x0, #USART_BRR]
  89. /* Enable UART */
  90. ldr w3, [x0, #USART_CR1]
  91. mov w4, #USART_CR1_UE
  92. orr w3, w3, w4
  93. str w3, [x0, #USART_CR1]
  94. /* Check TEACK bit */
  95. mov w2, #USART_TIMEOUT
  96. teack_loop:
  97. subs w2, w2, #1
  98. beq core_init_fail
  99. ldr w3, [x0, #USART_ISR]
  100. tst w3, #USART_ISR_TEACK
  101. beq teack_loop
  102. 1:
  103. mov w0, #1
  104. ret
  105. core_init_fail:
  106. mov w0, wzr
  107. ret
  108. endfunc console_stm32_core_init
  109. .globl console_stm32_register
  110. /* -------------------------------------------------------
  111. * int console_stm32_register(uintptr_t baseaddr,
  112. * uint32_t clock, uint32_t baud,
  113. * console_t *console);
  114. * Function to initialize and register a new STM32
  115. * console. Storage passed in for the console struct
  116. * *must* be persistent (i.e. not from the stack).
  117. * In: x0 - UART register base address
  118. * w1 - UART clock in Hz
  119. * w2 - Baud rate
  120. * x3 - pointer to empty console_t struct
  121. * Out: return 1 on success, 0 on error
  122. * Clobber list : x0, x1, x2, x6, x7, x14
  123. * -------------------------------------------------------
  124. */
  125. func console_stm32_register
  126. mov x7, x30
  127. mov x6, x3
  128. cbz x6, register_fail
  129. str x0, [x6, #CONSOLE_T_BASE]
  130. bl console_stm32_core_init
  131. cbz x0, register_fail
  132. mov x0, x6
  133. mov x30, x7
  134. finish_console_register stm32 putc=1, getc=0, flush=1
  135. register_fail:
  136. ret x7
  137. endfunc console_stm32_register
  138. /* --------------------------------------------------------
  139. * int console_stm32_core_putc(int c, uintptr_t base_addr)
  140. * Function to output a character over the console. It
  141. * returns the character printed on success or -1 on error.
  142. * In : w0 - character to be printed
  143. * x1 - console base address
  144. * Out : return -1 on error else return character.
  145. * Clobber list : x2
  146. * --------------------------------------------------------
  147. */
  148. func console_stm32_core_putc
  149. #if ENABLE_ASSERTIONS
  150. cmp x1, #0
  151. ASM_ASSERT(ne)
  152. #endif /* ENABLE_ASSERTIONS */
  153. /* Check Transmit Data Register Empty */
  154. txe_loop:
  155. ldr w2, [x1, #USART_ISR]
  156. tst w2, #USART_ISR_TXE
  157. beq txe_loop
  158. str w0, [x1, #USART_TDR]
  159. /* Check transmit complete flag */
  160. tc_loop:
  161. ldr w2, [x1, #USART_ISR]
  162. tst w2, #USART_ISR_TC
  163. beq tc_loop
  164. ret
  165. endfunc console_stm32_core_putc
  166. /* --------------------------------------------------------
  167. * int console_stm32_putc(int c, console_t *console)
  168. * Function to output a character over the console. It
  169. * returns the character printed on success or -1 on error.
  170. * In : w0 - character to be printed
  171. * x1 - pointer to console_t structure
  172. * Out : return -1 on error else return character.
  173. * Clobber list : x2
  174. * --------------------------------------------------------
  175. */
  176. func console_stm32_putc
  177. #if ENABLE_ASSERTIONS
  178. cmp x1, #0
  179. ASM_ASSERT(ne)
  180. #endif /* ENABLE_ASSERTIONS */
  181. ldr x1, [x1, #CONSOLE_T_BASE]
  182. b console_stm32_core_putc
  183. endfunc console_stm32_putc
  184. /* ---------------------------------------------
  185. * int console_stm32_core_getc(uintptr_t base_addr)
  186. * Function to get a character from the console.
  187. * It returns the character grabbed on success
  188. * or -1 if no character is available.
  189. * In : x0 - console base address
  190. * Out: w0 - character if available, else -1
  191. * Clobber list : x0, x1
  192. * ---------------------------------------------
  193. */
  194. func console_stm32_core_getc
  195. /* Not supported */
  196. mov w0, #-1
  197. ret
  198. endfunc console_stm32_core_getc
  199. /* ---------------------------------------------
  200. * int console_stm32_core_flush(uintptr_t base_addr)
  201. * Function to force a write of all buffered
  202. * data that hasn't been output.
  203. * In : x0 - console base address
  204. * Out : return -1 on error else return 0.
  205. * Clobber list : x0, x1
  206. * ---------------------------------------------
  207. */
  208. func console_stm32_core_flush
  209. #if ENABLE_ASSERTIONS
  210. cmp x0, #0
  211. ASM_ASSERT(ne)
  212. #endif /* ENABLE_ASSERTIONS */
  213. /* Check Transmit Data Register Empty */
  214. txe_loop_3:
  215. ldr w1, [x0, #USART_ISR]
  216. tst w1, #USART_ISR_TXE
  217. beq txe_loop_3
  218. mov w0, #0
  219. ret
  220. endfunc console_stm32_core_flush
  221. /* ---------------------------------------------
  222. * int console_stm32_flush(console_t *console)
  223. * Function to force a write of all buffered
  224. * data that hasn't been output.
  225. * In : x0 - pointer to console_t structure
  226. * Out : return -1 on error else return 0.
  227. * Clobber list : x0, x1
  228. * ---------------------------------------------
  229. */
  230. func console_stm32_flush
  231. #if ENABLE_ASSERTIONS
  232. cmp x0, #0
  233. ASM_ASSERT(ne)
  234. #endif /* ENABLE_ASSERTIONS */
  235. ldr x0, [x0, #CONSOLE_T_BASE]
  236. b console_stm32_core_flush
  237. endfunc console_stm32_flush