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#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 /* 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 86 bx lr 87endfunc console_stm32_core_init 88 89 .globl console_stm32_register 90 91 /* ------------------------------------------------------- 92 * int console_stm32_register(uintptr_t baseaddr, 93 * uint32_t clock, uint32_t baud, 94 * struct console_stm32 *console); 95 * 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 101 * r3 - pointer to empty console_stm32 struct 102 * 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 111 str r0, [r4, #CONSOLE_T_STM32_BASE] 112 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 124 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 */ 137func console_stm32_core_putc 138 /* Check the input parameter */ 139 cmp r1, #0 140 beq putc_error 141 /* Prepend '\r' to '\n' */ 142 cmp r0, #0xA 143 bne 2f 1441: 145 /* Check Transmit Data Register Empty */ 146txe_loop_1: 147 ldr r2, [r1, #USART_ISR] 148 tst r2, #USART_ISR_TXE 149 beq txe_loop_1 150 mov r2, #0xD 151 str r2, [r1, #USART_TDR] 152 /* Check transmit complete flag */ 153tc_loop_1: 154 ldr r2, [r1, #USART_ISR] 155 tst r2, #USART_ISR_TC 156 beq tc_loop_1 1572: 158 /* Check Transmit Data Register Empty */ 159txe_loop_2: 160 ldr r2, [r1, #USART_ISR] 161 tst r2, #USART_ISR_TXE 162 beq txe_loop_2 163 str r0, [r1, #USART_TDR] 164 /* Check transmit complete flag */ 165tc_loop_2: 166 ldr r2, [r1, #USART_ISR] 167 tst r2, #USART_ISR_TC 168 beq tc_loop_2 169 bx lr 170putc_error: 171 mov r0, #-1 172 bx lr 173endfunc console_stm32_core_putc 174 175 /* ------------------------------------------------------------ 176 * int console_stm32_putc(int c, struct console_stm32 *console) 177 * Function to output a character over the console. It 178 * returns the character printed on success or -1 on error. 179 * In: r0 - character to be printed 180 * r1 - pointer to console_t structure 181 * Out : return -1 on error else return character. 182 * Clobber list: r2 183 * ------------------------------------------------------------ 184 */ 185func console_stm32_putc 186#if ENABLE_ASSERTIONS 187 cmp r1, #0 188 ASM_ASSERT(ne) 189#endif /* ENABLE_ASSERTIONS */ 190 ldr r1, [r1, #CONSOLE_T_STM32_BASE] 191 b console_stm32_core_putc 192endfunc console_stm32_putc 193 194 /* ----------------------------------------------------------- 195 * int console_core_getc(uintptr_t base_addr) 196 * 197 * Function to get a character from the console. 198 * It returns the character grabbed on success or -1 on error. 199 * 200 * In : r0 - console base address 201 * Out : return -1. 202 * Clobber list : r0, r1 203 * ----------------------------------------------------------- 204 */ 205func console_stm32_core_getc 206 /* Not supported */ 207 mov r0, #-1 208 bx lr 209endfunc console_stm32_core_getc 210 211 /* --------------------------------------------------------------- 212 * int console_core_flush(uintptr_t base_addr) 213 * 214 * Function to force a write of all buffered data that hasn't been 215 * output. 216 * 217 * In : r0 - console base address 218 * Out : return -1 on error else return 0. 219 * Clobber list : r0, r1 220 * --------------------------------------------------------------- 221 */ 222func console_stm32_core_flush 223 cmp r0, #0 224 beq flush_error 225 /* Check Transmit Data Register Empty */ 226txe_loop_3: 227 ldr r1, [r0, #USART_ISR] 228 tst r1, #USART_ISR_TXE 229 beq txe_loop_3 230 mov r0, #0 231 bx lr 232flush_error: 233 mov r0, #-1 234 bx lr 235endfunc console_stm32_core_flush 236 237 /* ------------------------------------------------------ 238 * int console_stm32_flush(struct console_stm32 *console) 239 * Function to force a write of all buffered 240 * data that hasn't been output. 241 * In : r0 - pointer to console_t structure 242 * Out : return -1 on error else return 0. 243 * Clobber list: r0, r1 244 * ------------------------------------------------------ 245 */ 246func console_stm32_flush 247#if ENABLE_ASSERTIONS 248 cmp r0, #0 249 ASM_ASSERT(ne) 250#endif /* ENABLE_ASSERTIONS */ 251 ldr r0, [r0, #CONSOLE_T_STM32_BASE] 252 b console_stm32_core_flush 253endfunc console_stm32_flush 254