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 <stm32_console.h> 11#include <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#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 136 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 */ 149func console_stm32_core_putc 150 /* 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 184 bx lr 185endfunc 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 205 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 */ 217func console_stm32_core_getc 218 /* Not supported */ 219 mov r0, #-1 220 bx lr 221endfunc console_stm32_core_getc 222 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 */ 234func console_stm32_core_flush 235 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 246 bx lr 247endfunc 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 266