blob: 4d00e68ab3c04a77227307bc30e4ad30d7d28ca7 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
3 *
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>
8#define USE_FINISH_CONSOLE_REG_2
9#include <console_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <drivers/st/stm32_console.h>
11#include <drivers/st/stm32_uart_regs.h>
Yann Gautier4b0c72a2018-07-16 10:54:09 +020012
Yann Gautier69035a82018-07-05 16:48:16 +020013#define USART_TIMEOUT 0x1000
14
Yann Gautier4518c592018-11-15 09:51:06 +010015 /*
16 * "core" functions are low-level implementations that don't require
17 * writeable memory and are thus safe to call in BL1 crash context.
18 */
19 .globl console_stm32_core_init
20 .globl console_stm32_core_putc
21 .globl console_stm32_core_getc
22 .globl console_stm32_core_flush
23
24 .globl console_stm32_putc
25 .globl console_stm32_flush
26
27
Yann Gautier4b0c72a2018-07-16 10:54:09 +020028
29 /* -----------------------------------------------------------------
30 * int console_core_init(uintptr_t base_addr,
31 * unsigned int uart_clk,
32 * unsigned int baud_rate)
33 *
34 * Function to initialize the console without a C Runtime to print
35 * debug information. This function will be accessed by console_init
36 * and crash reporting.
37 *
38 * In: r0 - console base address
39 * r1 - Uart clock in Hz
40 * r2 - Baud rate
41 * Out: return 1 on success else 0 on error
42 * Clobber list : r1, r2, r3
43 * -----------------------------------------------------------------
44 */
Yann Gautier4518c592018-11-15 09:51:06 +010045func console_stm32_core_init
Yann Gautier69035a82018-07-05 16:48:16 +020046 /* Check the input base address */
47 cmp r0, #0
48 beq core_init_fail
49#if defined(IMAGE_BL2)
50 /* Check baud rate and uart clock for sanity */
51 cmp r1, #0
52 beq core_init_fail
53 cmp r2, #0
54 beq core_init_fail
55 /* Disable UART */
56 ldr r3, [r0, #USART_CR1]
57 bic r3, r3, #USART_CR1_UE
58 str r3, [r0, #USART_CR1]
59 /* Configure UART */
60 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
61 str r3, [r0, #USART_CR1]
62 ldr r3, [r0, #USART_CR2]
63 bic r3, r3, #USART_CR2_STOP
64 str r3, [r0, #USART_CR2]
65 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
66 lsl r3, r2, #1
67 add r3, r1, r3
68 udiv r3, r3, r2
69 str r3, [r0, #USART_BRR]
70 /* Enable UART */
71 ldr r3, [r0, #USART_CR1]
72 orr r3, r3, #USART_CR1_UE
73 str r3, [r0, #USART_CR1]
74 /* Check TEACK bit */
75 mov r2, #USART_TIMEOUT
76teack_loop:
77 subs r2, r2, #1
78 beq core_init_fail
79 ldr r3, [r0, #USART_ISR]
80 tst r3, #USART_ISR_TEACK
81 beq teack_loop
82#endif /* IMAGE_BL2 */
83 mov r0, #1
84 bx lr
85core_init_fail:
86 mov r0, #0
Yann Gautier4b0c72a2018-07-16 10:54:09 +020087 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +010088endfunc console_stm32_core_init
89
Yann Gautier4518c592018-11-15 09:51:06 +010090 .globl console_stm32_register
91
92 /* -------------------------------------------------------
93 * int console_stm32_register(uintptr_t baseaddr,
94 * uint32_t clock, uint32_t baud,
95 * struct console_stm32 *console);
96 * Function to initialize and register a new STM32
97 * console. Storage passed in for the console struct
98 * *must* be persistent (i.e. not from the stack).
99 * In: r0 - UART register base address
100 * r1 - UART clock in Hz
101 * r2 - Baud rate
102 * r3 - pointer to empty console_stm32 struct
103 * Out: return 1 on success, 0 on error
104 * Clobber list : r0, r1, r2
105 * -------------------------------------------------------
106 */
107func console_stm32_register
108 push {r4, lr}
109 mov r4, r3
110 cmp r4, #0
111 beq register_fail
112 str r0, [r4, #CONSOLE_T_STM32_BASE]
113
114 bl console_stm32_core_init
115 cmp r0, #0
116 beq register_fail
117
118 mov r0, r4
119 pop {r4, lr}
120 finish_console_register stm32 putc=1, getc=0, flush=1
121
122register_fail:
123 pop {r4, pc}
124endfunc console_stm32_register
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200125
126 /* ---------------------------------------------------------------
127 * int console_core_putc(int c, uintptr_t base_addr)
128 *
129 * Function to output a character over the console. It returns the
130 * character printed on success or -1 on error.
131 *
132 * In : r0 - character to be printed
133 * r1 - console base address
134 * Out : return -1 on error else return character.
135 * Clobber list : r2
136 * ---------------------------------------------------------------
137 */
Yann Gautier4518c592018-11-15 09:51:06 +0100138func console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200139 /* Check the input parameter */
140 cmp r1, #0
141 beq putc_error
142 /* Prepend '\r' to '\n' */
143 cmp r0, #0xA
144 bne 2f
1451:
146 /* Check Transmit Data Register Empty */
147txe_loop_1:
148 ldr r2, [r1, #USART_ISR]
149 tst r2, #USART_ISR_TXE
150 beq txe_loop_1
151 mov r2, #0xD
152 str r2, [r1, #USART_TDR]
153 /* Check transmit complete flag */
154tc_loop_1:
155 ldr r2, [r1, #USART_ISR]
156 tst r2, #USART_ISR_TC
157 beq tc_loop_1
1582:
159 /* Check Transmit Data Register Empty */
160txe_loop_2:
161 ldr r2, [r1, #USART_ISR]
162 tst r2, #USART_ISR_TXE
163 beq txe_loop_2
164 str r0, [r1, #USART_TDR]
165 /* Check transmit complete flag */
166tc_loop_2:
167 ldr r2, [r1, #USART_ISR]
168 tst r2, #USART_ISR_TC
169 beq tc_loop_2
170 bx lr
171putc_error:
172 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200173 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100174endfunc console_stm32_core_putc
175
176 /* ------------------------------------------------------------
177 * int console_stm32_putc(int c, struct console_stm32 *console)
178 * Function to output a character over the console. It
179 * returns the character printed on success or -1 on error.
180 * In: r0 - character to be printed
181 * r1 - pointer to console_t structure
182 * Out : return -1 on error else return character.
183 * Clobber list: r2
184 * ------------------------------------------------------------
185 */
186func console_stm32_putc
187#if ENABLE_ASSERTIONS
188 cmp r1, #0
189 ASM_ASSERT(ne)
190#endif /* ENABLE_ASSERTIONS */
191 ldr r1, [r1, #CONSOLE_T_STM32_BASE]
192 b console_stm32_core_putc
193endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200194
195 /* -----------------------------------------------------------
196 * int console_core_getc(uintptr_t base_addr)
197 *
198 * Function to get a character from the console.
199 * It returns the character grabbed on success or -1 on error.
200 *
201 * In : r0 - console base address
202 * Out : return -1.
203 * Clobber list : r0, r1
204 * -----------------------------------------------------------
205 */
Yann Gautier4518c592018-11-15 09:51:06 +0100206func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200207 /* Not supported */
208 mov r0, #-1
209 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100210endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200211
212 /* ---------------------------------------------------------------
213 * int console_core_flush(uintptr_t base_addr)
214 *
215 * Function to force a write of all buffered data that hasn't been
216 * output.
217 *
218 * In : r0 - console base address
219 * Out : return -1 on error else return 0.
220 * Clobber list : r0, r1
221 * ---------------------------------------------------------------
222 */
Yann Gautier4518c592018-11-15 09:51:06 +0100223func console_stm32_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200224 cmp r0, #0
225 beq flush_error
226 /* Check Transmit Data Register Empty */
227txe_loop_3:
228 ldr r1, [r0, #USART_ISR]
229 tst r1, #USART_ISR_TXE
230 beq txe_loop_3
231 mov r0, #0
232 bx lr
233flush_error:
234 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200235 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100236endfunc console_stm32_core_flush
237
238 /* ------------------------------------------------------
239 * int console_stm32_flush(struct console_stm32 *console)
240 * Function to force a write of all buffered
241 * data that hasn't been output.
242 * In : r0 - pointer to console_t structure
243 * Out : return -1 on error else return 0.
244 * Clobber list: r0, r1
245 * ------------------------------------------------------
246 */
247func console_stm32_flush
248#if ENABLE_ASSERTIONS
249 cmp r0, #0
250 ASM_ASSERT(ne)
251#endif /* ENABLE_ASSERTIONS */
252 ldr r0, [r0, #CONSOLE_T_STM32_BASE]
253 b console_stm32_core_flush
254endfunc console_stm32_flush