blob: 686b18b969bfd2023f4b0e6c28dcb875ae560268 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
Jimmy Brisson39f9eee2020-08-05 13:44:05 -05002 * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
Yann Gautier4b0c72a2018-07-16 10:54:09 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <asm_macros.S>
Yann Gautier4518c592018-11-15 09:51:06 +01007#include <assert_macros.S>
Yann Gautier4518c592018-11-15 09:51:06 +01008#include <console_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <drivers/st/stm32_console.h>
10#include <drivers/st/stm32_uart_regs.h>
Yann Gautier4b0c72a2018-07-16 10:54:09 +020011
Yann Gautier69035a82018-07-05 16:48:16 +020012#define USART_TIMEOUT 0x1000
13
Yann Gautier4518c592018-11-15 09:51:06 +010014 /*
15 * "core" functions are low-level implementations that don't require
16 * writeable memory and are thus safe to call in BL1 crash context.
17 */
18 .globl console_stm32_core_init
19 .globl console_stm32_core_putc
20 .globl console_stm32_core_getc
21 .globl console_stm32_core_flush
22
23 .globl console_stm32_putc
24 .globl console_stm32_flush
25
26
Yann Gautier4b0c72a2018-07-16 10:54:09 +020027
28 /* -----------------------------------------------------------------
29 * int console_core_init(uintptr_t base_addr,
30 * unsigned int uart_clk,
31 * unsigned int baud_rate)
32 *
33 * Function to initialize the console without a C Runtime to print
34 * debug information. This function will be accessed by console_init
35 * and crash reporting.
36 *
37 * In: r0 - console base address
38 * r1 - Uart clock in Hz
39 * r2 - Baud rate
40 * Out: return 1 on success else 0 on error
41 * Clobber list : r1, r2, r3
42 * -----------------------------------------------------------------
43 */
Yann Gautier4518c592018-11-15 09:51:06 +010044func console_stm32_core_init
Yann Gautier69035a82018-07-05 16:48:16 +020045 /* Check the input base address */
46 cmp r0, #0
47 beq core_init_fail
48#if defined(IMAGE_BL2)
49 /* Check baud rate and uart clock for sanity */
50 cmp r1, #0
51 beq core_init_fail
52 cmp r2, #0
53 beq core_init_fail
54 /* Disable UART */
55 ldr r3, [r0, #USART_CR1]
56 bic r3, r3, #USART_CR1_UE
57 str r3, [r0, #USART_CR1]
58 /* Configure UART */
59 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
60 str r3, [r0, #USART_CR1]
61 ldr r3, [r0, #USART_CR2]
62 bic r3, r3, #USART_CR2_STOP
63 str r3, [r0, #USART_CR2]
64 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
65 lsl r3, r2, #1
66 add r3, r1, r3
67 udiv r3, r3, r2
68 str r3, [r0, #USART_BRR]
69 /* Enable UART */
70 ldr r3, [r0, #USART_CR1]
71 orr r3, r3, #USART_CR1_UE
72 str r3, [r0, #USART_CR1]
73 /* Check TEACK bit */
74 mov r2, #USART_TIMEOUT
75teack_loop:
76 subs r2, r2, #1
77 beq core_init_fail
78 ldr r3, [r0, #USART_ISR]
79 tst r3, #USART_ISR_TEACK
80 beq teack_loop
81#endif /* IMAGE_BL2 */
82 mov r0, #1
83 bx lr
84core_init_fail:
85 mov r0, #0
Yann Gautier4b0c72a2018-07-16 10:54:09 +020086 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +010087endfunc console_stm32_core_init
88
Yann Gautier4518c592018-11-15 09:51:06 +010089 .globl console_stm32_register
90
91 /* -------------------------------------------------------
92 * int console_stm32_register(uintptr_t baseaddr,
93 * uint32_t clock, uint32_t baud,
Andre Przywara678c6fa2020-01-25 00:58:35 +000094 * console_t *console);
Yann Gautier4518c592018-11-15 09:51:06 +010095 * Function to initialize and register a new STM32
96 * console. Storage passed in for the console struct
97 * *must* be persistent (i.e. not from the stack).
98 * In: r0 - UART register base address
99 * r1 - UART clock in Hz
100 * r2 - Baud rate
Andre Przywara678c6fa2020-01-25 00:58:35 +0000101 * r3 - pointer to empty console_t struct
Yann Gautier4518c592018-11-15 09:51:06 +0100102 * Out: return 1 on success, 0 on error
103 * Clobber list : r0, r1, r2
104 * -------------------------------------------------------
105 */
106func console_stm32_register
107 push {r4, lr}
108 mov r4, r3
109 cmp r4, #0
110 beq register_fail
Andre Przywara678c6fa2020-01-25 00:58:35 +0000111 str r0, [r4, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100112
113 bl console_stm32_core_init
114 cmp r0, #0
115 beq register_fail
116
117 mov r0, r4
118 pop {r4, lr}
119 finish_console_register stm32 putc=1, getc=0, flush=1
120
121register_fail:
122 pop {r4, pc}
123endfunc console_stm32_register
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200124
125 /* ---------------------------------------------------------------
126 * int console_core_putc(int c, uintptr_t base_addr)
127 *
128 * Function to output a character over the console. It returns the
129 * character printed on success or -1 on error.
130 *
131 * In : r0 - character to be printed
132 * r1 - console base address
133 * Out : return -1 on error else return character.
134 * Clobber list : r2
135 * ---------------------------------------------------------------
136 */
Yann Gautier4518c592018-11-15 09:51:06 +0100137func console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200138 /* Check the input parameter */
139 cmp r1, #0
140 beq putc_error
Yann Gautiera30e5f72019-09-04 11:55:10 +0200141
Yann Gautier69035a82018-07-05 16:48:16 +0200142 /* Check Transmit Data Register Empty */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200143txe_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200144 ldr r2, [r1, #USART_ISR]
145 tst r2, #USART_ISR_TXE
Yann Gautiera30e5f72019-09-04 11:55:10 +0200146 beq txe_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200147 str r0, [r1, #USART_TDR]
148 /* Check transmit complete flag */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200149tc_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200150 ldr r2, [r1, #USART_ISR]
151 tst r2, #USART_ISR_TC
Yann Gautiera30e5f72019-09-04 11:55:10 +0200152 beq tc_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200153 bx lr
154putc_error:
155 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200156 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100157endfunc console_stm32_core_putc
158
159 /* ------------------------------------------------------------
Andre Przywara678c6fa2020-01-25 00:58:35 +0000160 * int console_stm32_putc(int c, console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100161 * Function to output a character over the console. It
162 * returns the character printed on success or -1 on error.
163 * In: r0 - character to be printed
164 * r1 - pointer to console_t structure
165 * Out : return -1 on error else return character.
166 * Clobber list: r2
167 * ------------------------------------------------------------
168 */
169func console_stm32_putc
170#if ENABLE_ASSERTIONS
171 cmp r1, #0
172 ASM_ASSERT(ne)
173#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000174 ldr r1, [r1, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100175 b console_stm32_core_putc
176endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200177
178 /* -----------------------------------------------------------
179 * int console_core_getc(uintptr_t base_addr)
180 *
181 * Function to get a character from the console.
182 * It returns the character grabbed on success or -1 on error.
183 *
184 * In : r0 - console base address
185 * Out : return -1.
186 * Clobber list : r0, r1
187 * -----------------------------------------------------------
188 */
Yann Gautier4518c592018-11-15 09:51:06 +0100189func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200190 /* Not supported */
191 mov r0, #-1
192 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100193endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200194
195 /* ---------------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500196 * void console_core_flush(uintptr_t base_addr)
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200197 *
198 * Function to force a write of all buffered data that hasn't been
199 * output.
200 *
201 * In : r0 - console base address
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500202 * Out : void.
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200203 * Clobber list : r0, r1
204 * ---------------------------------------------------------------
205 */
Yann Gautier4518c592018-11-15 09:51:06 +0100206func console_stm32_core_flush
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500207#if ENABLE_ASSERTIONS
Yann Gautier69035a82018-07-05 16:48:16 +0200208 cmp r0, #0
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500209 ASM_ASSERT(ne)
210#endif /* ENABLE_ASSERTIONS */
Yann Gautier69035a82018-07-05 16:48:16 +0200211 /* Check Transmit Data Register Empty */
212txe_loop_3:
213 ldr r1, [r0, #USART_ISR]
214 tst r1, #USART_ISR_TXE
215 beq txe_loop_3
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200216 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100217endfunc console_stm32_core_flush
218
219 /* ------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500220 * void console_stm32_flush(console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100221 * Function to force a write of all buffered
222 * data that hasn't been output.
223 * In : r0 - pointer to console_t structure
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500224 * Out : void.
Yann Gautier4518c592018-11-15 09:51:06 +0100225 * Clobber list: r0, r1
226 * ------------------------------------------------------
227 */
228func console_stm32_flush
229#if ENABLE_ASSERTIONS
230 cmp r0, #0
231 ASM_ASSERT(ne)
232#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000233 ldr r0, [r0, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100234 b console_stm32_core_flush
235endfunc console_stm32_flush