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 8#define USART_TIMEOUT 0x1000 9 10#define USART_CR1 0x00 11#define USART_CR1_UE 0x00000001 12#define USART_CR1_TE 0x00000008 13#define USART_CR1_FIFOEN 0x20000000 14 15#define USART_CR2 0x04 16#define USART_CR2_STOP 0x00003000 17 18#define USART_BRR 0x0C 19 20#define USART_ISR 0x1C 21#define USART_ISR_TC 0x00000040 22#define USART_ISR_TXE 0x00000080 23#define USART_ISR_TEACK 0x00200000 24 25#define USART_TDR 0x28 26 27 .globl console_core_init 28 .globl console_core_putc 29 .globl console_core_getc 30 .globl console_core_flush 31 32 /* ----------------------------------------------------------------- 33 * int console_core_init(uintptr_t base_addr, 34 * unsigned int uart_clk, 35 * unsigned int baud_rate) 36 * 37 * Function to initialize the console without a C Runtime to print 38 * debug information. This function will be accessed by console_init 39 * and crash reporting. 40 * 41 * In: r0 - console base address 42 * r1 - Uart clock in Hz 43 * r2 - Baud rate 44 * Out: return 1 on success else 0 on error 45 * Clobber list : r1, r2, r3 46 * ----------------------------------------------------------------- 47 */ 48func console_core_init 49 /* Check the input base address */ 50 cmp r0, #0 51 beq core_init_fail 52#if defined(IMAGE_BL2) 53 /* Check baud rate and uart clock for sanity */ 54 cmp r1, #0 55 beq core_init_fail 56 cmp r2, #0 57 beq core_init_fail 58 /* Disable UART */ 59 ldr r3, [r0, #USART_CR1] 60 bic r3, r3, #USART_CR1_UE 61 str r3, [r0, #USART_CR1] 62 /* Configure UART */ 63 orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN) 64 str r3, [r0, #USART_CR1] 65 ldr r3, [r0, #USART_CR2] 66 bic r3, r3, #USART_CR2_STOP 67 str r3, [r0, #USART_CR2] 68 /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */ 69 lsl r3, r2, #1 70 add r3, r1, r3 71 udiv r3, r3, r2 72 str r3, [r0, #USART_BRR] 73 /* Enable UART */ 74 ldr r3, [r0, #USART_CR1] 75 orr r3, r3, #USART_CR1_UE 76 str r3, [r0, #USART_CR1] 77 /* Check TEACK bit */ 78 mov r2, #USART_TIMEOUT 79teack_loop: 80 subs r2, r2, #1 81 beq core_init_fail 82 ldr r3, [r0, #USART_ISR] 83 tst r3, #USART_ISR_TEACK 84 beq teack_loop 85#endif /* IMAGE_BL2 */ 86 mov r0, #1 87 bx lr 88core_init_fail: 89 mov r0, #0 90 bx lr 91endfunc console_core_init 92 93 /* --------------------------------------------------------------- 94 * int console_core_putc(int c, uintptr_t base_addr) 95 * 96 * Function to output a character over the console. It returns the 97 * character printed on success or -1 on error. 98 * 99 * In : r0 - character to be printed 100 * r1 - console base address 101 * Out : return -1 on error else return character. 102 * Clobber list : r2 103 * --------------------------------------------------------------- 104 */ 105func console_core_putc 106 /* Check the input parameter */ 107 cmp r1, #0 108 beq putc_error 109 /* Prepend '\r' to '\n' */ 110 cmp r0, #0xA 111 bne 2f 1121: 113 /* Check Transmit Data Register Empty */ 114txe_loop_1: 115 ldr r2, [r1, #USART_ISR] 116 tst r2, #USART_ISR_TXE 117 beq txe_loop_1 118 mov r2, #0xD 119 str r2, [r1, #USART_TDR] 120 /* Check transmit complete flag */ 121tc_loop_1: 122 ldr r2, [r1, #USART_ISR] 123 tst r2, #USART_ISR_TC 124 beq tc_loop_1 1252: 126 /* Check Transmit Data Register Empty */ 127txe_loop_2: 128 ldr r2, [r1, #USART_ISR] 129 tst r2, #USART_ISR_TXE 130 beq txe_loop_2 131 str r0, [r1, #USART_TDR] 132 /* Check transmit complete flag */ 133tc_loop_2: 134 ldr r2, [r1, #USART_ISR] 135 tst r2, #USART_ISR_TC 136 beq tc_loop_2 137 bx lr 138putc_error: 139 mov r0, #-1 140 bx lr 141endfunc console_core_putc 142 143 /* ----------------------------------------------------------- 144 * int console_core_getc(uintptr_t base_addr) 145 * 146 * Function to get a character from the console. 147 * It returns the character grabbed on success or -1 on error. 148 * 149 * In : r0 - console base address 150 * Out : return -1. 151 * Clobber list : r0, r1 152 * ----------------------------------------------------------- 153 */ 154func console_core_getc 155 /* Not supported */ 156 mov r0, #-1 157 bx lr 158endfunc console_core_getc 159 160 /* --------------------------------------------------------------- 161 * int console_core_flush(uintptr_t base_addr) 162 * 163 * Function to force a write of all buffered data that hasn't been 164 * output. 165 * 166 * In : r0 - console base address 167 * Out : return -1 on error else return 0. 168 * Clobber list : r0, r1 169 * --------------------------------------------------------------- 170 */ 171func console_core_flush 172 cmp r0, #0 173 beq flush_error 174 /* Check Transmit Data Register Empty */ 175txe_loop_3: 176 ldr r1, [r0, #USART_ISR] 177 tst r1, #USART_ISR_TXE 178 beq txe_loop_3 179 mov r0, #0 180 bx lr 181flush_error: 182 mov r0, #-1 183 bx lr 184endfunc console_core_flush 185