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> 74353bb20SYann Gautier 8*278c34dfSYann Gautier#define USART_TIMEOUT 0x1000 9*278c34dfSYann Gautier 10*278c34dfSYann Gautier#define USART_CR1 0x00 11*278c34dfSYann Gautier#define USART_CR1_UE 0x00000001 12*278c34dfSYann Gautier#define USART_CR1_TE 0x00000008 13*278c34dfSYann Gautier#define USART_CR1_FIFOEN 0x20000000 14*278c34dfSYann Gautier 15*278c34dfSYann Gautier#define USART_CR2 0x04 16*278c34dfSYann Gautier#define USART_CR2_STOP 0x00003000 17*278c34dfSYann Gautier 18*278c34dfSYann Gautier#define USART_BRR 0x0C 19*278c34dfSYann Gautier 20*278c34dfSYann Gautier#define USART_ISR 0x1C 21*278c34dfSYann Gautier#define USART_ISR_TC 0x00000040 22*278c34dfSYann Gautier#define USART_ISR_TXE 0x00000080 23*278c34dfSYann Gautier#define USART_ISR_TEACK 0x00200000 24*278c34dfSYann Gautier 25*278c34dfSYann Gautier#define USART_TDR 0x28 26*278c34dfSYann Gautier 274353bb20SYann Gautier .globl console_core_init 284353bb20SYann Gautier .globl console_core_putc 294353bb20SYann Gautier .globl console_core_getc 304353bb20SYann Gautier .globl console_core_flush 314353bb20SYann Gautier 324353bb20SYann Gautier /* ----------------------------------------------------------------- 334353bb20SYann Gautier * int console_core_init(uintptr_t base_addr, 344353bb20SYann Gautier * unsigned int uart_clk, 354353bb20SYann Gautier * unsigned int baud_rate) 364353bb20SYann Gautier * 374353bb20SYann Gautier * Function to initialize the console without a C Runtime to print 384353bb20SYann Gautier * debug information. This function will be accessed by console_init 394353bb20SYann Gautier * and crash reporting. 404353bb20SYann Gautier * 414353bb20SYann Gautier * In: r0 - console base address 424353bb20SYann Gautier * r1 - Uart clock in Hz 434353bb20SYann Gautier * r2 - Baud rate 444353bb20SYann Gautier * Out: return 1 on success else 0 on error 454353bb20SYann Gautier * Clobber list : r1, r2, r3 464353bb20SYann Gautier * ----------------------------------------------------------------- 474353bb20SYann Gautier */ 484353bb20SYann Gautierfunc console_core_init 49*278c34dfSYann Gautier /* Check the input base address */ 50*278c34dfSYann Gautier cmp r0, #0 51*278c34dfSYann Gautier beq core_init_fail 52*278c34dfSYann Gautier#if defined(IMAGE_BL2) 53*278c34dfSYann Gautier /* Check baud rate and uart clock for sanity */ 54*278c34dfSYann Gautier cmp r1, #0 55*278c34dfSYann Gautier beq core_init_fail 56*278c34dfSYann Gautier cmp r2, #0 57*278c34dfSYann Gautier beq core_init_fail 58*278c34dfSYann Gautier /* Disable UART */ 59*278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 60*278c34dfSYann Gautier bic r3, r3, #USART_CR1_UE 61*278c34dfSYann Gautier str r3, [r0, #USART_CR1] 62*278c34dfSYann Gautier /* Configure UART */ 63*278c34dfSYann Gautier orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN) 64*278c34dfSYann Gautier str r3, [r0, #USART_CR1] 65*278c34dfSYann Gautier ldr r3, [r0, #USART_CR2] 66*278c34dfSYann Gautier bic r3, r3, #USART_CR2_STOP 67*278c34dfSYann Gautier str r3, [r0, #USART_CR2] 68*278c34dfSYann Gautier /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */ 69*278c34dfSYann Gautier lsl r3, r2, #1 70*278c34dfSYann Gautier add r3, r1, r3 71*278c34dfSYann Gautier udiv r3, r3, r2 72*278c34dfSYann Gautier str r3, [r0, #USART_BRR] 73*278c34dfSYann Gautier /* Enable UART */ 74*278c34dfSYann Gautier ldr r3, [r0, #USART_CR1] 75*278c34dfSYann Gautier orr r3, r3, #USART_CR1_UE 76*278c34dfSYann Gautier str r3, [r0, #USART_CR1] 77*278c34dfSYann Gautier /* Check TEACK bit */ 78*278c34dfSYann Gautier mov r2, #USART_TIMEOUT 79*278c34dfSYann Gautierteack_loop: 80*278c34dfSYann Gautier subs r2, r2, #1 81*278c34dfSYann Gautier beq core_init_fail 82*278c34dfSYann Gautier ldr r3, [r0, #USART_ISR] 83*278c34dfSYann Gautier tst r3, #USART_ISR_TEACK 84*278c34dfSYann Gautier beq teack_loop 85*278c34dfSYann Gautier#endif /* IMAGE_BL2 */ 86*278c34dfSYann Gautier mov r0, #1 87*278c34dfSYann Gautier bx lr 88*278c34dfSYann Gautiercore_init_fail: 89*278c34dfSYann Gautier mov r0, #0 904353bb20SYann Gautier bx lr 914353bb20SYann Gautierendfunc console_core_init 924353bb20SYann Gautier 934353bb20SYann Gautier /* --------------------------------------------------------------- 944353bb20SYann Gautier * int console_core_putc(int c, uintptr_t base_addr) 954353bb20SYann Gautier * 964353bb20SYann Gautier * Function to output a character over the console. It returns the 974353bb20SYann Gautier * character printed on success or -1 on error. 984353bb20SYann Gautier * 994353bb20SYann Gautier * In : r0 - character to be printed 1004353bb20SYann Gautier * r1 - console base address 1014353bb20SYann Gautier * Out : return -1 on error else return character. 1024353bb20SYann Gautier * Clobber list : r2 1034353bb20SYann Gautier * --------------------------------------------------------------- 1044353bb20SYann Gautier */ 1054353bb20SYann Gautierfunc console_core_putc 106*278c34dfSYann Gautier /* Check the input parameter */ 107*278c34dfSYann Gautier cmp r1, #0 108*278c34dfSYann Gautier beq putc_error 109*278c34dfSYann Gautier /* Prepend '\r' to '\n' */ 110*278c34dfSYann Gautier cmp r0, #0xA 111*278c34dfSYann Gautier bne 2f 112*278c34dfSYann Gautier1: 113*278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 114*278c34dfSYann Gautiertxe_loop_1: 115*278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 116*278c34dfSYann Gautier tst r2, #USART_ISR_TXE 117*278c34dfSYann Gautier beq txe_loop_1 118*278c34dfSYann Gautier mov r2, #0xD 119*278c34dfSYann Gautier str r2, [r1, #USART_TDR] 120*278c34dfSYann Gautier /* Check transmit complete flag */ 121*278c34dfSYann Gautiertc_loop_1: 122*278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 123*278c34dfSYann Gautier tst r2, #USART_ISR_TC 124*278c34dfSYann Gautier beq tc_loop_1 125*278c34dfSYann Gautier2: 126*278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 127*278c34dfSYann Gautiertxe_loop_2: 128*278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 129*278c34dfSYann Gautier tst r2, #USART_ISR_TXE 130*278c34dfSYann Gautier beq txe_loop_2 131*278c34dfSYann Gautier str r0, [r1, #USART_TDR] 132*278c34dfSYann Gautier /* Check transmit complete flag */ 133*278c34dfSYann Gautiertc_loop_2: 134*278c34dfSYann Gautier ldr r2, [r1, #USART_ISR] 135*278c34dfSYann Gautier tst r2, #USART_ISR_TC 136*278c34dfSYann Gautier beq tc_loop_2 137*278c34dfSYann Gautier bx lr 138*278c34dfSYann Gautierputc_error: 139*278c34dfSYann Gautier mov r0, #-1 1404353bb20SYann Gautier bx lr 1414353bb20SYann Gautierendfunc console_core_putc 1424353bb20SYann Gautier 1434353bb20SYann Gautier /* ----------------------------------------------------------- 1444353bb20SYann Gautier * int console_core_getc(uintptr_t base_addr) 1454353bb20SYann Gautier * 1464353bb20SYann Gautier * Function to get a character from the console. 1474353bb20SYann Gautier * It returns the character grabbed on success or -1 on error. 1484353bb20SYann Gautier * 1494353bb20SYann Gautier * In : r0 - console base address 1504353bb20SYann Gautier * Out : return -1. 1514353bb20SYann Gautier * Clobber list : r0, r1 1524353bb20SYann Gautier * ----------------------------------------------------------- 1534353bb20SYann Gautier */ 1544353bb20SYann Gautierfunc console_core_getc 1554353bb20SYann Gautier /* Not supported */ 1564353bb20SYann Gautier mov r0, #-1 1574353bb20SYann Gautier bx lr 1584353bb20SYann Gautierendfunc console_core_getc 1594353bb20SYann Gautier 1604353bb20SYann Gautier /* --------------------------------------------------------------- 1614353bb20SYann Gautier * int console_core_flush(uintptr_t base_addr) 1624353bb20SYann Gautier * 1634353bb20SYann Gautier * Function to force a write of all buffered data that hasn't been 1644353bb20SYann Gautier * output. 1654353bb20SYann Gautier * 1664353bb20SYann Gautier * In : r0 - console base address 1674353bb20SYann Gautier * Out : return -1 on error else return 0. 1684353bb20SYann Gautier * Clobber list : r0, r1 1694353bb20SYann Gautier * --------------------------------------------------------------- 1704353bb20SYann Gautier */ 1714353bb20SYann Gautierfunc console_core_flush 172*278c34dfSYann Gautier cmp r0, #0 173*278c34dfSYann Gautier beq flush_error 174*278c34dfSYann Gautier /* Check Transmit Data Register Empty */ 175*278c34dfSYann Gautiertxe_loop_3: 176*278c34dfSYann Gautier ldr r1, [r0, #USART_ISR] 177*278c34dfSYann Gautier tst r1, #USART_ISR_TXE 178*278c34dfSYann Gautier beq txe_loop_3 179*278c34dfSYann Gautier mov r0, #0 180*278c34dfSYann Gautier bx lr 181*278c34dfSYann Gautierflush_error: 182*278c34dfSYann Gautier mov r0, #-1 1834353bb20SYann Gautier bx lr 1844353bb20SYann Gautierendfunc console_core_flush 185