blob: 39e449b29d5558df057534f11383d2ba7a673cb9 [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>
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,
94 * struct console_stm32 *console);
95 * 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
101 * r3 - pointer to empty console_stm32 struct
102 * 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
111 str r0, [r4, #CONSOLE_T_STM32_BASE]
112
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
141 /* Prepend '\r' to '\n' */
142 cmp r0, #0xA
143 bne 2f
1441:
145 /* Check Transmit Data Register Empty */
146txe_loop_1:
147 ldr r2, [r1, #USART_ISR]
148 tst r2, #USART_ISR_TXE
149 beq txe_loop_1
150 mov r2, #0xD
151 str r2, [r1, #USART_TDR]
152 /* Check transmit complete flag */
153tc_loop_1:
154 ldr r2, [r1, #USART_ISR]
155 tst r2, #USART_ISR_TC
156 beq tc_loop_1
1572:
158 /* Check Transmit Data Register Empty */
159txe_loop_2:
160 ldr r2, [r1, #USART_ISR]
161 tst r2, #USART_ISR_TXE
162 beq txe_loop_2
163 str r0, [r1, #USART_TDR]
164 /* Check transmit complete flag */
165tc_loop_2:
166 ldr r2, [r1, #USART_ISR]
167 tst r2, #USART_ISR_TC
168 beq tc_loop_2
169 bx lr
170putc_error:
171 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200172 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100173endfunc console_stm32_core_putc
174
175 /* ------------------------------------------------------------
176 * int console_stm32_putc(int c, struct console_stm32 *console)
177 * Function to output a character over the console. It
178 * returns the character printed on success or -1 on error.
179 * In: r0 - character to be printed
180 * r1 - pointer to console_t structure
181 * Out : return -1 on error else return character.
182 * Clobber list: r2
183 * ------------------------------------------------------------
184 */
185func console_stm32_putc
186#if ENABLE_ASSERTIONS
187 cmp r1, #0
188 ASM_ASSERT(ne)
189#endif /* ENABLE_ASSERTIONS */
190 ldr r1, [r1, #CONSOLE_T_STM32_BASE]
191 b console_stm32_core_putc
192endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200193
194 /* -----------------------------------------------------------
195 * int console_core_getc(uintptr_t base_addr)
196 *
197 * Function to get a character from the console.
198 * It returns the character grabbed on success or -1 on error.
199 *
200 * In : r0 - console base address
201 * Out : return -1.
202 * Clobber list : r0, r1
203 * -----------------------------------------------------------
204 */
Yann Gautier4518c592018-11-15 09:51:06 +0100205func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200206 /* Not supported */
207 mov r0, #-1
208 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100209endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200210
211 /* ---------------------------------------------------------------
212 * int console_core_flush(uintptr_t base_addr)
213 *
214 * Function to force a write of all buffered data that hasn't been
215 * output.
216 *
217 * In : r0 - console base address
218 * Out : return -1 on error else return 0.
219 * Clobber list : r0, r1
220 * ---------------------------------------------------------------
221 */
Yann Gautier4518c592018-11-15 09:51:06 +0100222func console_stm32_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200223 cmp r0, #0
224 beq flush_error
225 /* Check Transmit Data Register Empty */
226txe_loop_3:
227 ldr r1, [r0, #USART_ISR]
228 tst r1, #USART_ISR_TXE
229 beq txe_loop_3
230 mov r0, #0
231 bx lr
232flush_error:
233 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200234 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100235endfunc console_stm32_core_flush
236
237 /* ------------------------------------------------------
238 * int console_stm32_flush(struct console_stm32 *console)
239 * Function to force a write of all buffered
240 * data that hasn't been output.
241 * In : r0 - pointer to console_t structure
242 * Out : return -1 on error else return 0.
243 * Clobber list: r0, r1
244 * ------------------------------------------------------
245 */
246func console_stm32_flush
247#if ENABLE_ASSERTIONS
248 cmp r0, #0
249 ASM_ASSERT(ne)
250#endif /* ENABLE_ASSERTIONS */
251 ldr r0, [r0, #CONSOLE_T_STM32_BASE]
252 b console_stm32_core_flush
253endfunc console_stm32_flush