blob: 66c9e2a2e7ec9a8da9161a3b07ebdfe81a8d4c80 [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>
10#include <stm32_console.h>
Yann Gautier3d48bae2018-11-14 18:18:12 +010011#include <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
90#if MULTI_CONSOLE_API
91 .globl console_stm32_register
92
93 /* -------------------------------------------------------
94 * int console_stm32_register(uintptr_t baseaddr,
95 * uint32_t clock, uint32_t baud,
96 * struct console_stm32 *console);
97 * Function to initialize and register a new STM32
98 * console. Storage passed in for the console struct
99 * *must* be persistent (i.e. not from the stack).
100 * In: r0 - UART register base address
101 * r1 - UART clock in Hz
102 * r2 - Baud rate
103 * r3 - pointer to empty console_stm32 struct
104 * Out: return 1 on success, 0 on error
105 * Clobber list : r0, r1, r2
106 * -------------------------------------------------------
107 */
108func console_stm32_register
109 push {r4, lr}
110 mov r4, r3
111 cmp r4, #0
112 beq register_fail
113 str r0, [r4, #CONSOLE_T_STM32_BASE]
114
115 bl console_stm32_core_init
116 cmp r0, #0
117 beq register_fail
118
119 mov r0, r4
120 pop {r4, lr}
121 finish_console_register stm32 putc=1, getc=0, flush=1
122
123register_fail:
124 pop {r4, pc}
125endfunc console_stm32_register
126#else
127 .globl console_core_init
128 .globl console_core_putc
129 .globl console_core_getc
130 .globl console_core_flush
131 .equ console_core_init, console_stm32_core_init
132 .equ console_core_putc, console_stm32_core_putc
133 .equ console_core_getc, console_stm32_core_getc
134 .equ console_core_flush, console_stm32_core_flush
135#endif
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200136
137 /* ---------------------------------------------------------------
138 * int console_core_putc(int c, uintptr_t base_addr)
139 *
140 * Function to output a character over the console. It returns the
141 * character printed on success or -1 on error.
142 *
143 * In : r0 - character to be printed
144 * r1 - console base address
145 * Out : return -1 on error else return character.
146 * Clobber list : r2
147 * ---------------------------------------------------------------
148 */
Yann Gautier4518c592018-11-15 09:51:06 +0100149func console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200150 /* Check the input parameter */
151 cmp r1, #0
152 beq putc_error
153 /* Prepend '\r' to '\n' */
154 cmp r0, #0xA
155 bne 2f
1561:
157 /* Check Transmit Data Register Empty */
158txe_loop_1:
159 ldr r2, [r1, #USART_ISR]
160 tst r2, #USART_ISR_TXE
161 beq txe_loop_1
162 mov r2, #0xD
163 str r2, [r1, #USART_TDR]
164 /* Check transmit complete flag */
165tc_loop_1:
166 ldr r2, [r1, #USART_ISR]
167 tst r2, #USART_ISR_TC
168 beq tc_loop_1
1692:
170 /* Check Transmit Data Register Empty */
171txe_loop_2:
172 ldr r2, [r1, #USART_ISR]
173 tst r2, #USART_ISR_TXE
174 beq txe_loop_2
175 str r0, [r1, #USART_TDR]
176 /* Check transmit complete flag */
177tc_loop_2:
178 ldr r2, [r1, #USART_ISR]
179 tst r2, #USART_ISR_TC
180 beq tc_loop_2
181 bx lr
182putc_error:
183 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200184 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100185endfunc console_stm32_core_putc
186
187 /* ------------------------------------------------------------
188 * int console_stm32_putc(int c, struct console_stm32 *console)
189 * Function to output a character over the console. It
190 * returns the character printed on success or -1 on error.
191 * In: r0 - character to be printed
192 * r1 - pointer to console_t structure
193 * Out : return -1 on error else return character.
194 * Clobber list: r2
195 * ------------------------------------------------------------
196 */
197func console_stm32_putc
198#if ENABLE_ASSERTIONS
199 cmp r1, #0
200 ASM_ASSERT(ne)
201#endif /* ENABLE_ASSERTIONS */
202 ldr r1, [r1, #CONSOLE_T_STM32_BASE]
203 b console_stm32_core_putc
204endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200205
206 /* -----------------------------------------------------------
207 * int console_core_getc(uintptr_t base_addr)
208 *
209 * Function to get a character from the console.
210 * It returns the character grabbed on success or -1 on error.
211 *
212 * In : r0 - console base address
213 * Out : return -1.
214 * Clobber list : r0, r1
215 * -----------------------------------------------------------
216 */
Yann Gautier4518c592018-11-15 09:51:06 +0100217func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200218 /* Not supported */
219 mov r0, #-1
220 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100221endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200222
223 /* ---------------------------------------------------------------
224 * int console_core_flush(uintptr_t base_addr)
225 *
226 * Function to force a write of all buffered data that hasn't been
227 * output.
228 *
229 * In : r0 - console base address
230 * Out : return -1 on error else return 0.
231 * Clobber list : r0, r1
232 * ---------------------------------------------------------------
233 */
Yann Gautier4518c592018-11-15 09:51:06 +0100234func console_stm32_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200235 cmp r0, #0
236 beq flush_error
237 /* Check Transmit Data Register Empty */
238txe_loop_3:
239 ldr r1, [r0, #USART_ISR]
240 tst r1, #USART_ISR_TXE
241 beq txe_loop_3
242 mov r0, #0
243 bx lr
244flush_error:
245 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200246 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100247endfunc console_stm32_core_flush
248
249 /* ------------------------------------------------------
250 * int console_stm32_flush(struct console_stm32 *console)
251 * Function to force a write of all buffered
252 * data that hasn't been output.
253 * In : r0 - pointer to console_t structure
254 * Out : return -1 on error else return 0.
255 * Clobber list: r0, r1
256 * ------------------------------------------------------
257 */
258func console_stm32_flush
259#if ENABLE_ASSERTIONS
260 cmp r0, #0
261 ASM_ASSERT(ne)
262#endif /* ENABLE_ASSERTIONS */
263 ldr r0, [r0, #CONSOLE_T_STM32_BASE]
264 b console_stm32_core_flush
265endfunc console_stm32_flush