1/* 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> 7#include <assert_macros.S> 8#define USE_FINISH_CONSOLE_REG_2 9#include <console_macros.S> 10#include <drivers/st/stm32_console.h> 11#include <drivers/st/stm32_uart_regs.h> 12 13#define USART_TIMEOUT 0x1000 14 15 /* 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 28 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 */ 45func console_stm32_core_init 46 /* 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 87 bx lr 88endfunc console_stm32_core_init 89 90 .globl console_stm32_register 91 92 /* ------------------------------------------------------- 93 * int console_stm32_register(uintptr_t baseaddr, 94 * uint32_t clock, uint32_t baud, 95 * struct console_stm32 *console); 96 * Function to initialize and register a new STM32 97 * console. Storage passed in for the console struct 98 * *must* be persistent (i.e. not from the stack). 99 * In: r0 - UART register base address 100 * r1 - UART clock in Hz 101 * r2 - Baud rate 102 * r3 - pointer to empty console_stm32 struct 103 * Out: return 1 on success, 0 on error 104 * Clobber list : r0, r1, r2 105 * ------------------------------------------------------- 106 */ 107func console_stm32_register 108 push {r4, lr} 109 mov r4, r3 110 cmp r4, #0 111 beq register_fail 112 str r0, [r4, #CONSOLE_T_STM32_BASE] 113 114 bl console_stm32_core_init 115 cmp r0, #0 116 beq register_fail 117 118 mov r0, r4 119 pop {r4, lr} 120 finish_console_register stm32 putc=1, getc=0, flush=1 121 122register_fail: 123 pop {r4, pc} 124endfunc console_stm32_register 125 126 /* --------------------------------------------------------------- 127 * int console_core_putc(int c, uintptr_t base_addr) 128 * 129 * Function to output a character over the console. It returns the 130 * character printed on success or -1 on error. 131 * 132 * In : r0 - character to be printed 133 * r1 - console base address 134 * Out : return -1 on error else return character. 135 * Clobber list : r2 136 * --------------------------------------------------------------- 137 */ 138func console_stm32_core_putc 139 /* Check the input parameter */ 140 cmp r1, #0 141 beq putc_error 142 /* Prepend '\r' to '\n' */ 143 cmp r0, #0xA 144 bne 2f 1451: 146 /* Check Transmit Data Register Empty */ 147txe_loop_1: 148 ldr r2, [r1, #USART_ISR] 149 tst r2, #USART_ISR_TXE 150 beq txe_loop_1 151 mov r2, #0xD 152 str r2, [r1, #USART_TDR] 153 /* Check transmit complete flag */ 154tc_loop_1: 155 ldr r2, [r1, #USART_ISR] 156 tst r2, #USART_ISR_TC 157 beq tc_loop_1 1582: 159 /* Check Transmit Data Register Empty */ 160txe_loop_2: 161 ldr r2, [r1, #USART_ISR] 162 tst r2, #USART_ISR_TXE 163 beq txe_loop_2 164 str r0, [r1, #USART_TDR] 165 /* Check transmit complete flag */ 166tc_loop_2: 167 ldr r2, [r1, #USART_ISR] 168 tst r2, #USART_ISR_TC 169 beq tc_loop_2 170 bx lr 171putc_error: 172 mov r0, #-1 173 bx lr 174endfunc console_stm32_core_putc 175 176 /* ------------------------------------------------------------ 177 * int console_stm32_putc(int c, struct console_stm32 *console) 178 * Function to output a character over the console. It 179 * returns the character printed on success or -1 on error. 180 * In: r0 - character to be printed 181 * r1 - pointer to console_t structure 182 * Out : return -1 on error else return character. 183 * Clobber list: r2 184 * ------------------------------------------------------------ 185 */ 186func console_stm32_putc 187#if ENABLE_ASSERTIONS 188 cmp r1, #0 189 ASM_ASSERT(ne) 190#endif /* ENABLE_ASSERTIONS */ 191 ldr r1, [r1, #CONSOLE_T_STM32_BASE] 192 b console_stm32_core_putc 193endfunc console_stm32_putc 194 195 /* ----------------------------------------------------------- 196 * int console_core_getc(uintptr_t base_addr) 197 * 198 * Function to get a character from the console. 199 * It returns the character grabbed on success or -1 on error. 200 * 201 * In : r0 - console base address 202 * Out : return -1. 203 * Clobber list : r0, r1 204 * ----------------------------------------------------------- 205 */ 206func console_stm32_core_getc 207 /* Not supported */ 208 mov r0, #-1 209 bx lr 210endfunc console_stm32_core_getc 211 212 /* --------------------------------------------------------------- 213 * int console_core_flush(uintptr_t base_addr) 214 * 215 * Function to force a write of all buffered data that hasn't been 216 * output. 217 * 218 * In : r0 - console base address 219 * Out : return -1 on error else return 0. 220 * Clobber list : r0, r1 221 * --------------------------------------------------------------- 222 */ 223func console_stm32_core_flush 224 cmp r0, #0 225 beq flush_error 226 /* Check Transmit Data Register Empty */ 227txe_loop_3: 228 ldr r1, [r0, #USART_ISR] 229 tst r1, #USART_ISR_TXE 230 beq txe_loop_3 231 mov r0, #0 232 bx lr 233flush_error: 234 mov r0, #-1 235 bx lr 236endfunc console_stm32_core_flush 237 238 /* ------------------------------------------------------ 239 * int console_stm32_flush(struct console_stm32 *console) 240 * Function to force a write of all buffered 241 * data that hasn't been output. 242 * In : r0 - pointer to console_t structure 243 * Out : return -1 on error else return 0. 244 * Clobber list: r0, r1 245 * ------------------------------------------------------ 246 */ 247func console_stm32_flush 248#if ENABLE_ASSERTIONS 249 cmp r0, #0 250 ASM_ASSERT(ne) 251#endif /* ENABLE_ASSERTIONS */ 252 ldr r0, [r0, #CONSOLE_T_STM32_BASE] 253 b console_stm32_core_flush 254endfunc console_stm32_flush 255