blob: 2b8879a11d803cd9fa0949868b6d56acb795cd03 [file] [log] [blame]
Yann Gautier4b0c72a2018-07-16 10:54:09 +02001/*
Yann Gautier9ee1f9c2021-09-09 17:34:53 +02002 * Copyright (c) 2018-2021, 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
Yann Gautier9ee1f9c2021-09-09 17:34:53 +020048#if !defined(IMAGE_BL2)
49 /* Skip UART initialization if it is already enabled */
50 ldr r3, [r0, #USART_CR1]
51 ands r3, r3, #USART_CR1_UE
52 bne 1f
53#endif /* IMAGE_BL2 */
Yann Gautier69035a82018-07-05 16:48:16 +020054 /* Check baud rate and uart clock for sanity */
55 cmp r1, #0
56 beq core_init_fail
57 cmp r2, #0
58 beq core_init_fail
59 /* Disable UART */
60 ldr r3, [r0, #USART_CR1]
61 bic r3, r3, #USART_CR1_UE
62 str r3, [r0, #USART_CR1]
63 /* Configure UART */
64 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
65 str r3, [r0, #USART_CR1]
66 ldr r3, [r0, #USART_CR2]
67 bic r3, r3, #USART_CR2_STOP
68 str r3, [r0, #USART_CR2]
69 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
70 lsl r3, r2, #1
71 add r3, r1, r3
72 udiv r3, r3, r2
73 str r3, [r0, #USART_BRR]
74 /* Enable UART */
75 ldr r3, [r0, #USART_CR1]
76 orr r3, r3, #USART_CR1_UE
77 str r3, [r0, #USART_CR1]
78 /* Check TEACK bit */
79 mov r2, #USART_TIMEOUT
80teack_loop:
81 subs r2, r2, #1
82 beq core_init_fail
83 ldr r3, [r0, #USART_ISR]
84 tst r3, #USART_ISR_TEACK
85 beq teack_loop
Yann Gautier9ee1f9c2021-09-09 17:34:53 +0200861:
Yann Gautier69035a82018-07-05 16:48:16 +020087 mov r0, #1
88 bx lr
89core_init_fail:
90 mov r0, #0
Yann Gautier4b0c72a2018-07-16 10:54:09 +020091 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +010092endfunc console_stm32_core_init
93
Yann Gautier4518c592018-11-15 09:51:06 +010094 .globl console_stm32_register
95
96 /* -------------------------------------------------------
97 * int console_stm32_register(uintptr_t baseaddr,
98 * uint32_t clock, uint32_t baud,
Andre Przywara678c6fa2020-01-25 00:58:35 +000099 * console_t *console);
Yann Gautier4518c592018-11-15 09:51:06 +0100100 * Function to initialize and register a new STM32
101 * console. Storage passed in for the console struct
102 * *must* be persistent (i.e. not from the stack).
103 * In: r0 - UART register base address
104 * r1 - UART clock in Hz
105 * r2 - Baud rate
Andre Przywara678c6fa2020-01-25 00:58:35 +0000106 * r3 - pointer to empty console_t struct
Yann Gautier4518c592018-11-15 09:51:06 +0100107 * Out: return 1 on success, 0 on error
108 * Clobber list : r0, r1, r2
109 * -------------------------------------------------------
110 */
111func console_stm32_register
112 push {r4, lr}
113 mov r4, r3
114 cmp r4, #0
115 beq register_fail
Andre Przywara678c6fa2020-01-25 00:58:35 +0000116 str r0, [r4, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100117
118 bl console_stm32_core_init
119 cmp r0, #0
120 beq register_fail
121
122 mov r0, r4
123 pop {r4, lr}
124 finish_console_register stm32 putc=1, getc=0, flush=1
125
126register_fail:
127 pop {r4, pc}
128endfunc console_stm32_register
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200129
130 /* ---------------------------------------------------------------
131 * int console_core_putc(int c, uintptr_t base_addr)
132 *
133 * Function to output a character over the console. It returns the
134 * character printed on success or -1 on error.
135 *
136 * In : r0 - character to be printed
137 * r1 - console base address
138 * Out : return -1 on error else return character.
139 * Clobber list : r2
140 * ---------------------------------------------------------------
141 */
Yann Gautier4518c592018-11-15 09:51:06 +0100142func console_stm32_core_putc
Yann Gautier69035a82018-07-05 16:48:16 +0200143 /* Check the input parameter */
144 cmp r1, #0
145 beq putc_error
Yann Gautiera30e5f72019-09-04 11:55:10 +0200146
Yann Gautier69035a82018-07-05 16:48:16 +0200147 /* Check Transmit Data Register Empty */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200148txe_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200149 ldr r2, [r1, #USART_ISR]
150 tst r2, #USART_ISR_TXE
Yann Gautiera30e5f72019-09-04 11:55:10 +0200151 beq txe_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200152 str r0, [r1, #USART_TDR]
153 /* Check transmit complete flag */
Yann Gautiera30e5f72019-09-04 11:55:10 +0200154tc_loop:
Yann Gautier69035a82018-07-05 16:48:16 +0200155 ldr r2, [r1, #USART_ISR]
156 tst r2, #USART_ISR_TC
Yann Gautiera30e5f72019-09-04 11:55:10 +0200157 beq tc_loop
Yann Gautier69035a82018-07-05 16:48:16 +0200158 bx lr
159putc_error:
160 mov r0, #-1
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200161 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100162endfunc console_stm32_core_putc
163
164 /* ------------------------------------------------------------
Andre Przywara678c6fa2020-01-25 00:58:35 +0000165 * int console_stm32_putc(int c, console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100166 * Function to output a character over the console. It
167 * returns the character printed on success or -1 on error.
168 * In: r0 - character to be printed
169 * r1 - pointer to console_t structure
170 * Out : return -1 on error else return character.
171 * Clobber list: r2
172 * ------------------------------------------------------------
173 */
174func console_stm32_putc
175#if ENABLE_ASSERTIONS
176 cmp r1, #0
177 ASM_ASSERT(ne)
178#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000179 ldr r1, [r1, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100180 b console_stm32_core_putc
181endfunc console_stm32_putc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200182
183 /* -----------------------------------------------------------
184 * int console_core_getc(uintptr_t base_addr)
185 *
186 * Function to get a character from the console.
187 * It returns the character grabbed on success or -1 on error.
188 *
189 * In : r0 - console base address
190 * Out : return -1.
191 * Clobber list : r0, r1
192 * -----------------------------------------------------------
193 */
Yann Gautier4518c592018-11-15 09:51:06 +0100194func console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200195 /* Not supported */
196 mov r0, #-1
197 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100198endfunc console_stm32_core_getc
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200199
200 /* ---------------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500201 * void console_core_flush(uintptr_t base_addr)
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200202 *
203 * Function to force a write of all buffered data that hasn't been
204 * output.
205 *
206 * In : r0 - console base address
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500207 * Out : void.
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200208 * Clobber list : r0, r1
209 * ---------------------------------------------------------------
210 */
Yann Gautier4518c592018-11-15 09:51:06 +0100211func console_stm32_core_flush
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500212#if ENABLE_ASSERTIONS
Yann Gautier69035a82018-07-05 16:48:16 +0200213 cmp r0, #0
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500214 ASM_ASSERT(ne)
215#endif /* ENABLE_ASSERTIONS */
Yann Gautier69035a82018-07-05 16:48:16 +0200216 /* Check Transmit Data Register Empty */
217txe_loop_3:
218 ldr r1, [r0, #USART_ISR]
219 tst r1, #USART_ISR_TXE
220 beq txe_loop_3
Yann Gautier4b0c72a2018-07-16 10:54:09 +0200221 bx lr
Yann Gautier4518c592018-11-15 09:51:06 +0100222endfunc console_stm32_core_flush
223
224 /* ------------------------------------------------------
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500225 * void console_stm32_flush(console_t *console)
Yann Gautier4518c592018-11-15 09:51:06 +0100226 * Function to force a write of all buffered
227 * data that hasn't been output.
228 * In : r0 - pointer to console_t structure
Jimmy Brisson39f9eee2020-08-05 13:44:05 -0500229 * Out : void.
Yann Gautier4518c592018-11-15 09:51:06 +0100230 * Clobber list: r0, r1
231 * ------------------------------------------------------
232 */
233func console_stm32_flush
234#if ENABLE_ASSERTIONS
235 cmp r0, #0
236 ASM_ASSERT(ne)
237#endif /* ENABLE_ASSERTIONS */
Andre Przywara678c6fa2020-01-25 00:58:35 +0000238 ldr r0, [r0, #CONSOLE_T_BASE]
Yann Gautier4518c592018-11-15 09:51:06 +0100239 b console_stm32_core_flush
240endfunc console_stm32_flush