14353bb20SYann Gautier/* 24353bb20SYann Gautier * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 34353bb20SYann Gautier * 44353bb20SYann Gautier * SPDX-License-Identifier: BSD-3-Clause 54353bb20SYann Gautier */ 64353bb20SYann Gautier#include <asm_macros.S> 76d264afcSYann Gautier#include <assert_macros.S> 86d264afcSYann Gautier#define USE_FINISH_CONSOLE_REG_2 96d264afcSYann Gautier#include <console_macros.S> 10*09d40e0eSAntonio Nino Diaz#include <drivers/st/stm32_console.h> 11*09d40e0eSAntonio Nino Diaz#include <drivers/st/stm32_uart_regs.h> 124353bb20SYann Gautier 13278c34dfSYann Gautier#define USART_TIMEOUT 0x1000 14278c34dfSYann Gautier 156d264afcSYann Gautier /* 166d264afcSYann Gautier * "core" functions are low-level implementations that don't require 176d264afcSYann Gautier * writeable memory and are thus safe to call in BL1 crash context. 186d264afcSYann Gautier */ 196d264afcSYann Gautier .globl console_stm32_core_init 206d264afcSYann Gautier .globl console_stm32_core_putc 216d264afcSYann Gautier .globl console_stm32_core_getc 226d264afcSYann Gautier .globl console_stm32_core_flush 236d264afcSYann Gautier 246d264afcSYann Gautier .globl console_stm32_putc 256d264afcSYann Gautier .globl console_stm32_flush 266d264afcSYann Gautier 276d264afcSYann Gautier 284353bb20SYann Gautier 294353bb20SYann Gautier /* ----------------------------------------------------------------- 304353bb20SYann Gautier * int console_core_init(uintptr_t base_addr, 314353bb20SYann Gautier * unsigned int uart_clk, 324353bb20SYann Gautier * unsigned int baud_rate) 334353bb20SYann Gautier * 344353bb20SYann Gautier * Function to initialize the console without a C Runtime to print 354353bb20SYann Gautier * debug information. This function will be accessed by console_init 364353bb20SYann Gautier * and crash reporting. 374353bb20SYann Gautier * 384353bb20SYann Gautier * In: r0 - console base address 394353bb20SYann Gautier * r1 - Uart clock in Hz 404353bb20SYann Gautier * r2 - Baud rate 414353bb20SYann Gautier * Out: return 1 on success else 0 on error 424353bb20SYann Gautier * Clobber list : r1, r2, r3 434353bb20SYann Gautier * ----------------------------------------------------------------- 444353bb20SYann Gautier */ 456d264afcSYann Gautierfunc console_stm32_core_init 46278c34dfSYann Gautier /* Check the input base address */ 47278c34dfSYann Gautier cmp r0, #0 48278c34dfSYann Gautier beq core_init_fail 49278c34dfSYann Gautier#if defined(IMAGE_BL2) 50278c34dfSYann Gautier /* Check baud rate and uart clock for sanity */ 51278c34dfSYann Gautier cmp r1, #0 52278c34dfSYann Gautier beq core_init_fail 53278c34dfSYann Gautier cmp r2, #0 54278c34dfSYann Gautier beq core_init_fail 55278c34dfSYann Gautier /* Disable UART */ 56278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 57278c34dfSYann Gautier bic r3, r3, #USART_CR1_UE 58278c34dfSYann Gautier str r3, [r0, #USART_CR1] 59278c34dfSYann Gautier /* Configure UART */ 60278c34dfSYann Gautier orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN) 61278c34dfSYann Gautier str r3, [r0, #USART_CR1] 62278c34dfSYann Gautier ldr r3, [r0, #USART_CR2] 63278c34dfSYann Gautier bic r3, r3, #USART_CR2_STOP 64278c34dfSYann Gautier str r3, [r0, #USART_CR2] 65278c34dfSYann Gautier /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */ 66278c34dfSYann Gautier lsl r3, r2, #1 67278c34dfSYann Gautier add r3, r1, r3 68278c34dfSYann Gautier udiv r3, r3, r2 69278c34dfSYann Gautier str r3, [r0, #USART_BRR] 70278c34dfSYann Gautier /* Enable UART */ 71278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 72278c34dfSYann Gautier orr r3, r3, #USART_CR1_UE 73278c34dfSYann Gautier str r3, [r0, #USART_CR1] 74278c34dfSYann Gautier /* Check TEACK bit */ 75278c34dfSYann Gautier mov r2, #USART_TIMEOUT 76278c34dfSYann Gautierteack_loop: 77278c34dfSYann Gautier subs r2, r2, #1 78278c34dfSYann Gautier beq core_init_fail 79278c34dfSYann Gautier ldr r3, [r0, #USART_ISR] 80278c34dfSYann Gautier tst r3, #USART_ISR_TEACK 81278c34dfSYann Gautier beq teack_loop 82278c34dfSYann Gautier#endif /* IMAGE_BL2 */ 83278c34dfSYann Gautier mov r0, #1 84278c34dfSYann Gautier bx lr 85278c34dfSYann Gautiercore_init_fail: 86278c34dfSYann Gautier mov r0, #0 874353bb20SYann Gautier bx lr 886d264afcSYann Gautierendfunc console_stm32_core_init 896d264afcSYann Gautier 906d264afcSYann Gautier .globl console_stm32_register 916d264afcSYann Gautier 926d264afcSYann Gautier /* ------------------------------------------------------- 936d264afcSYann Gautier * int console_stm32_register(uintptr_t baseaddr, 946d264afcSYann Gautier * uint32_t clock, uint32_t baud, 956d264afcSYann Gautier * struct console_stm32 *console); 966d264afcSYann Gautier * Function to initialize and register a new STM32 976d264afcSYann Gautier * console. Storage passed in for the console struct 986d264afcSYann Gautier * *must* be persistent (i.e. not from the stack). 996d264afcSYann Gautier * In: r0 - UART register base address 1006d264afcSYann Gautier * r1 - UART clock in Hz 1016d264afcSYann Gautier * r2 - Baud rate 1026d264afcSYann Gautier * r3 - pointer to empty console_stm32 struct 1036d264afcSYann Gautier * Out: return 1 on success, 0 on error 1046d264afcSYann Gautier * Clobber list : r0, r1, r2 1056d264afcSYann Gautier * ------------------------------------------------------- 1066d264afcSYann Gautier */ 1076d264afcSYann Gautierfunc console_stm32_register 1086d264afcSYann Gautier push {r4, lr} 1096d264afcSYann Gautier mov r4, r3 1106d264afcSYann Gautier cmp r4, #0 1116d264afcSYann Gautier beq register_fail 1126d264afcSYann Gautier str r0, [r4, #CONSOLE_T_STM32_BASE] 1136d264afcSYann Gautier 1146d264afcSYann Gautier bl console_stm32_core_init 1156d264afcSYann Gautier cmp r0, #0 1166d264afcSYann Gautier beq register_fail 1176d264afcSYann Gautier 1186d264afcSYann Gautier mov r0, r4 1196d264afcSYann Gautier pop {r4, lr} 1206d264afcSYann Gautier finish_console_register stm32 putc=1, getc=0, flush=1 1216d264afcSYann Gautier 1226d264afcSYann Gautierregister_fail: 1236d264afcSYann Gautier pop {r4, pc} 1246d264afcSYann Gautierendfunc console_stm32_register 1254353bb20SYann Gautier 1264353bb20SYann Gautier /* --------------------------------------------------------------- 1274353bb20SYann Gautier * int console_core_putc(int c, uintptr_t base_addr) 1284353bb20SYann Gautier * 1294353bb20SYann Gautier * Function to output a character over the console. It returns the 1304353bb20SYann Gautier * character printed on success or -1 on error. 1314353bb20SYann Gautier * 1324353bb20SYann Gautier * In : r0 - character to be printed 1334353bb20SYann Gautier * r1 - console base address 1344353bb20SYann Gautier * Out : return -1 on error else return character. 1354353bb20SYann Gautier * Clobber list : r2 1364353bb20SYann Gautier * --------------------------------------------------------------- 1374353bb20SYann Gautier */ 1386d264afcSYann Gautierfunc console_stm32_core_putc 139278c34dfSYann Gautier /* Check the input parameter */ 140278c34dfSYann Gautier cmp r1, #0 141278c34dfSYann Gautier beq putc_error 142278c34dfSYann Gautier /* Prepend '\r' to '\n' */ 143278c34dfSYann Gautier cmp r0, #0xA 144278c34dfSYann Gautier bne 2f 145278c34dfSYann Gautier1: 146278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 147278c34dfSYann Gautiertxe_loop_1: 148278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 149278c34dfSYann Gautier tst r2, #USART_ISR_TXE 150278c34dfSYann Gautier beq txe_loop_1 151278c34dfSYann Gautier mov r2, #0xD 152278c34dfSYann Gautier str r2, [r1, #USART_TDR] 153278c34dfSYann Gautier /* Check transmit complete flag */ 154278c34dfSYann Gautiertc_loop_1: 155278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 156278c34dfSYann Gautier tst r2, #USART_ISR_TC 157278c34dfSYann Gautier beq tc_loop_1 158278c34dfSYann Gautier2: 159278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 160278c34dfSYann Gautiertxe_loop_2: 161278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 162278c34dfSYann Gautier tst r2, #USART_ISR_TXE 163278c34dfSYann Gautier beq txe_loop_2 164278c34dfSYann Gautier str r0, [r1, #USART_TDR] 165278c34dfSYann Gautier /* Check transmit complete flag */ 166278c34dfSYann Gautiertc_loop_2: 167278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 168278c34dfSYann Gautier tst r2, #USART_ISR_TC 169278c34dfSYann Gautier beq tc_loop_2 170278c34dfSYann Gautier bx lr 171278c34dfSYann Gautierputc_error: 172278c34dfSYann Gautier mov r0, #-1 1734353bb20SYann Gautier bx lr 1746d264afcSYann Gautierendfunc console_stm32_core_putc 1756d264afcSYann Gautier 1766d264afcSYann Gautier /* ------------------------------------------------------------ 1776d264afcSYann Gautier * int console_stm32_putc(int c, struct console_stm32 *console) 1786d264afcSYann Gautier * Function to output a character over the console. It 1796d264afcSYann Gautier * returns the character printed on success or -1 on error. 1806d264afcSYann Gautier * In: r0 - character to be printed 1816d264afcSYann Gautier * r1 - pointer to console_t structure 1826d264afcSYann Gautier * Out : return -1 on error else return character. 1836d264afcSYann Gautier * Clobber list: r2 1846d264afcSYann Gautier * ------------------------------------------------------------ 1856d264afcSYann Gautier */ 1866d264afcSYann Gautierfunc console_stm32_putc 1876d264afcSYann Gautier#if ENABLE_ASSERTIONS 1886d264afcSYann Gautier cmp r1, #0 1896d264afcSYann Gautier ASM_ASSERT(ne) 1906d264afcSYann Gautier#endif /* ENABLE_ASSERTIONS */ 1916d264afcSYann Gautier ldr r1, [r1, #CONSOLE_T_STM32_BASE] 1926d264afcSYann Gautier b console_stm32_core_putc 1936d264afcSYann Gautierendfunc console_stm32_putc 1944353bb20SYann Gautier 1954353bb20SYann Gautier /* ----------------------------------------------------------- 1964353bb20SYann Gautier * int console_core_getc(uintptr_t base_addr) 1974353bb20SYann Gautier * 1984353bb20SYann Gautier * Function to get a character from the console. 1994353bb20SYann Gautier * It returns the character grabbed on success or -1 on error. 2004353bb20SYann Gautier * 2014353bb20SYann Gautier * In : r0 - console base address 2024353bb20SYann Gautier * Out : return -1. 2034353bb20SYann Gautier * Clobber list : r0, r1 2044353bb20SYann Gautier * ----------------------------------------------------------- 2054353bb20SYann Gautier */ 2066d264afcSYann Gautierfunc console_stm32_core_getc 2074353bb20SYann Gautier /* Not supported */ 2084353bb20SYann Gautier mov r0, #-1 2094353bb20SYann Gautier bx lr 2106d264afcSYann Gautierendfunc console_stm32_core_getc 2114353bb20SYann Gautier 2124353bb20SYann Gautier /* --------------------------------------------------------------- 2134353bb20SYann Gautier * int console_core_flush(uintptr_t base_addr) 2144353bb20SYann Gautier * 2154353bb20SYann Gautier * Function to force a write of all buffered data that hasn't been 2164353bb20SYann Gautier * output. 2174353bb20SYann Gautier * 2184353bb20SYann Gautier * In : r0 - console base address 2194353bb20SYann Gautier * Out : return -1 on error else return 0. 2204353bb20SYann Gautier * Clobber list : r0, r1 2214353bb20SYann Gautier * --------------------------------------------------------------- 2224353bb20SYann Gautier */ 2236d264afcSYann Gautierfunc console_stm32_core_flush 224278c34dfSYann Gautier cmp r0, #0 225278c34dfSYann Gautier beq flush_error 226278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 227278c34dfSYann Gautiertxe_loop_3: 228278c34dfSYann Gautier ldr r1, [r0, #USART_ISR] 229278c34dfSYann Gautier tst r1, #USART_ISR_TXE 230278c34dfSYann Gautier beq txe_loop_3 231278c34dfSYann Gautier mov r0, #0 232278c34dfSYann Gautier bx lr 233278c34dfSYann Gautierflush_error: 234278c34dfSYann Gautier mov r0, #-1 2354353bb20SYann Gautier bx lr 2366d264afcSYann Gautierendfunc console_stm32_core_flush 2376d264afcSYann Gautier 2386d264afcSYann Gautier /* ------------------------------------------------------ 2396d264afcSYann Gautier * int console_stm32_flush(struct console_stm32 *console) 2406d264afcSYann Gautier * Function to force a write of all buffered 2416d264afcSYann Gautier * data that hasn't been output. 2426d264afcSYann Gautier * In : r0 - pointer to console_t structure 2436d264afcSYann Gautier * Out : return -1 on error else return 0. 2446d264afcSYann Gautier * Clobber list: r0, r1 2456d264afcSYann Gautier * ------------------------------------------------------ 2466d264afcSYann Gautier */ 2476d264afcSYann Gautierfunc console_stm32_flush 2486d264afcSYann Gautier#if ENABLE_ASSERTIONS 2496d264afcSYann Gautier cmp r0, #0 2506d264afcSYann Gautier ASM_ASSERT(ne) 2516d264afcSYann Gautier#endif /* ENABLE_ASSERTIONS */ 2526d264afcSYann Gautier ldr r0, [r0, #CONSOLE_T_STM32_BASE] 2536d264afcSYann Gautier b console_stm32_core_flush 2546d264afcSYann Gautierendfunc console_stm32_flush 255