1/* 2 * Copyright (c) 2018-2020, 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 * console_t *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_t 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_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 142 /* Check Transmit Data Register Empty */ 143txe_loop: 144 ldr r2, [r1, #USART_ISR] 145 tst r2, #USART_ISR_TXE 146 beq txe_loop 147 str r0, [r1, #USART_TDR] 148 /* Check transmit complete flag */ 149tc_loop: 150 ldr r2, [r1, #USART_ISR] 151 tst r2, #USART_ISR_TC 152 beq tc_loop 153 bx lr 154putc_error: 155 mov r0, #-1 156 bx lr 157endfunc console_stm32_core_putc 158 159 /* ------------------------------------------------------------ 160 * int console_stm32_putc(int c, console_t *console) 161 * Function to output a character over the console. It 162 * returns the character printed on success or -1 on error. 163 * In: r0 - character to be printed 164 * r1 - pointer to console_t structure 165 * Out : return -1 on error else return character. 166 * Clobber list: r2 167 * ------------------------------------------------------------ 168 */ 169func console_stm32_putc 170#if ENABLE_ASSERTIONS 171 cmp r1, #0 172 ASM_ASSERT(ne) 173#endif /* ENABLE_ASSERTIONS */ 174 ldr r1, [r1, #CONSOLE_T_BASE] 175 b console_stm32_core_putc 176endfunc console_stm32_putc 177 178 /* ----------------------------------------------------------- 179 * int console_core_getc(uintptr_t base_addr) 180 * 181 * Function to get a character from the console. 182 * It returns the character grabbed on success or -1 on error. 183 * 184 * In : r0 - console base address 185 * Out : return -1. 186 * Clobber list : r0, r1 187 * ----------------------------------------------------------- 188 */ 189func console_stm32_core_getc 190 /* Not supported */ 191 mov r0, #-1 192 bx lr 193endfunc console_stm32_core_getc 194 195 /* --------------------------------------------------------------- 196 * void console_core_flush(uintptr_t base_addr) 197 * 198 * Function to force a write of all buffered data that hasn't been 199 * output. 200 * 201 * In : r0 - console base address 202 * Out : void. 203 * Clobber list : r0, r1 204 * --------------------------------------------------------------- 205 */ 206func console_stm32_core_flush 207#if ENABLE_ASSERTIONS 208 cmp r0, #0 209 ASM_ASSERT(ne) 210#endif /* ENABLE_ASSERTIONS */ 211 /* Check Transmit Data Register Empty */ 212txe_loop_3: 213 ldr r1, [r0, #USART_ISR] 214 tst r1, #USART_ISR_TXE 215 beq txe_loop_3 216 bx lr 217endfunc console_stm32_core_flush 218 219 /* ------------------------------------------------------ 220 * void console_stm32_flush(console_t *console) 221 * Function to force a write of all buffered 222 * data that hasn't been output. 223 * In : r0 - pointer to console_t structure 224 * Out : void. 225 * Clobber list: r0, r1 226 * ------------------------------------------------------ 227 */ 228func console_stm32_flush 229#if ENABLE_ASSERTIONS 230 cmp r0, #0 231 ASM_ASSERT(ne) 232#endif /* ENABLE_ASSERTIONS */ 233 ldr r0, [r0, #CONSOLE_T_BASE] 234 b console_stm32_core_flush 235endfunc console_stm32_flush 236