blob: 0ed37d1bddc436941bb997bbf4fde508012a8fd0 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
Yann Gautiera30e5f72019-09-04 11:55:10 +02002 * Copyright (c) 2018-2019, 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 /* ---------------------------------------------------------------
196 * int console_core_flush(uintptr_t base_addr)
197 *
198 * Function to force a write of all buffered data that hasn't been
199 * output.
200 *
201 * In : r0 - console base address
202 * Out : return -1 on error else return 0.
203 * Clobber list : r0, r1
204 * ---------------------------------------------------------------
205 */
Yann Gautier4518c592018-11-15 09:51:06 +0100206func console_stm32_core_flush
Yann Gautier69035a82018-07-05 16:48:16 +0200207 cmp r0, #0
208 beq flush_error
209 /* Check Transmit Data Register Empty */
210txe_loop_3:
211 ldr r1, [r0, #USART_ISR]
212 tst r1, #USART_ISR_TXE
213 beq txe_loop_3
214 mov r0, #0
215 bx lr
216flush_error:
217 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200218 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100219endfunc console_stm32_core_flush
220
221 /* ------------------------------------------------------
Andre Przywara678c6fa2020-01-25 00:58:35 +0000222 * int console_stm32_flush(console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100223 * Function to force a write of all buffered
224 * data that hasn't been output.
225 * In : r0 - pointer to console_t structure
226 * Out : return -1 on error else return 0.
227 * Clobber list: r0, r1
228 * ------------------------------------------------------
229 */
230func console_stm32_flush
231#if ENABLE_ASSERTIONS
232 cmp r0, #0
233 ASM_ASSERT(ne)
234#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000235 ldr r0, [r0, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100236 b console_stm32_core_flush
237endfunc console_stm32_flush