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> 7*8244d226SYann Gautier#include <stm32_uart_regs.h> 84353bb20SYann Gautier 9278c34dfSYann Gautier#define USART_TIMEOUT 0x1000 10278c34dfSYann Gautier 114353bb20SYann Gautier .globl console_core_init 124353bb20SYann Gautier .globl console_core_putc 134353bb20SYann Gautier .globl console_core_getc 144353bb20SYann Gautier .globl console_core_flush 154353bb20SYann Gautier 164353bb20SYann Gautier /* ----------------------------------------------------------------- 174353bb20SYann Gautier * int console_core_init(uintptr_t base_addr, 184353bb20SYann Gautier * unsigned int uart_clk, 194353bb20SYann Gautier * unsigned int baud_rate) 204353bb20SYann Gautier * 214353bb20SYann Gautier * Function to initialize the console without a C Runtime to print 224353bb20SYann Gautier * debug information. This function will be accessed by console_init 234353bb20SYann Gautier * and crash reporting. 244353bb20SYann Gautier * 254353bb20SYann Gautier * In: r0 - console base address 264353bb20SYann Gautier * r1 - Uart clock in Hz 274353bb20SYann Gautier * r2 - Baud rate 284353bb20SYann Gautier * Out: return 1 on success else 0 on error 294353bb20SYann Gautier * Clobber list : r1, r2, r3 304353bb20SYann Gautier * ----------------------------------------------------------------- 314353bb20SYann Gautier */ 324353bb20SYann Gautierfunc console_core_init 33278c34dfSYann Gautier /* Check the input base address */ 34278c34dfSYann Gautier cmp r0, #0 35278c34dfSYann Gautier beq core_init_fail 36278c34dfSYann Gautier#if defined(IMAGE_BL2) 37278c34dfSYann Gautier /* Check baud rate and uart clock for sanity */ 38278c34dfSYann Gautier cmp r1, #0 39278c34dfSYann Gautier beq core_init_fail 40278c34dfSYann Gautier cmp r2, #0 41278c34dfSYann Gautier beq core_init_fail 42278c34dfSYann Gautier /* Disable UART */ 43278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 44278c34dfSYann Gautier bic r3, r3, #USART_CR1_UE 45278c34dfSYann Gautier str r3, [r0, #USART_CR1] 46278c34dfSYann Gautier /* Configure UART */ 47278c34dfSYann Gautier orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN) 48278c34dfSYann Gautier str r3, [r0, #USART_CR1] 49278c34dfSYann Gautier ldr r3, [r0, #USART_CR2] 50278c34dfSYann Gautier bic r3, r3, #USART_CR2_STOP 51278c34dfSYann Gautier str r3, [r0, #USART_CR2] 52278c34dfSYann Gautier /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */ 53278c34dfSYann Gautier lsl r3, r2, #1 54278c34dfSYann Gautier add r3, r1, r3 55278c34dfSYann Gautier udiv r3, r3, r2 56278c34dfSYann Gautier str r3, [r0, #USART_BRR] 57278c34dfSYann Gautier /* Enable UART */ 58278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 59278c34dfSYann Gautier orr r3, r3, #USART_CR1_UE 60278c34dfSYann Gautier str r3, [r0, #USART_CR1] 61278c34dfSYann Gautier /* Check TEACK bit */ 62278c34dfSYann Gautier mov r2, #USART_TIMEOUT 63278c34dfSYann Gautierteack_loop: 64278c34dfSYann Gautier subs r2, r2, #1 65278c34dfSYann Gautier beq core_init_fail 66278c34dfSYann Gautier ldr r3, [r0, #USART_ISR] 67278c34dfSYann Gautier tst r3, #USART_ISR_TEACK 68278c34dfSYann Gautier beq teack_loop 69278c34dfSYann Gautier#endif /* IMAGE_BL2 */ 70278c34dfSYann Gautier mov r0, #1 71278c34dfSYann Gautier bx lr 72278c34dfSYann Gautiercore_init_fail: 73278c34dfSYann Gautier mov r0, #0 744353bb20SYann Gautier bx lr 754353bb20SYann Gautierendfunc console_core_init 764353bb20SYann Gautier 774353bb20SYann Gautier /* --------------------------------------------------------------- 784353bb20SYann Gautier * int console_core_putc(int c, uintptr_t base_addr) 794353bb20SYann Gautier * 804353bb20SYann Gautier * Function to output a character over the console. It returns the 814353bb20SYann Gautier * character printed on success or -1 on error. 824353bb20SYann Gautier * 834353bb20SYann Gautier * In : r0 - character to be printed 844353bb20SYann Gautier * r1 - console base address 854353bb20SYann Gautier * Out : return -1 on error else return character. 864353bb20SYann Gautier * Clobber list : r2 874353bb20SYann Gautier * --------------------------------------------------------------- 884353bb20SYann Gautier */ 894353bb20SYann Gautierfunc console_core_putc 90278c34dfSYann Gautier /* Check the input parameter */ 91278c34dfSYann Gautier cmp r1, #0 92278c34dfSYann Gautier beq putc_error 93278c34dfSYann Gautier /* Prepend '\r' to '\n' */ 94278c34dfSYann Gautier cmp r0, #0xA 95278c34dfSYann Gautier bne 2f 96278c34dfSYann Gautier1: 97278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 98278c34dfSYann Gautiertxe_loop_1: 99278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 100278c34dfSYann Gautier tst r2, #USART_ISR_TXE 101278c34dfSYann Gautier beq txe_loop_1 102278c34dfSYann Gautier mov r2, #0xD 103278c34dfSYann Gautier str r2, [r1, #USART_TDR] 104278c34dfSYann Gautier /* Check transmit complete flag */ 105278c34dfSYann Gautiertc_loop_1: 106278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 107278c34dfSYann Gautier tst r2, #USART_ISR_TC 108278c34dfSYann Gautier beq tc_loop_1 109278c34dfSYann Gautier2: 110278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 111278c34dfSYann Gautiertxe_loop_2: 112278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 113278c34dfSYann Gautier tst r2, #USART_ISR_TXE 114278c34dfSYann Gautier beq txe_loop_2 115278c34dfSYann Gautier str r0, [r1, #USART_TDR] 116278c34dfSYann Gautier /* Check transmit complete flag */ 117278c34dfSYann Gautiertc_loop_2: 118278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 119278c34dfSYann Gautier tst r2, #USART_ISR_TC 120278c34dfSYann Gautier beq tc_loop_2 121278c34dfSYann Gautier bx lr 122278c34dfSYann Gautierputc_error: 123278c34dfSYann Gautier mov r0, #-1 1244353bb20SYann Gautier bx lr 1254353bb20SYann Gautierendfunc console_core_putc 1264353bb20SYann Gautier 1274353bb20SYann Gautier /* ----------------------------------------------------------- 1284353bb20SYann Gautier * int console_core_getc(uintptr_t base_addr) 1294353bb20SYann Gautier * 1304353bb20SYann Gautier * Function to get a character from the console. 1314353bb20SYann Gautier * It returns the character grabbed on success or -1 on error. 1324353bb20SYann Gautier * 1334353bb20SYann Gautier * In : r0 - console base address 1344353bb20SYann Gautier * Out : return -1. 1354353bb20SYann Gautier * Clobber list : r0, r1 1364353bb20SYann Gautier * ----------------------------------------------------------- 1374353bb20SYann Gautier */ 1384353bb20SYann Gautierfunc console_core_getc 1394353bb20SYann Gautier /* Not supported */ 1404353bb20SYann Gautier mov r0, #-1 1414353bb20SYann Gautier bx lr 1424353bb20SYann Gautierendfunc console_core_getc 1434353bb20SYann Gautier 1444353bb20SYann Gautier /* --------------------------------------------------------------- 1454353bb20SYann Gautier * int console_core_flush(uintptr_t base_addr) 1464353bb20SYann Gautier * 1474353bb20SYann Gautier * Function to force a write of all buffered data that hasn't been 1484353bb20SYann Gautier * output. 1494353bb20SYann Gautier * 1504353bb20SYann Gautier * In : r0 - console base address 1514353bb20SYann Gautier * Out : return -1 on error else return 0. 1524353bb20SYann Gautier * Clobber list : r0, r1 1534353bb20SYann Gautier * --------------------------------------------------------------- 1544353bb20SYann Gautier */ 1554353bb20SYann Gautierfunc console_core_flush 156278c34dfSYann Gautier cmp r0, #0 157278c34dfSYann Gautier beq flush_error 158278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 159278c34dfSYann Gautiertxe_loop_3: 160278c34dfSYann Gautier ldr r1, [r0, #USART_ISR] 161278c34dfSYann Gautier tst r1, #USART_ISR_TXE 162278c34dfSYann Gautier beq txe_loop_3 163278c34dfSYann Gautier mov r0, #0 164278c34dfSYann Gautier bx lr 165278c34dfSYann Gautierflush_error: 166278c34dfSYann Gautier mov r0, #-1 1674353bb20SYann Gautier bx lr 1684353bb20SYann Gautierendfunc console_core_flush 169