1/* 2 * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6#include <asm_macros.S> 7#include <assert_macros.S> 8#include <console_macros.S> 9#include <drivers/st/stm32_console.h> 10#include <drivers/st/stm32_uart_regs.h> 11 12#define USART_TIMEOUT 0x1000 13 14 /* 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 27 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 */ 44func console_stm32_core_init 45 /* Check the input base address */ 46 cmp r0, #0 47 beq core_init_fail 48#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 */ 54 /* 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 861: 87 mov r0, #1 88 bx lr 89core_init_fail: 90 mov r0, #0 91 bx lr 92endfunc console_stm32_core_init 93 94 .globl console_stm32_register 95 96 /* ------------------------------------------------------- 97 * int console_stm32_register(uintptr_t baseaddr, 98 * uint32_t clock, uint32_t baud, 99 * console_t *console); 100 * 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 106 * r3 - pointer to empty console_t struct 107 * 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 116 str r0, [r4, #CONSOLE_T_BASE] 117 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 129 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 */ 142func console_stm32_core_putc 143 /* Check the input parameter */ 144 cmp r1, #0 145 beq putc_error 146 147 /* Check Transmit Data Register Empty */ 148txe_loop: 149 ldr r2, [r1, #USART_ISR] 150 tst r2, #USART_ISR_TXE 151 beq txe_loop 152 str r0, [r1, #USART_TDR] 153 /* Check transmit complete flag */ 154tc_loop: 155 ldr r2, [r1, #USART_ISR] 156 tst r2, #USART_ISR_TC 157 beq tc_loop 158 bx lr 159putc_error: 160 mov r0, #-1 161 bx lr 162endfunc console_stm32_core_putc 163 164 /* ------------------------------------------------------------ 165 * int console_stm32_putc(int c, console_t *console) 166 * 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 */ 179 ldr r1, [r1, #CONSOLE_T_BASE] 180 b console_stm32_core_putc 181endfunc console_stm32_putc 182 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 */ 194func console_stm32_core_getc 195 /* Not supported */ 196 mov r0, #-1 197 bx lr 198endfunc console_stm32_core_getc 199 200 /* --------------------------------------------------------------- 201 * void console_core_flush(uintptr_t base_addr) 202 * 203 * Function to force a write of all buffered data that hasn't been 204 * output. 205 * 206 * In : r0 - console base address 207 * Out : void. 208 * Clobber list : r0, r1 209 * --------------------------------------------------------------- 210 */ 211func console_stm32_core_flush 212#if ENABLE_ASSERTIONS 213 cmp r0, #0 214 ASM_ASSERT(ne) 215#endif /* ENABLE_ASSERTIONS */ 216 /* 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 221 bx lr 222endfunc console_stm32_core_flush 223 224 /* ------------------------------------------------------ 225 * void console_stm32_flush(console_t *console) 226 * Function to force a write of all buffered 227 * data that hasn't been output. 228 * In : r0 - pointer to console_t structure 229 * Out : void. 230 * 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 */ 238 ldr r0, [r0, #CONSOLE_T_BASE] 239 b console_stm32_core_flush 240endfunc console_stm32_flush 241